Current section
Files
Jump to
Current section
Files
src/commonmark@internal@parser@inline.erl
-module(commonmark@internal@parser@inline).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([parse_text/1]).
-export_type([inline_lexer/0, inline_wrapper/0]).
-type inline_lexer() :: {entity, binary(), binary()} |
{escaped, binary()} |
{text, binary()} |
less_than |
greater_than |
backtick |
tilde |
asterisk |
underscore |
soft_line_break |
{hard_line_break, binary()}.
-type inline_wrapper() :: {lexed_element, inline_lexer()} |
{email_autolink, list(inline_wrapper())} |
{uri_autolink, list(inline_wrapper())} |
{backtick_string, integer()} |
{tilde_string, integer()} |
{asterisk_string, integer()} |
{underscore_string, integer()} |
{emphasis, list(inline_wrapper()), commonmark@ast:emphasis_marker()} |
{strong_emphasis, list(inline_wrapper()), commonmark@ast:emphasis_marker()} |
{code_span, integer(), list(inline_wrapper())} |
{strikethrough, integer(), list(inline_wrapper())}.
-spec parse_code_span(integer(), list(inline_wrapper())) -> list(inline_wrapper()).
parse_code_span(Size, Previous) ->
case gleam@list:split_while(
Previous,
fun(N) -> N /= {backtick_string, Size} end
) of
{_, []} ->
[{backtick_string, Size} | Previous];
{Wrapped, [_ | Rest]} ->
[{code_span, Size, lists:reverse(Wrapped)} | Rest]
end.
-spec is_not_less_than(inline_wrapper()) -> boolean().
is_not_less_than(V) ->
case V of
{lexed_element, less_than} ->
false;
_ ->
true
end.
-spec parse_strikethrough(integer(), list(inline_wrapper())) -> list(inline_wrapper()).
parse_strikethrough(Size, Previous) ->
case gleam@list:split_while(
Previous,
fun(N) -> N /= {tilde_string, Size} end
) of
{_, []} ->
[{tilde_string, Size} | Previous];
{Wrapped, [_ | Rest]} ->
[{strikethrough, Size, lists:reverse(Wrapped)} | Rest]
end.
-spec parse_emphasis(inline_wrapper(), list(inline_wrapper())) -> {list(inline_wrapper()),
list(inline_wrapper())}.
parse_emphasis(Final, Previous) ->
{Wrapped, Rest} = gleam@list:split_while(
Previous,
fun(N) -> case {N, Final} of
{{asterisk_string, L}, {asterisk_string, R}} ->
not (((L > 0) andalso (R > 0)) andalso ((((L + R) rem 3) /= 0)
orelse (((L rem 3) =:= 0) andalso ((R rem 3) =:= 0))));
{{underscore_string, L}, {underscore_string, R}} ->
not (((L > 0) andalso (R > 0)) andalso ((((L + R) rem 3) /= 0)
orelse (((L rem 3) =:= 0) andalso ((R rem 3) =:= 0))));
{_, _} ->
true
end end
),
case {Final, Rest} of
{{asterisk_string, R@1}, [{asterisk_string, L@1} | Rest@1]} when (L@1 >= 2) andalso (R@1 >= 2) ->
{[{asterisk_string, R@1 - 2}],
[{strong_emphasis,
lists:reverse(Wrapped),
asterisk_emphasis_marker},
{asterisk_string, L@1 - 2} |
Rest@1]};
{{asterisk_string, R@2}, [{asterisk_string, L@2} | Rest@2]} ->
{[{asterisk_string, R@2 - 1}],
[{emphasis, lists:reverse(Wrapped), asterisk_emphasis_marker},
{asterisk_string, L@2 - 1} |
Rest@2]};
{{underscore_string, R@3}, [{underscore_string, L@3} | Rest@3]} when (L@3 >= 2) andalso (R@3 >= 2) ->
{[{underscore_string, R@3 - 2}],
[{strong_emphasis,
lists:reverse(Wrapped),
underscore_emphasis_marker},
{underscore_string, L@3 - 2} |
Rest@3]};
{{underscore_string, R@4}, [{underscore_string, L@4} | Rest@4]} ->
{[{underscore_string, R@4 - 1}],
[{emphasis, lists:reverse(Wrapped), underscore_emphasis_marker},
{underscore_string, L@4 - 1} |
Rest@4]};
{_, _} ->
{[], [Final | Previous]}
end.
-spec do_parse_emphasis(list(inline_wrapper()), list(inline_wrapper())) -> list(inline_wrapper()).
do_parse_emphasis(Wrapped, Acc) ->
case Wrapped of
[] ->
_pipe = Acc,
lists:reverse(_pipe);
[{tilde_string, Count} | Xs] ->
case Count =< 2 of
true ->
do_parse_emphasis(Xs, parse_strikethrough(Count, Acc));
false ->
do_parse_emphasis(Xs, [{tilde_string, Count} | Acc])
end;
[{asterisk_string, N} = Str | Xs@1] when N > 0 ->
{Prefix, Acc@1} = parse_emphasis(Str, Acc),
do_parse_emphasis(gleam@list:concat([Prefix, Xs@1]), Acc@1);
[{underscore_string, N} = Str | Xs@1] when N > 0 ->
{Prefix, Acc@1} = parse_emphasis(Str, Acc),
do_parse_emphasis(gleam@list:concat([Prefix, Xs@1]), Acc@1);
[X | Xs@2] ->
do_parse_emphasis(Xs@2, [X | Acc])
end.
-spec trim_left(binary()) -> binary().
trim_left(X) ->
case X of
<<" "/utf8, X@1/binary>> ->
trim_left(X@1);
<<"\t"/utf8, X@2/binary>> ->
trim_left(X@2);
_ ->
X
end.
-spec trim_right(binary()) -> binary().
trim_right(X) ->
_pipe = X,
_pipe@1 = gleam@string:reverse(_pipe),
_pipe@2 = trim_left(_pipe@1),
gleam@string:reverse(_pipe@2).
-spec do_finalise_plain_text(
list(commonmark@ast:inline_node()),
list(commonmark@ast:inline_node()),
boolean()
) -> list(commonmark@ast:inline_node()).
do_finalise_plain_text(Ast, Acc, Trim_ends) ->
case {Ast, Acc} of
{[], [{plain_text, Y} | Ys]} when Trim_ends ->
_pipe = [{plain_text, trim_right(Y)} | Ys],
lists:reverse(_pipe);
{[], _} ->
_pipe@1 = Acc,
lists:reverse(_pipe@1);
{[{plain_text, <<""/utf8>>} | Xs], _} ->
do_finalise_plain_text(Xs, Acc, Trim_ends);
{[{strong_emphasis, Content, Marker} | Xs@1], _} ->
do_finalise_plain_text(
Xs@1,
[{strong_emphasis,
do_finalise_plain_text(Content, [], false),
Marker} |
Acc],
Trim_ends
);
{[{emphasis, Content@1, Marker@1} | Xs@2], _} ->
do_finalise_plain_text(
Xs@2,
[{emphasis,
do_finalise_plain_text(Content@1, [], Trim_ends),
Marker@1} |
Acc],
Trim_ends
);
{[{strike_through, Content@2} | Xs@3], _} ->
do_finalise_plain_text(
Xs@3,
[{strike_through,
do_finalise_plain_text(Content@2, [], Trim_ends)} |
Acc],
Trim_ends
);
{[{plain_text, X} | Xs@4], [{plain_text, Y@1} | Ys@1]} ->
do_finalise_plain_text(
Xs@4,
[{plain_text, <<Y@1/binary, X/binary>>} | Ys@1],
Trim_ends
);
{[{plain_text, X@1} | Xs@5], []} when Trim_ends ->
do_finalise_plain_text(
Xs@5,
[{plain_text, trim_left(X@1)} | Acc],
Trim_ends
);
{[{plain_text, X@1} | Xs@5], [hard_line_break | _]} when Trim_ends ->
do_finalise_plain_text(
Xs@5,
[{plain_text, trim_left(X@1)} | Acc],
Trim_ends
);
{[{plain_text, X@1} | Xs@5], [soft_line_break | _]} when Trim_ends ->
do_finalise_plain_text(
Xs@5,
[{plain_text, trim_left(X@1)} | Acc],
Trim_ends
);
{[hard_line_break = X@2 | Xs@6], [{plain_text, Y@2} | Ys@2]} when Trim_ends ->
do_finalise_plain_text(
Xs@6,
[X@2, {plain_text, trim_right(Y@2)} | Ys@2],
Trim_ends
);
{[soft_line_break = X@2 | Xs@6], [{plain_text, Y@2} | Ys@2]} when Trim_ends ->
do_finalise_plain_text(
Xs@6,
[X@2, {plain_text, trim_right(Y@2)} | Ys@2],
Trim_ends
);
{[X@3 | Xs@7], _} ->
do_finalise_plain_text(Xs@7, [X@3 | Acc], Trim_ends)
end.
-spec replace_null_byte(integer()) -> integer().
replace_null_byte(N) ->
case gleam@list:contains([0], N) of
true ->
16#fffd;
false ->
N
end.
-spec translate_numerical_entity({ok, integer()} | {error, nil}, list(binary())) -> {ok,
{list(binary()), binary()}} |
{error, nil}.
translate_numerical_entity(Codepoint, Rest) ->
_pipe = Codepoint,
_pipe@1 = gleam@result:map(_pipe, fun replace_null_byte/1),
_pipe@2 = gleam@result:'try'(_pipe@1, fun gleam@string:utf_codepoint/1),
gleam@result:map(
_pipe@2,
fun(Cp) -> {Rest, gleam_stdlib:utf_codepoint_list_to_string([Cp])} end
).
-spec match_entity(list(binary())) -> {ok, {list(binary()), binary(), binary()}} |
{error, nil}.
match_entity(Input) ->
_pipe = commonmark@internal@parser@entity:match_html_entity(Input),
gleam@result:try_recover(
_pipe,
fun(_) ->
_assert_subject = gleam@regex:from_string(
<<"^#([0-9]{1,7});"/utf8>>
),
{ok, Dec_entity} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"commonmark/internal/parser/inline"/utf8>>,
function => <<"match_entity"/utf8>>,
line => 114})
end,
_assert_subject@1 = gleam@regex:from_string(
<<"^#([xX]([0-9a-fA-F]{1,6}));"/utf8>>
),
{ok, Hex_entity} = case _assert_subject@1 of
{ok, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"commonmark/internal/parser/inline"/utf8>>,
function => <<"match_entity"/utf8>>,
line => 115})
end,
Potential = begin
_pipe@1 = gleam@list:take(Input, 9),
gleam@string:join(_pipe@1, <<""/utf8>>)
end,
case {gleam@regex:scan(Dec_entity, Potential),
gleam@regex:scan(Hex_entity, Potential)} of
{[{match, Full, [{some, N}]}], _} ->
_pipe@2 = N,
_pipe@3 = gleam@int:parse(_pipe@2),
_pipe@4 = translate_numerical_entity(
_pipe@3,
gleam@list:drop(Input, gleam@string:length(Full))
),
gleam@result:map(
_pipe@4,
fun(R) ->
{erlang:element(1, R), N, erlang:element(2, R)}
end
);
{_, [{match, Full@1, [{some, M}, {some, N@1}]}]} ->
_pipe@5 = N@1,
_pipe@6 = gleam@int:base_parse(_pipe@5, 16),
_pipe@7 = translate_numerical_entity(
_pipe@6,
gleam@list:drop(Input, gleam@string:length(Full@1))
),
gleam@result:map(
_pipe@7,
fun(R@1) ->
{erlang:element(1, R@1), M, erlang:element(2, R@1)}
end
);
{_, _} ->
{error, nil}
end
end
).
-spec do_lex_inline_text(list(binary()), list(binary()), list(inline_lexer())) -> list(inline_lexer()).
do_lex_inline_text(Input, Text, Acc) ->
case Input of
[] ->
_pipe@2 = [{text,
begin
_pipe = Text,
_pipe@1 = lists:reverse(_pipe),
gleam@string:join(_pipe@1, <<""/utf8>>)
end} |
Acc],
_pipe@3 = gleam@list:filter(
_pipe@2,
fun(X) -> X /= {text, <<""/utf8>>} end
),
lists:reverse(_pipe@3);
[<<"<"/utf8>> | Xs] ->
do_lex_inline_text(
Xs,
[],
[less_than,
{text,
begin
_pipe@4 = Text,
_pipe@5 = lists:reverse(_pipe@4),
gleam@string:join(_pipe@5, <<""/utf8>>)
end} |
Acc]
);
[<<">"/utf8>> | Xs@1] ->
do_lex_inline_text(
Xs@1,
[],
[greater_than,
{text,
begin
_pipe@6 = Text,
_pipe@7 = lists:reverse(_pipe@6),
gleam@string:join(_pipe@7, <<""/utf8>>)
end} |
Acc]
);
[<<"`"/utf8>> | Xs@2] ->
do_lex_inline_text(
Xs@2,
[],
[backtick,
{text,
begin
_pipe@8 = Text,
_pipe@9 = lists:reverse(_pipe@8),
gleam@string:join(_pipe@9, <<""/utf8>>)
end} |
Acc]
);
[<<"~"/utf8>> | Xs@3] ->
do_lex_inline_text(
Xs@3,
[],
[tilde,
{text,
begin
_pipe@10 = Text,
_pipe@11 = lists:reverse(_pipe@10),
gleam@string:join(_pipe@11, <<""/utf8>>)
end} |
Acc]
);
[<<"_"/utf8>> | Xs@4] ->
do_lex_inline_text(
Xs@4,
[],
[underscore,
{text,
begin
_pipe@12 = Text,
_pipe@13 = lists:reverse(_pipe@12),
gleam@string:join(_pipe@13, <<""/utf8>>)
end} |
Acc]
);
[<<"*"/utf8>> | Xs@5] ->
do_lex_inline_text(
Xs@5,
[],
[asterisk,
{text,
begin
_pipe@14 = Text,
_pipe@15 = lists:reverse(_pipe@14),
gleam@string:join(_pipe@15, <<""/utf8>>)
end} |
Acc]
);
[<<"\\"/utf8>>, <<"\n"/utf8>> | Xs@6] ->
do_lex_inline_text(
Xs@6,
[],
[{hard_line_break, <<"\\\n"/utf8>>},
{text,
begin
_pipe@16 = Text,
_pipe@17 = lists:reverse(_pipe@16),
gleam@string:join(_pipe@17, <<""/utf8>>)
end} |
Acc]
);
[<<" "/utf8>>, <<" "/utf8>>, <<"\n"/utf8>> | Xs@7] ->
do_lex_inline_text(
Xs@7,
[],
[{hard_line_break, <<" \n"/utf8>>},
{text,
begin
_pipe@18 = Text,
_pipe@19 = lists:reverse(_pipe@18),
gleam@string:join(_pipe@19, <<""/utf8>>)
end} |
Acc]
);
[<<"\n"/utf8>> | Xs@8] ->
do_lex_inline_text(
Xs@8,
[],
[soft_line_break,
{text,
begin
_pipe@20 = Text,
_pipe@21 = lists:reverse(_pipe@20),
gleam@string:join(_pipe@21, <<""/utf8>>)
end} |
Acc]
);
[<<"&"/utf8>> | Xs@9] ->
case match_entity(Xs@9) of
{ok, {Rest, E, Replacement}} ->
do_lex_inline_text(
Rest,
[],
[{entity, E, Replacement},
{text,
begin
_pipe@22 = Text,
_pipe@23 = lists:reverse(_pipe@22),
gleam@string:join(_pipe@23, <<""/utf8>>)
end} |
Acc]
);
{error, _} ->
do_lex_inline_text(Xs@9, [<<"&"/utf8>> | Text], Acc)
end;
[<<"\\"/utf8>>, G | Xs@10] ->
case gleam@list:contains(
[<<"!"/utf8>>,
<<"\""/utf8>>,
<<"#"/utf8>>,
<<"$"/utf8>>,
<<"%"/utf8>>,
<<"&"/utf8>>,
<<"'"/utf8>>,
<<"("/utf8>>,
<<")"/utf8>>,
<<"*"/utf8>>,
<<"+"/utf8>>,
<<","/utf8>>,
<<"-"/utf8>>,
<<"."/utf8>>,
<<"/"/utf8>>,
<<":"/utf8>>,
<<";"/utf8>>,
<<"<"/utf8>>,
<<"="/utf8>>,
<<">"/utf8>>,
<<"?"/utf8>>,
<<"@"/utf8>>,
<<"["/utf8>>,
<<"]"/utf8>>,
<<"\\"/utf8>>,
<<"^"/utf8>>,
<<"_"/utf8>>,
<<"`"/utf8>>,
<<"{"/utf8>>,
<<"|"/utf8>>,
<<"}"/utf8>>,
<<"~"/utf8>>],
G
) of
true ->
do_lex_inline_text(
Xs@10,
[],
[{escaped, G},
{text,
begin
_pipe@24 = Text,
_pipe@25 = lists:reverse(_pipe@24),
gleam@string:join(_pipe@25, <<""/utf8>>)
end} |
Acc]
);
false ->
do_lex_inline_text(Xs@10, [G, <<"\\"/utf8>> | Text], Acc)
end;
[X@1 | Xs@11] ->
do_lex_inline_text(Xs@11, [X@1 | Text], Acc)
end.
-spec list_to_string(list(inline_wrapper())) -> binary().
list_to_string(Els) ->
_pipe = gleam@list:map(Els, fun to_string/1),
gleam@string:join(_pipe, <<""/utf8>>).
-spec to_string(inline_wrapper()) -> binary().
to_string(El) ->
case El of
{lexed_element, {hard_line_break, S}} ->
S;
{lexed_element, {text, S}} ->
S;
{lexed_element, {escaped, S@1}} ->
<<"\\"/utf8, S@1/binary>>;
{lexed_element, less_than} ->
<<"<"/utf8>>;
{lexed_element, greater_than} ->
<<">"/utf8>>;
{lexed_element, backtick} ->
<<"`"/utf8>>;
{lexed_element, tilde} ->
<<"~"/utf8>>;
{lexed_element, asterisk} ->
<<"*"/utf8>>;
{lexed_element, underscore} ->
<<"_"/utf8>>;
{lexed_element, soft_line_break} ->
<<"\n"/utf8>>;
{lexed_element, {entity, E, _}} ->
<<"&"/utf8, E/binary>>;
{emphasis, Contents, Marker} ->
case Marker of
asterisk_emphasis_marker ->
<<<<"*"/utf8, (list_to_string(Contents))/binary>>/binary,
"*"/utf8>>;
underscore_emphasis_marker ->
<<<<"_"/utf8, (list_to_string(Contents))/binary>>/binary,
"_"/utf8>>
end;
{strong_emphasis, Contents@1, Marker@1} ->
case Marker@1 of
asterisk_emphasis_marker ->
<<<<"**"/utf8, (list_to_string(Contents@1))/binary>>/binary,
"**"/utf8>>;
underscore_emphasis_marker ->
<<<<"__"/utf8, (list_to_string(Contents@1))/binary>>/binary,
"__"/utf8>>
end;
{backtick_string, Count} ->
gleam@string:repeat(<<"`"/utf8>>, Count);
{asterisk_string, Count@1} ->
gleam@string:repeat(<<"*"/utf8>>, Count@1);
{underscore_string, Count@2} ->
gleam@string:repeat(<<"_"/utf8>>, Count@2);
{code_span, Count@3, Content} ->
<<<<(gleam@string:repeat(<<"`"/utf8>>, Count@3))/binary,
(list_to_string(Content))/binary>>/binary,
(gleam@string:repeat(<<"`"/utf8>>, Count@3))/binary>>;
{tilde_string, Count@4} ->
gleam@string:repeat(<<"~"/utf8>>, Count@4);
{strikethrough, Count@5, Content@1} ->
<<<<(gleam@string:repeat(<<"~"/utf8>>, Count@5))/binary,
(list_to_string(Content@1))/binary>>/binary,
(gleam@string:repeat(<<"~"/utf8>>, Count@5))/binary>>;
{email_autolink, Ls} ->
<<<<"<"/utf8, (list_to_string(Ls))/binary>>/binary, ">"/utf8>>;
{uri_autolink, Ls@1} ->
<<<<"<"/utf8, (list_to_string(Ls@1))/binary>>/binary, ">"/utf8>>
end.
-spec parse_autolink(list(inline_wrapper())) -> {ok, inline_wrapper()} |
{error, nil}.
parse_autolink(Href) ->
_assert_subject = gleam@regex:from_string(
<<"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"/utf8>>
),
{ok, Email_regex} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"commonmark/internal/parser/inline"/utf8>>,
function => <<"parse_autolink"/utf8>>,
line => 234})
end,
_assert_subject@1 = gleam@regex:from_string(
<<"^[a-zA-Z][-a-zA-Z+.]{1,31}:[^ \t]+$"/utf8>>
),
{ok, Uri_regex} = case _assert_subject@1 of
{ok, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"commonmark/internal/parser/inline"/utf8>>,
function => <<"parse_autolink"/utf8>>,
line => 238})
end,
Href_str = list_to_string(Href),
case {gleam@regex:check(Email_regex, Href_str),
gleam@regex:check(Uri_regex, Href_str)} of
{true, _} ->
{ok, {email_autolink, Href}};
{_, true} ->
{ok, {uri_autolink, Href}};
{false, false} ->
{error, nil}
end.
-spec do_parse_inline_wrappers(list(inline_lexer()), list(inline_wrapper())) -> list(inline_wrapper()).
do_parse_inline_wrappers(Lexed, Acc) ->
case Lexed of
[] ->
_pipe = Acc,
lists:reverse(_pipe);
[greater_than | Ls] ->
case gleam@list:split_while(Acc, fun is_not_less_than/1) of
{_, []} ->
do_parse_inline_wrappers(
Ls,
[{lexed_element, greater_than} | Acc]
);
{To_wrap, [_ | Rest]} ->
case parse_autolink(
begin
_pipe@1 = To_wrap,
lists:reverse(_pipe@1)
end
) of
{ok, Wrapped} ->
do_parse_inline_wrappers(Ls, [Wrapped | Rest]);
{error, _} ->
do_parse_inline_wrappers(
Ls,
[{lexed_element, greater_than} | Acc]
)
end
end;
[backtick, backtick | Ls@1] ->
case Acc of
[{backtick_string, Count} | Rest@1] ->
do_parse_inline_wrappers(
[backtick | Ls@1],
[{backtick_string, Count + 1} | Rest@1]
);
_ ->
do_parse_inline_wrappers(
[backtick | Ls@1],
[{backtick_string, 1} | Acc]
)
end;
[backtick | Ls@2] ->
Acc@1 = case Acc of
[{backtick_string, Count@1} | Rest@2] ->
parse_code_span(Count@1 + 1, Rest@2);
_ ->
parse_code_span(1, Acc)
end,
do_parse_inline_wrappers(Ls@2, Acc@1);
[asterisk, asterisk | Ls@3] ->
case Acc of
[{asterisk_string, Count@2} | Rest@3] ->
do_parse_inline_wrappers(
[asterisk | Ls@3],
[{asterisk_string, Count@2 + 1} | Rest@3]
);
_ ->
do_parse_inline_wrappers(
[asterisk | Ls@3],
[{asterisk_string, 1} | Acc]
)
end;
[asterisk | Ls@4] ->
case Acc of
[{asterisk_string, Count@3} | Rest@4] ->
do_parse_inline_wrappers(
Ls@4,
[{asterisk_string, Count@3 + 1} | Rest@4]
);
_ ->
do_parse_inline_wrappers(Ls@4, [{asterisk_string, 1} | Acc])
end;
[underscore, underscore | Ls@5] ->
case Acc of
[{underscore_string, Count@4} | Rest@5] ->
do_parse_inline_wrappers(
[underscore | Ls@5],
[{underscore_string, Count@4 + 1} | Rest@5]
);
_ ->
do_parse_inline_wrappers(
[underscore | Ls@5],
[{underscore_string, 1} | Acc]
)
end;
[underscore | Ls@6] ->
case Acc of
[{underscore_string, Count@5} | Rest@6] ->
do_parse_inline_wrappers(
Ls@6,
[{underscore_string, Count@5 + 1} | Rest@6]
);
_ ->
do_parse_inline_wrappers(
Ls@6,
[{underscore_string, 1} | Acc]
)
end;
[tilde, tilde | Ls@7] ->
case gleam@list:first(Acc) of
{ok, {tilde_string, Count@6}} ->
do_parse_inline_wrappers(
[tilde | Ls@7],
[{tilde_string, Count@6 + 1} | gleam@list:drop(Acc, 1)]
);
_ ->
do_parse_inline_wrappers(
[tilde | Ls@7],
[{tilde_string, 1} | Acc]
)
end;
[tilde | Ls@8] ->
{Count@8, Acc@2} = case gleam@list:first(Acc) of
{ok, {tilde_string, Count@7}} ->
{Count@7 + 1, gleam@list:drop(Acc, 1)};
_ ->
{1, Acc}
end,
do_parse_inline_wrappers(Ls@8, [{tilde_string, Count@8} | Acc@2]);
[{entity, _, _} = V | Ls@9] ->
do_parse_inline_wrappers(Ls@9, [{lexed_element, V} | Acc]);
[{escaped, _} = V | Ls@9] ->
do_parse_inline_wrappers(Ls@9, [{lexed_element, V} | Acc]);
[less_than = V | Ls@9] ->
do_parse_inline_wrappers(Ls@9, [{lexed_element, V} | Acc]);
[{hard_line_break, _} = V | Ls@9] ->
do_parse_inline_wrappers(Ls@9, [{lexed_element, V} | Acc]);
[soft_line_break = V | Ls@9] ->
do_parse_inline_wrappers(Ls@9, [{lexed_element, V} | Acc]);
[{text, _} = V | Ls@9] ->
do_parse_inline_wrappers(Ls@9, [{lexed_element, V} | Acc])
end.
-spec do_parse_inline_ast(
list(inline_wrapper()),
list(commonmark@ast:inline_node())
) -> list(commonmark@ast:inline_node()).
do_parse_inline_ast(Wrapped, Acc) ->
case Wrapped of
[] ->
_pipe = Acc,
lists:reverse(_pipe);
[{email_autolink, L} | Ws] ->
do_parse_inline_ast(Ws, [{email_autolink, list_to_string(L)} | Acc]);
[{uri_autolink, L@1} | Ws@1] ->
do_parse_inline_ast(
Ws@1,
[{uri_autolink, list_to_string(L@1)} | Acc]
);
[{backtick_string, Count} | Ws@2] ->
do_parse_inline_ast(
Ws@2,
[{plain_text, gleam@string:repeat(<<"`"/utf8>>, Count)} | Acc]
);
[{code_span, _, Contents} | Ws@3] ->
_assert_subject = gleam@regex:from_string(<<"^ (.*) $"/utf8>>),
{ok, R} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"commonmark/internal/parser/inline"/utf8>>,
function => <<"do_parse_inline_ast"/utf8>>,
line => 451})
end,
C = begin
_pipe@1 = Contents,
_pipe@2 = list_to_string(_pipe@1),
gleam@string:replace(_pipe@2, <<"\n"/utf8>>, <<" "/utf8>>)
end,
case gleam@regex:scan(R, C) of
[{match, _, [{some, Span}]}] ->
do_parse_inline_ast(Ws@3, [{code_span, Span} | Acc]);
_ ->
do_parse_inline_ast(Ws@3, [{code_span, C} | Acc])
end;
[{tilde_string, Count@1} | Ws@4] ->
do_parse_inline_ast(
Ws@4,
[{plain_text, gleam@string:repeat(<<"~"/utf8>>, Count@1)} | Acc]
);
[{strikethrough, _, Contents@1} | Ws@5] ->
do_parse_inline_ast(
Ws@5,
[{strike_through, do_parse_inline_ast(Contents@1, [])} | Acc]
);
[{emphasis, Contents@2, Marker} | Ws@6] ->
do_parse_inline_ast(
Ws@6,
[{emphasis, do_parse_inline_ast(Contents@2, []), Marker} | Acc]
);
[{strong_emphasis, Contents@3, Marker@1} | Ws@7] ->
do_parse_inline_ast(
Ws@7,
[{strong_emphasis,
do_parse_inline_ast(Contents@3, []),
Marker@1} |
Acc]
);
[{asterisk_string, Count@2} | Ws@8] ->
do_parse_inline_ast(
Ws@8,
[{plain_text, gleam@string:repeat(<<"*"/utf8>>, Count@2)} | Acc]
);
[{underscore_string, Count@3} | Ws@9] ->
do_parse_inline_ast(
Ws@9,
[{plain_text, gleam@string:repeat(<<"_"/utf8>>, Count@3)} | Acc]
);
[{lexed_element, {escaped, S}} | Ws@10] ->
do_parse_inline_ast(Ws@10, [{plain_text, S} | Acc]);
[{lexed_element, {entity, _, R@1}} | Ws@11] ->
do_parse_inline_ast(Ws@11, [{plain_text, R@1} | Acc]);
[{lexed_element, soft_line_break} | Ws@12] ->
do_parse_inline_ast(Ws@12, [soft_line_break | Acc]);
[{lexed_element, {hard_line_break, _}} | Ws@13] ->
do_parse_inline_ast(Ws@13, [hard_line_break | Acc]);
[{lexed_element, asterisk} | Ws@14] ->
do_parse_inline_ast(
[{lexed_element, {text, <<"*"/utf8>>}} | Ws@14],
Acc
);
[{lexed_element, underscore} | Ws@15] ->
do_parse_inline_ast(
[{lexed_element, {text, <<"_"/utf8>>}} | Ws@15],
Acc
);
[{lexed_element, backtick} | Ws@16] ->
do_parse_inline_ast(
[{lexed_element, {text, <<"`"/utf8>>}} | Ws@16],
Acc
);
[{lexed_element, tilde} | Ws@17] ->
do_parse_inline_ast(
[{lexed_element, {text, <<"~"/utf8>>}} | Ws@17],
Acc
);
[{lexed_element, greater_than} | Ws@18] ->
do_parse_inline_ast(
[{lexed_element, {text, <<">"/utf8>>}} | Ws@18],
Acc
);
[{lexed_element, less_than} | Ws@19] ->
do_parse_inline_ast(
[{lexed_element, {text, <<"<"/utf8>>}} | Ws@19],
Acc
);
[{lexed_element, {text, T}} | Ws@20] ->
do_parse_inline_ast(Ws@20, [{plain_text, T} | Acc])
end.
-spec parse_text(binary()) -> list(commonmark@ast:inline_node()).
parse_text(Text) ->
_pipe = Text,
_pipe@1 = gleam@string:to_graphemes(_pipe),
_pipe@2 = do_lex_inline_text(_pipe@1, [], []),
_pipe@3 = do_parse_inline_wrappers(_pipe@2, []),
_pipe@4 = do_parse_emphasis(_pipe@3, []),
_pipe@5 = do_parse_inline_ast(_pipe@4, []),
do_finalise_plain_text(_pipe@5, [], true).