kortfat/lib/kortfat.ml
2024-09-24 11:58:17 +02:00

72 lines
1.8 KiB
OCaml

module SM = Map.Make(String)
let heading_to_string heading =
Cmarkit.Block.Heading.inline heading
|> Cmarkit.Inline.to_plain_text ~break_on_soft:false
|> List.map (String.concat "")
|> String.concat "\n"
let aggregate t doc =
let rec aggregate t heading = function
| [] -> t
| Cmarkit.Block.Heading (heading, _) :: rest ->
let heading = heading_to_string heading in
let t =
SM.update heading
(function
| None -> Some []
| Some blocks -> Some blocks)
t
in
aggregate t heading rest
| block :: rest ->
let t =
SM.update heading
(function
| None ->
Some [ block ]
| Some blocks ->
Some (block :: blocks))
t
in
aggregate t heading rest
in
match Cmarkit.Doc.block doc with
| Cmarkit.Block.Blocks (blocks, _) ->
aggregate t "" blocks
| Cmarkit.Block.Heading (heading, _) ->
let heading = heading_to_string heading in
SM.update heading
(function
| None -> Some []
| Some blocks -> Some blocks)
t
| block ->
SM.update ""
(function
| None ->
Some [ block ]
| Some blocks ->
Some (block :: blocks))
t
let kortfat docs =
let rev_t = List.fold_left aggregate SM.empty docs in
let t = SM.map List.rev rev_t in
let blocks =
SM.fold
(fun heading blocks acc ->
let heading =
Cmarkit.Block.Heading
(Cmarkit.Block.Heading.make
~level:2
(Cmarkit.Inline.Text
(heading, Cmarkit.Meta.none)),
Cmarkit.Meta.none)
in
heading :: blocks @ acc)
t
[]
in
Cmarkit.Block.Blocks (blocks, Cmarkit.Meta.none)
|> Cmarkit.Doc.make