From 2993a35c809e302f2a1b9c932945d1d85273f714 Mon Sep 17 00:00:00 2001 From: Catalin Mititiuc Date: Wed, 14 May 2025 17:09:34 -0700 Subject: [PATCH] WIP: Wrap posts in an article tag --- command.moon | 43 +++++++ ...st-all-files-in-a-directory-with-elixir.md | 108 ++++++++---------- ...open-an-iex-shell-from-an-elixir-script.md | 6 - ...alyzer-with-gui-from-a-docker-container.md | 6 - ...ming-multiview-projections-to-isometric.md | 5 - ...erated-html-with-docker-on-digitalocean.md | 6 - docs/2023-11-15-test-mix-task-file-modify.md | 6 - ...1-build-static-website-generator-part-1.md | 10 +- posts.moon | 40 ++++--- site.moon | 63 ++++++++-- templates/blog.html | 19 ++- templates/root.html | 2 +- 12 files changed, 192 insertions(+), 122 deletions(-) create mode 100644 command.moon diff --git a/command.moon b/command.moon new file mode 100644 index 0000000..3e997f0 --- /dev/null +++ b/command.moon @@ -0,0 +1,43 @@ +-- ========================================================================= +-- capture output of a system command +-- ========================================================================= +handle = io.popen "ls" +result = handle\read("*a") +print result +handle\close! + +-- ========================================================================= +-- how changing the config in the Site class works +-- ========================================================================= +-- f = class Site, config: { "one" } -- simulate `f = require "sitegen.site"` +-- f.config = { "two" } + +-- simulate `n = require "sitegen.site"` +-- n = f -- because it has already been required, it returns the existing `f` +-- n! + +-- { v } = n.config +-- print v + + + +-- ========================================================================= +-- markdown link pseudo-protocols +-- ========================================================================= +-- [what-is-this](class:asdf) +-- +-- [reference link][blah] +-- +-- [blah]: "titlehere" +-- +-- [App Platform](id:doesthiswork>) +-- +-- > %class-one% +-- > +-- > Lorem ipsum... +-- +-- [postoffice](class:caps "asdf") +-- +-- [postoffice][caps] +-- +-- [caps]: class:caps 'ALL UPPER CASE, ALL THE TIME' diff --git a/docs/2023-08-03-recursively-list-all-files-in-a-directory-with-elixir.md b/docs/2023-08-03-recursively-list-all-files-in-a-directory-with-elixir.md index 8675387..87171ec 100644 --- a/docs/2023-08-03-recursively-list-all-files-in-a-directory-with-elixir.md +++ b/docs/2023-08-03-recursively-list-all-files-in-a-directory-with-elixir.md @@ -1,7 +1,3 @@ -{ - id: "recursively-list-all-files-in-a-directory-with-elixir" -} - ## Introduction We wish to print a list of all the files in a directory, ignoring files beginning with certain characters, sorted alphabetically, with the directories last. @@ -43,37 +39,35 @@ end The data structure holding the results of the file search. -``` -iex(1)> directory_tree = Files.find("hello") -{"hello", - [ - "README.md", - {"hello/test", - [ - {"hello/test/support", ["conn_case.ex"]}, - "test_helper.exs", - {"hello/test/hello_web", - [{"hello/test/hello_web/controllers", ["error_json_test.exs"]}]} - ]}, - {"hello/lib", - [ - "hello.ex", - {"hello/lib/hello", ["application.ex"]}, - "hello_web.ex", - {"hello/lib/hello_web", - [ - {"hello/lib/hello_web/controllers", ["error_json.ex"]}, - "telemetry.ex", - "router.ex", - "endpoint.ex" - ]} - ]}, - {"hello/priv", [{"hello/priv/static", ["robots.txt", "favicon.ico"]}]}, - {"hello/config", - ["config.exs", "dev.exs", "test.exs", "prod.exs", "runtime.exs"]}, - "mix.exs" - ]} -``` + iex(1)> directory_tree = Files.find("hello") + {"hello", + [ + "README.md", + {"hello/test", + [ + {"hello/test/support", ["conn_case.ex"]}, + "test_helper.exs", + {"hello/test/hello_web", + [{"hello/test/hello_web/controllers", ["error_json_test.exs"]}]} + ]}, + {"hello/lib", + [ + "hello.ex", + {"hello/lib/hello", ["application.ex"]}, + "hello_web.ex", + {"hello/lib/hello_web", + [ + {"hello/lib/hello_web/controllers", ["error_json.ex"]}, + "telemetry.ex", + "router.ex", + "endpoint.ex" + ]} + ]}, + {"hello/priv", [{"hello/priv/static", ["robots.txt", "favicon.ico"]}]}, + {"hello/config", + ["config.exs", "dev.exs", "test.exs", "prod.exs", "runtime.exs"]}, + "mix.exs" + ]} ## Sorting and printing @@ -107,29 +101,27 @@ end Print all the files sorted. -``` -iex(2)> Paths.puts(directory_tree) -hello/mix.exs -hello/README.md -hello/config/config.exs -hello/config/dev.exs -hello/config/prod.exs -hello/config/runtime.exs -hello/config/test.exs -hello/lib/hello.ex -hello/lib/hello_web.ex -hello/lib/hello/application.ex -hello/lib/hello_web/endpoint.ex -hello/lib/hello_web/router.ex -hello/lib/hello_web/telemetry.ex -hello/lib/hello_web/controllers/error_json.ex -hello/priv/static/favicon.ico -hello/priv/static/robots.txt -hello/test/test_helper.exs -hello/test/hello_web/controllers/error_json_test.exs -hello/test/support/conn_case.ex -:ok -``` + iex(2)> Paths.puts(directory_tree) + hello/mix.exs + hello/README.md + hello/config/config.exs + hello/config/dev.exs + hello/config/prod.exs + hello/config/runtime.exs + hello/config/test.exs + hello/lib/hello.ex + hello/lib/hello_web.ex + hello/lib/hello/application.ex + hello/lib/hello_web/endpoint.ex + hello/lib/hello_web/router.ex + hello/lib/hello_web/telemetry.ex + hello/lib/hello_web/controllers/error_json.ex + hello/priv/static/favicon.ico + hello/priv/static/robots.txt + hello/test/test_helper.exs + hello/test/hello_web/controllers/error_json_test.exs + hello/test/support/conn_case.ex + :ok ## Conclusion diff --git a/docs/2023-09-15-open-an-iex-shell-from-an-elixir-script.md b/docs/2023-09-15-open-an-iex-shell-from-an-elixir-script.md index 81288e5..46da21c 100644 --- a/docs/2023-09-15-open-an-iex-shell-from-an-elixir-script.md +++ b/docs/2023-09-15-open-an-iex-shell-from-an-elixir-script.md @@ -1,14 +1,8 @@ { - id: "open-an-iex-shell-from-an-elixir-script" title: "Open An IEx Shell From An Elixir Script" blurb: "We can run an Elixir script with either the elixir or the iex command. Both will execute the code, but the second command opens an interactive IEx shell afterward. What if, we won't know until runtime whether we want a shell or not? How can we start an IEx session even when we use elixir, instead of iex, to run our script?" } ---- -title: "Open An IEx Shell From An Elixir Script" -blurb: "We can run an Elixir script with either the elixir or the iex command. Both will execute the code, but the second command opens an interactive IEx shell afterward. What if, we won't know until runtime whether we want a shell or not? How can we start an IEx session even when we use elixir, instead of iex, to run our script?" -... - ## Method 1 Here's a quick test script: diff --git a/docs/2023-10-08-start-erlangs-dialyzer-with-gui-from-a-docker-container.md b/docs/2023-10-08-start-erlangs-dialyzer-with-gui-from-a-docker-container.md index 44ae3bb..c1211f5 100644 --- a/docs/2023-10-08-start-erlangs-dialyzer-with-gui-from-a-docker-container.md +++ b/docs/2023-10-08-start-erlangs-dialyzer-with-gui-from-a-docker-container.md @@ -1,14 +1,8 @@ { - id: "start-erlangs-dialyzer-with-gui-from-a-docker-container" title: "Start Erlang's Dialyzer With GUI From A Docker Container" blurb: "Everything in OTP is command-line driven, so using containers during development has been without issue. But, Dialyzer, Erlang's static analysis tool, actually has a Graphical User Interface. How can we still use Dialyzer and its GUI even though Elixir is running inside a container?" } ---- -title: "Start Erlang's Dialyzer With GUI From A Docker Container" -blurb: "Everything in OTP is command-line driven, so using containers during development has been without issue. But, Dialyzer, Erlang's static analysis tool, actually has a Graphical User Interface. How can we still use Dialyzer and its GUI even though Elixir is running inside a container?" -... - I use Docker mostly when working on software projects and I figured out how to get Erlang's Dialyzer GUI working in a Docker container. 1. Start a container with X11 forwarding: diff --git a/docs/2023-10-16-fix-distortion-introduced-when-transforming-multiview-projections-to-isometric.md b/docs/2023-10-16-fix-distortion-introduced-when-transforming-multiview-projections-to-isometric.md index baab015..6b759aa 100644 --- a/docs/2023-10-16-fix-distortion-introduced-when-transforming-multiview-projections-to-isometric.md +++ b/docs/2023-10-16-fix-distortion-introduced-when-transforming-multiview-projections-to-isometric.md @@ -1,12 +1,7 @@ { - id: "fix-distortion-introduced-when-transforming-multiview-projections-to-isometric" blurb: "One thing we learned from a week of trying to make isometric vector drawings." } ---- -blurb: "One thing we learned from a week of trying to make isometric vector drawings." -... - ## Objective Construct an isometric vector image of an object from top, front, and side view projections (like [this](https://workforce.libretexts.org/Bookshelves/Drafting_and_Design_Technology/Introduction_to_Drafting_and_AutoCAD_3D_(Baumback)/02%3A_Part_2/2.01%3A_Module_7-_Visualizing_Multiview_Drawings), but using Inkscape instead of AutoCAD). diff --git a/docs/2023-11-01-deploy-elixir-generated-html-with-docker-on-digitalocean.md b/docs/2023-11-01-deploy-elixir-generated-html-with-docker-on-digitalocean.md index 36b005b..59dcc01 100644 --- a/docs/2023-11-01-deploy-elixir-generated-html-with-docker-on-digitalocean.md +++ b/docs/2023-11-01-deploy-elixir-generated-html-with-docker-on-digitalocean.md @@ -1,14 +1,8 @@ { - id: "deploy-elixir-generated-html-with-docker-on-digitalocean" title: "Deploy Elixir-Generated HTML With Docker On DigitalOcean" blurb: "This is a simple proof of concept where we create a boilerplate HTML file with Elixir, containerize our build process with Docker, and deploy our markup live with DigitalOcean's hosting service." } ---- -title: "Deploy Elixir-Generated HTML With Docker On DigitalOcean" -blurb: "This is a simple proof of concept where we create a boilerplate HTML file with Elixir, containerize our build process with Docker, and deploy our markup live with DigitalOcean's hosting service." -... - ## Introduction DigitalOcean has this [App Platform](https://www.digitalocean.com/products/app-platform) service that can host a static website, as well as build it from a Docker image, if provided a `Dockerfile`. We thought a static website built by an Elixir app could be an instructive project. To explore if the idea is viable, we wrote a small Elixir application that generates a simple `index.html` file and deployed it live on DigitalOcean's service. diff --git a/docs/2023-11-15-test-mix-task-file-modify.md b/docs/2023-11-15-test-mix-task-file-modify.md index 639153d..04e9646 100644 --- a/docs/2023-11-15-test-mix-task-file-modify.md +++ b/docs/2023-11-15-test-mix-task-file-modify.md @@ -1,14 +1,8 @@ { - id: "test-mix-task-file-modify" title: "Temporary Directories For Testing Mix Tasks That Modify Files" blurb: "Writing a test for a simple Mix task gets surprisingly complex. Application environment variables, temporary test directories, and IO capture are all involved." } ---- -title: "Temporary Directories For Testing Mix Tasks That Modify Files" -blurb: "Writing a test for a simple Mix task gets surprisingly complex. Application environment variables, temporary test directories, and IO capture are all involved." -... - ## Intro Last time, we added a Mix task to our project that writes an HTML file to a directory `/public` in the container's filesystem. Today, we will write a test for that task. diff --git a/docs/2023-12-01-build-static-website-generator-part-1.md b/docs/2023-12-01-build-static-website-generator-part-1.md index 1f6ead0..1750ff5 100644 --- a/docs/2023-12-01-build-static-website-generator-part-1.md +++ b/docs/2023-12-01-build-static-website-generator-part-1.md @@ -1,15 +1,9 @@ { - id: "build-static-website-generator-part-1" title: "Build A Static-Website Generator With Elixir, Part 1" blurb: "We take the first steps in designing and implementing the \"world's simplest static-website generator\". Building on tools and knowledge we acquired previously, and utilizing an incremental and iterative development process, we go through the entire software life-cycle from creating the initial project files to deploying to production. We spare nothing, from spelling out every command, to ensuring application integrity with tests, and even updating the README file. Grab a drink and some snacks, and dive right in!" } ---- -title: "Build A Static-Website Generator With Elixir, Part 1" -blurb: "We take the first steps in designing and implementing the \"world's simplest static-website generator\". Building on tools and knowledge we acquired previously, and utilizing an incremental and iterative development process, we go through the entire software life-cycle from creating the initial project files to deploying to production. We spare nothing, from spelling out every command, to ensuring application integrity with tests, and even updating the README file. Grab a drink and some snacks, and dive right in!" -... - -::: info +
$markdown{[[ This post was originally intended to be the first in a multi-part series. However, the deeper we got into this project, the more we realized we were basically implementing our own version of a web framework. Rather than @@ -18,7 +12,7 @@ framework, [Phoenix](https://www.phoenixframework.org/), and simply added a Markdown-to-HTML conversion feature. As a consequence, there are no other parts to this post, but a description of the solution we chose instead can be found [here](/posts/publish-markdown-documents-as-static-web-pages-with-pandoc-and-phoenix). -::: +]]}
This is one of our longer posts, so we've included a table of contents. diff --git a/posts.moon b/posts.moon index 181b99b..2305e3e 100644 --- a/posts.moon +++ b/posts.moon @@ -1,27 +1,35 @@ date = require "date" path = require "sitegen.path" -moon = require("moon") -common = require("sitegen.common") +-- import slugify from "sitegen.common" +common = require "sitegen.common" +rootname = (str) -> + result = string.gsub str, "%..+", "" + result + +extract_id = (source) -> string.match path.filename(source), "%a[%w%-]+" extract_date = (source) -> string.match path.filename(source), "%d+%-%d%d%-%d%d" format_date = (str) -> date(str)\fmt "%b %d, %Y" publish_date = (path) -> format_date extract_date path -posts = [{ - id: p.meta.id - tgt: p.meta.target - src: p.source - title: p.meta.title or p.meta.id - blurb: p.meta.blurb -} for _, p in pairs site.pages when p.meta.template == "blog"] - -table.sort posts, (a, b) -> a.src > b.src +pages = site\query_pages { is_a: "post" } +table.sort pages, (a, b) -> a.source > b.source html -> [tag["section"] { - tag["h3"] { tag["a"] { href: p.tgt .. ".html", p.title }} - tag["time"] { publish_date p.src } - {"—", if p.blurb then text(p.blurb)} - tag["a"] { class: "read-post-link", href: p.tgt .. ".html", "Read post →"} - } for _, p in ipairs posts] + tag["h3"] { + tag["a"] { + href: p.meta.target .. ".html", + p.meta.title or p.meta.id + } + } + tag["time"] { publish_date p.source } + { "—", if p.meta.blurb then text p.meta.blurb } + + tag["a"] { + class: "read-post-link", + href: p.meta.target .. ".html", + "Read post →" + } + } for _, p in ipairs pages] diff --git a/site.moon b/site.moon index b496047..787c1ff 100644 --- a/site.moon +++ b/site.moon @@ -3,6 +3,11 @@ tools = require "sitegen.tools" site = require "sitegen.site" lfs = require "lfs" +date = require "date" +path = require "sitegen.path" +-- import slugify from "sitegen.common" +common = require "sitegen.common" + rootname = (str) -> result = string.gsub str, "%..+", "" result @@ -22,7 +27,7 @@ posts = (path=".") -> -- site = site! site.config.out_dir = "html/" -css = tools.system_command "cat < %s > %s", "css" +css = tools.system_command "cp %s %s", "css" ps = posts("docs") @@ -49,8 +54,27 @@ one = () -> tag.a { href: "momo", "yayaya" } tag.a { href: "momo", "yayaya" } +require("sitegen.renderers.markdown").render = (page, md_source) => + discount = require "discount" + + md_source = page\pipe "renderer.markdown.pre_render", md_source + md_source, escapes = escape_cosmo md_source + + html_source = assert discount md_source + html_source = unescape_cosmo html_source, escapes + print("DDDDDDDDDDDDDD") + + super page, html_source + +-- require("moon").p require("sitegen.renderers.markdown") + +extract_id = (source) -> string.match path.filename(source), "%a[%w%-]+" +extract_date = (source) -> string.match path.filename(source), "%d+%-%d%d%-%d%d" +format_date = (str) -> date(str)\fmt "%b %d, %Y" +publish_date = (path) -> format_date extract_date path + sitegen.create => - @title = "WebDevCat.me · Catalin Mititiuc" + @site_title = "WebDevCat.me · Catalin Mititiuc" @app_name = "stasis" @version = "0.2.12" @val = "yes" @@ -82,21 +106,44 @@ sitegen.create => -- require("moon").p get_site @test = (page) -> {{"b": 1, "c": 2}, {"d": 3, "e": 4}} @what = (page) -> + page -- require("moon").p [{ln, lv} for ln, lv in pairs debug.getlocal(2, idx)] -- require("moon").p - "what?" -- require("moon").p @ - -- require("moon").p @site + -- @what = (page) => + -- require("moon").p @ + + -- require("moon").p site.pages + + -- @what! add "index.html", o: one - add path, target: out, template: "blog" for path, out in pairs posts "docs" - -- add "test.html", id: "test" + add path, target: out, template: "blog", is_a: "post", post: { + publish_date: publish_date(path) + }, id: extract_id(path) for path, out in pairs posts "docs" + + add "test.html", id: "test" -- feed "posts.moon", "feed.xml" -- require("moon").p site - build css, "app.css" + -- build css, "app.css" + copy "app.css" --- require("moon").p site + -- filter "docs", (body) => + -- require("moon").p body + + -- require("moon").p search "start", "docs" + + -- filter "2023%-08%-03", (body) => + -- table.concat { body, "

hey there

" } + + -- require("moon").p body + -- body\gsub "

.-

", (header) -> + -- table.concat { body, "yoyoasdf" } + -- body .. "yoyo" + -- body\gsub "{.-}", (header) -> + -- require("moon").p header + -- table.concat { '', header, '
' } diff --git a/templates/blog.html b/templates/blog.html index cf5ec94..3657a1a 100644 --- a/templates/blog.html +++ b/templates/blog.html @@ -1,4 +1,6 @@ -$render{"templates/root"} +

templates/blog.html

+ +$wrap{"root"}

Web Log

@@ -8,4 +10,17 @@ $render{"templates/root"}

-$body +
+
+
+

$(title or id)

+ +
+
+ + $body + + +
diff --git a/templates/root.html b/templates/root.html index 1bccef3..75fb775 100644 --- a/templates/root.html +++ b/templates/root.html @@ -3,7 +3,7 @@ - $title + $site_title