From 20867a62c3ec50c9ce79d8af82e35050aa8790c5 Mon Sep 17 00:00:00 2001 From: giles Date: Sun, 7 Jun 2026 02:55:23 +0000 Subject: [PATCH] content: SEO page-full w/ meta description (page-full.sx) + 4 tests (485/485) Co-Authored-By: Claude Opus 4.8 (1M context) --- lib/content/conformance.sh | 3 ++- lib/content/page-full.sx | 23 ++++++++++++++++++++ lib/content/scoreboard.json | 5 +++-- lib/content/scoreboard.md | 3 ++- lib/content/tests/page-full.sx | 39 ++++++++++++++++++++++++++++++++++ plans/content-on-sx.md | 7 +++++- 6 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 lib/content/page-full.sx create mode 100644 lib/content/tests/page-full.sx diff --git a/lib/content/conformance.sh b/lib/content/conformance.sh index f4382aa4..664dd8ea 100755 --- a/lib/content/conformance.sh +++ b/lib/content/conformance.sh @@ -15,7 +15,7 @@ if [ ! -x "$SX_SERVER" ]; then fi fi -SUITES=(block doc render api meta page markdown text section stats table validate store snapshot crdt crdt-store sync md-import md-doc fed) +SUITES=(block doc render api meta page page-full markdown text section stats table validate store snapshot crdt crdt-store sync md-import md-doc fed) OUT_JSON="lib/content/scoreboard.json" OUT_MD="lib/content/scoreboard.md" @@ -48,6 +48,7 @@ run_suite() { (load "lib/content/stats.sx") (load "lib/content/table.sx") (load "lib/content/page.sx") +(load "lib/content/page-full.sx") (load "lib/content/markdown.sx") (load "lib/content/validate.sx") (load "lib/content/store.sx") diff --git a/lib/content/page-full.sx b/lib/content/page-full.sx new file mode 100644 index 00000000..b941aaba --- /dev/null +++ b/lib/content/page-full.sx @@ -0,0 +1,23 @@ +;; content-on-sx — SEO-complete HTML page. +;; +;; content/page-full extends content/page with a lang attribute and a +;; drawn from the document excerpt (plain text, +;; truncated). Composes the page, metadata and text layers. +;; +;; Requires (loaded by harness): page.sx (ct-html-escape, content/page-title), +;; text.sx (content/excerpt), render.sx (asHTML). + +(define CONTENT-EXCERPT-LEN 160) + +(define + content/page-full + (fn + (doc) + (str + "" + (ct-html-escape (content/page-title doc)) + "" + (asHTML doc) + ""))) diff --git a/lib/content/scoreboard.json b/lib/content/scoreboard.json index 289c7a8f..580c50e6 100644 --- a/lib/content/scoreboard.json +++ b/lib/content/scoreboard.json @@ -6,6 +6,7 @@ "api": {"pass": 26, "fail": 0}, "meta": {"pass": 27, "fail": 0}, "page": {"pass": 7, "fail": 0}, + "page-full": {"pass": 4, "fail": 0}, "markdown": {"pass": 20, "fail": 0}, "text": {"pass": 20, "fail": 0}, "section": {"pass": 25, "fail": 0}, @@ -21,7 +22,7 @@ "md-doc": {"pass": 12, "fail": 0}, "fed": {"pass": 20, "fail": 0} }, - "total_pass": 481, + "total_pass": 485, "total_fail": 0, - "total": 481 + "total": 485 } diff --git a/lib/content/scoreboard.md b/lib/content/scoreboard.md index d5824dd6..78bd17db 100644 --- a/lib/content/scoreboard.md +++ b/lib/content/scoreboard.md @@ -10,6 +10,7 @@ _Generated by `lib/content/conformance.sh`_ | api | 26 | 0 | 26 | | meta | 27 | 0 | 27 | | page | 7 | 0 | 7 | +| page-full | 4 | 0 | 4 | | markdown | 20 | 0 | 20 | | text | 20 | 0 | 20 | | section | 25 | 0 | 25 | @@ -24,4 +25,4 @@ _Generated by `lib/content/conformance.sh`_ | md-import | 38 | 0 | 38 | | md-doc | 12 | 0 | 12 | | fed | 20 | 0 | 20 | -| **Total** | **481** | **0** | **481** | +| **Total** | **485** | **0** | **485** | diff --git a/lib/content/tests/page-full.sx b/lib/content/tests/page-full.sx new file mode 100644 index 00000000..6e10affd --- /dev/null +++ b/lib/content/tests/page-full.sx @@ -0,0 +1,39 @@ +;; Extension — SEO-complete HTML page (lang + meta description). + +(st-bootstrap-classes!) +(content/bootstrap!) +(content-bootstrap-text!) + +(define + d + (doc-with-title + (doc-append + (doc-append (doc-empty "post") (mk-heading "h" 1 "Hi")) + (mk-text "p" "Hello world")) + "My Title")) + +(content-test + "page-full" + (content/page-full d) + "My Title

Hi

Hello world

") + +;; description escaped +(content-test + "page-full escapes description" + (content/page-full + (doc-with-title + (doc-append (doc-empty "x") (mk-text "p" "a < b & c")) + "T")) + "T

a < b & c

") + +;; title falls back to id, empty description for empty doc +(content-test + "page-full empty" + (content/page-full (doc-empty "fallback")) + "fallback") + +;; body reflects edits +(content-test + "page-full reflects edits" + (content/page-full (doc-update d "p" "text" "Bye now")) + "My Title

Hi

Bye now

") diff --git a/plans/content-on-sx.md b/plans/content-on-sx.md index 7800b3f9..222846ae 100644 --- a/plans/content-on-sx.md +++ b/plans/content-on-sx.md @@ -19,7 +19,7 @@ injected adapter, not core. ## Status (rolling) -`bash lib/content/conformance.sh` → **481/481** (Phases 1–4 COMPLETE + extensions: HTML/SX escaping, Markdown render + import/export incl. tables & frontmatter (full round-trip), CRDT replication, tree-aware validation, snapshot cache, doc metadata, plain-text render, nested block trees, doc stats, table block, HTML page wrapper) +`bash lib/content/conformance.sh` → **485/485** (Phases 1–4 COMPLETE + extensions: HTML/SX escaping, Markdown render + import/export incl. tables & frontmatter (full round-trip), CRDT replication, tree-aware validation, snapshot cache, doc metadata, plain-text render, nested block trees, doc stats, table block, HTML page wrapper + SEO page) ## Ground rules @@ -90,9 +90,14 @@ lib/content/api.sx ── (content/edit) (content/render) (content/history) ─ - [x] document statistics (`stats.sx`: word/char/block counts, reading time) - [x] table block (`table.sx`: CtTable, renders html/sx/text/md, validated) - [x] HTML page wrapper (`page.sx`: content/page, escaped title from metadata) +- [x] SEO page (`page-full.sx`: content/page-full, lang + meta description from excerpt) ## Progress log +- 2026-06-07 — Extension: SEO-complete page (`page-full.sx`). `content/page-full` + extends content/page with `` and a `` + drawn from the document excerpt (plain text, escaped, 160 chars), composing the + page/metadata/text layers into the SEO-ready artifact. 4 tests; suite 485/485. - 2026-06-07 — Extension: Markdown document export (`md-doc.sx`). `content/markdown-doc` emits a `---` frontmatter block from metadata (title/slug/tags, only present fields) ahead of the Markdown body, or plain