about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--front.lua42
-rw-r--r--links/main.css538
-rw-r--r--makefile4
-rw-r--r--src/main.zig2
4 files changed, 331 insertions, 255 deletions
diff --git a/front.lua b/front.lua
new file mode 100644
index 0000000..a6046b1
--- /dev/null
+++ b/front.lua
@@ -0,0 +1,42 @@
+---@diagnostic disable: undefined-global
+-- see https://pandoc.org/lua-filters.html
+return {
+    Pandoc = function(doc)
+        local front = {}
+
+        local toc = pandoc.structure.table_of_contents(doc)
+        if doc.meta.toc and toc then
+            table.insert(front, pandoc.RawBlock("html5", '<section class="table-of-contents">'))
+            table.insert(front, pandoc.RawBlock("html5", '<nav class="capital">'))
+            table.insert(front, pandoc.RawBlock("html5", "<ol>"))
+            -- insert jump to top
+            table.insert(front, pandoc.Link("back to top", "#top"))
+            -- create custom toc
+            toc:walk({
+                Link = function(e)
+                    table.insert(front, pandoc.RawBlock("html5", "<li>"))
+                    table.insert(front, e)
+                    table.insert(front, pandoc.RawBlock("html5", "</li>"))
+                end,
+            })
+            table.insert(front, pandoc.RawBlock("html5", "</ol>"))
+            table.insert(front, pandoc.RawBlock("html5", "</nav>"))
+            table.insert(front, pandoc.RawBlock("html5", "</section>"))
+        end
+
+        -- insert date blocks
+        if doc.meta.date then
+            table.insert(front, pandoc.RawBlock("html5", '<span class="date">'))
+            table.insert(front, doc.meta.date)
+            table.insert(front, pandoc.RawBlock("html5", "</span>"))
+        end
+
+        -- prepend front stuffs
+        for i = #front, 1, -1 do
+            table.insert(doc.blocks, 1, front[i])
+        end
+
+        -- return finished ast
+        return doc
+    end,
+}
diff --git a/links/main.css b/links/main.css
index 99ad25f..71c51c7 100644
--- a/links/main.css
+++ b/links/main.css
@@ -1,525 +1,559 @@
 :root {
-	--black: #0f0f0f;
-	--white: whitesmoke;
-	--ac: hotpink;
+  --black: #0f0f0f;
+  --white: whitesmoke;
+  --ac: hotpink;
 
-	--fg: var(--black);
-	--bg: var(--white);
-	--body-spacing: 45px;
+  --fg: var(--black);
+  --bg: var(--white);
 
-	color-scheme: light dark;
+  --body-spacing: 45px;
+  --body-line-height: 1.3;
 
-	font-synthesis: none;
-	text-rendering: optimizeLegibility;
-	-webkit-font-smoothing: antialiased;
-	-moz-osx-font-smoothing: grayscale;
-	text-align: justify;
-	text-justify: inter-word;
+  color-scheme: light dark;
+
+  font-synthesis: none;
+  text-rendering: optimizeLegibility;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  text-align: justify;
+  text-justify: inter-word;
 }
 
 ::selection {
-	background: var(--ac);
-	opacity: 1.0;
-	color: var(--black);
-	padding: 10px;
-	/* Safari */
+  background: var(--ac);
+  opacity: 1.0;
+  color: var(--black);
+  padding: 10px;
+  /* Safari */
 }
 
 body {
-	background: var(--bg);
-	color: var(--fg);
-	overflow-x: hidden;
-	font-family: sans-serif;
-	padding: var(--body-spacing);
-	margin: 0;
+  background: var(--bg);
+  color: var(--fg);
+  overflow-x: hidden;
+  font-family: sans-serif;
+  padding: var(--body-spacing);
+  margin: 0;
 }
 
 body>*+* {
-	margin-top: var(--body-spacing);
+  margin-top: var(--body-spacing);
 }
 
 header a {
-	text-decoration: none;
+  text-decoration: none;
 }
 
 header a img {
-	vertical-align: bottom;
+  vertical-align: bottom;
 }
 
 header h1 {
-	--gap: 10px;
+  --gap: 10px;
 
-	display: inline-block;
-	margin: 0;
-	padding: 5px;
+  display: inline-block;
+  margin: 0;
+  padding: 5px;
 
-	border-left: 2px solid var(--fg);
-	margin-left: var(--gap);
+  border-left: 2px solid var(--fg);
+  margin-left: var(--gap);
 
-	font-weight: 800;
+  font-weight: 800;
 }
 
 header h1::before {
-	content: "";
-	margin-left: var(--gap);
+  content: "";
+  margin-left: var(--gap);
 }
 
 nav {
-	padding: 0 25px;
-	padding-top: 0;
-	float: right;
+  padding: 0 25px;
+  padding-top: 0;
+  float: right;
 }
 
 nav details summary {
-	margin-bottom: 25px;
+  margin-bottom: 25px;
 }
 
 nav .site-nav section {
-	line-height: 22px;
-	margin-bottom: 40px;
+  line-height: var(--body-line-height);
+  margin-bottom: 40px;
 
-	border-left: 1px solid var(--fg);
-	padding-left: 15px;
-	margin-left: -15px;
+  border-left: 1px solid var(--fg);
+  padding-left: 15px;
+  margin-left: -15px;
 }
 
 nav .site-nav section:first-child {
-	border-width: 2px;
+  border-width: 2px;
 }
 
 nav .site-nav section h2 {
-	margin: 20px 0 20px 0;
+  margin: 20px 0 20px 0;
 }
 
 nav .site-nav section ul {
-	margin: 0px;
-	padding: 0px;
+  margin: 0px;
+  padding: 0px;
 }
 
 main {
-	max-width: 700px;
+  max-width: 700px;
 }
 
 main img {
-	width: 100%;
-	max-width: 700px;
-	margin-bottom: 15px;
+  width: 100%;
+  max-width: 700px;
+  margin-bottom: 15px;
 }
 
 main>* {
-	margin-bottom: 30px
+  margin-bottom: 30px
 }
 
 main>h1 {
-	font-size: 45px;
-	text-transform: capitalize;
-	display: none
+  font-size: 1.5rem;
+  text-transform: capitalize;
+  display: none
 }
 
 main>h2 {
-	font-size: 30px;
-	text-transform: capitalize
+  font-size: 1.3rem;
+  text-transform: capitalize
 }
 
 main>h3 {
-	font-size: 20px;
-	text-transform: capitalize
+  font-size: 1.2rem;
+  text-transform: capitalize
 }
 
 main>h4 {
-	font-size: 35px;
-	text-transform: capitalize
+  font-size: 1.1rem;
+  text-transform: capitalize
 }
 
 main p {
-	line-height: 25px;
-	font-size: 16px;
-	margin-top: 0px;
+  line-height: var(--body-line-height);
+  margin-top: 0px;
 }
 
 main>ul {
-	line-height: 25px;
+  line-height: var(--body-line-height);
 }
 
 figure {
-	margin: 0;
-	padding-bottom: 20px
+  margin: 0;
+  padding-bottom: 20px
 }
 
 figcaption {
-	font-size: 14px;
-	padding: 2px
+  font-size: smaller;
+  padding: 2px
 }
 
 code.button {
-	background: var(--fg);
-	color: var(--bg);
-	font-size: smaller;
-	display: inline-block;
-	padding: 0px 6px;
-	font-weight: bold;
-	border-radius: 2px;
-	line-height: 22px
+  background: var(--fg);
+  color: var(--bg);
+  font-size: smaller;
+  display: inline-block;
+  padding: 0px 6px;
+  font-weight: bold;
+  border-radius: 2px;
+  line-height: var(--body-line-height);
 }
 
 main hr {
-	border: 1px;
-	clear: both;
+  border: 1px;
+  clear: both;
 }
 
 main>ul.jump {
-	columns: 2;
-	line-height: 20px
+  columns: 2;
+  line-height: var(--body-line-height);
 }
 
 main>ul.jump li {
-	list-style-type: decimal-leading-zero;
-	list-style-position: inside;
-	text-transform: capitalize;
+  list-style-type: decimal-leading-zero;
+  list-style-position: inside;
+  text-transform: capitalize;
 }
 
 main img.medium {
-	max-width: 300px;
-	padding: 10px
+  max-width: 300px;
+  padding: 10px
 }
 
 main img.normal {
-	max-width: 192px;
+  max-width: 192px;
 }
 
 main img.sm {
-	max-width: 88px
+  max-width: 88px
 }
 
 main>q {
-	font-size: 20px;
-	max-width: 500px;
-	display: block;
-	margin-left: 30px;
+  /*font-size: 20px;*/
+  max-width: 500px;
+  display: block;
+  margin-left: 30px;
 }
 
 main>pre {
-	font-family: monospace;
-	background: var(--fg);
-	color: var(--bg);
-	padding: 15px;
+  font-family: monospace;
+  background: var(--fg);
+  color: var(--bg);
+  padding: 15px;
 }
 
 main>code {
-	font-family: monospace;
-	font-size: 12px;
-	margin-bottom: 30px;
-	display: block;
-	background: var(--fg);
-	color: var(--bg);
-	padding: 15px;
-	white-space: pre
+  font-family: monospace;
+  /*font-size: 12px;*/
+  margin-bottom: 30px;
+  display: block;
+  background: var(--fg);
+  color: var(--bg);
+  padding: 15px;
+  white-space: pre
 }
 
 main>code comment {
-	color: #777
+  color: #777
 }
 
 main ul.gallery {
-	background: none
+  background: none
 }
 
 main ul.gallery li {
-	clear: both;
-	display: block;
-	height: 260px;
-	margin-top: -2px
+  clear: both;
+  display: block;
+  height: 260px;
+  margin-top: -2px
 }
 
 main ul.gallery li:last-child {
-	border-bottom: 0px
+  border-bottom: 0px
 }
 
 main ul.gallery li a {
-	display: block;
-	padding: 10px
+  display: block;
+  padding: 10px
 }
 
 main ul.gallery li img {
-	width: 250px;
-	display: block;
-	margin-right: 15px;
+  width: 250px;
+  display: block;
+  margin-right: 15px;
 }
 
 main .project {
-	border-left: 2px solid var(--fg);
-	padding-left: 30px;
-	max-width: 555px;
+  border-left: 2px solid var(--fg);
+  padding-left: 30px;
+  max-width: 555px;
 }
 
 main .project>* {
-	margin-bottom: 30px
+  margin-bottom: 30px
 }
 
 main .project p {
-	padding: 0px;
-	margin-top: 0px;
-	margin-bottom: 30px;
+  padding: 0px;
+  margin-top: 0px;
+  margin-bottom: 30px;
 }
 
 main .project img {
-	display: block;
-	max-width: 100%;
+  display: block;
+  max-width: 100%;
 }
 
 main .button {
-	background-color: #000;
-	border: 2px solid var(--fg);
-	color: var(--bg);
-	padding: 13px 28px;
-	text-align: center;
-	text-decoration: none;
-	display: inline-block;
-	font-size: 14px;
-	border-radius: 200px;
-	font-weight: bold;
-	margin-right: 15px;
-	margin-bottom: 30px;
+  background-color: #000;
+  border: 2px solid var(--fg);
+  color: var(--bg);
+  padding: 13px 28px;
+  text-align: center;
+  text-decoration: none;
+  display: inline-block;
+  /*font-size: 14px;*/
+  border-radius: 200px;
+  font-weight: bold;
+  margin-right: 15px;
+  margin-bottom: 30px;
 }
 
 main .button:hover {
-	background-color: #333 !important;
-	color: var(--bg);
-	cursor: pointer;
+  background-color: #333 !important;
+  color: var(--bg);
+  cursor: pointer;
 }
 
 main .button small {
-	color: var(--fg);
+  color: var(--fg);
 }
 
 body select {
-	color: var(--fg);
-	margin-bottom: 20px
+  color: var(--fg);
+  margin-bottom: 20px
 }
 
 main table.drpdown {
-	padding-bottom: 15px;
-	font-size: 18px
+  padding-bottom: 15px;
+  /*font-size: 18px*/
 }
 
 main table.drpdown td {
-	padding-bottom: 15px;
-	color: var(--fg);
+  padding-bottom: 15px;
+  color: var(--fg);
 }
 
 main>table.col tr th {
-	text-align: left
+  text-align: left
 }
 
 main>table.col tr td {
-	border-right: 1.5px solid var(--fg)
+  border-right: 1.5px solid var(--fg)
 }
 
 main>table.col tr>* {
-	padding: 5px 20px
+  padding: 5px 20px
 }
 
 main>table.col tr td:last-child {
-	border-right: 0px
+  border-right: 0px
 }
 
 main>table.col tr>*:first-child {
-	padding-left: 0px
+  padding-left: 0px
 }
 
 main>table.col b {
-	font-weight: bold
+  font-weight: bold
 }
 
 main .progress {
-	padding: 2px;
-	width: 100%;
-	max-width: 100%;
-	border: 1px solid grey
+  padding: 2px;
+  width: 100%;
+  max-width: 100%;
+  border: 1px solid grey
 }
 
 main .progress>div {
-	height: 100%;
-	width: 100%;
-	background-color: var(--fg)
+  height: 100%;
+  width: 100%;
+  background-color: var(--fg)
 }
 
 main .progress>div>span {
-	color: var(--bg);
-	padding: 0px 2px
+  color: var(--bg);
+  padding: 0px 2px
 }
 
 main img.detail {
-	max-width: 64px;
-	border: 1px solid #777;
-	padding: 20px;
-	margin: 0px 20px 20px 0px;
-	border-radius: 3px;
+  max-width: 64px;
+  border: 1px solid #777;
+  padding: 20px;
+  margin: 0px 20px 20px 0px;
+  border-radius: 3px;
 }
 
 main .shortcut,
 main kbd {
-	background: var(--bg);
-	color: var(--fg);
-	display: inline-block;
-	padding: 2px 5px;
-	margin: 0px;
-	font-size: 12px;
-	line-height: 16px;
-	border-radius: 2px;
-	font-weight: bold
+  background: var(--bg);
+  color: var(--fg);
+  display: inline-block;
+  padding: 2px 5px;
+  margin: 0px;
+  /*font-size: 12px;*/
+  line-height: var(--body-line-height);
+  border-radius: 2px;
+  font-weight: bold
 }
 
 main .shortcut-list dt,
 main .shortcut-list dd {
-	display: inline;
-	line-height: 25px;
-	margin-left: 0;
-	margin-right: 10px;
+  display: inline;
+  line-height: var(--body-line-height);
+  margin-left: 0;
+  margin-right: 10px;
 }
 
 main>table.logbook tr td {
-	padding-bottom: 15px;
-	padding-top: 15px;
+  padding-bottom: 15px;
+  padding-top: 15px;
 }
 
 main>table img {
-	max-width: 100%;
-	display: block;
-	margin: 20px 0;
+  max-width: 100%;
+  display: block;
+  margin: 20px 0;
 }
 
 main>table tr th {
-	text-align: left;
-	font-weight: bold
+  text-align: left;
+  font-weight: bold
 }
 
 main>table tr>* {
-	padding: 5px 15px;
-	vertical-align: top;
+  padding: 5px 15px;
+  vertical-align: top;
 }
 
 main span.date {
-	font-family: monospace;
-	padding-bottom: 20px;
-	float: right;
+  font-family: monospace;
+  display: inline-block;
+  width: 100%;
+  text-align: end;
+}
+
+main>section.table-of-contents {
+  /*max-width: 30ch;*/
+
+  position: sticky;
+  top: 1rem;
+
+  float: right;
+  margin-right: -22ch;
+}
+
+main>section.table-of-contents>nav {
+  float: unset;
+}
+
+main>section.table-of-contents>nav>ol>:first-child {
+  text-transform: none;
+  line-height: 2.0;
 }
 
 main>section#footnotes {
-	margin-bottom: 0;
-	font-size: 12px;
+  margin-bottom: 0;
+  font-size: smaller;
+}
+
+.footnote-back {
+  margin-left: 1ch;
 }
 
 
 footer {
-	border-top: 1px solid color-mix(in srgb, var(--fg) 20%, var(--bg));
-	padding-top: var(--body-spacing);
-	line-height: 25px;
-	clear: both;
+  border-top: 1px solid color-mix(in srgb, var(--fg) 20%, var(--bg));
+  padding-top: var(--body-spacing);
+  line-height: var(--body-line-height);
+  clear: both;
 }
 
 /* Modular */
 
 a {
-	color: var(--fg);
+  color: var(--fg);
 }
 
+ol,
 ul {
-	margin: 0px 0px 30px 0px;
+  margin: 0px 0px 30px 0px;
 }
 
 .col2 {
-	columns: 2
+  columns: 2
 }
 
 .capital {
-	text-transform: capitalize
+  text-transform: capitalize
+}
+
+.nocapital {
+  text-transform: unset !important;
 }
 
 .notice {
-	padding: 15px;
-	border: 1px solid var(--ac);
-	background-color: color-mix(in srgb, var(--ac) 10%, var(--bg));
-	color: color-mix(in srgb, var(--fg) 90%, var(--bg));
-	font-size: 12px;
+  padding: 15px;
+  border: 1px solid var(--ac);
+  background-color: color-mix(in srgb, var(--ac) 10%, var(--bg));
+  color: color-mix(in srgb, var(--fg) 90%, var(--bg));
+}
+
+.notice,
+.notice>* {
+  font-size: 0.8rem;
 }
 
 .notice h1 {
-	text-align: end;
-	font-size: 14px;
-	text-transform: capitalize;
+  text-align: end;
+  font-size: 0.9rem;
+  text-transform: capitalize;
 }
 
 ul.nobull li {
-	list-style-type: none
+  list-style-type: none
 }
 
 .hidden {
-	display: none
+  display: none
 }
 
 /* Theme */
 
 @media (prefers-color-scheme: dark) {
-	:root {
-		--fg: var(--white);
-		--bg: var(--black);
-	}
+  :root {
+    --fg: var(--white);
+    --bg: var(--black);
+  }
 
-	.mono {
-		filter: invert(1)
-	}
+  .mono {
+    filter: invert(1)
+  }
 }
 
 /* Mobile */
 
 @media (max-width: 1100px) {
-	:root {
-		--body-spacing: 25px;
-	}
+  :root {
+    --body-spacing: 25px;
+  }
 
-	nav {
-		float: none;
-	}
+  nav {
+    float: none;
+  }
 
-	nav .site-nav section {
-		display: inline-block;
-		margin: 0 10px 10px 0;
-	}
+  nav .site-nav section {
+    display: inline-block;
+    margin: 0 10px 10px 0;
+  }
 }
 
 @media (max-width: 1100px) and (min-width: 651px) {
-	nav .site-nav section {
-		width: calc(25% - 10px);
-	}
+  nav .site-nav section {
+    width: calc(25% - 10px);
+  }
 
-	nav .site-nav section:nth-child(4n + 1) {
-		clear: left;
-	}
+  nav .site-nav section:nth-child(4n + 1) {
+    clear: left;
+  }
 }
 
 @media (max-width: 650px) and (min-width: 501px) {
-	nav .site-nav section {
-		width: calc(33% - 10px);
-	}
+  nav .site-nav section {
+    width: calc(33% - 10px);
+  }
 
-	nav .site-nav section:nth-child(3n + 1) {
-		clear: left;
-	}
+  nav .site-nav section:nth-child(3n + 1) {
+    clear: left;
+  }
 }
 
 @media (max-width: 500px) and (min-width: 351px) {
-	nav .site-nav section {
-		width: calc(50% - 10px);
-	}
+  nav .site-nav section {
+    width: calc(50% - 10px);
+  }
 
-	nav .site-nav section:nth-child(2n + 1) {
-		clear: left;
-	}
+  nav .site-nav section:nth-child(2n + 1) {
+    clear: left;
+  }
 }
 
 @media (max-width: 350px) {
-	nav .site-nav section {
-		width: 100%;
-	}
+  nav .site-nav section {
+    width: 100%;
+  }
 }
diff --git a/makefile b/makefile
index 5a5e6fd..b36f10b 100644
--- a/makefile
+++ b/makefile
@@ -8,8 +8,8 @@ SRC     := $(htm_SRC) $(md_SRC:%.md=%.htm)
 DST     := site
 
 # see https://pandoc.org/MANUAL.html#pandocs-markdown
-%.htm: %.md
-	$(PANDOC) --from=markdown --to=html --output $@ $<
+%.htm: %.md front.lua
+	$(PANDOC) -fmarkdown -thtml5 --lua-filter=front.lua -o $@ $<
 
 # generator
 ZIG     ?= zig
diff --git a/src/main.zig b/src/main.zig
index 392a75c..e4301b3 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -203,7 +203,7 @@ fn build(allocator: std.mem.Allocator, f: std.fs.File, page_name: []const u8, sr
         \\
         \\<!-- Generated file, do not edit -->
         \\
-        \\<h1>{[PAGE_NAME]s}</h1>
+        \\<h1 id="title">{[PAGE_NAME]s}</h1>
         \\
     , .{
         .PAGE_NAME = page_name,