aboutsummaryrefslogtreecommitdiff
path: root/src/tour.gleam
diff options
context:
space:
mode:
Diffstat (limited to 'src/tour.gleam')
-rw-r--r--src/tour.gleam334
1 files changed, 213 insertions, 121 deletions
diff --git a/src/tour.gleam b/src/tour.gleam
index 0b09e1c..a5e04ea 100644
--- a/src/tour.gleam
+++ b/src/tour.gleam
@@ -9,6 +9,8 @@ import htmb.{h, text}
import simplifile
import snag
import tour/widgets
+import tour/document
+import tour/page
const static = "static"
@@ -533,7 +535,7 @@ fn everything_chapter_lesson_html(lesson: Lesson, index: Int, end_index: Int) {
h("h2", [#("class", "lesson-title")], [text(lesson.name)]),
]),
htmb.dangerous_unescaped_fragment(string_builder.from_string(lesson.text)),
- h("pre", [#("class", "lesson-snippet")], [
+ h("pre", [#("class", "lesson-snippet hljs gleam language-gleam")], [
h("code", [], [text(lesson.code)]),
h(
"a",
@@ -598,13 +600,9 @@ fn everything_html(chapters: List(Chapter)) -> String {
[],
list.map(chapter.lessons, fn(lesson) {
h("li", [], [
- h(
- "a",
- [
- #("href", "#" <> slugify_path(lesson.path)),
- #("class", "link"),
- ],
- [text(lesson.name)],
+ link_html(
+ Link(label: lesson.name, to: "#" <> slugify_path(lesson.path)),
+ [#("class", "link padded")],
),
])
}),
@@ -613,17 +611,68 @@ fn everything_html(chapters: List(Chapter)) -> String {
)
})
+ let render_next = True
+
+ case render_next {
+ True ->
+ page.html(
+ page.PageConfig(
+ path: "everything",
+ title: "Everything!",
+ scripts: page.ScriptConfig(head: [], body: [
+ document.script(
+ "/highlight/highlight.core.min.js",
+ document.ScriptOptions(module: True, defer: True),
+ [],
+ ),
+ document.script(
+ "/highlight/highlight-gleam.js",
+ document.ScriptOptions(module: True, defer: True),
+ [],
+ ),
+ ]),
+ stylesheets: ["/highlight/highlight.css"],
+ content: [
+ h("main", [#("id", "everything")], [
+ h(
+ "aside",
+ [#("id", "everything-contents"), #("class", "dim-bg")],
+ table_of_contents,
+ ),
+ h("section", [#("id", "everything-lessons")], chapter_lessons),
+ ]),
+ ],
+ ),
+ )
+ |> page.render
+ _ ->
+ page_html(
+ at: "everything",
+ titled: "Everything!!!",
+ containing: [
+ h("main", [#("id", "everything")], [
+ h(
+ "aside",
+ [#("id", "everything-contents"), #("class", "dim-bg")],
+ table_of_contents,
+ ),
+ h("section", [#("id", "everything-lessons")], chapter_lessons),
+ ]),
+ h(
+ "script",
+ [#("src", "/highlight/highlight.core.min.js"), #("type", "module")],
+ [],
+ ),
+ h(
+ "script",
+ [#("src", "/highlight/highlight-gleam.js"), #("type", "module")],
+ [],
+ ),
+ ],
+ with_styles: ["/highlight/highlight.css"],
+ )
+ }
// TODO: use proper values for location and such
- page_html(at: "everything", titled: "Everything!!!", containing: [
- h("main", [#("id", "everything")], [
- h(
- "aside",
- [#("id", "everything-contents"), #("class", "dim-bg")],
- table_of_contents,
- ),
- h("section", [#("id", "everything-lessons")], chapter_lessons),
- ]),
- ])
}
fn lesson_html(page: Lesson) -> String {
@@ -634,129 +683,172 @@ fn lesson_html(page: Lesson) -> String {
}
}
- page_html(at: page.path, titled: page.name, containing: [
- h("article", [#("id", "playground")], [
- h("section", [#("id", "left")], [
- h("h2", [], [text(page.name)]),
- htmb.dangerous_unescaped_fragment(string_builder.from_string(page.text)),
- h("nav", [#("class", "prev-next")], [
- navlink("Back", page.previous),
- text(" — "),
- h("a", [#("href", path_table_of_contents)], [text("Contents")]),
- text(" — "),
- navlink("Next", page.next),
+ page_html(
+ at: page.path,
+ titled: page.name,
+ containing: [
+ h("article", [#("id", "playground")], [
+ h("section", [#("id", "left")], [
+ h("h2", [], [text(page.name)]),
+ htmb.dangerous_unescaped_fragment(string_builder.from_string(
+ page.text,
+ )),
+ h("nav", [#("class", "prev-next")], [
+ navlink("Back", page.previous),
+ text(" — "),
+ h("a", [#("href", path_table_of_contents)], [text("Contents")]),
+ text(" — "),
+ navlink("Next", page.next),
+ ]),
]),
- ]),
- h("section", [#("id", "right")], [
- h("section", [#("id", "editor")], [
- h("div", [#("id", "editor-target")], []),
+ h("section", [#("id", "right")], [
+ h("section", [#("id", "editor")], [
+ h("div", [#("id", "editor-target")], []),
+ ]),
+ h("aside", [#("id", "output")], []),
]),
- h("aside", [#("id", "output")], []),
]),
+ h("script", [#("type", "gleam"), #("id", "code")], [
+ htmb.dangerous_unescaped_fragment(string_builder.from_string(page.code)),
+ ]),
+ h("script", [#("type", "module"), #("src", "/index.js")], []),
+ ],
+ with_styles: [],
+ )
+}
+
+type Link {
+ Link(label: String, to: String)
+}
+
+fn link_html(for link: Link, attributes attributes: List(#(String, String))) {
+ let link_attributes = [#("href", link.to), ..attributes]
+
+ h("a", link_attributes, [text(link.label)])
+}
+
+/// Renders the tour's navbar as html
+fn page_navbar(
+ titled title: String,
+ links additional_links: List(Link),
+) -> htmb.Html {
+ let links = {
+ [Link(label: "gleam.run", to: "http://gleam.run"), ..additional_links]
+ |> list.map(fn(l) { link_html(l, [#("class", "link")]) })
+ }
+ let nav_right_items = list.flatten([links, [widgets.theme_picker()]])
+
+ h("nav", [#("class", "navbar")], [
+ h("a", [#("href", "/"), #("class", "logo")], [
+ h(
+ "img",
+ [
+ #("src", "https://gleam.run/images/lucy/lucy.svg"),
+ #("alt", "Lucy the star, Gleam's mascot"),
+ ],
+ [],
+ ),
+ text(title),
]),
- h("script", [#("type", "gleam"), #("id", "code")], [
- htmb.dangerous_unescaped_fragment(string_builder.from_string(page.code)),
- ]),
- h("script", [#("type", "module"), #("src", "/index.js")], []),
+ h("div", [#("class", "nav-right")], nav_right_items),
])
}
-fn page_html(
+/// Renders the page head as HTML
+fn page_head(
at path: String,
titled title: String,
- containing content: List(htmb.Html),
-) -> String {
+ with_styles styles: List(String),
+) -> htmb.Html {
let metaprop = fn(property, content) {
h("meta", [#("property", property), #("content", content)], [])
}
let link = fn(rel, href) { h("link", [#("rel", rel), #("href", href)], []) }
+ let stylesheet = fn(src: String) { link("stylesheet", src) }
let title = title <> " - The Gleam Language Tour"
let description =
"An interactive introduction and reference to the Gleam programming language. Learn Gleam in your browser!"
+ let metaprops = [
+ metaprop("og:type", "website"),
+ metaprop("og:title", title),
+ metaprop("og:description", description),
+ metaprop("og:url", "https://tour.gleam.run/" <> path),
+ metaprop("og:image", "https://gleam.run/images/og-image.png"),
+ metaprop("twitter:card", "summary_large_image"),
+ metaprop("twitter:url", "https://tour.gleam.run/" <> path),
+ metaprop("twitter:title", title),
+ metaprop("twitter:description", description),
+ metaprop("twitter:image", "https://gleam.run/images/og-image.png"),
+ ]
+
+ let metadata = [
+ h("meta", [#("charset", "utf-8")], []),
+ h(
+ "meta",
+ [
+ #("name", "viewport"),
+ #("content", "width=device-width, initial-scale=1"),
+ ],
+ [],
+ ),
+ h("title", [], [text(title)]),
+ h("meta", [#("name", "description"), #("content", description)], []),
+ ..metaprops
+ ]
+
+ let links = [
+ link("shortcut icon", "https://gleam.run/images/lucy/lucy.svg"),
+ link("stylesheet", "/common.css"),
+ link("stylesheet", "/style.css"),
+ ..list.map(styles, stylesheet)
+ ]
+
+ let scripts = [
+ h(
+ "script",
+ [
+ #("defer", ""),
+ #("data-domain", "tour.gleam.run"),
+ #("src", "https://plausible.io/js/script.js"),
+ ],
+ [],
+ ),
+ h("script", [#("type", "module")], [
+ htmb.dangerous_unescaped_fragment(string_builder.from_string(
+ widgets.theme_picker_js,
+ )),
+ ]),
+ ]
+
+ let head_content = {
+ let parts = [metadata, links, scripts]
+ parts
+ |> list.concat
+ }
+
+ h("head", [], head_content)
+}
+
+fn page_html(
+ at path: String,
+ titled title: String,
+ containing content: List(htmb.Html),
+ with_styles styles: List(String),
+) -> String {
+ let head = {
+ let static_styles = ["/common.css", "/styles.css"]
+ let head_styles =
+ [static_styles, styles]
+ |> list.concat()
+
+ page_head(at: path, titled: title, with_styles: head_styles)
+ }
h("html", [#("lang", "en-gb"), #("class", "theme-light")], [
- h("head", [], [
- h("meta", [#("charset", "utf-8")], []),
- h(
- "meta",
- [
- #("name", "viewport"),
- #("content", "width=device-width, initial-scale=1"),
- ],
- [],
- ),
- h("title", [], [text(title)]),
- h("meta", [#("name", "description"), #("content", description)], []),
- metaprop("og:type", "website"),
- metaprop("og:title", title),
- metaprop("og:description", description),
- metaprop("og:url", "https://tour.gleam.run/" <> path),
- metaprop("og:image", "https://gleam.run/images/og-image.png"),
- metaprop("twitter:card", "summary_large_image"),
- metaprop("twitter:url", "https://tour.gleam.run/" <> path),
- metaprop("twitter:title", title),
- metaprop("twitter:description", description),
- metaprop("twitter:image", "https://gleam.run/images/og-image.png"),
- link("shortcut icon", "https://gleam.run/images/lucy/lucy.svg"),
- link("stylesheet", "/common.css"),
- link("stylesheet", "/style.css"),
- h(
- "script",
- [
- #("defer", ""),
- #("data-domain", "tour.gleam.run"),
- #("src", "https://plausible.io/js/script.js"),
- ],
- [],
- ),
- h("script", [#("type", "module")], [
- htmb.dangerous_unescaped_fragment(string_builder.from_string(
- widgets.theme_picker_js,
- )),
- ]),
- ]),
+ head,
h("body", [], [
- h("nav", [#("class", "navbar")], [
- h("a", [#("href", "/"), #("class", "logo")], [
- h(
- "img",
- [
- #("src", "https://gleam.run/images/lucy/lucy.svg"),
- #("alt", "Lucy the star, Gleam's mascot"),
- ],
- [],
- ),
- text("Gleam Language Tour"),
- ]),
- h("div", [#("class", "nav-right")], [
- h("a", [#("href", "https://gleam.run")], [text("gleam.run")]),
- h("div", [#("class", "theme-picker")], [
- h(
- "button",
- [
- #("type", "button"),
- #("alt", "Switch to light mode"),
- #("title", "Switch to light mode"),
- #("class", "theme-button -light"),
- #("data-light-theme-toggle", ""),
- ],
- [widgets.icon_moon(), widgets.icon_toggle_left()],
- ),
- h(
- "button",
- [
- #("type", "button"),
- #("alt", "Switch to dark mode"),
- #("title", "Switch to dark mode"),
- #("class", "theme-button -dark"),
- #("data-dark-theme-toggle", ""),
- ],
- [widgets.icon_sun(), widgets.icon_toggle_right()],
- ),
- ]),
- ]),
- ]),
+ page_navbar(titled: "Gleam Language Tour", links: []),
..content
]),
])