diff --git a/lib/content/block.sx b/lib/content/block.sx index d4aabf06..4aec68ef 100644 --- a/lib/content/block.sx +++ b/lib/content/block.sx @@ -15,6 +15,10 @@ ;; CtEmbed (url provider) ;; CtDivider ;; CtList (ordered items) +;; Plus self-contained blocks registered by their own files: CtSection, +;; CtTable, CtCallout, CtMedia. ct-class-for-type maps every tag (so mk-block, +;; content/from-data and CRDT materialise build them uniformly); the classes +;; themselves are registered by content-bootstrap-section!/table!/callout!/media!. (define ct-def-method! @@ -87,6 +91,10 @@ ((= tag "embed") "CtEmbed") ((= tag "divider") "CtDivider") ((= tag "list") "CtList") + ((= tag "section") "CtSection") + ((= tag "table") "CtTable") + ((= tag "callout") "CtCallout") + ((= tag "media") "CtMedia") (else (error (str "unknown block type: " tag)))))) ;; Generic constructor — wire tag + id + (name value) field pairs. diff --git a/lib/content/scoreboard.json b/lib/content/scoreboard.json index 648f3581..bd3c1bc1 100644 --- a/lib/content/scoreboard.json +++ b/lib/content/scoreboard.json @@ -28,7 +28,7 @@ "table": {"pass": 15, "fail": 0}, "callout": {"pass": 12, "fail": 0}, "media": {"pass": 15, "fail": 0}, - "data": {"pass": 21, "fail": 0}, + "data": {"pass": 25, "fail": 0}, "wire": {"pass": 11, "fail": 0}, "validate": {"pass": 23, "fail": 0}, "store": {"pass": 29, "fail": 0}, @@ -41,7 +41,7 @@ "md-doc": {"pass": 12, "fail": 0}, "fed": {"pass": 20, "fail": 0} }, - "total_pass": 727, + "total_pass": 731, "total_fail": 0, - "total": 727 + "total": 731 } diff --git a/lib/content/scoreboard.md b/lib/content/scoreboard.md index 885ba020..65aeabd4 100644 --- a/lib/content/scoreboard.md +++ b/lib/content/scoreboard.md @@ -32,7 +32,7 @@ _Generated by `lib/content/conformance.sh`_ | table | 15 | 0 | 15 | | callout | 12 | 0 | 12 | | media | 15 | 0 | 15 | -| data | 21 | 0 | 21 | +| data | 25 | 0 | 25 | | wire | 11 | 0 | 11 | | validate | 23 | 0 | 23 | | store | 29 | 0 | 29 | @@ -44,4 +44,4 @@ _Generated by `lib/content/conformance.sh`_ | md-import | 38 | 0 | 38 | | md-doc | 12 | 0 | 12 | | fed | 20 | 0 | 20 | -| **Total** | **727** | **0** | **727** | +| **Total** | **731** | **0** | **731** | diff --git a/lib/content/tests/data.sx b/lib/content/tests/data.sx index 33eca9e5..9459758b 100644 --- a/lib/content/tests/data.sx +++ b/lib/content/tests/data.sx @@ -6,6 +6,8 @@ (content-bootstrap-markdown!) (content-bootstrap-section!) (content-bootstrap-table!) +(content-bootstrap-callout!) +(content-bootstrap-media!) ;; ── block->data shape ── (define h (mk-heading "h" 2 "Hi")) @@ -73,6 +75,27 @@ (table-headers (doc-find rtt "t")) (list "A" "B")) +;; ── callout + media round-trip (regression: ct-class-for-type must know them) ── +(define + dcm + (doc-append + (doc-append (doc-empty "d") (mk-callout "co" "warning" "careful")) + (mk-video "vid" "/clip.mp4"))) +(define rtcm (content/from-data (content/to-data dcm))) +(content-test "rt callout+media render" (asHTML rtcm) (asHTML dcm)) +(content-test + "rt callout kind" + (str (blk-send (doc-find rtcm "co") "kind")) + "warning") +(content-test + "rt media kind" + (str (blk-send (doc-find rtcm "vid") "kind")) + "video") +(content-test + "rt callout+media types" + (doc-types rtcm) + (list "callout" "media")) + ;; ── data is plain (no st-instance markers at top level) ── (define dat (content/to-data d)) (content-test "data id field" (get dat :id) "post") diff --git a/plans/content-on-sx.md b/plans/content-on-sx.md index 588a3a24..d30126bc 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` → **727/727** (Phases 1–4 COMPLETE + ~34 extensions: HTML/SX escaping, Markdown render + import/export incl. tables & frontmatter (full round-trip), CvRDT flat + nested-tree + durable replication, tree-aware validation, snapshot cache, doc metadata, plain-text render, nested block trees + deep editing + flatten + relative reorder, doc stats + summary + multi-doc index, table + callout + media blocks, HTML page wrapper + SEO page, doc composition + id-remap, portable data + wire serialization, block query + transforms + find/replace, TOC + anchored headings + outline, normalization) +`bash lib/content/conformance.sh` → **731/731** (Phases 1–4 COMPLETE + ~34 extensions: HTML/SX escaping, Markdown render + import/export incl. tables & frontmatter (full round-trip), CvRDT flat + nested-tree + durable replication, tree-aware validation, snapshot cache, doc metadata, plain-text render, nested block trees + deep editing + flatten + relative reorder, doc stats + summary + multi-doc index, table + callout + media blocks, HTML page wrapper + SEO page, doc composition + id-remap, portable data + wire serialization, block query + transforms + find/replace, TOC + anchored headings + outline, normalization) ## Ground rules @@ -113,6 +113,13 @@ lib/content/api.sx ── (content/edit) (content/render) (content/history) ─ ## Progress log +- 2026-06-07 — Hardening: fixed `ct-class-for-type` (block.sx) to map all block + tags (added section/table/callout/media). Latent bug: `content/from-data` and + CRDT materialise of callout/media blocks failed with "unknown block type" (they + fell through to `mk-block`, which only knew the original 8 types). Now all block + types build uniformly via mk-block; data/wire/CRDT round-trips of callout/media + work. +4 data regression tests; full no-regression gate over the foundational + block.sx change: suite 731/731. - 2026-06-07 — Extension: nested-tree CvRDT (`crdt-tree.sx`). Extends the flat CvRDT to a TREE: each element carries a `parent` (containing section id, "" = root) beside its Logoot pos; merge reuses crdt.sx's pos/register/field joins +