replace omd with cmarkit

This commit is contained in:
Hannes Mehnert 2023-08-25 11:04:35 +02:00 committed by Reynir Björnsson
parent e6af891748
commit 5feb615e12
6 changed files with 20 additions and 125 deletions

View file

@ -45,7 +45,7 @@ depends: [
"cmdliner" {>= "1.1.0"} "cmdliner" {>= "1.1.0"}
"uri" "uri"
"fmt" {>= "0.8.7"} "fmt" {>= "0.8.7"}
"omd" {>= "2.0.0~alpha3"} "cmarkit"
"tar" "tar"
"owee" "owee"
"solo5-elftool" {>= "0.3.0"} "solo5-elftool" {>= "0.3.0"}

View file

@ -11,7 +11,7 @@
caqti-lwt caqti-lwt
opamdiff opamdiff
ptime.clock.os ptime.clock.os
omd cmarkit
tar tar
owee owee
solo5-elftool solo5-elftool

View file

@ -45,110 +45,6 @@ let compare_pkgs p1 p2 =
in in
diff_map (parse_pkgs p1) (parse_pkgs p2) diff_map (parse_pkgs p1) (parse_pkgs p2)
module Omd = struct
let make_safe omd =
let rec safe_block = function
| Omd.Paragraph (attr, inline) ->
safe_inline inline
|> Option.map (fun inline -> Omd.Paragraph (attr, inline))
| Omd.List (attr, typ, spacing, blocks) ->
let blocks = List.filter_map (fun b ->
let b = List.filter_map safe_block b in
if b = [] then None else Some b)
blocks
in
if blocks = [] then None else
Some (Omd.List (attr, typ, spacing, blocks))
| Omd.Blockquote (attr, blocks) ->
let blocks = List.filter_map safe_block blocks in
if blocks = [] then None else
Some (Omd.Blockquote (attr, blocks))
| Omd.Heading (attr, level, inline) ->
safe_inline inline
|> Option.map (fun inline -> Omd.Heading (attr, level, inline))
| Omd.Html_block _ -> None
| Omd.Definition_list (attr, def_elts) ->
let def_elts = List.filter_map safe_def_elts def_elts in
if def_elts = [] then None else
Some (Omd.Definition_list (attr, def_elts))
| Omd.Code_block _
| Omd.Thematic_break _ as v -> Some v
| Omd.Table (attr, header_row, rows) ->
let header_row =
List.fold_left (fun acc (cell, alignment) ->
match acc with
| None -> None
| Some xs ->
Option.map (fun cell -> xs @ [ cell, alignment ])
(safe_inline cell))
(Some []) header_row
in
Option.map
(fun header_row ->
let rows =
List.filter_map (fun row ->
List.fold_left (fun acc cell ->
match acc with
| None -> None
| Some xs -> Option.map (fun cell -> xs @ [ cell ])
(safe_inline cell))
(Some []) row)
rows
in
Omd.Table (attr, header_row, rows))
header_row
and safe_def_elts { term ; defs } =
let defs = List.filter_map safe_inline defs in
safe_inline term
|> Option.map (fun term -> { Omd.term ; defs })
and safe_inline = function
| Concat (attr, inline) ->
Some (Concat (attr, List.filter_map safe_inline inline))
| Emph (attr, inline) ->
safe_inline inline
|> Option.map (fun inline -> Omd.Emph (attr, inline))
| Strong (attr, inline) ->
safe_inline inline
|> Option.map (fun inline -> Omd.Strong (attr, inline))
| Link (attr, link) ->
begin match safe_link link with
| `No_label | `Relative -> safe_inline link.Omd.label
| `Link l -> Some (Omd.Link (attr, l))
end
| Image (attr, link) ->
begin match safe_link link with
| `No_label | `Relative -> None
| `Link l -> Some (Omd.Image (attr, l))
end
| Html _ -> None
| Text _
| Code _
| Hard_break _
| Soft_break _ as v -> Some v
and safe_link ({ label ; destination ; _ } as l) =
let absolute_link =
String.(length destination >= 2 && equal (sub destination 0 2) "//") ||
String.(length destination >= 7 && equal (sub destination 0 7) "http://") ||
String.(length destination >= 8 && equal (sub destination 0 8) "https://")
in
if absolute_link then
match safe_inline label with
| None -> `No_label
| Some label -> `Link { l with label }
else
`Relative
in
List.filter_map safe_block omd
let html_of_string markdown =
markdown
|> Omd.of_string
|> make_safe
|> Omd.to_html
end
module Path = struct module Path = struct
let to_url ~path ~queries = let to_url ~path ~queries =

View file

@ -285,7 +285,7 @@ have questions or suggestions.
let make_header = let make_header =
[ [
H.Unsafe.data (Utils.Omd.html_of_string data); H.Unsafe.data (Cmarkit_html.of_doc ~safe:true (Cmarkit.Doc.of_string ~heading_auto_ids:true data));
H.form ~a:H.[a_action "/hash"; a_method `Get] [ H.form ~a:H.[a_action "/hash"; a_method `Get] [
H.label [ H.label [
H.txt "Search artifact by SHA256"; H.txt "Search artifact by SHA256";
@ -383,7 +383,7 @@ module Job = struct
[ [
H.h2 ~a:H.[a_id "readme"] [H.txt "README"]; H.h2 ~a:H.[a_id "readme"] [H.txt "README"];
H.a ~a:H.[a_href "#builds"] [H.txt "Skip to builds"]; H.a ~a:H.[a_href "#builds"] [H.txt "Skip to builds"];
H.Unsafe.data (Utils.Omd.html_of_string data) H.Unsafe.data (Cmarkit_html.of_doc ~safe:true (Cmarkit.Doc.of_string ~heading_auto_ids:true data))
] ]
) )

View file

@ -6,7 +6,7 @@
(test (test
(name markdown_to_html) (name markdown_to_html)
(modules markdown_to_html) (modules markdown_to_html)
(libraries builder_web alcotest)) (libraries builder_web cmarkit alcotest))
(test (test
(name router) (name router)

View file

@ -1,14 +1,14 @@
let markdown_to_html = Builder_web__Utils.Omd.html_of_string let markdown_to_html data = Cmarkit_html.of_doc ~safe:true (Cmarkit.Doc.of_string ~heading_auto_ids:true data)
let test_simple () = let test_simple () =
let markdown = {|# Hello world|} in let markdown = {|# Hello world|} in
let html = markdown_to_html markdown in let html = markdown_to_html markdown in
Alcotest.(check string "simple html" "<h1 id=\"hello-world\">Hello world</h1>\n" html) Alcotest.(check string "simple html" "<h1 id=\"hello-world\"><a class=\"anchor\" aria-hidden=\"true\" href=\"#hello-world\"></a>Hello world</h1>\n" html)
let test_html_script () = let test_html_script () =
let markdown = {|# <script>Hello world</script>|} in let markdown = {|# <script>Hello world</script>|} in
let html = markdown_to_html markdown in let html = markdown_to_html markdown in
Alcotest.(check string "html script header" "<h1 id=\"hello-world\">Hello world</h1>\n" html) Alcotest.(check string "html script header" "<h1 id=\"hello-world\"><a class=\"anchor\" aria-hidden=\"true\" href=\"#hello-world\"></a><!-- CommonMark raw HTML omitted -->Hello world<!-- CommonMark raw HTML omitted --></h1>\n" html)
let test_preserve_span_content () = let test_preserve_span_content () =
let markdown = {|* <span id="myref">My ref</span> let markdown = {|* <span id="myref">My ref</span>
@ -16,10 +16,8 @@ let test_preserve_span_content () =
let html = markdown_to_html markdown in let html = markdown_to_html markdown in
Alcotest.(check string "html span content preserved" Alcotest.(check string "html span content preserved"
{|<ul> {|<ul>
<li>My ref <li><!-- CommonMark raw HTML omitted -->My ref<!-- CommonMark raw HTML omitted --></li>
</li> <li><a href="#myref">See my ref</a> for more information</li>
<li>See my ref for more information
</li>
</ul> </ul>
|} |}
html) html)
@ -27,20 +25,21 @@ let test_preserve_span_content () =
let test_remove_script () = let test_remove_script () =
let markdown = {|<script>alert(1);</script>|} in let markdown = {|<script>alert(1);</script>|} in
let html = markdown_to_html markdown in let html = markdown_to_html markdown in
Alcotest.(check string "html script removed" "" html) Alcotest.(check string "html script removed" "<!-- CommonMark HTML block omitted -->\n" html)
let test_list_with_html_block_and_markdown () = let test_list_with_html_block_and_markdown () =
let markdown = "* <div> Hello, World!</div> *this is not html*" in let markdown = "* <div> Hello, World!</div> *this is not html*" in
let html = markdown_to_html markdown in let html = markdown_to_html markdown in
Alcotest.(check string "list with html block and markdown" Alcotest.(check string "list with html block and markdown"
(*"<ul>\n<li><em>this is not html</em>\n</li>\n</ul>\n"*) "" (*"<ul>\n<li><em>this is not html</em>\n</li>\n</ul>\n"*)
"<ul>\n<li>\n<!-- CommonMark HTML block omitted -->\n</li>\n</ul>\n"
html) html)
let test_list_with_inline_html_and_markdown () = let test_list_with_inline_html_and_markdown () =
let markdown = "* <span> Hello, World!</span> *this is not html*" in let markdown = "* <span> Hello, World!</span> *this is not html*" in
let html = markdown_to_html markdown in let html = markdown_to_html markdown in
Alcotest.(check string "list with html block and markdown" Alcotest.(check string "list with html block and markdown"
"<ul>\n<li> Hello, World! <em>this is not html</em>\n</li>\n</ul>\n" "<ul>\n<li><!-- CommonMark raw HTML omitted --> Hello, World!<!-- CommonMark raw HTML omitted --> <em>this is not html</em></li>\n</ul>\n"
html) html)
let test_absolute_link () = let test_absolute_link () =
@ -51,35 +50,35 @@ let test_absolute_link () =
let test_relative_link () = let test_relative_link () =
let markdown = "[foo](../foo.jpg)" in let markdown = "[foo](../foo.jpg)" in
let html = markdown_to_html markdown in let html = markdown_to_html markdown in
Alcotest.(check string "relative link" "<p>foo</p>\n" html) Alcotest.(check string "relative link" "<p><a href=\"../foo.jpg\">foo</a></p>\n" html)
let test_absolute_image () = let test_absolute_image () =
let markdown = "![alttext](https://foo.com/bar.jpg)" in let markdown = "![alttext](https://foo.com/bar.jpg)" in
let html = markdown_to_html markdown in let html = markdown_to_html markdown in
Alcotest.(check string "absolute image" Alcotest.(check string "absolute image"
"<p><img src=\"https://foo.com/bar.jpg\" alt=\"alttext\" /></p>\n" html) "<p><img src=\"https://foo.com/bar.jpg\" alt=\"alttext\" ></p>\n" html)
let test_absolute_image_no_alt () = let test_absolute_image_no_alt () =
let markdown = "![](https://foo.com/bar.jpg)" in let markdown = "![](https://foo.com/bar.jpg)" in
let html = markdown_to_html markdown in let html = markdown_to_html markdown in
Alcotest.(check string "absolute image" Alcotest.(check string "absolute image"
"<p><img src=\"https://foo.com/bar.jpg\" alt=\"\" /></p>\n" html) "<p><img src=\"https://foo.com/bar.jpg\" alt=\"\" ></p>\n" html)
let test_relative_image () = let test_relative_image () =
let markdown = "![](/bar.jpg)" in let markdown = "![](/bar.jpg)" in
let html = markdown_to_html markdown in let html = markdown_to_html markdown in
Alcotest.(check string "relative image" "" html) Alcotest.(check string "relative image" "<p><img src=\"/bar.jpg\" alt=\"\" ></p>\n" html)
let test_absolute_image_script_alt () = let test_absolute_image_script_alt () =
let markdown = "![<script src=\"bla.js\"></script>](https://foo.com/bar.jpg)" in let markdown = "![<script src=\"bla.js\"></script>](https://foo.com/bar.jpg)" in
let html = markdown_to_html markdown in let html = markdown_to_html markdown in
Alcotest.(check string "absolute image with script alt text" Alcotest.(check string "absolute image with script alt text"
"<p><img src=\"https://foo.com/bar.jpg\" alt=\"\" /></p>\n" html) "<p><img src=\"https://foo.com/bar.jpg\" alt=\"\" ></p>\n" html)
let test_fragment_link () = let test_fragment_link () =
let markdown = "[fragment](#fragment)" in let markdown = "[fragment](#fragment)" in
let html = markdown_to_html markdown in let html = markdown_to_html markdown in
Alcotest.(check string "fragment link" "<p>fragment</p>\n" html) Alcotest.(check string "fragment link" "<p><a href=\"#fragment\">fragment</a></p>\n" html)
let markdown_tests = [ let markdown_tests = [
Alcotest.test_case "Simple" `Quick test_simple; Alcotest.test_case "Simple" `Quick test_simple;