;; Extension — list-card summary projection. (st-bootstrap-classes!) (content/bootstrap!) (content-bootstrap-text!) (define d (doc-with-title (doc-append (doc-append (doc-append (doc-empty "post") (mk-heading "h" 1 "Hello")) (mk-text "p" "one two three four")) (mk-image "img" "/cover.png" "cover")) "My Post")) ;; image alt ("cover") is part of the plain-text projection, so it counts. (define s (content/summary d)) (content-test "summary id" (get s :id) "post") (content-test "summary title" (get s :title) "My Post") (content-test "summary excerpt" (get s :excerpt) "Hello one two three four cover") (content-test "summary words" (get s :words) 6) (content-test "summary reading" (get s :reading-minutes) 1) (content-test "summary cover" (get s :cover) "/cover.png") ;; ── title falls back to id ── (content-test "summary title fallback" (get (content/summary (doc-append (doc-empty "x") (mk-text "p" "y"))) :title) "x") ;; ── no image → cover nil ── (content-test "no cover" (get (content/summary (doc-append (doc-empty "x") (mk-text "p" "y"))) :cover) nil) (content-test "cover helper nil" (content/cover (doc-empty "e")) nil) ;; ── first image wins as cover ── (define d2 (doc-append (doc-append (doc-empty "d") (mk-image "i1" "/a.png" "a")) (mk-image "i2" "/b.png" "b"))) (content-test "first image cover" (content/cover d2) "/a.png") ;; ── empty doc ── (define se (content/summary (doc-empty "e"))) (content-test "empty summary words" (get se :words) 0) (content-test "empty summary excerpt" (get se :excerpt) "") (content-test "empty summary cover" (get se :cover) nil) ;; ── excerpt truncates long content ── (content-test "excerpt truncated" (> (string-length (get (content/summary (doc-append (doc-empty "d") (mk-text "p" "word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word"))) :excerpt)) 100) true)