diff options
Diffstat (limited to 'src/tour.gleam')
-rw-r--r-- | src/tour.gleam | 334 |
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 ]), ]) |