1
1
open Omd
2
2
open Base
3
3
4
- let escape_url_chars = Staged. unstage @@ String.Escaping. escape ~escapeworthy: [ '<' ; '>' ; '|' ] ~escape_char: '\\'
5
-
6
4
(* https://api.slack.com/reference/surfaces/formatting#escaping *)
7
5
let escape_mrkdwn =
8
6
String. concat_map ~f: (function
@@ -11,58 +9,6 @@ let escape_mrkdwn =
11
9
| '&' -> " &"
12
10
| c -> String. make 1 c)
13
11
14
- (* * Unescape markdown characters escaped because "any ASCII punctuation
15
- character may be backslash-escaped"
16
- https://spec.commonmark.org/0.30/#backslash-escapes
17
-
18
- This pertains to '\\', '[', ']', '(', ')', '`', '*' unconditionally,
19
- and '.', '-', '+', '!', '<', '>', '#' depending on chars before/after.
20
- Argument escapeworthy_map can be left blank because escaped chars are
21
- unescaped to themselves. *)
22
- let unescape_omd = Staged. unstage @@ String.Escaping. unescape_gen_exn ~escapeworthy_map: [] ~escape_char: '\\'
23
-
24
- (* * Escape the `escape_char` '\\' for use with `unescape_omd` later *)
25
- let escape_omd = Staged. unstage @@ String.Escaping. escape_gen_exn ~escapeworthy_map: [] ~escape_char: '\\'
26
-
27
- let transform_text = escape_mrkdwn
28
-
29
- (* * `Omd.to_markdown` escapes backslash (and other applicable chars) in
30
- `Text` elements but not `Code` elements, so do the same for the latter so
31
- that `unescape_omd` can apply uniformly to the whole mrkdwn string later *)
32
- let transform_code s = escape_omd @@ escape_mrkdwn s
33
-
34
- let rec transform_list = List. map ~f: transform
35
-
36
- and transform_flatten = List. map ~f: transform_list
37
-
38
- and surround s t =
39
- let t = to_markdown @@ transform_list t in
40
- Raw (Printf. sprintf " %s%s%s" s t s)
41
-
42
- (* * massage markdown AST so that rendered result looks like slack mrkdwn *)
43
- and transform = function
44
- | H1 t | H2 t | H3 t | H4 t | H5 t | H6 t -> Paragraph (transform_list [ Bold t ])
45
- | Paragraph t -> Paragraph (transform_list t)
46
- | Emph t -> surround " _" (transform_list t)
47
- | Bold t -> surround " *" (transform_list t)
48
- | Ul ts -> Ul (transform_flatten ts)
49
- | Ol ts -> Ol (transform_flatten ts)
50
- | Ulp ts -> Ulp (transform_flatten ts)
51
- | Olp ts -> Olp (transform_flatten ts)
52
- | Url (href , label , title ) ->
53
- let label = escape_url_chars @@ to_markdown @@ transform_list label in
54
- let title = if String. length title > 0 then Printf. sprintf " %s - " @@ escape_url_chars title else title in
55
- Raw (Printf. sprintf " <%s|%s%s>" href title label)
56
- | Html _ as e -> Raw (Printf. sprintf " `%s`" @@ to_markdown [ e ])
57
- | Html_comment _ -> Br
58
- | Html_block _ as e -> Code_block (" " , to_markdown [ e ])
59
- | Blockquote t -> Blockquote (transform_list t)
60
- | Img (alt , src , title ) -> transform @@ Url (src, [ Text alt ], title)
61
- | Code_block (_ , str ) -> Code_block (" " , transform_code str)
62
- | Code (_ , str ) -> Code (" " , transform_code str)
63
- | Text s -> Text (transform_text s)
64
- | (Br | Hr | NL | Ref _ | Img_ref _ | Raw _ | Raw_block _ | X _ ) as e -> e
65
-
66
12
(* * Translates omd AST to a Slack mrkdwn string. Code heavily adapted
67
13
from omd 1.3.1 source.
68
14
https://github.com/ocaml/omd/blob/1.3.1/src/omd_backend.ml#L872
@@ -224,8 +170,7 @@ let rec mrkdwn_of_md md =
224
170
loop list_indent s;
225
171
Buffer. add_char b '>' ;
226
172
loop list_indent tl
227
- | H1 md' | H2 md' | H3 md' | H4 md' | H5 md' | H6 md' ->
228
- loop list_indent (Paragraph (transform_list [ Bold md' ]) :: tl)
173
+ | H1 md' | H2 md' | H3 md' | H4 md' | H5 md' | H6 md' -> loop list_indent (Paragraph [ Bold md' ] :: tl)
229
174
| Br ->
230
175
(* the string "\\n" (backslash-newline) or end of line double-space renders Br *)
231
176
nl b;
@@ -254,4 +199,4 @@ let rec mrkdwn_of_md md =
254
199
end ;
255
200
Buffer. contents b
256
201
257
- let mrkdwn_of_markdown str = unescape_omd @@ to_markdown @@ transform_list @@ of_string str
202
+ let mrkdwn_of_markdown str = mrkdwn_of_md @@ of_string str
0 commit comments