;; content-on-sx — public API facade. ;; ;; The stable surface other code calls. Composes block + doc + render. Document ;; values are immutable; every edit returns a new document, so callers hold ;; explicit versions (the persist op log in Phase 2 becomes the source of truth). ;; ;; Requires (loaded by the harness): block.sx, doc.sx, render.sx and a base ;; Smalltalk class table (st-bootstrap-classes!). ;; Register the content class hierarchy + render methods. Caller bootstraps the ;; base Smalltalk classes first; this only adds content classes (idempotent). (define content/bootstrap! (fn () (begin (content-bootstrap-blocks!) (content-bootstrap-doc!) (content-bootstrap-render!) true))) ;; ── documents ── (define content/new doc-new) (define content/empty doc-empty) (define content/append doc-append) (define content/blocks doc-blocks) (define content/count doc-count) (define content/find doc-find) (define content/has? doc-has?) (define content/ids doc-ids) (define content/types doc-types) ;; ── blocks ── (define content/block mk-block) ;; ── edit ops (data payload) ── (define content/insert op-insert) (define content/update op-update) (define content/move op-move) (define content/delete op-delete) (define content/op? (fn (x) (and (dict? x) (has-key? x :op)))) ;; edit — apply one op or a stream of ops; returns a new document. (define content/edit (fn (doc ops) (if (content/op? ops) (doc-apply doc ops) (doc-apply-all doc ops)))) ;; ── render boundary ── ;; fmt is "html"/"sx" (or :html/:sx — keywords evaluate to their name). (define content/render (fn (doc fmt) (cond ((= fmt "html") (asHTML doc)) ((= fmt "sx") (asSx doc)) (else (error (str "unknown render format: " fmt)))))) (define content/html asHTML) (define content/sx asSx)