;; 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)))))