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