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_state/0]).
-type inline_state() :: {text_accumulator, list(binary())} |
{autolink_accumulator, list(binary())}.
-spec replace_null_byte(integer()) -> integer().
replace_null_byte(N) ->
case N of
0 ->
16#fffd;
_ ->
N
end.
-spec finalise_plain_text(list(binary()), boolean(), boolean()) -> binary().
finalise_plain_text(Graphemes, Trim_end, Trim_start) ->
_pipe = Graphemes,
_pipe@1 = gleam@list:drop_while(
_pipe,
fun(G) ->
Trim_end andalso ((G =:= <<" "/utf8>>) orelse (G =:= <<"\t"/utf8>>))
end
),
_pipe@2 = lists:reverse(_pipe@1),
_pipe@3 = gleam@list:drop_while(
_pipe@2,
fun(G@1) ->
Trim_start andalso ((G@1 =:= <<" "/utf8>>) orelse (G@1 =:= <<"\t"/utf8>>))
end
),
gleam@string:join(_pipe@3, <<""/utf8>>).
-spec match_entity(list(binary())) -> {ok, {list(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 => 44})
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 => 45})
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 = gleam@result:map(_pipe@3, fun replace_null_byte/1),
_pipe@5 = gleam@result:'try'(
_pipe@4,
fun gleam@string:utf_codepoint/1
),
gleam@result:map(
_pipe@5,
fun(Cp) ->
{gleam@list:drop(Input, gleam@string:length(Full)),
gleam_stdlib:utf_codepoint_list_to_string([Cp])}
end
);
{_, [{match, Full@1, [{some, N@1}]}]} ->
_pipe@6 = N@1,
_pipe@7 = gleam@int:base_parse(_pipe@6, 16),
_pipe@8 = gleam@result:map(_pipe@7, fun replace_null_byte/1),
_pipe@9 = gleam@result:'try'(
_pipe@8,
fun gleam@string:utf_codepoint/1
),
gleam@result:map(
_pipe@9,
fun(Cp@1) ->
{gleam@list:drop(Input, gleam@string:length(Full@1)),
gleam_stdlib:utf_codepoint_list_to_string(
[Cp@1]
)}
end
);
{_, _} ->
{error, nil}
end
end
).
-spec do_parse_text(
list(binary()),
inline_state(),
list(commonmark@ast:inline_node())
) -> list(commonmark@ast:inline_node()).
do_parse_text(Text, State, Acc) ->
case {State, Text} of
{{autolink_accumulator, Ts}, []} ->
[{plain_text,
begin
_pipe = [<<"<"/utf8>> | lists:reverse(Ts)],
gleam@string:join(_pipe, <<""/utf8>>)
end} |
Acc];
{{text_accumulator, Ts@1}, []} ->
_pipe@1 = [{plain_text, finalise_plain_text(Ts@1, true, true)} |
Acc],
lists:reverse(_pipe@1);
{{text_accumulator, Ts@2},
[<<" "/utf8>>, <<" "/utf8>>, <<"\n"/utf8>> | Gs]} ->
do_parse_text(
Gs,
{text_accumulator, []},
[hard_line_break,
{plain_text, finalise_plain_text(Ts@2, true, true)} |
Acc]
);
{{text_accumulator, Ts@2}, [<<"\\"/utf8>>, <<"\n"/utf8>> | Gs]} ->
do_parse_text(
Gs,
{text_accumulator, []},
[hard_line_break,
{plain_text, finalise_plain_text(Ts@2, true, true)} |
Acc]
);
{{autolink_accumulator, Ts@3},
[<<" "/utf8>>, <<" "/utf8>>, <<"\n"/utf8>> | Gs@1]} ->
do_parse_text(
Gs@1,
{text_accumulator, []},
[hard_line_break,
{plain_text,
begin
_pipe@2 = lists:reverse([<<"<"/utf8>> | Ts@3]),
gleam@string:join(_pipe@2, <<""/utf8>>)
end} |
Acc]
);
{{autolink_accumulator, Ts@3}, [<<"\\"/utf8>>, <<"\n"/utf8>> | Gs@1]} ->
do_parse_text(
Gs@1,
{text_accumulator, []},
[hard_line_break,
{plain_text,
begin
_pipe@2 = lists:reverse([<<"<"/utf8>> | Ts@3]),
gleam@string:join(_pipe@2, <<""/utf8>>)
end} |
Acc]
);
{{text_accumulator, Ts@4}, [<<"\n"/utf8>> | Gs@2]} ->
do_parse_text(
Gs@2,
{text_accumulator, []},
[soft_line_break,
{plain_text, finalise_plain_text(Ts@4, true, true)} |
Acc]
);
{{autolink_accumulator, Ts@5}, [<<"\n"/utf8>> | Gs@3]} ->
do_parse_text(
Gs@3,
{text_accumulator, []},
[soft_line_break,
{plain_text,
begin
_pipe@3 = lists:reverse([<<"<"/utf8>> | Ts@5]),
gleam@string:join(_pipe@3, <<""/utf8>>)
end} |
Acc]
);
{{text_accumulator, Ts@6}, [<<"\\"/utf8>>, G | Gs@4]} ->
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_parse_text(Gs@4, {text_accumulator, [G | Ts@6]}, Acc);
false ->
do_parse_text(
Gs@4,
{text_accumulator, [G, <<"\\"/utf8>> | Ts@6]},
Acc
)
end;
{{text_accumulator, Ts@7}, [<<"&"/utf8>> | Gs@5]} ->
case match_entity(Gs@5) of
{ok, {Rest, Replacement}} ->
do_parse_text(
Rest,
{text_accumulator, [Replacement | Ts@7]},
Acc
);
{error, _} ->
do_parse_text(
Gs@5,
{text_accumulator, [<<"&"/utf8>> | Ts@7]},
Acc
)
end;
{{text_accumulator, Ts@8}, [<<"<"/utf8>> | Gs@6]} ->
do_parse_text(
Gs@6,
{autolink_accumulator, []},
[{plain_text, finalise_plain_text(Ts@8, false, false)} | Acc]
);
{{autolink_accumulator, Ts@9}, [<<"\t"/utf8>> = Space | Gs@7]} ->
do_parse_text(
Gs@7,
{text_accumulator, [Space | lists:append(Ts@9, [<<"<"/utf8>>])]},
Acc
);
{{autolink_accumulator, Ts@9}, [<<" "/utf8>> = Space | Gs@7]} ->
do_parse_text(
Gs@7,
{text_accumulator, [Space | lists:append(Ts@9, [<<"<"/utf8>>])]},
Acc
);
{{autolink_accumulator, Ts@10}, [<<">"/utf8>> | Gs@8]} ->
do_parse_text(
Gs@8,
{text_accumulator, []},
[commonmark@internal@parser@helpers:parse_autolink(
finalise_plain_text(Ts@10, false, false)
) |
Acc]
);
{{autolink_accumulator, Ts@11}, [G@1 | Gs@9]} ->
do_parse_text(Gs@9, {autolink_accumulator, [G@1 | Ts@11]}, Acc);
{{text_accumulator, Ts@12}, [G@2 | Gs@10]} ->
do_parse_text(Gs@10, {text_accumulator, [G@2 | Ts@12]}, Acc)
end.
-spec parse_text(binary()) -> list(commonmark@ast:inline_node()).
parse_text(Text) ->
_pipe = Text,
_pipe@1 = gleam@string:to_graphemes(_pipe),
do_parse_text(_pipe@1, {text_accumulator, []}, []).