Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: add Escaped type #117

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/export/html.ml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ and inline config t =
| Plain s
| Spaces s ->
[ Xml.data s ]
| Escaped s -> [ Xml.data ("\\" ^ s) ]
| Superscript l -> [ Xml.block "sup" (map_inline config l) ]
| Subscript l -> [ Xml.block "sub" (map_inline config l) ]
| Emphasis (kind, data) ->
Expand Down
6 changes: 6 additions & 0 deletions lib/export/markdown.ml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ let rec inline state config (t : Inline.t) : t list =
map_raw_text [ String.ltrim s ]
) else
map_raw_text [ s ]
| Escaped s ->
if state.last_newline then (
state.last_newline <- false;
map_raw_text [ "\\"; s ]
) else
map_raw_text [ "\\"; s ]
| Link l -> inline_link l
| Nested_link l -> inline_nested_link l
| Target s -> map_raw_text [ "<<"; s; ">>" ]
Expand Down
7 changes: 1 addition & 6 deletions lib/mldoc_parser.ml
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,7 @@ let parsers config =

let parse config input =
match parse_string ~consume:All (parsers config) input with
| Ok result ->
let ast = Paragraph.concat_paragraph_lines config result in
if Conf.is_markdown config then
List.map (fun (t, pos) -> (Type_op.md_unescaped t, pos)) ast
else
ast
| Ok result -> Paragraph.concat_paragraph_lines config result
| Error err -> failwith err

let load_file f =
Expand Down
16 changes: 11 additions & 5 deletions lib/syntax/inline.ml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ and t =
| Email of Email_address.t
| Inline_Hiccup of string
| Inline_Html of string
| Escaped of string
[@@deriving yojson]

and t_with_pos = t * pos_meta option
Expand Down Expand Up @@ -208,6 +209,13 @@ let in_plain_delims config c =

let whitespaces = ws >>| fun spaces -> Plain spaces

let md_escaped_char set_last_char =
char '\\' >>= fun _ ->
satisfy is_md_escape_char >>| fun c ->
let s = String.make 1 c in
set_last_char s;
Escaped s

let plain ?state config =
let set_last_char s =
Option.(
Expand All @@ -223,10 +231,7 @@ let plain ?state config =
<|> ( ws >>| fun s ->
set_last_char s;
Plain s )
<|> ( char '\\' *> satisfy is_md_escape_char >>| fun c ->
let s = String.make 1 c in
set_last_char s;
Plain ("\\" ^ s) )
<|> md_escaped_char set_last_char
<|> ( any_char >>= fun c ->
if in_plain_delims config c then (
let s = String.make 1 c in
Expand Down Expand Up @@ -487,7 +492,7 @@ let entity =
try
let entity = Entity.find s in
Entity entity
with Not_found -> Plain s
with Not_found -> Plain ("\\" ^ s)

(* FIXME: nested emphasis not working *)
(* foo_bar, foo_{bar}, foo^bar, foo^{bar} *)
Expand Down Expand Up @@ -919,6 +924,7 @@ let nested_link_or_link config =
let nested_emphasis ?state config =
let rec aux_nested_emphasis = function
| Plain s -> Plain s
| Escaped s -> Escaped s
| Emphasis (`Italic, [ Emphasis (`Bold, _) ]) as e -> e
| Emphasis (typ, l) ->
let parser =
Expand Down
113 changes: 0 additions & 113 deletions lib/syntax/type_op.ml
Original file line number Diff line number Diff line change
Expand Up @@ -52,116 +52,3 @@ let rec type_move_forawrd t forward_pos =
| Footnote_Definition (s, l) ->
Footnote_Definition (s, inline_list_move_forward l forward_pos)
| _ -> t

let unescaped_md_string s =
let open Bytes in
let b = of_string s in
let n = ref 0 in
let i = ref 0 in
let lenb = length b in
while !i < lenb do
n :=
!n
+
match get b !i with
| '\\' when !i + 1 < lenb && Parsers.is_md_escape_char (get b (!i + 1)) ->
i := !i + 2;
1
| _ ->
incr i;
1
done;
if !n = length b then
s
else
let b' = create !n in
n := 0;
let i = ref 0 in
let len_1 = length b - 1 in
while !i <= len_1 do
(match get b !i with
| '\\' when !i < len_1 ->
let c = get b (!i + 1) in
if Parsers.is_md_escape_char c then
set b' !n c
else (
set b' !n '\\';
incr n;
set b' !n c
);
incr i
| c -> set b' !n c);
incr n;
incr i
done;
to_string b'

let map_escaped_string t f =
let rec inline_aux (t : Inline.t) =
match t with
| Inline.Emphasis (em_type, tl) ->
Inline.Emphasis (em_type, List.map inline_aux tl)
| Inline.Tag tl -> Inline.Tag (List.map inline_aux tl)
| Inline.Plain s -> Inline.Plain (f s)
| Inline.Link link ->
let label = List.map inline_aux link.label in
let url =
match link.url with
| Inline.File s -> Inline.File (f s)
| Inline.Search s -> Inline.Search (f s)
| Inline.Page_ref s -> Inline.Page_ref (f s)
| Inline.Complex complex ->
Inline.Complex { complex with link = f complex.link }
| Inline.Block_ref _ -> link.url
| Inline.Embed_data _ -> link.url
in
Inline.Link { link with label; url }
| Inline.Subscript tl -> Inline.Subscript (List.map inline_aux tl)
| Inline.Superscript tl -> Inline.Superscript (List.map inline_aux tl)
| Inline.Footnote_Reference fr ->
Inline.Footnote_Reference
{ fr with definition = Option.map (List.map inline_aux) fr.definition }
| _ -> t
in
let rec block_list_aux list_item =
let content' = List.map block_aux list_item.content in
let items = List.map block_list_aux list_item.items in
let name =
List.map (fun (t', pos) -> (inline_aux t', pos)) list_item.name
in
{ list_item with content = content'; items; name }
and block_aux (t : Type.t) =
match t with
| Paragraph l ->
Paragraph (List.map (fun (t', pos) -> (inline_aux t', pos)) l)
| Heading heading ->
let title' =
List.map (fun (t', pos) -> (inline_aux t', pos)) heading.title
in
Heading { heading with title = title' }
| List l -> List (List.map block_list_aux l)
| Quote tl -> Quote (List.map block_aux tl)
| Custom (name, opts, data, s) ->
let data' = List.map block_aux data in
Custom (name, opts, data', s)
| Footnote_Definition (name, content) ->
let content' = List.map (fun (t', pos) -> (inline_aux t', pos)) content in
Footnote_Definition (name, content')
| Table table ->
let header = Option.map (List.map (List.map inline_aux)) table.header in
let groups =
List.map (List.map (List.map (List.map inline_aux))) table.groups
in
Table { table with header; groups }
| _ -> t
in
block_aux t

(** unescape string in Type.Plain:
e.g. \* -> *
see also Parsers.md_escape_chars
text in code fence should preserve '\' *)
let md_unescaped t = map_escaped_string t unescaped_md_string

(** TODO *)
let md_escaped _t = failwith "not impl yet"
12 changes: 10 additions & 2 deletions test/test_export_markdown.ml
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ let export_md =
\t\t [[line6]]\n\
\t\t\t-\n\
\t\t\t ```\n\
\t\t\t dwdw\n\
\t\t\t jdiejdie\n\
\t\t\t \t dwdw\n\
\t\t\t \t jdiejdie\n\
\t\t\t ```" )
; ( "(5)"
, `Quick
Expand Down Expand Up @@ -173,6 +173,14 @@ let export_md =
, `Quick
, check_aux "- {{cloze (content1,content2)}}" "- (content1,content2)"
)
; ("escaped", `Quick, check_aux "- a\\`b" "- a\\`b")
; ( "escaped"
, `Quick
, check_aux "- a\\^b \\*non-italic*" "- a\\^b \\*non-italic*" )
; ( "escaped"
, `Quick
, check_aux "- example postgres cmd: \\dt"
"- example postgres cmd: \\dt" )
] )
]

Expand Down
27 changes: 19 additions & 8 deletions test/test_markdown.ml
Original file line number Diff line number Diff line change
Expand Up @@ -696,28 +696,39 @@ let inline =
[ ( "emphasis(1)"
, `Quick
, check_aux "*a\\*b*"
(paragraph [ Inline.Emphasis (`Italic, [ Inline.Plain "a*b" ]) ])
)
(paragraph
[ Inline.Emphasis
(`Italic, [ I.Plain "a"; I.Escaped "*"; I.Plain "b" ])
]) )
; ( "emphasis(2)"
, `Quick
, check_aux "*a\\\\\\*b*"
(paragraph
[ Inline.Emphasis (`Italic, [ Inline.Plain "a\\*b" ]) ]) )
[ Inline.Emphasis
( `Italic
, [ I.Plain "a"
; I.Escaped "\\"
; I.Escaped "*"
; I.Plain "b"
] )
]) )
; ( "code"
, `Quick
, check_aux "`a\\``"
(paragraph [ Inline.Code "a\\"; Inline.Plain "`" ]) )
; ( "nested emphasis"
, `Quick
, check_aux "_a*b\\*_"
(paragraph [ Inline.Emphasis (`Italic, [ Inline.Plain "a*b*" ]) ])
)
(paragraph
[ Inline.Emphasis
(`Italic, [ Inline.Plain "a*b"; I.Escaped "*" ])
]) )
; ( "link (1)"
, `Quick
, check_aux "[[\\]]]"
(paragraph
[ Inline.Link
{ url = Inline.Page_ref "]"
{ url = Inline.Page_ref "\\]"
; label = [ Inline.Plain "" ]
; full_text = "[[\\]]]"
; metadata = ""
Expand All @@ -730,7 +741,7 @@ let inline =
(paragraph
[ Inline.Link
{ url = Inline.Search "xxx"
; label = [ Inline.Plain "label](x)" ]
; label = [ Inline.Plain "label\\](x)" ]
; full_text = "[label\\](x)](xxx)"
; metadata = ""
; title = None
Expand All @@ -741,7 +752,7 @@ let inline =
, check_aux "[label](ur\\)l)"
(paragraph
[ Inline.Link
{ url = Inline.Search "ur)l"
{ url = Inline.Search "ur\\)l"
; label = [ Inline.Plain "label" ]
; full_text = "[label](ur\\)l)"
; metadata = ""
Expand Down