Skip to content

Commit

Permalink
add news section to eyg
Browse files Browse the repository at this point in the history
  • Loading branch information
CrowdHailer committed Aug 24, 2024
1 parent 3728488 commit 8ff5758
Show file tree
Hide file tree
Showing 11 changed files with 671 additions and 11 deletions.
7 changes: 5 additions & 2 deletions eyg/gleam.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ gleam_bitwise = "~> 1.2"
lustre = "~> 4.0"
gleam_json = ">= 1.0.0 and < 3.0.0"
gleam_fetch = "~> 1.0"
plinth = ">= 0.4.5 and < 1.0.0"
plinth = ">= 0.4.9 and < 1.0.0"
# plinth = {path= "../../plinth"}
simplifile = "~> 1.0"
gleam_http = "~> 3.5"
gleam_community_codec = {path= "../../codec"}
midas = ">= 0.4.2 and < 1.0.0"
# midas = ">= 0.4.4 and < 1.0.0"
midas = {path= "../../midas"}
snag = ">= 0.3.0 and < 1.0.0"
jot = ">= 1.0.1 and < 2.0.0"


[dev-dependencies]
Expand Down
47 changes: 47 additions & 0 deletions eyg/layout2.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* https://css-tricks.com/box-sizing/#aa-universal-box-sizing-with-inheritance */
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}

.vstack {
display: flex;
flex-direction: column;
align-items: center;
min-height: 100%;
justify-content: center;
}

body > .vstack, body.vstack {
min-height: 100vh;
}

.vstack>*.expand {
flex-grow: 1;
}

.vstack>*.cover {
align-self: stretch;
}

.hstack {
display: flex;
/* not sure why this needs width 100% but vstack is flex grow */
width: 100%;
align-items: center;
justify-content: center;
}

body>.hstack {
min-height: 100vh;
}

.hstack>*.expand {
flex-grow: 1;
}

.hstack>*.cover {
align-self: stretch;
}
21 changes: 12 additions & 9 deletions eyg/manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ packages = [
{ name = "gleam_erlang", version = "0.25.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "054D571A7092D2A9727B3E5D183B7507DAB0DA41556EC9133606F09C15497373" },
{ name = "gleam_fetch", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_http", "gleam_javascript", "gleam_stdlib"], otp_app = "gleam_fetch", source = "hex", outer_checksum = "4AE60B21A9A664137A79B1BEB93F751CB27F1DDED4086CA00C0260F5FFACBD80" },
{ name = "gleam_http", version = "3.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "8C07DF9DF8CC7F054C650839A51C30A7D3C26482AC241C899C1CEA86B22DBE51" },
{ name = "gleam_javascript", version = "0.8.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_javascript", source = "hex", outer_checksum = "14D5B7E1A70681E0776BF0A0357F575B822167960C844D3D3FA114D3A75F05A8" },
{ name = "gleam_javascript", version = "0.11.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_javascript", source = "hex", outer_checksum = "483631D3001FCE8EB12ADEAD5E1B808440038E96F93DA7A32D326C82F480C0B2" },
{ name = "gleam_json", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "9063D14D25406326C0255BDA0021541E797D8A7A12573D849462CAFED459F6EB" },
{ name = "gleam_otp", version = "0.10.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "0B04FE915ACECE539B317F9652CAADBBC0F000184D586AAAF2D94C100945D72B" },
{ name = "gleam_stdlib", version = "0.38.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "663CF11861179AF415A625307447775C09404E752FF99A24E2057C835319F1BE" },
{ name = "gleeunit", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "72CDC3D3F719478F26C4E2C5FED3E657AC81EC14A47D2D2DEBB8693CA3220C3B" },
{ name = "lustre", version = "4.2.6", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_json", "gleam_otp", "gleam_stdlib"], otp_app = "lustre", source = "hex", outer_checksum = "9ABD71D63F4B8F362CB824DED2C4CA64895DEFACD8F22B0FF055BF15241B1AE2" },
{ name = "midas", version = "0.4.2", build_tools = ["gleam"], requirements = ["gleam_http", "gleam_json", "gleam_stdlib", "snag"], otp_app = "midas", source = "hex", outer_checksum = "5F57A50A9B9612EF4E965D32445CD16F35EB35C08ABEDEE06DF7A785566229BB" },
{ name = "plinth", version = "0.4.5", build_tools = ["gleam"], requirements = ["conversation", "gleam_javascript", "gleam_json", "gleam_stdlib"], otp_app = "plinth", source = "hex", outer_checksum = "D0C8D885C08B76F1C17EBF40D0C145D244D0AD928275E9B19313C03E5156491B" },
{ name = "gleam_otp", version = "0.11.1", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "54C04621B3B5C8E5AE5DC7EF250EEA3C9109FB4F729723A865E41211E77EBEE0" },
{ name = "gleam_stdlib", version = "0.39.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "2D7DE885A6EA7F1D5015D1698920C9BAF7241102836CE0C3837A4F160128A9C4" },
{ name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" },
{ name = "jot", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "jot", source = "hex", outer_checksum = "A0A52BD8D079AB0ABF80BE11DC63B85CF5791125991A029FAD7D17820D9419D8" },
{ name = "lustre", version = "4.3.2", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_json", "gleam_otp", "gleam_stdlib"], otp_app = "lustre", source = "hex", outer_checksum = "7F4CE2DB524A882F97C94AA3D320986B6CAC415146D5F98DE4782E1B0B59098F" },
{ name = "midas", version = "0.4.5", build_tools = ["gleam"], requirements = ["gleam_http", "gleam_json", "gleam_stdlib", "snag"], source = "local", path = "../../midas" },
{ name = "plinth", version = "0.4.12", build_tools = ["gleam"], requirements = ["conversation", "gleam_javascript", "gleam_json", "gleam_stdlib"], otp_app = "plinth", source = "hex", outer_checksum = "3727B517C05BD4D49A4AF34BA7E63E03CA77B4E8AD2A4DCE60266B28717C1F9A" },
{ name = "simplifile", version = "1.7.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "1D5DFA3A2F9319EC85825F6ED88B8E449F381B0D55A62F5E61424E748E7DDEB0" },
{ name = "snag", version = "0.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "snag", source = "hex", outer_checksum = "54D32E16E33655346AA3E66CBA7E191DE0A8793D2C05284E3EFB90AD2CE92BCC" },
{ name = "thoas", version = "1.2.1", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "E38697EDFFD6E91BD12CEA41B155115282630075C2A727E7A6B2947F5408B86A" },
Expand All @@ -31,7 +32,9 @@ gleam_javascript = { version = "~> 0.8" }
gleam_json = { version = ">= 1.0.0 and < 3.0.0" }
gleam_stdlib = { version = "~> 0.20" }
gleeunit = { version = "~> 1.0" }
jot = { version = ">= 1.0.1 and < 2.0.0"}
lustre = { version = "~> 4.0" }
midas = { version = ">= 0.4.2 and < 1.0.0" }
plinth = { version = ">= 0.4.5 and < 1.0.0" }
midas = { path = "../../midas" }
plinth = { version = ">= 0.4.9 and < 1.0.0" }
simplifile = { version = "~> 1.0" }
snag = { version = ">= 0.3.0 and < 1.0.0" }
136 changes: 136 additions & 0 deletions eyg/src/eyg/website/news.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import eyg/website/news/archive
import eyg/website/news/edition.{Edition}
import eyg/website/utils
import gleam/bit_array
import gleam/int
import gleam/list
import gleam/result
import gleam/string
import lustre/attribute as a
import lustre/element
import lustre/element/html as h
import midas/task as t
import snag

const replace_string = "!CONTENT!"

pub fn build() {
use layout <- t.do(t.read("layout2.css"))
let layout = #("/assets/layout.css", layout)
use pea <- t.do(t.read("src/eyg/website/news/pea.webp"))
let pea = #("/assets/pea.webp", pea)
use brocolli <- t.do(t.read("src/eyg/website/news/brocolli.webp"))
let brocolli = #("/assets/brocolli.webp", brocolli)

use template <- t.do(t.read("src/eyg/website/news/edition/email.html"))
use template <- t.try(
bit_array.to_string(template)
|> result.replace_error(snag.new("not a utf8 string")),
)
let assert [latest, ..] = archive.published
let content =
element.to_string(edition.render(latest, list.length(archive.published)))
let template = string.replace(template, replace_string, content)

t.done([
#("/news/_email.html", <<template:utf8>>),
layout,
pea,
brocolli,
..web_editions(archive.published, layout)
])
}

// archive is a reverse order stack of editions
fn web_editions(editions, layout) {
list.index_map(list.reverse(editions), fn(edition, index) {
let index = index + 1
let Edition(title: title, ..) = edition
let edition = edition.render(edition, index)

let path = "/news/editions/" <> int.to_string(index) <> "/index.html"
let page =
h.html([], [
h.head([], [
h.meta([a.attribute("charset", "UTF-8")]),
h.meta([
a.name("viewport"),
a.attribute("content", "width=device-width, initial-scale=1.0"),
]),
h.title([], "EYG news: " <> title),
h.meta([
a.name("description"),
a.attribute(
"content",
"Updates from the development of the EYG language and editor.",
),
]),
utils.css(layout),
h.link([a.rel("shortcut icon"), a.href("/assets/pea.webp")]),
h.script(
[
a.attribute("defer", ""),
a.attribute("data-domain", "eyg.run"),
a.src("https://plausible.io/js/script.js"),
],
"",
),
]),
h.body(
[
a.class("vstack"),
a.style([
// #("margin", "12px auto"),
// #("max-width", "660px"),
#("background", edition.charcoal),
// #("padding", "12px"),
#("border-radius", "12px"),
]),
],
[
// inline_subscribe(),
h.div(
[
a.style([
#("margin", "12px auto"),
#("max-width", "660px"),
#("background", "white"),
#("padding", "12px"),
#("border-radius", "12px"),
]),
],
[edition],
),
inline_subscribe(),
],
),
])
|> element.to_document_string
|> bit_array.from_string
#(path, page)
})
}

fn inline_subscribe() {
h.div(
[
a.style([
#("margin", "0 auto"),
#("width", "600px"),
#("background", "white"),
]),
],
[
h.script(
[
a.src(
"https://eocampaign1.com/form/b3a478b8-39e2-11ef-97b9-955caf3f5f36.js",
),
a.attribute("async", ""),
a.attribute("data-form", "b3a478b8-39e2-11ef-97b9-955caf3f5f36"),
],
"",
),
],
)
}
13 changes: 13 additions & 0 deletions eyg/src/eyg/website/news/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Edition has articles/stories/features/items, which are multiple so not used
instead we say an edition has content. Content could be anything, discounted word was material/subject

periodical/newsletter/publication refer to the total sequence of editions
newsletter sounds like the thing that is shipped to subscribers so the whole thread is called news

Edition is a singal instance issue/volume where other names
Chapters is a subset of an article or somethingelse
almanac as the yearly summary

New issues are added to the archive which is the source of truth,
not called source because articles can have sources

55 changes: 55 additions & 0 deletions eyg/src/eyg/website/news/archive.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import eyg/website/news/edition.{Edition}

pub const published = [
Edition(
"2024-08-24",
"JavaScript interpreter available on npm",
"
EYG is an intermediate representation for programs that never crash and can run in all kinds of environments.
Running EYG programs in JavaScript environments is now possible using the `eyg-run` package published to [npm](https://www.npmjs.com/package/eyg-run).
This interpreter can be used on [node.js](https://nodejs.org) and in the browser.
## Running programs on node.
EYG programs can be run on node, using npx, as follows:
```json
echo '{\"0\":\"a\",\"f\":{\"0\":\"p\",\"l\":\"Log\"},\"a\":{\"0\":\"s\",\"v\":\"Hello, World!\"}}' > hello.json
cat hello.json | npx eyg-run
```
The default node runner includes only the `Log` effect.
To implement other external effects, follow the browser instructions.
## Running in the browser.
To run in the browser requires building a runner.
In this example the `Log` effect is handled by the `window.alert` API.
```js
import { exec, Record, native } from \"https://esm.run/eyg-run\";
const extrinsic = {
Log(message) {
window.alert(message)
return (Record())
}
}
async function run() {
let source = {\"0\":\"a\",\"f\":{\"0\":\"p\",\"l\":\"Log\"},\"a\":{\"0\":\"s\",\"v\":\"Hello, World!\"}}
let result = await exec(source, extrinsic)
console.log(native(result))
}
run()
```
## Documentation of the EYG intermediate representation (IR)
Documentation describing the JSON format for EYG programs is now available on github.
[https://github.com/CrowdHailer/eyg-lang/tree/main/ir](https://github.com/CrowdHailer/eyg-lang/tree/main/ir)",
),
]
Binary file added eyg/src/eyg/website/news/brocolli.webp
Binary file not shown.
Loading

0 comments on commit 8ff5758

Please sign in to comment.