From 9a07e665f792b1cc1c6ae27b0472c3c785ec4e5f Mon Sep 17 00:00:00 2001 From: oyenuga17 <64274826+oyenuga17@users.noreply.github.com> Date: Fri, 24 Nov 2023 17:22:57 +0100 Subject: [PATCH] Replace Dependency on omd with cmarkit, advance opam-repository pin (#1642) --------- Co-authored-by: Sabine Schmaltz --- .devcontainer/Dockerfile | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/dummy.yml | 2 +- .github/workflows/linkcheck.yml | 2 +- .github/workflows/scrape.yml | 2 +- Dockerfile | 2 +- Makefile | 2 +- dune-project | 6 +- ocamlorg.opam | 4 +- src/ocamlorg_data/data.mli | 1 - src/ocamlorg_web/lib/dune | 2 +- src/ocamlorg_web/lib/handler.ml | 4 +- tool/ood-gen/lib/academic_institution.ml | 4 +- tool/ood-gen/lib/book.ml | 4 +- tool/ood-gen/lib/changelog.ml | 9 ++- tool/ood-gen/lib/dune | 2 +- tool/ood-gen/lib/event.ml | 4 +- tool/ood-gen/lib/exercise.ml | 64 ++++++++-------- tool/ood-gen/lib/industrial_user.ml | 4 +- tool/ood-gen/lib/is_ocaml_yet.ml | 11 ++- tool/ood-gen/lib/news.ml | 4 +- tool/ood-gen/lib/page.ml | 7 +- tool/ood-gen/lib/planet.ml | 7 +- tool/ood-gen/lib/release.ml | 14 +++- tool/ood-gen/lib/success_story.ml | 4 +- tool/ood-gen/lib/tool.ml | 2 +- tool/ood-gen/lib/tutorial.ml | 98 ++++++++++-------------- tool/ood-gen/lib/workshop.ml | 11 +-- 28 files changed, 145 insertions(+), 135 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 1717e2d1c3..8851cd128b 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,7 +1,7 @@ FROM ocaml/opam:debian-ocaml-4.14 # Branch freeze was opam-repo HEAD at the time of commit -RUN cd ~/opam-repository && git checkout -b freeze c1fcfbe8369cb5a7cb8d7be63db59856dbd85d19 && opam update +RUN cd ~/opam-repository && git checkout -b freeze 8cc107f96e33a4601f7c39346eb19fbbe46486d3 && opam update # Dev tools RUN opam install -y dune-release merlin ocamlformat=0.24.1 utop ocaml-lsp-server diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75dbf4be92..52fd51d662 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: ocaml-compiler: ${{ matrix.ocaml-compiler }} dune-cache: ${{ matrix.os != 'macos-latest' }} opam-repositories: | - pin: git+https://github.com/ocaml/opam-repository#c1fcfbe8369cb5a7cb8d7be63db59856dbd85d19 + pin: git+https://github.com/ocaml/opam-repository#8cc107f96e33a4601f7c39346eb19fbbe46486d3 opam-disable-sandboxing: true - name: Install system dependencies (Linux) diff --git a/.github/workflows/dummy.yml b/.github/workflows/dummy.yml index 2def8b257f..c621ed8ffc 100644 --- a/.github/workflows/dummy.yml +++ b/.github/workflows/dummy.yml @@ -23,7 +23,7 @@ jobs: with: ocaml-compiler: ocaml-base-compiler.4.14.1 opam-repositories: | - pin: git+https://github.com/ocaml/opam-repository#c1fcfbe8369cb5a7cb8d7be63db59856dbd85d19 + pin: git+https://github.com/ocaml/opam-repository#8cc107f96e33a4601f7c39346eb19fbbe46486d3 opam-disable-sandboxing: true - run: git rev-parse HEAD diff --git a/.github/workflows/linkcheck.yml b/.github/workflows/linkcheck.yml index 816548f14b..d0b9a2a0df 100644 --- a/.github/workflows/linkcheck.yml +++ b/.github/workflows/linkcheck.yml @@ -33,7 +33,7 @@ jobs: ocaml-compiler: ${{ matrix.ocaml-compiler }} dune-cache: ${{ matrix.os != 'macos-latest' }} opam-repositories: | - pin: git+https://github.com/ocaml/opam-repository#c1fcfbe8369cb5a7cb8d7be63db59856dbd85d19 + pin: git+https://github.com/ocaml/opam-repository#8cc107f96e33a4601f7c39346eb19fbbe46486d3 opam-disable-sandboxing: true opam-depext-flags: "--update" diff --git a/.github/workflows/scrape.yml b/.github/workflows/scrape.yml index c0e5221fb4..984ea7a0a2 100644 --- a/.github/workflows/scrape.yml +++ b/.github/workflows/scrape.yml @@ -30,7 +30,7 @@ jobs: ocaml-compiler: ${{ matrix.ocaml-compiler }} dune-cache: ${{ matrix.os != 'macos-latest' }} opam-repositories: | - pin: git+https://github.com/ocaml/opam-repository#c1fcfbe8369cb5a7cb8d7be63db59856dbd85d19 + pin: git+https://github.com/ocaml/opam-repository#8cc107f96e33a4601f7c39346eb19fbbe46486d3 opam-disable-sandboxing: true - name: Install system dependencies diff --git a/Dockerfile b/Dockerfile index 84366302ab..d9aa5bb1eb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ FROM ocaml/opam:alpine-3.18-ocaml-4.14 as build RUN sudo apk update && sudo apk add --update libev-dev openssl-dev gmp-dev oniguruma-dev inotify-tools curl-dev autoconf # Branch freeze was opam-repo HEAD at the time of commit -RUN cd opam-repository && git pull origin c1fcfbe8369cb5a7cb8d7be63db59856dbd85d19 && opam update +RUN cd opam-repository && git pull origin 8cc107f96e33a4601f7c39346eb19fbbe46486d3 && opam update WORKDIR /home/opam diff --git a/Makefile b/Makefile index 3d4d534ddf..8e1458d18b 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ deps: create_switch ## Install development dependencies .PHONY: create_switch create_switch: ## Create switch and pinned opam repo - opam switch create . 4.14.1 --no-install --repos pin=git+https://github.com/ocaml/opam-repository#c1fcfbe8369cb5a7cb8d7be63db59856dbd85d19 + opam switch create . 4.14.1 --no-install --repos pin=git+https://github.com/ocaml/opam-repository#8cc107f96e33a4601f7c39346eb19fbbe46486d3 .PHONY: switch switch: deps ## Create an opam switch and install development dependencies diff --git a/dune-project b/dune-project index ebcd55bdbf..f215344e78 100644 --- a/dune-project +++ b/dune-project @@ -45,8 +45,8 @@ fpath fmt logs - (omd - (>= "2.0.0~alpha4")) + (cmarkit + (>= 0.2.0)) opam-format (timedesc (>= 1.1.1)) @@ -54,7 +54,7 @@ lwt tailwindcss (hilite - (>= 0.3.0)) + (>= 0.4.0)) river syndic (alcotest :with-test) diff --git a/ocamlorg.opam b/ocamlorg.opam index 96df5e04d8..8ab462ae43 100644 --- a/ocamlorg.opam +++ b/ocamlorg.opam @@ -31,13 +31,13 @@ depends: [ "fpath" "fmt" "logs" - "omd" {>= "2.0.0~alpha4"} + "cmarkit" {>= "0.2.0"} "opam-format" "timedesc" {>= "1.1.1"} "yojson" "lwt" "tailwindcss" - "hilite" {>= "0.3.0"} + "hilite" {>= "0.4.0"} "river" "syndic" "alcotest" {with-test} diff --git a/src/ocamlorg_data/data.mli b/src/ocamlorg_data/data.mli index e4ce512189..36862b1bc8 100644 --- a/src/ocamlorg_data/data.mli +++ b/src/ocamlorg_data/data.mli @@ -356,7 +356,6 @@ module Workshop : sig presentations : presentation list; program_committee : committee_member list; organising_committee : committee_member list; - toc_html : string; body_md : string; body_html : string; } diff --git a/src/ocamlorg_web/lib/dune b/src/ocamlorg_web/lib/dune index d6b6ed88fe..3ce0d20645 100644 --- a/src/ocamlorg_web/lib/dune +++ b/src/ocamlorg_web/lib/dune @@ -7,7 +7,7 @@ dream dream-accept dream-encoding - omd + cmarkit ocamlorg.data timedesc mirage-kv-mem)) diff --git a/src/ocamlorg_web/lib/handler.ml b/src/ocamlorg_web/lib/handler.ml index 340495f49a..c0568abe53 100644 --- a/src/ocamlorg_web/lib/handler.ml +++ b/src/ocamlorg_web/lib/handler.ml @@ -448,7 +448,9 @@ module Package_helper = struct (Option.map Ocamlorg_package.Version.to_string latest_version); synopsis = info.Ocamlorg_package.Info.synopsis; description = - info.Ocamlorg_package.Info.description |> Omd.of_string |> Omd.to_html; + info.Ocamlorg_package.Info.description + |> Cmarkit.Doc.of_string ~strict:true + |> Cmarkit_html.of_doc ~safe:true; tags = info.tags; rev_deps; authors = List.map owner info.authors; diff --git a/tool/ood-gen/lib/academic_institution.ml b/tool/ood-gen/lib/academic_institution.ml index 9f607cedb9..7f238548e3 100644 --- a/tool/ood-gen/lib/academic_institution.ml +++ b/tool/ood-gen/lib/academic_institution.ml @@ -39,7 +39,9 @@ let of_metadata m = of_metadata m ~slug:(Utils.slugify m.name) let decode (_, (head, body_md)) = let metadata = metadata_of_yaml head in - let body_html = Omd.of_string body_md |> Omd.to_html in + let body_html = + Cmarkit.Doc.of_string ~strict:true body_md |> Cmarkit_html.of_doc ~safe:true + in Result.map (of_metadata ~body_md ~body_html) metadata let all () = Utils.map_files decode "academic_institutions" diff --git a/tool/ood-gen/lib/book.ml b/tool/ood-gen/lib/book.ml index e68c00343b..06e4721fdf 100644 --- a/tool/ood-gen/lib/book.ml +++ b/tool/ood-gen/lib/book.ml @@ -46,7 +46,9 @@ let of_metadata m = of_metadata m let decode (_, (head, body)) = let metadata = metadata_of_yaml head in let body_md = String.trim body in - let body_html = Omd.of_string body |> Omd.to_html in + let body_html = + Cmarkit.Doc.of_string ~strict:true body_md |> Cmarkit_html.of_doc ~safe:true + in Result.map (of_metadata ~body_md ~body_html) metadata let all () = diff --git a/tool/ood-gen/lib/changelog.ml b/tool/ood-gen/lib/changelog.ml index 509341515c..fdc0cab0aa 100644 --- a/tool/ood-gen/lib/changelog.ml +++ b/tool/ood-gen/lib/changelog.ml @@ -26,7 +26,9 @@ let decode (fname, (head, body)) = let slug = Filename.basename (Filename.remove_extension fname) in let metadata = metadata_of_yaml head in let body_html = - Omd.to_html (Hilite.Md.transform (Omd.of_string (String.trim body))) + Cmarkit_html.of_doc ~safe:false + (Hilite.Md.transform + (Cmarkit.Doc.of_string ~strict:true (String.trim body))) in Result.map @@ -36,8 +38,9 @@ let decode (fname, (head, body)) = | None -> None | Some changelog -> Some - (Omd.to_html - (Hilite.Md.transform (Omd.of_string (String.trim changelog)))) + (Cmarkit.Doc.of_string ~strict:true (String.trim changelog) + |> Hilite.Md.transform + |> Cmarkit_html.of_doc ~safe:false) in of_metadata ~slug ~changelog_html ~body_html metadata) metadata diff --git a/tool/ood-gen/lib/dune b/tool/ood-gen/lib/dune index 0ec62e985c..3dfc555eee 100644 --- a/tool/ood-gen/lib/dune +++ b/tool/ood-gen/lib/dune @@ -2,7 +2,7 @@ (name ood_gen) (libraries ocamlorg.global - omd + cmarkit yaml unix ptime diff --git a/tool/ood-gen/lib/event.ml b/tool/ood-gen/lib/event.ml index f72efa82d5..f3e64278e3 100644 --- a/tool/ood-gen/lib/event.ml +++ b/tool/ood-gen/lib/event.ml @@ -30,7 +30,9 @@ let of_metadata m = of_metadata m ~slug:(Utils.slugify m.title) let decode (_, (head, body_md)) = let metadata = metadata_of_yaml head in - let body_html = Omd.of_string body_md |> Omd.to_html in + let body_html = + Cmarkit.Doc.of_string body_md |> Cmarkit_html.of_doc ~safe:true + in Result.map (of_metadata ~body_md ~body_html) metadata let all () = diff --git a/tool/ood-gen/lib/exercise.ml b/tool/ood-gen/lib/exercise.ml index 7cd132d7d0..6a797410d0 100644 --- a/tool/ood-gen/lib/exercise.ml +++ b/tool/ood-gen/lib/exercise.ml @@ -21,32 +21,23 @@ type metadata = { } [@@deriving of_yaml] -let split_statement_statement (blocks : _ Omd.block list) = - let rec blocks_until_heading acc = function - | [] -> (List.rev acc, []) - | Omd.Heading (_, 1, _) :: _ as l -> (List.rev acc, l) - | el :: rest -> blocks_until_heading (el :: acc) rest +let get_title (h : Cmarkit.Block.Heading.t) = + let title = + Cmarkit.Inline.to_plain_text ~break_on_soft:false + (Cmarkit.Block.Heading.inline h) in - let rec skip_non_heading_blocks = function - | [] -> [] - | Omd.Heading (_, 1, _) :: _ as l -> l - | _ :: rest -> skip_non_heading_blocks rest - in - let err = - "The format of the statement file is not valid. Expected exactly two \ - top-level headings: \"Solution\" and \"Statement\"" - in - match skip_non_heading_blocks blocks with - | Omd.Heading (_, 1, Omd.Text (_, "Solution")) :: rest -> ( - let solution_blocks, rest = blocks_until_heading [] rest in - match rest with - | Omd.Heading (_, 1, Omd.Text (_, "Statement")) :: rest -> ( - let statements_blocks, rest = blocks_until_heading [] rest in - match rest with - | [] -> (statements_blocks, solution_blocks) - | _ -> raise (Exn.Decode_error err)) - | _ -> raise (Exn.Decode_error err)) - | _ -> raise (Exn.Decode_error err) + String.concat "\n" (List.map (String.concat "") title) + +let split_statement_solution (body : string) = + match Str.split (Str.regexp {|#[ ]*Solution|}) body with + | [ _; statement_and_solution ] -> ( + match + Str.split (Str.regexp {|#[ ]*Statement|}) statement_and_solution + with + | [ solution; statement ] -> + Ok (Cmarkit.Doc.of_string statement, Cmarkit.Doc.of_string solution) + | _ -> Error (`Msg "Failed to split on '# Statement' heading")) + | _ -> Error (`Msg "Failed to split on '# Solution' heading") type t = { title : string; @@ -62,14 +53,23 @@ type t = { stable_record ~version:metadata ~remove:[ statement; solution ], show { with_path = false }] -let decode (_, (head, body)) = - let metadata = metadata_of_yaml head in - let statement_blocks, solution_blocks = - split_statement_statement (Omd.of_string body) +let attach_filepath fpath (`Msg m) = `Msg ("Error in file '" ^ fpath ^ "': " ^ m) + +let decode (fpath, (head, body)) : (t, [> `Msg of string ]) result = + let ( let* ) = Result.bind in + let* metadata = + metadata_of_yaml head |> Result.map_error (attach_filepath fpath) + in + let* statement_doc, solution_doc = + split_statement_solution body |> Result.map_error (attach_filepath fpath) + in + let statement = + Cmarkit_html.of_doc ~safe:false (Hilite.Md.transform statement_doc) + in + let solution = + Cmarkit_html.of_doc ~safe:false (Hilite.Md.transform solution_doc) in - let statement = Omd.to_html (Hilite.Md.transform statement_blocks) in - let solution = Omd.to_html (Hilite.Md.transform solution_blocks) in - Result.map (of_metadata ~statement ~solution) metadata + Ok (metadata |> of_metadata ~statement ~solution) let all () = Utils.map_files decode "exercises/*.md" diff --git a/tool/ood-gen/lib/industrial_user.ml b/tool/ood-gen/lib/industrial_user.ml index 15c4a912bf..d82c11e4f1 100644 --- a/tool/ood-gen/lib/industrial_user.ml +++ b/tool/ood-gen/lib/industrial_user.ml @@ -29,7 +29,9 @@ let of_metadata m = of_metadata m ~slug:(Utils.slugify m.name) let decode (_, (head, body_md)) = let metadata = metadata_of_yaml head in - let body_html = Omd.of_string body_md |> Omd.to_html in + let body_html = + Cmarkit.Doc.of_string ~strict:true body_md |> Cmarkit_html.of_doc ~safe:true + in Result.map (of_metadata ~body_md ~body_html) metadata let all () = Utils.map_files decode "industrial_users" diff --git a/tool/ood-gen/lib/is_ocaml_yet.ml b/tool/ood-gen/lib/is_ocaml_yet.ml index e0d5a5874e..9434438acc 100644 --- a/tool/ood-gen/lib/is_ocaml_yet.ml +++ b/tool/ood-gen/lib/is_ocaml_yet.ml @@ -33,7 +33,9 @@ type t = { let decode (_, (head, body_md)) = let metadata = metadata_of_yaml head in - let body_html = Omd.of_string body_md |> Omd.to_html in + let body_html = + Cmarkit.Doc.of_string ~strict:true body_md |> Cmarkit_html.of_doc ~safe:true + in Result.map (fun (metadata : metadata) -> let categories = @@ -42,9 +44,10 @@ let decode (_, (head, body_md)) = { category with description = - Omd.to_html - (Hilite.Md.transform - (Omd.of_string (String.trim category.description))); + Cmarkit.Doc.of_string ~strict:true + (String.trim category.description) + |> Hilite.Md.transform + |> Cmarkit_html.of_doc ~safe:false; }) metadata.categories in diff --git a/tool/ood-gen/lib/news.ml b/tool/ood-gen/lib/news.ml index b9b077d974..967602410f 100644 --- a/tool/ood-gen/lib/news.ml +++ b/tool/ood-gen/lib/news.ml @@ -23,7 +23,9 @@ let decode (fname, (head, body)) = let slug = Filename.basename (Filename.remove_extension fname) in let metadata = metadata_of_yaml head in let body_html = - Omd.to_html (Hilite.Md.transform (Omd.of_string (String.trim body))) + Cmarkit.Doc.of_string ~strict:true (String.trim body) + |> Hilite.Md.transform + |> Cmarkit_html.of_doc ~safe:false in Result.map (of_metadata ~slug ~body_html) metadata diff --git a/tool/ood-gen/lib/page.ml b/tool/ood-gen/lib/page.ml index 8cad89ecbd..a01942843b 100644 --- a/tool/ood-gen/lib/page.ml +++ b/tool/ood-gen/lib/page.ml @@ -21,8 +21,11 @@ type t = { let decode (file, (head, body_md)) = let metadata = metadata_of_yaml head in - let omd = Omd.of_string body_md in - let body_html = Omd.to_html (Hilite.Md.transform omd) in + let body_html = + Cmarkit.Doc.of_string ~strict:true body_md + |> Hilite.Md.transform + |> Cmarkit_html.of_doc ~safe:false + in let slug = file |> Filename.basename |> Filename.remove_extension |> String.map (function '_' -> '-' | c -> c) diff --git a/tool/ood-gen/lib/planet.ml b/tool/ood-gen/lib/planet.ml index f1acf0887c..a233c38877 100644 --- a/tool/ood-gen/lib/planet.ml +++ b/tool/ood-gen/lib/planet.ml @@ -80,7 +80,9 @@ module Local = struct let decode (fpath, (head, body)) = let metadata = metadata_of_yaml head in let body_html = - Omd.to_html (Hilite.Md.transform (Omd.of_string (String.trim body))) + Cmarkit.Doc.of_string ~strict:true (String.trim body) + |> Hilite.Md.transform + |> Cmarkit_html.of_doc ~safe:false in let source, slug = match Str.split (Str.regexp_string "/") fpath with @@ -191,7 +193,8 @@ module External = struct let decode (fpath, (head, body)) = let metadata = metadata_of_yaml head in let body_html = - Omd.to_html (Hilite.Md.transform (Omd.of_string (String.trim body))) + Cmarkit.Doc.of_string ~strict:true (String.trim body) + |> Cmarkit_html.of_doc ~safe:true in let source = match Str.split (Str.regexp_string "/") fpath with diff --git a/tool/ood-gen/lib/release.ml b/tool/ood-gen/lib/release.ml index b8aa83c3e9..bcab964959 100644 --- a/tool/ood-gen/lib/release.ml +++ b/tool/ood-gen/lib/release.ml @@ -42,10 +42,14 @@ type t = { let of_metadata m = of_metadata m ~intro_md:m.intro - ~intro_html:(Omd.of_string m.intro |> Omd.to_html) + ~intro_html: + (Cmarkit.Doc.of_string ~strict:true m.intro + |> Cmarkit_html.of_doc ~safe:true) ~highlights_md:m.highlights ~highlights_html: - (Omd.of_string m.highlights |> Hilite.Md.transform |> Omd.to_html) + (Cmarkit.Doc.of_string ~strict:true m.highlights + |> Hilite.Md.transform + |> Cmarkit_html.of_doc ~safe:false) let sort_by_decreasing_version x y = let to_list s = List.map int_of_string_opt @@ String.split_on_char '.' s in @@ -53,7 +57,11 @@ let sort_by_decreasing_version x y = let decode (_, (head, body_md)) = let metadata = metadata_of_yaml head in - let body_html = Omd.of_string body_md |> Hilite.Md.transform |> Omd.to_html in + let body_html = + Cmarkit.Doc.of_string ~strict:true body_md + |> Hilite.Md.transform + |> Cmarkit_html.of_doc ~safe:false + in Result.map (of_metadata ~body_md ~body_html) metadata let all () = diff --git a/tool/ood-gen/lib/success_story.ml b/tool/ood-gen/lib/success_story.ml index dae061dfa1..d59fff2753 100644 --- a/tool/ood-gen/lib/success_story.ml +++ b/tool/ood-gen/lib/success_story.ml @@ -27,7 +27,9 @@ let of_metadata m = of_metadata m ~slug:(Utils.slugify m.title) let decode (_, (head, body_md)) = let metadata = metadata_of_yaml head in - let body_html = Omd.of_string body_md |> Omd.to_html in + let body_html = + Cmarkit.Doc.of_string ~strict:true body_md |> Cmarkit_html.of_doc ~safe:true + in Result.map (of_metadata ~body_md ~body_html) metadata let all () = Utils.map_files decode "success_stories" diff --git a/tool/ood-gen/lib/tool.ml b/tool/ood-gen/lib/tool.ml index c4ced0f809..244713826f 100644 --- a/tool/ood-gen/lib/tool.ml +++ b/tool/ood-gen/lib/tool.ml @@ -37,7 +37,7 @@ type t = { let of_metadata m = of_metadata m ~slug:(Utils.slugify m.name) ~modify_description:(fun v -> - Omd.of_string v |> Omd.to_html) + Cmarkit.Doc.of_string ~strict:true v |> Cmarkit_html.of_doc ~safe:true) let decode s = Result.map of_metadata (metadata_of_yaml s) let all () = Utils.yaml_sequence_file decode "tools.yml" diff --git a/tool/ood-gen/lib/tutorial.ml b/tool/ood-gen/lib/tutorial.ml index 3ccd2a1380..fe41549889 100644 --- a/tool/ood-gen/lib/tutorial.ml +++ b/tool/ood-gen/lib/tutorial.ml @@ -39,82 +39,62 @@ type t = { let of_metadata m = of_metadata m ~slug:m.id -(* Copied from ocaml/omd, html.ml *) -let to_plain_text t = - let buf = Buffer.create 1024 in - let rec go : _ Omd.inline -> unit = function - | Concat (_, l) -> List.iter go l - | Text (_, t) | Code (_, t) -> Buffer.add_string buf t - | Emph (_, i) - | Strong (_, i) - | Link (_, { label = i; _ }) - | Image (_, { label = i; _ }) -> - go i - | Hard_break _ | Soft_break _ -> Buffer.add_char buf ' ' - | Html _ -> () - in - go t; - Buffer.contents buf - -let doc_with_ids doc = - let open Omd in - List.map - (function - | Heading (attr, level, inline) -> - let id, attr = List.partition (fun (key, _) -> key = "id") attr in - let id = - match id with - | [] -> Utils.slugify (to_plain_text inline) - | (_, slug) :: _ -> slug (* Discard extra ids *) - in - let link : _ Omd.link = - { label = Text (attr, ""); destination = "#" ^ id; title = None } - in - Heading - ( ("id", id) :: attr, - level, - Concat ([], [ Link ([ ("class", "anchor") ], link); inline ]) ) - | el -> el) - doc - -(* emit a structured toc from the Omd.doc *) -let find_id attributes = - List.find_map - (function k, v when String.equal "id" k -> Some v | _ -> None) - attributes - -let href_of attributes = - match find_id attributes with None -> "#" | Some id -> "#" ^ id +let id_to_href id = + match id with + | None -> "#" + | Some (`Auto id) -> "#" ^ id + | Some (`Id id) -> "#" ^ id let rec create_toc ~max_level level - (headings : ('attr * int * 'a Omd.inline) list) : toc list = + (headings : Cmarkit.Block.Heading.t Cmarkit.node list) : toc list = match headings with | [] -> [] - | (_, l, _) :: rest when l > max_level -> create_toc ~max_level level rest - | (attrs, l, title) :: rest when l = level -> + | (h, _) :: rest when Cmarkit.Block.Heading.level h > max_level -> + create_toc ~max_level level rest + | (h, _) :: rest when Cmarkit.Block.Heading.level h = level -> + let l = Cmarkit.Block.Heading.level h in let child_headings, remaining_headings = collect_children ~max_level (l + 1) rest [] in let children = create_toc ~max_level (l + 1) child_headings in - { title = to_plain_text title; href = href_of attrs; children } + let title = + Cmarkit.Inline.to_plain_text ~break_on_soft:false + (Cmarkit.Block.Heading.inline h) + in + { + title = String.concat "\n" (List.map (String.concat "") title); + href = id_to_href (Cmarkit.Block.Heading.id h); + children; + } :: create_toc ~max_level level remaining_headings - | (_, l, _) :: _ when l > level -> create_toc ~max_level (level + 1) headings + | (h, _) :: _ when Cmarkit.Block.Heading.level h > level -> + create_toc ~max_level (level + 1) headings | _ :: rest -> create_toc ~max_level level rest and collect_children ~max_level level - (headings : ('attr * int * 'a Omd.inline) list) acc = + (headings : Cmarkit.Block.Heading.t Cmarkit.node list) acc = match headings with | [] -> (acc, []) - | (_, l, _) :: rest when l > max_level -> + | (h, _) :: rest when Cmarkit.Block.Heading.level h > max_level -> collect_children ~max_level level rest acc - | (_, l, _) :: _ when l < level -> (acc, headings) + | (h, _) :: _ when Cmarkit.Block.Heading.level h < level -> (acc, headings) | heading :: rest -> collect_children level ~max_level rest (acc @ [ heading ]) +let headers (doc : Cmarkit.Doc.t) : Cmarkit.Block.Heading.t Cmarkit.node list = + let rec headers_from_block (block : Cmarkit.Block.t) = + match block with + | Cmarkit.Block.Heading h -> [ h ] + | Cmarkit.Block.Blocks (blocks, _) -> + List.map headers_from_block blocks |> List.concat + | _ -> [] + in + + Cmarkit.Doc.block doc |> headers_from_block + let toc ?(start_level = 1) ?(max_level = 2) doc = if max_level <= start_level then invalid_arg "toc: ~max_level must be >= ~start_level"; - let headers = Omd.headers ~remove_links:true doc in - create_toc ~max_level start_level headers + create_toc ~max_level start_level (headers doc) let decode (fpath, (head, body_md)) = let metadata = metadata_of_yaml head in @@ -122,9 +102,9 @@ let decode (fpath, (head, body_md)) = List.nth (String.split_on_char '/' fpath) 1 |> Section.of_string |> Result.get_ok in - let omd = doc_with_ids (Omd.of_string body_md) in - let toc = toc ~start_level:2 ~max_level:4 omd in - let body_html = Omd.to_html (Hilite.Md.transform omd) in + let doc = Cmarkit.Doc.of_string ~strict:true ~heading_auto_ids:true body_md in + let toc = toc ~start_level:2 ~max_level:4 doc in + let body_html = Hilite.Md.transform doc |> Cmarkit_html.of_doc ~safe:false in Result.map (of_metadata ~fpath ~section ~toc ~body_md ~body_html) metadata let all () = diff --git a/tool/ood-gen/lib/workshop.ml b/tool/ood-gen/lib/workshop.ml index 2594a79019..1044a2a1c9 100644 --- a/tool/ood-gen/lib/workshop.ml +++ b/tool/ood-gen/lib/workshop.ml @@ -51,22 +51,20 @@ type t = { presentations : presentation list; program_committee : committee_member list; organising_committee : committee_member list; - toc_html : string; body_md : string; body_html : string; } [@@deriving - stable_record ~version:metadata ~remove:[ slug; toc_html; body_md; body_html ], + stable_record ~version:metadata ~remove:[ slug; body_md; body_html ], show { with_path = false }] let of_metadata m = of_metadata m ~slug:(Utils.slugify m.title) let decode (_, (head, body_md)) = let metadata = metadata_of_yaml head in - let omd = Omd.of_string body_md in - let toc_html = Omd.to_html (Omd.toc ~depth:4 omd) in - let body_html = Omd.to_html omd in - Result.map (of_metadata ~toc_html ~body_md ~body_html) metadata + let doc = Cmarkit.Doc.of_string body_md in + let body_html = Cmarkit_html.of_doc ~safe:true doc in + Result.map (of_metadata ~body_md ~body_html) metadata let all () = Utils.map_files decode "workshops/*.md" @@ -108,7 +106,6 @@ type t = { presentations : presentation list; program_committee : committee_member list; organising_committee : committee_member list; - toc_html : string; body_md : string; body_html : string; }