(** README documentation rendering. *) let contains text fragment = let text_length = String.length text in let fragment_length = String.length fragment in let rec loop index = if index > text_length - fragment_length then false else if String.sub text index fragment_length = fragment then true else loop (index + 1) in fragment_length <= text_length && loop 0 let count text fragment = let text_length = String.length text in let fragment_length = String.length fragment in let rec loop index acc = if index > text_length - fragment_length then acc else if String.sub text index fragment_length = fragment then loop (index + 1) (acc + 1) else loop (index + 1) acc in if fragment_length > text_length then 0 else loop 0 0 let render ~filename content = Prose.Render.render ~filename content |> Dream_html.to_string let test_markdown_document () = let html = render ~filename:"README.md" "# Project\n\nIntroduction.\n\n## Installation\n\n- Download\n- Run\n" in Alcotest.(check bool) "documentation container" true (contains html "readme-document readme-markdown"); Alcotest.(check bool) "h1 heading" true (contains html "

Project"); Alcotest.(check bool) "nested h2 heading" true (contains html "

Author"); Alcotest.(check bool) "Org heading" true (contains html "

= 2) let test_org_toc () = let html = render ~filename:"README.org" "#+TITLE: My Project\n\ #+AUTHOR: Ada\n\n\ * Overview\n\n\ ** Installation\n\n\ Text.\n\n\ * Usage\n" in Alcotest.(check bool) "Org TOC disclosure present" true (contains html "readme-toc"); Alcotest.(check bool) "Org TOC links to Overview" true (contains html "href=\"#overview\""); Alcotest.(check bool) "Org TOC links to Installation" true (contains html "href=\"#installation\""); Alcotest.(check bool) "Org TOC links to Usage" true (contains html "href=\"#usage\""); Alcotest.(check bool) "Org TOC has nested list for subheadings" true (count html "toc-list" >= 2); let find s sub = let slen = String.length s and sublen = String.length sub in let rec f i = if i > slen - sublen then -1 else if String.sub s i sublen = sub then i else f (i + 1) in f 0 in let toc_at = find html "readme-toc\"" in let meta_at = find html "readme-org-metadata" in Alcotest.(check bool) "Org metadata appears before TOC" true (toc_at >= 0 && meta_at >= 0 && meta_at < toc_at) let test_no_toc_without_headings () = let html = render ~filename:"README.md" "Just a paragraph.\n" in Alcotest.(check bool) "no TOC when no headings" false (contains html "readme-toc") let test_org_inline_verbatim () = let html = render ~filename:"README.org" "* Notes\n\nUse =verbatim= for emphasis.\n" in Alcotest.(check bool) "verbatim span" true (contains html "verbatim"); Alcotest.(check bool) "surrounding text preserved" true (contains html "Use ") let test_org_inline_code () = let html = render ~filename:"README.org" "* Notes\n\nCall ~List.map~ here.\n" in Alcotest.(check bool) "code element" true (contains html "List.map") let test_org_link_with_description () = let html = render ~filename:"README.org" "* Links\n\nSee [[https://example.com][Example Site]] for details.\n" in Alcotest.(check bool) "link href" true (contains html "href=\"https://example.com\""); Alcotest.(check bool) "link text" true (contains html ">Example Site") let test_org_link_bare () = let html = render ~filename:"README.org" "* Links\n\nVisit [[https://example.com]] today.\n" in Alcotest.(check bool) "bare link href" true (contains html "href=\"https://example.com\""); Alcotest.(check bool) "bare link text equals URL" true (contains html ">https://example.com") let test_org_unordered_list () = let html = render ~filename:"README.org" "* Tasks\n\n- First item\n- Second item\n- Third item\n" in Alcotest.(check bool) "unordered list" true (contains html "