Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 56s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
50 lines
1.5 KiB
Plaintext
50 lines
1.5 KiB
Plaintext
;; content-on-sx — document statistics (word/char/block counts, reading time).
|
|
;;
|
|
;; Counts derive from the plain-text projection (asText, tree-accurate via
|
|
;; section recursion) and a tree block count (inline class check, so this needs
|
|
;; no section.sx). Reading time uses 200 wpm, rounded up.
|
|
;;
|
|
;; Requires (loaded by harness): block.sx, doc.sx, text.sx (asText).
|
|
|
|
(define
|
|
ct-words
|
|
(fn (s) (filter (fn (w) (if (= w "") false true)) (split s " "))))
|
|
|
|
(define ct-ceil-div (fn (a b) (quotient (+ a (- b 1)) b)))
|
|
|
|
(define
|
|
ct-stat-section?
|
|
(fn (b) (and (st-instance? b) (= (get b :class) "CtSection"))))
|
|
(define
|
|
ct-stat-count
|
|
(fn
|
|
(blocks)
|
|
(if
|
|
(= (len blocks) 0)
|
|
0
|
|
(let
|
|
((b (first blocks)))
|
|
(+
|
|
(+
|
|
1
|
|
(if
|
|
(ct-stat-section? b)
|
|
(let
|
|
((ch (st-iv-get b "children")))
|
|
(if (list? ch) (ct-stat-count ch) 0))
|
|
0))
|
|
(ct-stat-count (rest blocks)))))))
|
|
|
|
(define content/word-count (fn (doc) (len (ct-words (asText doc)))))
|
|
(define content/char-count (fn (doc) (string-length (asText doc))))
|
|
(define content/block-count (fn (doc) (ct-stat-count (doc-blocks doc))))
|
|
(define
|
|
content/reading-minutes
|
|
(fn
|
|
(doc)
|
|
(let
|
|
((w (content/word-count doc)))
|
|
(if (= w 0) 0 (ct-ceil-div w 200)))))
|
|
|
|
(define content/stats (fn (doc) {:blocks (content/block-count doc) :reading-minutes (content/reading-minutes doc) :words (content/word-count doc) :chars (content/char-count doc)}))
|