From af3e1f667da4c1c2a6c8c42fa2d44fa25e5b2396 Mon Sep 17 00:00:00 2001 From: Corentin Leruth Date: Mon, 18 Mar 2024 09:59:38 +0100 Subject: [PATCH 1/2] basic cmarkit to mrkdwn converter --- lib/dune | 1 + lib/mrkdwn.ml | 61 +++++++++++++++++++++++++++++++++ lib_test/mrkdwn/dune | 11 ++++++ lib_test/mrkdwn/mrkdwn_of_md.ml | 1 + lib_test/mrkdwn/mrkdwn_of_md.t | 30 ++++++++++++++++ 5 files changed, 104 insertions(+) create mode 100644 lib_test/mrkdwn/dune create mode 100644 lib_test/mrkdwn/mrkdwn_of_md.ml create mode 100644 lib_test/mrkdwn/mrkdwn_of_md.t diff --git a/lib/dune b/lib/dune index 349b14c..5fcced5 100644 --- a/lib/dune +++ b/lib/dune @@ -5,6 +5,7 @@ atdgen atdgen-runtime biniou + cmarkit cstruct devkit extlib diff --git a/lib/mrkdwn.ml b/lib/mrkdwn.ml index 99a96a9..3c2b2cd 100644 --- a/lib/mrkdwn.ml +++ b/lib/mrkdwn.ml @@ -55,3 +55,64 @@ let highlight_mentions get_id_by_slack_name s = |> Option.default s in Re2.replace_exn mention_re s ~f:(fun m -> subst (Re2.Match.get_exn ~sub:(`Index 0) m)) + +module Cmarkit_slack = struct + let renderer = + (* https://www.markdownguide.org/tools/slack/#slack-markdown-support-in-posts *) + (* https://slack.com/intl/en-gb/help/articles/202288908-Format-your-messages *) + let inline c inline = + let open Cmarkit in + let module C = Cmarkit_renderer.Context in + let strong_emphasis c e = + let i = Inline.Emphasis.inline e in + C.byte c '*'; + C.inline c i; + C.byte c '*' + in + let emphasis c e = + let i = Inline.Emphasis.inline e in + C.byte c '_'; + C.inline c i; + C.byte c '_' + in + let strikethrough c s = + let i = Inline.Strikethrough.inline s in + C.byte c '~'; + C.inline c i; + C.byte c '~' + in + let link c l = + match Inline.Link.reference l with + | `Inline (ld, _) -> + begin + match Link_definition.dest ld with + | None -> C.inline c (Inline.Link.text l) + | Some (dest, _) -> + C.byte c '<'; + C.string c dest; + C.byte c '|'; + C.inline c (Inline.Link.text l); + C.byte c '>' + end; + true + | _ -> false + in + match inline with + | Inline.Strong_emphasis (e, _) -> + strong_emphasis c e; + true + | Inline.Emphasis (e, _) -> + emphasis c e; + true + | Inline.Ext_strikethrough (s, _) -> + strikethrough c s; + true + | Inline.Link (l, _) -> link c l + | _ -> false (* let the default renderer handle that *) + in + let default_renderer = Cmarkit_commonmark.renderer () in + let renderer = Cmarkit_renderer.make ~inline () in + Cmarkit_renderer.compose default_renderer renderer +end + +let of_doc = Cmarkit_renderer.doc_to_string Cmarkit_slack.renderer diff --git a/lib_test/mrkdwn/dune b/lib_test/mrkdwn/dune new file mode 100644 index 0000000..af6145f --- /dev/null +++ b/lib_test/mrkdwn/dune @@ -0,0 +1,11 @@ +(executable + (name mrkdwn_of_md) + (libraries slack_lib cmarkit)) + +(env + (_ + (binaries + (./mrkdwn_of_md.exe as mrkdwn_of_md)))) + +(cram + (deps %{bin:mrkdwn_of_md})) diff --git a/lib_test/mrkdwn/mrkdwn_of_md.ml b/lib_test/mrkdwn/mrkdwn_of_md.ml new file mode 100644 index 0000000..ef24764 --- /dev/null +++ b/lib_test/mrkdwn/mrkdwn_of_md.ml @@ -0,0 +1 @@ +let () = print_string (Cmarkit.Doc.of_string ~strict:false (In_channel.input_all stdin) |> Slack_lib.Mrkdwn.of_doc) diff --git a/lib_test/mrkdwn/mrkdwn_of_md.t b/lib_test/mrkdwn/mrkdwn_of_md.t new file mode 100644 index 0000000..4d499af --- /dev/null +++ b/lib_test/mrkdwn/mrkdwn_of_md.t @@ -0,0 +1,30 @@ +bold + $ mrkdwn_of_md << "MD" + > **bold** + > __bold__ + > MD + *bold* + *bold* + +italic + $ mrkdwn_of_md << "MD" + > *italic* + > _italic_ + > MD + _italic_ + _italic_ + + +strikethrough + $ mrkdwn_of_md << "MD" + > ~~strike~~ + > ~strike~ + > MD + ~strike~ + ~strike~ + +link + $ mrkdwn_of_md << "MD" + > [hello](https://google.be) + > MD + From bddd8fd25e4132d394323df2c5cad6b373354ab5 Mon Sep 17 00:00:00 2001 From: Corentin Leruth Date: Mon, 18 Mar 2024 13:29:37 +0100 Subject: [PATCH 2/2] print headings as bold --- lib/mrkdwn.ml | 15 ++++++++++++++- lib_test/mrkdwn/mrkdwn_of_md.t | 16 ++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/mrkdwn.ml b/lib/mrkdwn.ml index 3c2b2cd..16c1f1f 100644 --- a/lib/mrkdwn.ml +++ b/lib/mrkdwn.ml @@ -110,8 +110,21 @@ module Cmarkit_slack = struct | Inline.Link (l, _) -> link c l | _ -> false (* let the default renderer handle that *) in + let block c block = + let open Cmarkit in + let module C = Cmarkit_renderer.Context in + match block with + | Block.Heading (heading, _) -> + let inline = Block.Heading.inline heading in + C.byte c '*'; + C.inline c inline; + C.byte c '*'; + C.byte c '\n'; + true + | _ -> false + in let default_renderer = Cmarkit_commonmark.renderer () in - let renderer = Cmarkit_renderer.make ~inline () in + let renderer = Cmarkit_renderer.make ~inline ~block () in Cmarkit_renderer.compose default_renderer renderer end diff --git a/lib_test/mrkdwn/mrkdwn_of_md.t b/lib_test/mrkdwn/mrkdwn_of_md.t index 4d499af..ff25f28 100644 --- a/lib_test/mrkdwn/mrkdwn_of_md.t +++ b/lib_test/mrkdwn/mrkdwn_of_md.t @@ -28,3 +28,19 @@ link > [hello](https://google.be) > MD + +headings + $ mrkdwn_of_md << "MD" + > # one + > ## two + > ### three + > #### four + > ##### five + > ###### six + > MD + *one* + *two* + *three* + *four* + *five* + *six*