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/2]).
-export_type([section/0, fence/0, section_builder/0, line_content/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(false).
-type section() :: {other, integer(), list(binary())} |
{fenced_code,
integer(),
binary(),
list(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()), binary(), fence()}.
-type line_content() :: {line_content, binary(), binary()}.
-file("src/checkmark/internal/parser.gleam", 34).
?DOC(false).
-spec to_string_with_prefix(line_content()) -> binary().
to_string_with_prefix(Line) ->
<<(erlang:element(2, Line))/binary, (erlang:element(3, Line))/binary>>.
-file("src/checkmark/internal/parser.gleam", 45).
?DOC(false).
-spec add_parts(section_builder(), line_content()) -> section_builder().
add_parts(Builder, Line) ->
case Builder of
{fenced_code_builder, _, _, _, _} ->
{fenced_code_builder,
erlang:element(2, Builder),
[erlang:element(3, Line) | erlang:element(3, Builder)],
erlang:element(4, Builder),
erlang:element(5, Builder)};
{other_builder, _, _} ->
{other_builder,
erlang:element(2, Builder),
[to_string_with_prefix(Line) | erlang:element(3, Builder)]}
end.
-file("src/checkmark/internal/parser.gleam", 185).
?DOC(false).
-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", 194).
?DOC(false).
-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", 189).
?DOC(false).
-spec strip_indent(list(binary()), integer()) -> list(binary()).
strip_indent(Lines, Indent) ->
_pipe = Lines,
gleam@list:map(
_pipe,
fun(_capture) -> remove_indent_up_to(_capture, Indent) end
).
-file("src/checkmark/internal/parser.gleam", 57).
?DOC(false).
-spec to_section(section_builder(), gleam@option:option(fence())) -> section().
to_section(Builder, End_fence) ->
case Builder of
{fenced_code_builder, Line_number, Lines, Prefix, Start_fence} ->
{fenced_code,
Line_number,
Prefix,
begin
_pipe = strip_indent(Lines, erlang:element(4, Start_fence)),
lists:reverse(_pipe)
end,
Start_fence,
End_fence};
{other_builder, Line_number@1, Lines@1} ->
{other, Line_number@1, lists:reverse(Lines@1)}
end.
-file("src/checkmark/internal/parser.gleam", 203).
?DOC(false).
-spec parse_comment(binary()) -> {binary(), binary(), boolean()}.
parse_comment(Line) ->
case Line of
<<"/// "/utf8, Rest/binary>> ->
{<<"/// "/utf8>>, Rest, true};
<<"//// "/utf8, Rest@1/binary>> ->
{<<"//// "/utf8>>, Rest@1, true};
_ ->
{<<""/utf8>>, Line, false}
end.
-file("src/checkmark/internal/parser.gleam", 230).
?DOC(false).
-spec build_fence(binary(), integer(), integer(), binary()) -> fence().
build_fence(Character, Indent, Delimiters, Rest) ->
case gleam_stdlib:string_pop_grapheme(Rest) of
{ok, {First, Rest@1}} when First =:= Character ->
build_fence(Character, Indent, Delimiters + 1, Rest@1);
_ ->
Fence = gleam@string:repeat(Character, Delimiters),
{fence, Fence, Rest, Indent}
end.
-file("src/checkmark/internal/parser.gleam", 211).
?DOC(false).
-spec parse_fence(line_content()) -> gleam@option:option(fence()).
parse_fence(Line) ->
case erlang:element(3, Line) of
<<"```"/utf8, Rest/binary>> ->
{some, build_fence(<<"`"/utf8>>, 0, 3, Rest)};
<<" ```"/utf8, Rest@1/binary>> ->
{some, build_fence(<<"`"/utf8>>, 1, 3, Rest@1)};
<<" ```"/utf8, Rest@2/binary>> ->
{some, build_fence(<<"`"/utf8>>, 2, 3, Rest@2)};
<<" ```"/utf8, Rest@3/binary>> ->
{some, build_fence(<<"`"/utf8>>, 3, 3, Rest@3)};
<<"~~~"/utf8, Rest@4/binary>> ->
{some, build_fence(<<"~"/utf8>>, 0, 3, Rest@4)};
<<" ~~~"/utf8, Rest@5/binary>> ->
{some, build_fence(<<"~"/utf8>>, 1, 3, Rest@5)};
<<" ~~~"/utf8, Rest@6/binary>> ->
{some, build_fence(<<"~"/utf8>>, 2, 3, Rest@6)};
<<" ~~~"/utf8, Rest@7/binary>> ->
{some, build_fence(<<"~"/utf8>>, 3, 3, Rest@7)};
_ ->
none
end.
-file("src/checkmark/internal/parser.gleam", 73).
?DOC(false).
-spec parse_lines(
boolean(),
integer(),
list(section()),
gleam@option:option(section_builder()),
binary(),
list(binary())
) -> list(section()).
parse_lines(
Search_in_comments,
Line_number,
Sections,
Current_builder,
Line,
Rest
) ->
{Prefix, Line@1, Is_comment} = case Search_in_comments of
true ->
parse_comment(Line);
false ->
{<<""/utf8>>, Line, false}
end,
Line@2 = {line_content, Prefix, Line@1},
{Sections@1, Current_section@1} = case Search_in_comments andalso not Is_comment of
true ->
case Current_builder of
none ->
{Sections,
{some,
{other_builder,
Line_number,
[to_string_with_prefix(Line@2)]}}};
{some, Builder} ->
case Builder of
{fenced_code_builder, _, _, _, _} ->
{[to_section(Builder, none) | Sections],
{some,
{other_builder,
Line_number,
[to_string_with_prefix(Line@2)]}}};
{other_builder, _, _} ->
{Sections, {some, add_parts(Builder, Line@2)}}
end
end;
false ->
case parse_fence(Line@2) of
none ->
Current_section = case Current_builder of
none ->
{other_builder,
Line_number,
[to_string_with_prefix(Line@2)]};
{some, Builder@1} ->
add_parts(Builder@1, Line@2)
end,
{Sections, {some, Current_section}};
{some, Current_fence} ->
case Current_builder of
none ->
{Sections,
{some,
{fenced_code_builder,
Line_number,
[],
erlang:element(2, Line@2),
Current_fence}}};
{some, {other_builder, _, _} = Other_builder} ->
{[to_section(Other_builder, none) | Sections],
{some,
{fenced_code_builder,
Line_number,
[],
erlang:element(2, Line@2),
Current_fence}}};
{some,
{fenced_code_builder, _, _, _, Start_fence} = Fence_builder} ->
case should_close(Start_fence, Current_fence) of
true ->
{[to_section(
Fence_builder,
{some, Current_fence}
) |
Sections],
none};
false ->
{Sections,
{some, add_parts(Fence_builder, Line@2)}}
end
end
end
end,
case Rest of
[] ->
Sections@2 = case Current_section@1 of
none ->
Sections@1;
{some, Builder@2} ->
[to_section(Builder@2, none) | Sections@1]
end,
lists:reverse(Sections@2);
[Next_line | Rest@1] ->
parse_lines(
Search_in_comments,
Line_number + 1,
Sections@1,
Current_section@1,
Next_line,
Rest@1
)
end.
-file("src/checkmark/internal/parser.gleam", 38).
?DOC(false).
-spec parse(list(binary()), boolean()) -> list(section()).
parse(Lines, Search_in_comments) ->
case Lines of
[First | Rest] ->
parse_lines(Search_in_comments, 1, [], none, First, Rest);
[] ->
[]
end.