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