aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDeniz Akşimşek <deniz@denizaksimsek.com>2022-05-16 12:27:01 +0300
committerDeniz Akşimşek <deniz@denizaksimsek.com>2022-05-16 12:27:01 +0300
commit44d2d6d244b575a3960f0f9adfeaf5a9810b43a1 (patch)
tree3c94bf0956772d783093885c3082efbf52441373
parent77df6301f193eed1917ca30e5bf31f689302e2b5 (diff)
downloadmissing-44d2d6d244b575a3960f0f9adfeaf5a9810b43a1.tar.gz
missing-44d2d6d244b575a3960f0f9adfeaf5a9810b43a1.zip
Switch to Deno & Lume
Minified CSS build doesn't work. There are some weird character encoding glitches.
-rw-r--r--.vscode/settings.json3
-rw-r--r--build/postcss.js75
-rw-r--r--build/postcss.ts69
-rw-r--r--deno.json7
-rw-r--r--import_map.json5
-rw-r--r--www/_build/filters.ts55
-rw-r--r--www/_build/get-dates-from-git.ts28
-rw-r--r--www/_build/highlighting.ts16
-rw-r--r--www/_build/util.ts16
-rw-r--r--www/_config.ts42
-rw-r--r--www/_includes/layout.eta (renamed from www/includes/layout.html)4
-rw-r--r--www/_includes/prose.eta7
-rw-r--r--www/demos.md8
-rw-r--r--www/demos/blogpost.html2
-rw-r--r--www/demos/cards.html2
-rw-r--r--www/demos/grid.html2
-rw-r--r--www/demos/html5.html2
-rw-r--r--www/demos/landing-page.html2
-rw-r--r--www/demos/shell.html2
-rw-r--r--www/demos/tabs.html2
-rw-r--r--www/docs/docs.json2
-rw-r--r--www/includes/prose.html7
-rw-r--r--www/index.md2
-rw-r--r--www/pages/concepts.md2
-rw-r--r--www/pages/rfp.md2
-rw-r--r--www/playground.html2
26 files changed, 265 insertions, 101 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json
index fe2f34f..32b38a8 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -6,5 +6,6 @@
"titleBar.inactiveBackground": "#5a938099",
"titleBar.inactiveForeground": "#e7e7e799"
},
- "peacock.color": "#5a9380"
+ "peacock.color": "#5a9380",
+ "deno.enable": true
} \ No newline at end of file
diff --git a/build/postcss.js b/build/postcss.js
deleted file mode 100644
index 0111630..0000000
--- a/build/postcss.js
+++ /dev/null
@@ -1,75 +0,0 @@
-import { readFile, mkdir, writeFile } from 'node:fs/promises'
-import { join, dirname } from 'node:path'
-import { fileURLToPath } from 'node:url'
-import { brotliCompress as brotli, gzip } from 'node:zlib'
-
-import postcss from 'postcss'
-
-// Plugins
-import presetEnv from 'postcss-preset-env'
-import atImport from 'postcss-import'
-import importGlob from 'postcss-import-ext-glob'
-import mixins from 'postcss-mixins'
-import cssnano from 'cssnano'
-
-
-// Paths
-const __dirname = dirname(fileURLToPath(import.meta.url))
-
-const entrypoint = join(__dirname, '../src/main.css')
-const dist = join(__dirname, '../dist/')
-
-const prodTarget = join(dist, '/missing.min.css')
-const devTarget = join(dist, '/missing.css')
-
-
-const build = async () => {
- const postcssMain = postcss([
- importGlob(),
- atImport(),
- presetEnv({
- browsers: 'supports css-variables',
- stage: 0,
- features: {
- 'custom-properties': false,
- },
- }),
- mixins(),
- ])
-
- const postcssMinifier = postcss([cssnano({ preset: 'default' })])
-
- const css = await readFile(entrypoint, { encoding: 'utf8' })
-
- await mkdir(dist, { recursive: true })
-
- const result =
- await postcssMain.process(css, { from: entrypoint, to: devTarget })
- await w(result.css, devTarget)
-
- const { css: minifiedCSS } =
- await postcssMinifier.process(result, { from: entrypoint, to: prodTarget })
- await w(minifiedCSS, prodTarget)
-
- await Promise.all([
- compress(minifiedCSS, brotli).then(c => w(c, prodTarget + ".br")),
- compress(minifiedCSS, gzip ).then(c => w(c, prodTarget + ".gz")),
- ])
-}
-
-const compress = (data, compressor) => new Promise((resolve, reject) =>
- compressor(data, (err, compressed) => {
- if (err) reject(err)
- else resolve(compressed)
- })
-)
-
-const w = async (data, path) => {
- await writeFile(path, data, { flag: "w" })
- console.log("Wrote " + path)
-}
-
-build()
-
-export default build
-
diff --git a/build/postcss.ts b/build/postcss.ts
new file mode 100644
index 0000000..15bd000
--- /dev/null
+++ b/build/postcss.ts
@@ -0,0 +1,69 @@
+
+import { join, dirname, fromFileUrl } from 'https://deno.land/std@0.139.0/path/mod.ts'
+
+import { gzip } from "https://deno.land/x/compress@v0.4.5/mod.ts"
+import { compress as brotli } from 'https://deno.land/x/brotli@v0.1.4/mod.ts'
+
+import postcss from "https://esm.sh/postcss@8.4.13"
+
+// Plugins
+import nesting from 'https://esm.sh/postcss-nesting?deps=postcss@8.4.13'
+import customSelectors from 'https://esm.sh/postcss-custom-selectors?deps=postcss@8.4.13'
+import atImport from 'https://esm.sh/postcss-import?deps=postcss@8.4.13'
+import importGlob from 'https://esm.sh/postcss-import-ext-glob?deps=postcss@8.4.13'
+import mixins from 'https://esm.sh/postcss-mixins?deps=postcss@8.4.13'
+import cssnano from 'https://esm.sh/cssnano?deps=postcss@8.4.13'
+
+// Paths
+const __dirname = dirname(fromFileUrl(import.meta.url))
+
+const entrypoint = join(__dirname, '../src/main.css')
+const dist = join(__dirname, '../dist/')
+
+const prodTarget = join(dist, '/missing.min.css')
+const devTarget = join(dist, '/missing.css')
+
+const dec = new TextDecoder
+const enc = new TextEncoder
+
+const build = async () => {
+ const postcssMain = postcss([
+ nesting(),
+ customSelectors(),
+ importGlob(),
+ atImport(),
+ mixins(),
+ ])
+
+ // const postcssMinifier = postcss([cssnano({ preset: 'default' })])
+
+ const css = dec.decode(await Deno.readFile(entrypoint))
+
+ await Deno.mkdir(dist, { recursive: true })
+
+ const result =
+ await postcssMain.process(css, { from: entrypoint, to: devTarget })
+ const outputCss = enc.encode(result.css)
+ await w(outputCss, devTarget)
+
+ // const minifyResult =
+ // await postcssMinifier.process(result, { from: entrypoint, to: prodTarget })
+ // const minifiedCSS = enc.encode(minifyResult.css)
+ // await w(minifiedCSS, prodTarget)
+
+ // await Promise.all([
+ // w(brotli(minifiedCSS), prodTarget + ".br"),
+ // w(gzip (minifiedCSS), prodTarget + ".gz"),
+ // ])
+}
+
+
+const w = async (data: Uint8Array, path: string | URL) => {
+ await Deno.writeFile(path, data)
+ console.log("Wrote " + path)
+}
+
+build()
+
+export default build
+
diff --git a/deno.json b/deno.json
new file mode 100644
index 0000000..e56e2ba
--- /dev/null
+++ b/deno.json
@@ -0,0 +1,7 @@
+{
+ "importMap": "import_map.json",
+ "tasks": {
+ "build": "deno run -A https://deno.land/x/lume@v1.7.4/ci.ts --config=www/_config.ts",
+ "serve": "deno task build -- -s"
+ }
+} \ No newline at end of file
diff --git a/import_map.json b/import_map.json
new file mode 100644
index 0000000..6610cfe
--- /dev/null
+++ b/import_map.json
@@ -0,0 +1,5 @@
+{
+ "imports": {
+ "lume/": "https://deno.land/x/lume@v1.7.4/"
+ }
+} \ No newline at end of file
diff --git a/www/_build/filters.ts b/www/_build/filters.ts
new file mode 100644
index 0000000..460be6e
--- /dev/null
+++ b/www/_build/filters.ts
@@ -0,0 +1,55 @@
+import type { Site } from "lume/core.ts";
+
+/**
+ * Includes the filters:
+ * - `peekHtml` for generating a text extract from HTML
+ * - `repeat`, a loop with extra features
+ */
+export default () => {
+ return (site: Site) => {
+ site.filter("peekHtml", peekHtml)
+ site.filter("repeat", repeat)
+ }
+}
+
+function peekHtml(html: string, n: number = 80) {
+ const text = html.replace(/<\/?[^>]+(>|$)/g, "").replace(/\s+/g, " ")
+ if (text.length < n) return text
+ else return text.slice(0, n - 1) + "…"
+}
+
+interface LoopContext {
+ i: number
+ first: boolean
+ last?: boolean
+ sep(s: string): string
+}
+
+function repeat<T>(
+ root: Iterable<T>,
+ cb: (t: T, loop: LoopContext) => void
+): void {
+ // deno-lint-ignore no-explicit-any
+ function hasLength(a: any): a is { length: number } {
+ return "length" in a && typeof a.length === "number"
+ }
+
+ let i = 0
+ for (const t of root) {
+ const ctx: LoopContext = {
+ i,
+ first: i === 0,
+ sep(s) {
+ return this.last ? "" : s
+ }
+ }
+
+ if (hasLength(root)) {
+ ctx.last = i === root.length - 1
+ }
+
+ cb(t, ctx)
+ i++
+ }
+}
+
diff --git a/www/_build/get-dates-from-git.ts b/www/_build/get-dates-from-git.ts
new file mode 100644
index 0000000..7f65a1e
--- /dev/null
+++ b/www/_build/get-dates-from-git.ts
@@ -0,0 +1,28 @@
+import type { Site, Page } from "lume/core.ts";
+import { exec } from "./util.ts";
+
+/**
+ * Set created and last modified dates for pages by looking at Git history.
+ */
+export default () => {
+ return (site: Site) => {
+ site.preprocess("*", async (page: Page) => {
+ // Pull content dates from git.
+
+ const gitLog = await exec([
+ "git", "log", // git commits
+ "--follow", // handle renames
+ "--format=%aI", // commit date, as ISO date
+ "www" + page.src.path + page.src.ext // for this file
+ ])
+
+ const dates = gitLog.split("\n")
+ dates.pop() // remove trailing newline
+
+ if (dates.length === 0) return
+
+ if (dates.length > 1) page.data["last modified"] = new Date(dates[0])
+ page.data.date = new Date(dates[dates.length - 1])
+ })
+ }
+}
diff --git a/www/_build/highlighting.ts b/www/_build/highlighting.ts
new file mode 100644
index 0000000..b314688
--- /dev/null
+++ b/www/_build/highlighting.ts
@@ -0,0 +1,16 @@
+
+import prismHighlight from "https://raw.githubusercontent.com/lumeland/experimental-plugins/main/prism/mod.ts"
+import Prism from "https://raw.githubusercontent.com/lumeland/experimental-plugins/main/prism/deps.ts"
+import prismHyperscript from "https://esm.sh/prism-hyperscript"
+import type { Site } from "lume/core.ts"
+
+/**
+ * Highlight code, including _hyperscript, with Prism.
+ */
+export default () => {
+ prismHyperscript(Prism)
+
+ return (site: Site) => {
+ site.use(prismHighlight())
+ }
+}
diff --git a/www/_build/util.ts b/www/_build/util.ts
new file mode 100644
index 0000000..8425d6a
--- /dev/null
+++ b/www/_build/util.ts
@@ -0,0 +1,16 @@
+
+export async function exec(cmd: string[]) {
+ const proc = await Deno.run({
+ cmd,
+ stdout: "piped",
+ stdin: "null"
+ })
+
+ let str = ""
+ const decoder = new TextDecoder
+ const buf = new Uint8Array(1024);
+ const n = await proc.stdout.read(buf) as number
+ str += decoder.decode(buf.subarray(0, n))
+
+ return str
+}
diff --git a/www/_config.ts b/www/_config.ts
new file mode 100644
index 0000000..498a49d
--- /dev/null
+++ b/www/_config.ts
@@ -0,0 +1,42 @@
+
+import "https://deno.land/x/dotenv@v3.2.0/load.ts"
+
+import lume from "lume/mod.ts"
+import date from "lume/plugins/date.ts"
+import basePath from "lume/plugins/base_path.ts"
+import resolveUrls from "lume/plugins/resolve_urls.ts"
+import eta from "lume/plugins/eta.ts"
+
+import highlighting from "./_build/highlighting.ts"
+import getDatesFromGit from "./_build/get-dates-from-git.ts"
+import myFilters from "./_build/filters.ts"
+
+import mdAttrs from "https://esm.sh/markdown-it-attrs"
+import mdDeflist from "https://esm.sh/markdown-it-deflist"
+import mdContainer from "https://esm.sh/@gerhobbelt/markdown-it-container"
+
+import postcss from "../build/postcss.ts"
+
+export default lume(
+ {
+ location: new URL("https://missing.style/"),
+ src: "www",
+ dest: "dist",
+ }, {
+ markdown: {
+ plugins: [
+ mdAttrs,
+ mdDeflist,
+ [mdContainer, "box"],
+ ]
+ }
+ }
+ )
+ .addEventListener("afterBuild", postcss)
+ .use(date())
+ .use(highlighting())
+ .use(basePath())
+ .use(resolveUrls())
+ .use(eta())
+ .use(myFilters())
+ .use(getDatesFromGit())
diff --git a/www/includes/layout.html b/www/_includes/layout.eta
index 6906d2f..32d6088 100644
--- a/www/includes/layout.html
+++ b/www/_includes/layout.eta
@@ -2,7 +2,7 @@
---
<!doctype html>
-<html lang="{{ lang | d(en) }}">
+<html lang="<%= it.lang ?? "en" %>">
<head>
<meta charset="utf=8">
<meta name="viewport" content="width=device-width">
@@ -11,7 +11,7 @@
<script src="https://unpkg.com/hyperscript.org"></script>
</head>
<body>
- {{ content | safe }}
+ <%~ content %>
<footer>
<p><a href="/">Missing.css</a>, from
diff --git a/www/_includes/prose.eta b/www/_includes/prose.eta
new file mode 100644
index 0000000..6037d7a
--- /dev/null
+++ b/www/_includes/prose.eta
@@ -0,0 +1,7 @@
+---
+layout: layout.eta
+---
+
+<main>
+ <%~ content %>
+</main>
diff --git a/www/demos.md b/www/demos.md
index f2417d6..b4f21a7 100644
--- a/www/demos.md
+++ b/www/demos.md
@@ -1,5 +1,5 @@
---
-layout: layout.html
+layout: layout.eta
---
<main>
@@ -7,9 +7,9 @@ layout: layout.html
# Demos
<ul class='list-of-links'>
-{% for demo in collections.demos -%}
-<li><p><a href="{{demo.url}}">{{demo.data.name}}</a>
-{% endfor %}
+<% for (const demo in collections.demos _%>
+<li><p><a href="<%= demo.url %>"><%= demo.data.name %></a>
+<% } %>
</ul>
</main>
diff --git a/www/demos/blogpost.html b/www/demos/blogpost.html
index efed34a..7d0e0f5 100644
--- a/www/demos/blogpost.html
+++ b/www/demos/blogpost.html
@@ -1,6 +1,6 @@
---
name: Blog post
-layout: layout.html
+layout: layout.eta
---
<main>
diff --git a/www/demos/cards.html b/www/demos/cards.html
index daebd0e..23adec1 100644
--- a/www/demos/cards.html
+++ b/www/demos/cards.html
@@ -1,5 +1,5 @@
---
-layout: layout.html
+layout: layout.eta
name: Cards
---
diff --git a/www/demos/grid.html b/www/demos/grid.html
index 798b8e6..c5ab2c0 100644
--- a/www/demos/grid.html
+++ b/www/demos/grid.html
@@ -1,5 +1,5 @@
---
-layout: layout.html
+layout: layout.eta
name: Grid
---
diff --git a/www/demos/html5.html b/www/demos/html5.html
index 57895f9..4ba1e90 100644
--- a/www/demos/html5.html
+++ b/www/demos/html5.html
@@ -1,5 +1,5 @@
---
-layout: layout.html
+layout: layout.eta
name: HTML5 Element Catalog
---
diff --git a/www/demos/landing-page.html b/www/demos/landing-page.html
index a7b2692..aad0833 100644
--- a/www/demos/landing-page.html
+++ b/www/demos/landing-page.html
@@ -1,5 +1,5 @@
---
-layout: layout.html
+layout: layout.eta
name: Landing Page
---
diff --git a/www/demos/shell.html b/www/demos/shell.html
index 1bc46cb..80676d8 100644
--- a/www/demos/shell.html
+++ b/www/demos/shell.html
@@ -1,5 +1,5 @@
---
-layout: layout.html
+layout: layout.eta
name: Shell
---
diff --git a/www/demos/tabs.html b/www/demos/tabs.html
index 4644354..f7794b0 100644
--- a/www/demos/tabs.html
+++ b/www/demos/tabs.html
@@ -1,5 +1,5 @@
---
-layout: layout.html
+layout: layout.eta
name: Tabs
---
diff --git a/www/docs/docs.json b/www/docs/docs.json
index c19f8c4..f03e27b 100644
--- a/www/docs/docs.json
+++ b/www/docs/docs.json
@@ -1,3 +1,3 @@
{
- "layout": "prose.html"
+ "layout": "prose.eta"
} \ No newline at end of file
diff --git a/www/includes/prose.html b/www/includes/prose.html
deleted file mode 100644
index 4c88c0b..0000000
--- a/www/includes/prose.html
+++ /dev/null
@@ -1,7 +0,0 @@
----
-layout: layout.html
----
-
-<main>
- {{ content | safe }}
-</main>
diff --git a/www/index.md b/www/index.md
index ce30715..da19e9b 100644
--- a/www/index.md
+++ b/www/index.md
@@ -1,5 +1,5 @@
---
-layout: layout.html
+layout: layout.eta
---
<main>
diff --git a/www/pages/concepts.md b/www/pages/concepts.md
index f5cadd1..dbd4fd6 100644
--- a/www/pages/concepts.md
+++ b/www/pages/concepts.md
@@ -1,6 +1,6 @@
---
permalink: concepts/
-layout: prose.html
+layout: prose.eta
---
# Concepts
diff --git a/www/pages/rfp.md b/www/pages/rfp.md
index 65719c7..bbfa865 100644
--- a/www/pages/rfp.md
+++ b/www/pages/rfp.md
@@ -1,6 +1,6 @@
---
permalink: rfp/
-layout: prose.html
+layout: prose.eta
---
# missing CSS Library RFP
diff --git a/www/playground.html b/www/playground.html
index c0c22d6..8addcde 100644
--- a/www/playground.html
+++ b/www/playground.html
@@ -1,5 +1,5 @@
---
-layout: layout.html
+layout: layout.eta
permalink: /playground/
---