content: tree-wide block transforms (transform.sx) + 12 tests (586/586)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 29s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 29s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
52
lib/content/transform.sx
Normal file
52
lib/content/transform.sx
Normal file
@@ -0,0 +1,52 @@
|
||||
;; content-on-sx — tree-wide block transforms.
|
||||
;;
|
||||
;; The write counterpart to query: apply a function to every matching block
|
||||
;; across the tree (descending into sections), returning a new document. For
|
||||
;; bulk edits — rewrite image srcs, bump heading levels, sanitise text. Tree
|
||||
;; detection/rebuild is inline (class + st-iv-get/set!) so this needs no
|
||||
;; section.sx. Immutable.
|
||||
;;
|
||||
;; Requires (loaded by harness): block.sx, doc.sx.
|
||||
|
||||
(define
|
||||
xf-section?
|
||||
(fn (b) (and (st-instance? b) (= (get b :class) "CtSection"))))
|
||||
|
||||
(define
|
||||
block-tree-transform
|
||||
(fn
|
||||
(blocks pred f)
|
||||
(map
|
||||
(fn
|
||||
(b)
|
||||
(let
|
||||
((nb (if (pred b) (f b) b)))
|
||||
(if
|
||||
(xf-section? nb)
|
||||
(let
|
||||
((ch (st-iv-get nb "children")))
|
||||
(if
|
||||
(list? ch)
|
||||
(st-iv-set! nb "children" (block-tree-transform ch pred f))
|
||||
nb))
|
||||
nb)))
|
||||
blocks)))
|
||||
|
||||
(define
|
||||
content/map-blocks
|
||||
(fn
|
||||
(doc pred f)
|
||||
(doc-with-blocks doc (block-tree-transform (doc-blocks doc) pred f))))
|
||||
|
||||
(define
|
||||
content/map-type
|
||||
(fn
|
||||
(doc type f)
|
||||
(content/map-blocks doc (fn (b) (= (blk-type b) type)) f)))
|
||||
|
||||
;; convenience: set a field on every block of a type.
|
||||
(define
|
||||
content/set-field-on
|
||||
(fn
|
||||
(doc type field value)
|
||||
(content/map-type doc type (fn (b) (blk-set b field value)))))
|
||||
Reference in New Issue
Block a user