-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, <>} | 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).