-module(kirala@bbmarkdown@parser). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([ret_string_trim/1, ret_string/1, parse/2, parse_all/1]). -export_type([align/0, list_type/0, parse_res/0, token_res/0, url_data/0, token/0, src_pos/0]). -type align() :: align_left | align_right | align_center. -type list_type() :: std_list | ordered_list | checked_list | unchecked_list. -type parse_res() :: {parse_res, binary(), bitstring()}. -type token_res() :: {token_res, token(), bitstring()}. -type url_data() :: {url_plain, binary()} | {url_foot_note, binary()}. -type token() :: {line, list(token())} | {line_indent, integer(), list(token())} | {text, binary()} | {bold, token()} | {italic, token()} | {strike_through, token()} | {marked_text, token()} | {inserted_text, token()} | {note, binary(), token()} | {h, integer(), integer(), token()} | {code_block, binary(), binary(), binary()} | {code_span, binary()} | {code_line, binary()} | {block_quote, integer(), token()} | {list_item, list_type(), integer(), token()} | {url, url_data()} | {url_link, binary(), url_data()} | {img_link, binary(), binary(), url_data()} | {foot_note, binary(), token()} | {foot_note_url_def, binary(), binary(), binary()} | {table, list(token()), list(align()), list(list(token()))} | {definition_of, token()} | {definition, list(token())} | {definition_is, binary(), token()} | hr. -type src_pos() :: {src_pos, integer(), integer()}. -spec ret_string_trim(bitstring()) -> binary(). ret_string_trim(Bitstr) -> _assert_subject = gleam@bit_array:to_string(Bitstr), {ok, Str} = 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 => <<"kirala/bbmarkdown/parser"/utf8>>, function => <<"ret_string_trim"/utf8>>, line => 67}) end, _pipe = Str, gleam@string:trim(_pipe). -spec ret_string(bitstring()) -> binary(). ret_string(Bitstr) -> kirala@bbmarkdown@sub_ffi:format(<<"~ts"/utf8>>, {Bitstr}). -spec get_indent_nextchar(integer(), bitstring()) -> {integer(), binary()}. get_indent_nextchar(Indent, Src) -> case Src of <<>> -> {0, <<""/utf8>>}; <<" "/utf8, Rest/bitstring>> -> get_indent_nextchar(Indent + 1, Rest); <<"\t"/utf8, Rest/bitstring>> -> get_indent_nextchar(Indent + 1, Rest); <<"\n\r"/utf8, Rest@1/bitstring>> -> {0, <<""/utf8>>}; <<"\r\n"/utf8, Rest@1/bitstring>> -> {0, <<""/utf8>>}; <<"\n"/utf8, Rest@1/bitstring>> -> {0, <<""/utf8>>}; <<"\r"/utf8, Rest@1/bitstring>> -> {0, <<""/utf8>>}; <> -> {Indent, begin _pipe = <>, ret_string(_pipe) end}; Unhandable -> {0, <<""/utf8>>} end. -spec get_nextchar(bitstring()) -> binary(). get_nextchar(Src) -> case Src of <<>> -> <<""/utf8>>; <<" "/utf8, Rest/bitstring>> -> get_nextchar(Rest); <<"\t"/utf8, Rest/bitstring>> -> get_nextchar(Rest); <<"\n\r"/utf8, Rest/bitstring>> -> get_nextchar(Rest); <<"\r\n"/utf8, Rest/bitstring>> -> get_nextchar(Rest); <<"\n"/utf8, Rest/bitstring>> -> get_nextchar(Rest); <<"\r"/utf8, Rest/bitstring>> -> get_nextchar(Rest); <> -> _pipe = <>, ret_string(_pipe); Unhandable -> <<""/utf8>> end. -spec get_line(bitstring(), bitstring()) -> parse_res(). get_line(Src, Acc) -> case Src of <<>> -> {parse_res, ret_string_trim(Acc), <<>>}; <<"\n\r"/utf8, Rest/bitstring>> -> {parse_res, ret_string_trim(Acc), Rest}; <<"\r\n"/utf8, Rest/bitstring>> -> {parse_res, ret_string_trim(Acc), Rest}; <<"\n"/utf8, Rest/bitstring>> -> {parse_res, ret_string_trim(Acc), Rest}; <<"\r"/utf8, Rest/bitstring>> -> {parse_res, ret_string_trim(Acc), Rest}; <> -> get_line(Rest@1, <>); Unhandable -> {parse_res, ret_string_trim(Acc), <<>>} end. -spec string_end_with(binary(), binary()) -> boolean(). string_end_with(Src, End_with) -> Slen = gleam@string:length(Src), Elen = gleam@string:length(End_with), Endstr = gleam@string:slice(Src, Slen - Elen, Elen), Endstr =:= End_with. -spec string_skip_first(binary()) -> binary(). string_skip_first(Src) -> gleam@string:slice(Src, 1, gleam@string:length(Src) - 1). -spec is_img_url_(binary(), list(binary())) -> boolean(). is_img_url_(Url, Exts) -> case Exts of [] -> false; [Ext | Rest] -> case string_end_with(Url, Ext) of true -> true; _ -> is_img_url_(Url, Rest) end end. -spec is_img_url(binary()) -> boolean(). is_img_url(Url) -> is_img_url_( Url, [<<".jpg"/utf8>>, <<".jpeg"/utf8>>, <<".png"/utf8>>, <<".gif"/utf8>>] ). -spec decode_url_(bitstring(), bitstring()) -> parse_res(). decode_url_(Src, Acc) -> case Src of <<>> -> {parse_res, ret_string_trim(Acc), <<>>}; <<" "/utf8, Rest/bitstring>> -> {parse_res, ret_string_trim(Acc), Rest}; <<"\n\r"/utf8, Rest/bitstring>> -> {parse_res, ret_string_trim(Acc), Rest}; <<"\r\n"/utf8, Rest/bitstring>> -> {parse_res, ret_string_trim(Acc), Rest}; <<"\n"/utf8, Rest/bitstring>> -> {parse_res, ret_string_trim(Acc), Rest}; <<"\r"/utf8, Rest/bitstring>> -> {parse_res, ret_string_trim(Acc), Rest}; <> -> decode_url_(Rest@1, <>); Unhandable -> {parse_res, ret_string_trim(Acc), <<>>} end. -spec decode_url(bitstring()) -> token_res(). decode_url(Src) -> {parse_res, Url, Rest} = decode_url_(Src, <<>>), T = case is_img_url(Url) of true -> {img_link, <<""/utf8>>, <<""/utf8>>, {url_plain, Url}}; _ -> {url, {url_plain, Url}} end, {token_res, T, Rest}. -spec decode_codeblock_(bitstring(), bitstring()) -> parse_res(). decode_codeblock_(Src, Acc) -> case Src of <<"```"/utf8, Rest/bitstring>> -> {parse_res, _, Rest2} = get_line(Rest, <<>>), {parse_res, ret_string(Acc), Rest2}; <> -> decode_codeblock_(Rest@1, <>); Unhandable -> {parse_res, ret_string(Acc), <<>>} end. -spec decode_codeblock(bitstring()) -> token_res(). decode_codeblock(Src) -> {parse_res, Inf, Rest0} = get_line(Src, <<>>), {Syntax@2, Filename@1} = case gleam@string:split(Inf, <<":"/utf8>>) of [Syntax] -> {Syntax, <<""/utf8>>}; [Syntax@1, Filename] -> {Syntax@1, Filename}; _ -> {<<""/utf8>>, <<""/utf8>>} end, {parse_res, Code, Rest1} = decode_codeblock_(Rest0, <<>>), {token_res, {code_block, Syntax@2, Filename@1, Code}, Rest1}. -spec get_until1_(bitstring(), bitstring(), integer()) -> parse_res(). get_until1_(Src, Acc, Nterm) -> case Src of <<>> -> {parse_res, <<""/utf8>>, <<>>}; <> when Str =:= Nterm -> {parse_res, ret_string(Acc), Rest}; <> -> get_until1_(Rest@1, <>, Nterm); Unhandable -> {parse_res, ret_string(Acc), <<>>} end. -spec get_until1(bitstring(), binary()) -> parse_res(). get_until1(Src, Terminator) -> _assert_subject = gleam_stdlib:identity(Terminator), <> = case _assert_subject of <<_:8>> -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"kirala/bbmarkdown/parser"/utf8>>, function => <<"get_until1"/utf8>>, line => 297}) end, get_until1_(Src, <<>>, Nterm). -spec get_until2_(bitstring(), bitstring(), integer()) -> parse_res(). get_until2_(Src, Acc, Nterm) -> case Src of <<>> -> {parse_res, <<""/utf8>>, <<>>}; <> when Str =:= Nterm -> {parse_res, ret_string(Acc), Rest}; <> -> get_until2_(Rest@1, <>, Nterm); Unhandable -> {parse_res, ret_string(Acc), <<>>} end. -spec get_until2(bitstring(), binary()) -> parse_res(). get_until2(Src, Terminator) -> _assert_subject = gleam_stdlib:identity(Terminator), <> = case _assert_subject of <<_:16>> -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"kirala/bbmarkdown/parser"/utf8>>, function => <<"get_until2"/utf8>>, line => 312}) end, get_until2_(Src, <<>>, Nterm). -spec get_until3_(bitstring(), bitstring(), integer()) -> parse_res(). get_until3_(Src, Acc, Nterm) -> case Src of <<>> -> {parse_res, <<""/utf8>>, <<>>}; <> when Str =:= Nterm -> {parse_res, ret_string(Acc), Rest}; <> -> get_until3_(Rest@1, <>, Nterm); Unhandable -> {parse_res, ret_string(Acc), <<>>} end. -spec get_until3(bitstring(), binary()) -> parse_res(). get_until3(Src, Terminator) -> _assert_subject = gleam_stdlib:identity(Terminator), <> = case _assert_subject of <<_:24>> -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"kirala/bbmarkdown/parser"/utf8>>, function => <<"get_until3"/utf8>>, line => 327}) end, get_until3_(Src, <<>>, Nterm). -spec get_until4_(bitstring(), bitstring(), integer()) -> parse_res(). get_until4_(Src, Acc, Nterm) -> case Src of <<>> -> {parse_res, <<""/utf8>>, <<>>}; <> when Str =:= Nterm -> {parse_res, ret_string(Acc), Rest}; <> -> get_until4_(Rest@1, <>, Nterm); Unhandable -> {parse_res, ret_string(Acc), <<>>} end. -spec get_until4(bitstring(), binary()) -> parse_res(). get_until4(Src, Terminator) -> _assert_subject = gleam_stdlib:identity(Terminator), <> = case _assert_subject of <<_:32>> -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"kirala/bbmarkdown/parser"/utf8>>, function => <<"get_until4"/utf8>>, line => 342}) end, get_until4_(Src, <<>>, Nterm). -spec decode_codespan(bitstring()) -> token_res(). decode_codespan(Src) -> {parse_res, Str, Rest} = get_until1(Src, <<"`"/utf8>>), {token_res, {code_span, Str}, Rest}. -spec decode_hr(bitstring()) -> token_res(). decode_hr(Src) -> {parse_res, Str, Rest} = get_line(Src, <<>>), {token_res, hr, Rest}. -spec decode_footnote_urldef(bitstring()) -> token_res(). decode_footnote_urldef(Src) -> {parse_res, Line, Rest} = get_line(Src, <<>>), {parse_res, Id, Lrest} = get_until2( begin _pipe = Line, gleam_stdlib:identity(_pipe) end, <<"]:"/utf8>> ), {parse_res, Xurl, Lrest2} = get_line(Lrest, <<>>), {Url@2, Alt@1} = case gleam@string:split(Xurl, <<" \""/utf8>>) of [Url] -> {Url, <<""/utf8>>}; [Url@1, Alt] -> case gleam@string:split(Alt, <<"\""/utf8>>) of [Str] -> {Url@1, Str}; [Str@1 | _] -> {Url@1, Str@1}; _ -> {Url@1, Alt} end; _ -> {Xurl, <<""/utf8>>} end, {token_res, {foot_note_url_def, Id, Url@2, Alt@1}, Rest}. -spec decode_imglink(bitstring()) -> token_res(). decode_imglink(Src) -> {parse_res, Caption, Rest} = get_until1(Src, <<"]"/utf8>>), case get_nextchar(Rest) of <<"["/utf8>> -> {parse_res, _, Rest2} = get_until1(Rest, <<"["/utf8>>), {parse_res, Url, Rest3} = get_until1(Rest2, <<"]"/utf8>>), {token_res, {img_link, Caption, <<""/utf8>>, {url_foot_note, Url}}, Rest3}; _ -> {parse_res, _, Rest2@1} = get_until1(Rest, <<"("/utf8>>), {parse_res, Xurl, Rest3@1} = get_until1(Rest2@1, <<")"/utf8>>), {Url@3, Alt@1} = case gleam@string:split(Xurl, <<" \""/utf8>>) of [Url@1] -> {Url@1, <<""/utf8>>}; [Url@2, Alt] -> case gleam@string:split(Alt, <<"\""/utf8>>) of [Str] -> {Url@2, Str}; _ -> {Url@2, Alt} end; _ -> {Xurl, <<""/utf8>>} end, {token_res, {img_link, Caption, Alt@1, {url_plain, Url@3}}, Rest3@1} end. -spec decode_footnote_link(bitstring()) -> token_res(). decode_footnote_link(Src) -> {parse_res, Id, Rest} = get_until1(Src, <<"]"/utf8>>), {token_res, {url, {url_foot_note, Id}}, Rest}. -spec decode_urllink(bitstring()) -> token_res(). decode_urllink(Src) -> {parse_res, Sline, Rest} = get_line(Src, <<>>), Line = gleam_stdlib:identity(Sline), {parse_res, Urlid, Rest@1} = get_until2(Line, <<"]:"/utf8>>), {parse_res, Caption, Rest@2} = get_until1(Line, <<"]"/utf8>>), case {Urlid, Caption} of {<<""/utf8>>, _} -> case get_nextchar(Rest@2) of <<"["/utf8>> -> {parse_res, _, Rest2} = get_until1(Rest@2, <<"["/utf8>>), {parse_res, Url, Rest3} = get_until1(Rest2, <<"]"/utf8>>), {token_res, {url_link, Caption, {url_foot_note, Url}}, Rest3}; _ -> {parse_res, _, Rest2@1} = get_until1(Rest@2, <<"("/utf8>>), {parse_res, Url@1, Rest3@1} = get_until1( Rest2@1, <<")"/utf8>> ), {token_res, {url_link, Caption, {url_plain, Url@1}}, Rest3@1} end; _ -> decode_footnote_urldef(Src) end. -spec decode_text(bitstring(), bitstring()) -> token_res(). decode_text(Src, Acc) -> case Src of <<>> -> {token_res, {text, ret_string(Acc)}, <<>>}; <<"https://"/utf8, Rest/bitstring>> -> {token_res, {text, ret_string(Acc)}, Src}; <<"http://"/utf8, Rest/bitstring>> -> {token_res, {text, ret_string(Acc)}, Src}; <<"!["/utf8, Rest/bitstring>> -> {token_res, {text, ret_string(Acc)}, Src}; <<"["/utf8, Rest/bitstring>> -> {token_res, {text, ret_string(Acc)}, Src}; <<"`"/utf8, Rest/bitstring>> -> {token_res, {text, ret_string(Acc)}, Src}; <<" **"/utf8, Rest/bitstring>> -> {token_res, {text, ret_string(Acc)}, Src}; <<" *"/utf8, Rest/bitstring>> -> {token_res, {text, ret_string(Acc)}, Src}; <<"~~ "/utf8, Rest/bitstring>> -> {token_res, {text, ret_string(Acc)}, Src}; <> -> decode_text(Rest@1, <>); Unhandable -> {token_res, {text, ret_string(Acc)}, <<>>} end. -spec list_remove_last(list(FKD)) -> list(FKD). list_remove_last(L) -> _assert_subject = gleam@list:reverse(L), [_ | Tail] = case _assert_subject of [_ | _] -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"kirala/bbmarkdown/parser"/utf8>>, function => <<"list_remove_last"/utf8>>, line => 581}) end, _pipe = Tail, gleam@list:reverse(_pipe). -spec parse_(integer(), bitstring(), integer()) -> token_res(). parse_(Lineno, Src, Indent) -> case Src of <<" "/utf8, Rest/bitstring>> -> parse_(Lineno, Rest, Indent + 1); <<"#######"/utf8, Rest@1/bitstring>> -> decode_h(Lineno, 7, Rest@1); <<"######"/utf8, Rest@2/bitstring>> -> decode_h(Lineno, 6, Rest@2); <<"#####"/utf8, Rest@3/bitstring>> -> decode_h(Lineno, 5, Rest@3); <<"####"/utf8, Rest@4/bitstring>> -> decode_h(Lineno, 4, Rest@4); <<"###"/utf8, Rest@5/bitstring>> -> decode_h(Lineno, 3, Rest@5); <<"##"/utf8, Rest@6/bitstring>> -> decode_h(Lineno, 2, Rest@6); <<"#"/utf8, Rest@7/bitstring>> -> decode_h(Lineno, 1, Rest@7); <<"```"/utf8, Rest@8/bitstring>> -> decode_codeblock(Rest@8); <<":::"/utf8, Rest@9/bitstring>> -> decode_note(Rest@9); <<"---"/utf8, Rest@10/bitstring>> -> decode_hr(Rest@10); <<"___"/utf8, Rest@11/bitstring>> -> decode_hr(Rest@11); <<"***"/utf8, Rest@12/bitstring>> -> decode_hr(Rest@12); <<"> > > "/utf8, Rest@13/bitstring>> -> decode_blockquote(3, Rest@13); <<">> "/utf8, Rest@14/bitstring>> -> decode_blockquote(2, Rest@14); <<"> "/utf8, Rest@15/bitstring>> -> decode_blockquote(1, Rest@15); <<"- [x] "/utf8, Rest@16/bitstring>> -> decode_checklist(Indent, true, Rest@16); <<"- [ ] "/utf8, Rest@17/bitstring>> -> decode_checklist(Indent, false, Rest@17); <<"[^"/utf8, Rest@18/bitstring>> -> decode_footnote(Rest@18); <<"*["/utf8, Rest@19/bitstring>> -> decode_footnote(Rest@19); <> when (16#30 =< Dch1) andalso (Dch1 =< 16#39) -> decode_ordered_list(Indent, Rest@20); <> when (((16#30 =< Dch1@1) andalso (Dch1@1 =< 16#39)) andalso (16#30 =< Dch2)) andalso (Dch2 =< 16#39) -> decode_ordered_list(Indent, Rest@21); <<"* "/utf8, Rest@22/bitstring>> -> decode_list(Indent, Rest@22); <<"+ "/utf8, Rest@22/bitstring>> -> decode_list(Indent, Rest@22); <<"- "/utf8, Rest@22/bitstring>> -> decode_list(Indent, Rest@22); <<"|"/utf8, Rest@23/bitstring>> -> decode_table(Rest@23); <<": "/utf8, Rest@24/bitstring>> -> decode_definition(Indent, Rest@24); <<":"/utf8, Rest@25/bitstring>> -> decode_definition_is(Indent, Rest@25); _ -> decode_line2(Indent, Src) end. -spec decode_note(bitstring()) -> token_res(). decode_note(Src) -> {parse_res, Title, Rest0} = get_line(Src, <<>>), {parse_res, Code, Rest1} = get_until3(Rest0, <<":::"/utf8>>), {token_res, T, _} = parse( 0, begin _pipe = Code, gleam_stdlib:identity(_pipe) end ), {token_res, {note, Title, T}, Rest1}. -spec parse(integer(), bitstring()) -> token_res(). parse(Lineno, Src) -> parse_(Lineno, Src, 1). -spec parse_all_(integer(), bitstring(), list(token())) -> list(token()). parse_all_(Lineno, Src, Acc) -> case erlang:byte_size(Src) of 0 -> gleam@list:reverse(Acc); _ -> {token_res, T, Rest} = parse(Lineno, Src), parse_all_(Lineno + 1, Rest, [T | Acc]) end. -spec parse_all(binary()) -> list(token()). parse_all(Src) -> parse_all_(1, gleam_stdlib:identity(Src), []). -spec decode_bold(bitstring(), binary()) -> token_res(). decode_bold(Src, Terminator) -> {parse_res, Str, Rest} = get_until2(Src, Terminator), {token_res, T, _} = decode_line( begin _pipe = Str, gleam_stdlib:identity(_pipe) end ), {token_res, {bold, T}, Rest}. -spec decode_line(bitstring()) -> token_res(). decode_line(Src) -> {parse_res, Linestr, Rest} = get_line(Src, <<>>), Line = begin _pipe = Linestr, gleam_stdlib:identity(_pipe) end, Ts = decode_line_(<<" "/utf8, Line/bitstring, " "/utf8>>, []), {token_res, {line, Ts}, Rest}. -spec decode_line_(bitstring(), list(token())) -> list(token()). decode_line_(Src, Acc) -> case Src of <<>> -> gleam@list:reverse(Acc); _ -> {token_res, T, Rest} = decode_line__(Src), decode_line_(Rest, [T | Acc]) end. -spec decode_line__(bitstring()) -> token_res(). decode_line__(Src) -> case Src of <<"`"/utf8, Rest/bitstring>> -> decode_codespan(Rest); <<" **"/utf8, Rest@1/bitstring>> -> decode_bold(Rest@1, <<"**"/utf8>>); <<" __"/utf8, Rest@2/bitstring>> -> decode_bold(Rest@2, <<"__"/utf8>>); <<" *"/utf8, Rest@3/bitstring>> -> decode_italic(Rest@3, <<"*"/utf8>>); <<" _"/utf8, Rest@4/bitstring>> -> decode_italic(Rest@4, <<"_"/utf8>>); <<" ~~"/utf8, Rest@5/bitstring>> -> decode_strikethrough(Rest@5); <<"https://"/utf8, Rest@6/bitstring>> -> decode_url(Src); <<"http://"/utf8, Rest@7/bitstring>> -> decode_url(Src); <<"!["/utf8, Rest@8/bitstring>> -> decode_imglink(Rest@8); <<"[^"/utf8, Rest@9/bitstring>> -> decode_footnote_link(Rest@9); <<"["/utf8, Rest@10/bitstring>> -> decode_urllink(Rest@10); <<" =="/utf8, Rest@11/bitstring>> -> decode_marked_text(Rest@11); <<" ++"/utf8, Rest@12/bitstring>> -> decode_inserted_text(Rest@12); _ -> decode_text(Src, <<>>) end. -spec decode_definition_(integer(), bitstring(), list(token())) -> token_res(). decode_definition_(Nindent, Src, Acc) -> case get_indent_nextchar(0, Src) of {Next_indent, _} when Next_indent =/= 0 -> {token_res, T, Rest} = decode_line(Src), decode_definition_(Nindent, Rest, [T | Acc]); {Next_indent@1, _} -> {token_res, {definition, gleam@list:reverse(Acc)}, Src} end. -spec decode_definition(integer(), bitstring()) -> token_res(). decode_definition(Indent, Src) -> {token_res, T, Rest} = decode_line(Src), decode_definition_(Indent, Rest, [T]). -spec decode_definition_is(integer(), bitstring()) -> token_res(). decode_definition_is(Indent, Src) -> {parse_res, Str, Rest} = get_line(Src, <<>>), case gleam@string:split_once(Str, <<" "/utf8>>) of {ok, {Left, Right}} -> {token_res, T, _} = decode_line( begin _pipe = Right, _pipe@1 = gleam@string:trim(_pipe), gleam_stdlib:identity(_pipe@1) end ), {token_res, {definition_is, gleam@string:trim(Left), T}, Rest}; _ -> {token_res, T@1, _} = decode_line( begin _pipe@2 = Str, _pipe@3 = gleam@string:trim(_pipe@2), gleam_stdlib:identity(_pipe@3) end ), {token_res, {definition, [T@1]}, Rest} end. -spec decode_ordered_list(integer(), bitstring()) -> token_res(). decode_ordered_list(Indent, Src) -> {token_res, T, Rest} = decode_line(Src), {token_res, {list_item, ordered_list, Indent, T}, Rest}. -spec decode_list(integer(), bitstring()) -> token_res(). decode_list(Indent, Src) -> {token_res, T, Rest} = decode_line(Src), {token_res, {list_item, std_list, Indent, T}, Rest}. -spec decode_checklist(integer(), boolean(), bitstring()) -> token_res(). decode_checklist(Indent, Check, Src) -> {token_res, T, Rest} = decode_line(Src), case Check of true -> {token_res, {list_item, checked_list, Indent, T}, Rest}; _ -> {token_res, {list_item, unchecked_list, Indent, T}, Rest} end. -spec decode_blockquote(integer(), bitstring()) -> token_res(). decode_blockquote(Indent, Src) -> {token_res, T, Rest} = decode_line(Src), {token_res, {block_quote, Indent, T}, Rest}. -spec decode_h(integer(), integer(), bitstring()) -> token_res(). decode_h(Id, N, Src) -> {token_res, T, Rest} = decode_line(Src), {token_res, {h, Id, N, T}, Rest}. -spec decode_italic(bitstring(), binary()) -> token_res(). decode_italic(Src, Terminator) -> {parse_res, Str, Rest} = get_until1(Src, Terminator), {token_res, T, _} = decode_line( begin _pipe = Str, gleam_stdlib:identity(_pipe) end ), {token_res, {italic, T}, Rest}. -spec decode_strikethrough(bitstring()) -> token_res(). decode_strikethrough(Src) -> {parse_res, Str, Rest} = get_until3(Src, <<"~~ "/utf8>>), {token_res, T, _} = decode_line( begin _pipe = Str, gleam_stdlib:identity(_pipe) end ), {token_res, {strike_through, T}, Rest}. -spec decode_marked_text(bitstring()) -> token_res(). decode_marked_text(Src) -> {parse_res, Str, Rest} = get_until3(Src, <<"== "/utf8>>), {token_res, T, _} = decode_line( begin _pipe = Str, gleam_stdlib:identity(_pipe) end ), {token_res, {marked_text, T}, Rest}. -spec decode_inserted_text(bitstring()) -> token_res(). decode_inserted_text(Src) -> {parse_res, Str, Rest} = get_until3(Src, <<"++ "/utf8>>), {token_res, T, _} = decode_line( begin _pipe = Str, gleam_stdlib:identity(_pipe) end ), {token_res, {inserted_text, T}, Rest}. -spec decode_footnote(bitstring()) -> token_res(). decode_footnote(Src) -> {parse_res, Line, Rest} = get_line(Src, <<>>), {parse_res, Id, Lrest} = get_until2( begin _pipe = Line, gleam_stdlib:identity(_pipe) end, <<"]:"/utf8>> ), {token_res, T, _} = decode_line(Lrest), {token_res, {foot_note, Id, T}, Rest}. -spec decode_line2(integer(), bitstring()) -> token_res(). decode_line2(Indent, Src) -> case Indent of I when I >= 2 -> {parse_res, Linestr, Rest} = get_line(Src, <<>>), {token_res, {code_line, Linestr}, Rest}; _ -> {parse_res, Linestr@1, Rest@1} = get_line(Src, <<>>), Line = begin _pipe = Linestr@1, gleam_stdlib:identity(_pipe) end, Ts = decode_line_(<<" "/utf8, Line/bitstring, " "/utf8>>, []), case get_nextchar(Rest@1) of <<":"/utf8>> -> {token_res, {definition_of, {line, Ts}}, Rest@1}; _ -> {token_res, {line_indent, Indent, Ts}, Rest@1} end end. -spec decode_table_row(bitstring()) -> {list(token()), bitstring()}. decode_table_row(Src) -> {parse_res, Header, Rest} = get_line(Src, <<>>), Splitted = begin _pipe = gleam@string:split(Header, <<"|"/utf8>>), list_remove_last(_pipe) end, Tlist = gleam@list:map( Splitted, fun(Str) -> {token_res, T, _} = decode_line( begin _pipe@1 = Str, gleam_stdlib:identity(_pipe@1) end ), T end ), {Tlist, Rest}. -spec decode_table_items(bitstring(), list(list(token()))) -> {list(list(token())), bitstring()}. decode_table_items(Src, Acc) -> case Src of <<"|"/utf8, Rest/bitstring>> -> {Trow, Rest2} = decode_table_row(Rest), decode_table_items(Rest2, [Trow | Acc]); _ -> {gleam@list:reverse(Acc), Src} end. -spec decode_table(bitstring()) -> token_res(). decode_table(Src) -> {Header, Rest} = decode_table_row(Src), {parse_res, Align_line, Rest2} = get_line(Rest, <<>>), Splitted_align = begin _pipe = gleam@string:split(Align_line, <<"|"/utf8>>), list_remove_last(_pipe) end, Aligns = gleam@list:map( Splitted_align, fun(A) -> case string_end_with(A, <<"-:"/utf8>>) of true -> align_right; _ -> align_left end end ), {Lines, Rest3} = decode_table_items(Rest2, []), {token_res, {table, Header, Aligns, Lines}, Rest3}.