Current section
Files
Jump to
Current section
Files
src/kirala@bbmarkdown@parser.erl
-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>>};
<<Chr, Rest@2/bitstring>> ->
{Indent,
begin
_pipe = <<Chr>>,
ret_string(_pipe)
end};
Unhandable ->
{0, <<"<unhandable>"/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);
<<Chr, Rest@1/bitstring>> ->
_pipe = <<Chr>>,
ret_string(_pipe);
Unhandable ->
<<"<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};
<<Chr, Rest@1/bitstring>> ->
get_line(Rest@1, <<Acc/bitstring, Chr>>);
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};
<<Chr, Rest@1/bitstring>> ->
decode_url_(Rest@1, <<Acc/bitstring, Chr>>);
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};
<<Chr, Rest@1/bitstring>> ->
decode_codeblock_(Rest@1, <<Acc/bitstring, Chr>>);
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>>, <<>>};
<<Str:8, Rest/bitstring>> when Str =:= Nterm ->
{parse_res, ret_string(Acc), Rest};
<<Chr, Rest@1/bitstring>> ->
get_until1_(Rest@1, <<Acc/bitstring, Chr>>, 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),
<<Nterm:8>> = 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>>, <<>>};
<<Str:16, Rest/bitstring>> when Str =:= Nterm ->
{parse_res, ret_string(Acc), Rest};
<<Chr, Rest@1/bitstring>> ->
get_until2_(Rest@1, <<Acc/bitstring, Chr>>, 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),
<<Nterm:16>> = 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>>, <<>>};
<<Str:24, Rest/bitstring>> when Str =:= Nterm ->
{parse_res, ret_string(Acc), Rest};
<<Chr, Rest@1/bitstring>> ->
get_until3_(Rest@1, <<Acc/bitstring, Chr>>, 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),
<<Nterm:24>> = 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>>, <<>>};
<<Str:32, Rest/bitstring>> when Str =:= Nterm ->
{parse_res, ret_string(Acc), Rest};
<<Chr, Rest@1/bitstring>> ->
get_until4_(Rest@1, <<Acc/bitstring, Chr>>, 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),
<<Nterm:32>> = 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};
<<Chr, Rest@1/bitstring>> ->
decode_text(Rest@1, <<Acc/bitstring, Chr>>);
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);
<<Dch1, "."/utf8, Rest@20/bitstring>> when (16#30 =< Dch1) andalso (Dch1 =< 16#39) ->
decode_ordered_list(Indent, Rest@20);
<<Dch1@1, Dch2, "."/utf8, Rest@21/bitstring>> 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}.