Current section
Files
Jump to
Current section
Files
src/checkmark@internal@parser.erl
-module(checkmark@internal@parser).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/checkmark/internal/parser.gleam").
-export([parse/1]).
-export_type([section/0, fence/0, section_builder/0]).
-type section() :: {other, integer(), binary()} |
{fenced_code, integer(), binary(), fence(), gleam@option:option(fence())}.
-type fence() :: {fence, binary(), binary(), integer()}.
-type section_builder() :: {other_builder, integer(), list(binary())} |
{fenced_code_builder, integer(), list(binary()), fence()}.
-file("src/checkmark/internal/parser.gleam", 131).
-spec should_close(fence(), fence()) -> boolean().
should_close(Start, End) ->
gleam_stdlib:string_starts_with(
erlang:element(2, End),
erlang:element(2, Start)
).
-file("src/checkmark/internal/parser.gleam", 142).
-spec remove_indent_up_to(binary(), integer()) -> binary().
remove_indent_up_to(String, Indent) ->
case {Indent, String} of
{0, _} ->
String;
{_, <<" "/utf8, Rest/binary>>} ->
remove_indent_up_to(Rest, Indent - 1);
{_, _} ->
String
end.
-file("src/checkmark/internal/parser.gleam", 135).
-spec parts_to_string(list(binary()), integer()) -> binary().
parts_to_string(Parts, Indent) ->
_pipe = Parts,
_pipe@1 = gleam@list:map(
_pipe,
fun(_capture) -> remove_indent_up_to(_capture, Indent) end
),
_pipe@2 = lists:reverse(_pipe@1),
gleam@string:join(_pipe@2, <<""/utf8>>).
-file("src/checkmark/internal/parser.gleam", 168).
-spec build_fence(binary(), integer(), integer(), binary(), binary()) -> fence().
build_fence(Character, Indent, Delimiters, Rest, Ending) ->
case gleam_stdlib:string_pop_grapheme(Rest) of
{ok, {First, Rest@1}} when First =:= Character ->
build_fence(Character, Indent, Delimiters + 1, Rest@1, Ending);
_ ->
{fence,
gleam@string:repeat(Character, Delimiters),
<<Rest/binary, Ending/binary>>,
Indent}
end.
-file("src/checkmark/internal/parser.gleam", 150).
-spec parse_fence(binary(), binary()) -> gleam@option:option(fence()).
parse_fence(Line, Ending) ->
case Line of
<<"```"/utf8, Rest/binary>> ->
{some, build_fence(<<"`"/utf8>>, 0, 3, Rest, Ending)};
<<" ```"/utf8, Rest@1/binary>> ->
{some, build_fence(<<"`"/utf8>>, 1, 3, Rest@1, Ending)};
<<" ```"/utf8, Rest@2/binary>> ->
{some, build_fence(<<"`"/utf8>>, 2, 3, Rest@2, Ending)};
<<" ```"/utf8, Rest@3/binary>> ->
{some, build_fence(<<"`"/utf8>>, 3, 3, Rest@3, Ending)};
<<"~~~"/utf8, Rest@4/binary>> ->
{some, build_fence(<<"~"/utf8>>, 0, 3, Rest@4, Ending)};
<<" ~~~"/utf8, Rest@5/binary>> ->
{some, build_fence(<<"~"/utf8>>, 1, 3, Rest@5, Ending)};
<<" ~~~"/utf8, Rest@6/binary>> ->
{some, build_fence(<<"~"/utf8>>, 2, 3, Rest@6, Ending)};
<<" ~~~"/utf8, Rest@7/binary>> ->
{some, build_fence(<<"~"/utf8>>, 3, 3, Rest@7, Ending)};
_ ->
none
end.
-file("src/checkmark/internal/parser.gleam", 34).
-spec parse_lines(
splitter:splitter(),
integer(),
list(section()),
gleam@option:option(section_builder()),
binary(),
binary(),
binary()
) -> list(section()).
parse_lines(Splitter, Line, Sections, Current_section, Content, Ending, Rest) ->
{Sections@1, Current_section@2} = case parse_fence(Content, Ending) of
none ->
Current_section@1 = case Current_section of
none ->
{other_builder, Line, [Ending, Content]};
{some, Builder} ->
Parts = [Ending, Content | erlang:element(3, Builder)],
case Builder of
{fenced_code_builder, Line@1, _, Start_fence} ->
{fenced_code_builder, Line@1, Parts, Start_fence};
{other_builder, Line@2, _} ->
{other_builder, Line@2, Parts}
end
end,
{Sections, {some, Current_section@1}};
{some, Fence} ->
case Current_section of
none ->
{Sections, {some, {fenced_code_builder, Line, [], Fence}}};
{some, {other_builder, Prev_line, Parts@1}} ->
{[{other, Prev_line, parts_to_string(Parts@1, 0)} |
Sections],
{some, {fenced_code_builder, Line, [], Fence}}};
{some,
{fenced_code_builder, Start_line, Parts@2, Start_fence@1}} ->
case should_close(Start_fence@1, Fence) of
true ->
{[{fenced_code,
Start_line,
parts_to_string(
Parts@2,
erlang:element(4, Start_fence@1)
),
Start_fence@1,
{some, Fence}} |
Sections],
none};
false ->
{Sections,
{some,
{fenced_code_builder,
Start_line,
[Ending, Content | Parts@2],
Start_fence@1}}}
end
end
end,
case Rest of
<<""/utf8>> ->
Sections@2 = case Current_section@2 of
none ->
Sections@1;
{some, Builder@1} ->
case Builder@1 of
{fenced_code_builder,
Start_line@1,
Parts@3,
Start_fence@2} ->
[{fenced_code,
Start_line@1,
parts_to_string(
Parts@3,
erlang:element(4, Start_fence@2)
),
Start_fence@2,
none} |
Sections@1];
{other_builder, Start_line@2, Parts@4} ->
[{other, Start_line@2, parts_to_string(Parts@4, 0)} |
Sections@1]
end
end,
lists:reverse(Sections@2);
Rest@1 ->
{Content@1, Ending@1, Rest@2} = splitter_ffi:split(Splitter, Rest@1),
parse_lines(
Splitter,
Line + 1,
Sections@1,
Current_section@2,
Content@1,
Ending@1,
Rest@2
)
end.
-file("src/checkmark/internal/parser.gleam", 26).
-spec parse(binary()) -> list(section()).
parse(Content) ->
gleam@bool:guard(
Content =:= <<""/utf8>>,
[],
fun() ->
Line_ends = splitter:new([<<"\n"/utf8>>, <<"\r\n"/utf8>>]),
{Line, Ending, Rest} = splitter_ffi:split(Line_ends, Content),
parse_lines(Line_ends, 1, [], none, Line, Ending, Rest)
end
).