-module(commonmark@internal@parser@block). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([parse_document/1]). -export_type([block_state/0, block_parse_state/0]). -type block_state() :: outside_block | {paragraph_builder, list(binary())} | {fenced_code_block_builder, binary(), gleam@option:option(binary()), gleam@option:option(binary()), list(binary()), integer()} | {indented_code_block_builder, list(binary())} | {block_quote_builder, list(binary())} | {unordered_list_builder, list(binary()), list(list(block_parse_state())), boolean(), binary(), integer()} | {ordered_list_builder, list(binary()), list(list(block_parse_state())), boolean(), binary(), integer(), integer()}. -type block_parse_state() :: {paragraph, binary()} | horizontal_break | {heading, integer(), gleam@option:option(binary())} | {code_block, gleam@option:option(binary()), gleam@option:option(binary()), binary()} | {block_quote, list(block_parse_state())} | {unordered_list, list(list(block_parse_state())), boolean(), commonmark@ast:unordered_list_marker()} | {ordered_list, list(list(block_parse_state())), integer(), boolean(), commonmark@ast:ordered_list_marker()}. -spec merge_references( list(gleam@dict:dict(binary(), commonmark@ast:reference_())) ) -> gleam@dict:dict(binary(), commonmark@ast:reference_()). merge_references(Refs) -> _pipe = Refs, _pipe@1 = gleam@list:reduce(_pipe, fun gleam@dict:merge/2), gleam@result:unwrap(_pipe@1, gleam@dict:new()). -spec parse_block_state(block_parse_state()) -> {commonmark@ast:block_node(), gleam@dict:dict(binary(), commonmark@ast:reference_())}. parse_block_state(State) -> case State of {paragraph, Lines} -> {begin _pipe = Lines, _pipe@1 = commonmark@internal@parser@inline:parse_text( _pipe ), {paragraph, _pipe@1} end, gleam@dict:new()}; {code_block, Info, Full_info, Lines@1} -> {{code_block, Info, Full_info, Lines@1}, gleam@dict:new()}; horizontal_break -> {horizontal_break, gleam@dict:new()}; {heading, Level, {some, Contents}} -> {{heading, Level, commonmark@internal@parser@inline:parse_text(Contents)}, gleam@dict:new()}; {heading, Level@1, none} -> {{heading, Level@1, []}, gleam@dict:new()}; {block_quote, Blocks} -> _pipe@2 = Blocks, _pipe@3 = gleam@list:map(_pipe@2, fun parse_block_state/1), _pipe@4 = gleam@list:unzip(_pipe@3), _pipe@5 = gleam@pair:map_first( _pipe@4, fun(Field@0) -> {block_quote, Field@0} end ), gleam@pair:map_second(_pipe@5, fun merge_references/1); {unordered_list, Items, Tight, Marker} -> Xs = begin _pipe@6 = Items, _pipe@7 = gleam@list:map( _pipe@6, fun(_capture) -> gleam@list:map( _capture, fun(_capture@1) -> parse_block_state(_capture@1) end ) end ), gleam@list:map(_pipe@7, fun gleam@list:unzip/1) end, {{unordered_list, gleam@list:map(Xs, fun(L) -> case Tight of true -> {tight_list_item, erlang:element(1, L)}; false -> {list_item, erlang:element(1, L)} end end), Marker}, begin _pipe@8 = Xs, _pipe@9 = gleam@list:flat_map( _pipe@8, fun gleam@pair:second/1 ), merge_references(_pipe@9) end}; {ordered_list, Items@1, Start, Tight@1, Marker@1} -> Xs@1 = begin _pipe@10 = Items@1, _pipe@11 = gleam@list:map( _pipe@10, fun(_capture@2) -> gleam@list:map( _capture@2, fun(_capture@3) -> parse_block_state(_capture@3) end ) end ), gleam@list:map(_pipe@11, fun gleam@list:unzip/1) end, {{ordered_list, gleam@list:map(Xs@1, fun(L@1) -> case Tight@1 of true -> {tight_list_item, erlang:element(1, L@1)}; false -> {list_item, erlang:element(1, L@1)} end end), Start, Marker@1}, begin _pipe@12 = Xs@1, _pipe@13 = gleam@list:flat_map( _pipe@12, fun gleam@pair:second/1 ), merge_references(_pipe@13) end} end. -spec apply_regex(binary(), gleam@regex:regex()) -> {ok, list(gleam@option:option(binary()))} | {error, nil}. apply_regex(Line, Regex) -> case gleam@regex:scan(Regex, Line) of [{match, _, Submatches}] -> {ok, Submatches}; _ -> {error, nil} end. -spec is_empty_line(binary()) -> boolean(). is_empty_line(L) -> begin _pipe = L, commonmark@internal@parser@helpers:trim_indent(_pipe, 4) end =:= <<""/utf8>>. -spec parse_blocks(list(binary())) -> list(block_parse_state()). parse_blocks(Lines) -> do_parse_blocks(outside_block, [], Lines). -spec do_parse_blocks(block_state(), list(block_parse_state()), list(binary())) -> list(block_parse_state()). do_parse_blocks(State, Acc, Lines) -> _assert_subject = gleam@regex:from_string( <<"^ {0,3}(?:\\*[* \t]*\\*[* \t]*\\*|-[- \t]*-[- \t]*-|_[_ \t]*_[_ \t]*_)[ \t]*$"/utf8>> ), {ok, Hr_regex} = 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 => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 144}) end, _assert_subject@1 = gleam@regex:from_string( <<"^ {0,3}(#{1,6})([ \t]+.*?)?(?:(?<=[ \t])#*)?[ \t]*$"/utf8>> ), {ok, Atx_header_regex} = case _assert_subject@1 of {ok, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 148}) end, _assert_subject@2 = gleam@regex:from_string( <<"^ {0,3}([-=])+[ \t]*$"/utf8>> ), {ok, Setext_header_regex} = case _assert_subject@2 of {ok, _} -> _assert_subject@2; _assert_fail@2 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@2, module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 150}) end, _assert_subject@3 = case State of {fenced_code_block_builder, Break, _, _, _, _} -> gleam@regex:from_string( <<<<"^ {0,3}"/utf8, Break/binary>>/binary, "+[ \t]*$"/utf8>> ); _ -> gleam@regex:from_string( <<"^( {0,3})([~`]{3,})[ \t]*(([^\\s]+).*?)?[ \t]*$"/utf8>> ) end, {ok, Fenced_code_regex} = case _assert_subject@3 of {ok, _} -> _assert_subject@3; _assert_fail@3 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@3, module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 152}) end, _assert_subject@4 = gleam@regex:from_string( <<<<"^"/utf8, "(?: {0,3}\t| )"/utf8>>/binary, "|^[ \t]*$"/utf8>> ), {ok, Valid_indented_code_regex} = case _assert_subject@4 of {ok, _} -> _assert_subject@4; _assert_fail@4 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@4, module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 157}) end, _assert_subject@5 = gleam@regex:from_string(<<"^ {0,3}> ?(.*)$"/utf8>>), {ok, Block_quote_regex} = case _assert_subject@5 of {ok, _} -> _assert_subject@5; _assert_fail@5 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@5, module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 159}) end, _assert_subject@6 = gleam@regex:from_string( <<"^( {0,3})([-*+])(?:( {1,4})(.*))?$"/utf8>> ), {ok, Ul_regex} = case _assert_subject@6 of {ok, _} -> _assert_subject@6; _assert_fail@6 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@6, module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 160}) end, _assert_subject@7 = gleam@regex:from_string( <<"^( {0,3})([0-9]{1,9})([.)])(?:( {1,4})(.*))?$"/utf8>> ), {ok, Ol_regex} = case _assert_subject@7 of {ok, _} -> _assert_subject@7; _assert_fail@7 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@7, module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 162}) end, L = gleam@list:first(Lines), Atx_header_results = begin _pipe = L, gleam@result:'try'( _pipe, fun(_capture) -> apply_regex(_capture, Atx_header_regex) end ) end, Setext_header_results = begin _pipe@1 = L, gleam@result:'try'( _pipe@1, fun(_capture@1) -> apply_regex(_capture@1, Setext_header_regex) end ) end, Fenced_code_results = begin _pipe@2 = L, gleam@result:'try'( _pipe@2, fun(_capture@2) -> apply_regex(_capture@2, Fenced_code_regex) end ) end, Block_quote_results = begin _pipe@3 = L, gleam@result:'try'( _pipe@3, fun(_capture@3) -> apply_regex(_capture@3, Block_quote_regex) end ) end, Ul_results = begin _pipe@4 = L, gleam@result:'try'( _pipe@4, fun(_capture@4) -> apply_regex(_capture@4, Ul_regex) end ) end, Ol_results = begin _pipe@5 = L, gleam@result:'try'( _pipe@5, fun(_capture@5) -> apply_regex(_capture@5, Ol_regex) end ) end, Is_hr = begin _pipe@6 = L, _pipe@7 = gleam@result:map( _pipe@6, fun(_capture@6) -> gleam@regex:check(Hr_regex, _capture@6) end ), gleam@result:unwrap(_pipe@7, false) end, Is_indented_code_block = begin _pipe@8 = L, _pipe@9 = gleam@result:map( _pipe@8, fun(_capture@7) -> gleam@regex:check(Valid_indented_code_regex, _capture@7) end ), gleam@result:unwrap(_pipe@9, false) end, Is_atx_header = begin _pipe@10 = Atx_header_results, gleam@result:is_ok(_pipe@10) end, Is_setext_header = begin _pipe@11 = Setext_header_results, gleam@result:is_ok(_pipe@11) end, Is_fenced_code_block = begin _pipe@12 = Fenced_code_results, gleam@result:is_ok(_pipe@12) end, Is_block_quote = begin _pipe@13 = Block_quote_results, gleam@result:is_ok(_pipe@13) end, Is_ul = begin _pipe@14 = Ul_results, gleam@result:is_ok(_pipe@14) end, Is_ol = begin _pipe@15 = Ol_results, gleam@result:is_ok(_pipe@15) end, Is_list_continuation = case State of {unordered_list_builder, _, _, _, _, Indent} -> _assert_subject@8 = gleam@regex:from_string( <<<<"^"/utf8, (commonmark@internal@parser@helpers:indent_pattern( Indent ))/binary>>/binary, "|^[ \t]*$"/utf8>> ), {ok, Indent_pattern} = case _assert_subject@8 of {ok, _} -> _assert_subject@8; _assert_fail@8 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@8, module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 200}) end, _pipe@16 = L, _pipe@17 = gleam@result:'try'( _pipe@16, fun(_capture@8) -> apply_regex(_capture@8, Indent_pattern) end ), gleam@result:is_ok(_pipe@17); {ordered_list_builder, _, _, _, _, _, Indent} -> _assert_subject@8 = gleam@regex:from_string( <<<<"^"/utf8, (commonmark@internal@parser@helpers:indent_pattern( Indent ))/binary>>/binary, "|^[ \t]*$"/utf8>> ), {ok, Indent_pattern} = case _assert_subject@8 of {ok, _} -> _assert_subject@8; _assert_fail@8 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@8, module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 200}) end, _pipe@16 = L, _pipe@17 = gleam@result:'try'( _pipe@16, fun(_capture@8) -> apply_regex(_capture@8, Indent_pattern) end ), gleam@result:is_ok(_pipe@17); _ -> false end, Is_paragraph = (((((not Is_hr andalso not Is_atx_header) andalso not Is_setext_header) andalso not Is_fenced_code_block) andalso not Is_block_quote) andalso not Is_ul) andalso not Is_ol, Is_blank_line = begin _pipe@18 = L, _pipe@19 = gleam@result:map(_pipe@18, fun is_empty_line/1), gleam@result:unwrap(_pipe@19, false) end, case {State, Lines} of {{paragraph_builder, Lines@1}, []} -> _pipe@22 = [{paragraph, begin _pipe@20 = Lines@1, _pipe@21 = lists:reverse(_pipe@20), gleam@string:join(_pipe@21, <<"\n"/utf8>>) end} | Acc], lists:reverse(_pipe@22); {{indented_code_block_builder, Lines@2}, []} -> _pipe@28 = [{code_block, none, none, begin _pipe@25 = [<<""/utf8>> | begin _pipe@23 = Lines@2, _pipe@24 = gleam@list:map( _pipe@23, fun(_capture@9) -> commonmark@internal@parser@helpers:trim_indent( _capture@9, 4 ) end ), gleam@list:drop_while( _pipe@24, fun(N) -> N =:= <<""/utf8>> end ) end], _pipe@26 = lists:reverse(_pipe@25), _pipe@27 = gleam@list:drop_while( _pipe@26, fun(N@1) -> N@1 =:= <<""/utf8>> end ), gleam@string:join(_pipe@27, <<"\n"/utf8>>) end} | Acc], lists:reverse(_pipe@28); {{fenced_code_block_builder, _, Info, Full_info, Contents, Indent@1}, [<<""/utf8>>]} -> _pipe@32 = [{code_block, Info, Full_info, begin _pipe@29 = [<<""/utf8>> | Contents], _pipe@30 = gleam@list:map( _pipe@29, fun(_capture@10) -> commonmark@internal@parser@helpers:trim_indent( _capture@10, Indent@1 ) end ), _pipe@31 = lists:reverse(_pipe@30), gleam@string:join(_pipe@31, <<"\n"/utf8>>) end} | Acc], lists:reverse(_pipe@32); {{fenced_code_block_builder, _, Info, Full_info, Contents, Indent@1}, []} -> _pipe@32 = [{code_block, Info, Full_info, begin _pipe@29 = [<<""/utf8>> | Contents], _pipe@30 = gleam@list:map( _pipe@29, fun(_capture@10) -> commonmark@internal@parser@helpers:trim_indent( _capture@10, Indent@1 ) end ), _pipe@31 = lists:reverse(_pipe@30), gleam@string:join(_pipe@31, <<"\n"/utf8>>) end} | Acc], lists:reverse(_pipe@32); {{block_quote_builder, Bs}, []} -> _pipe@35 = [{block_quote, begin _pipe@33 = Bs, _pipe@34 = lists:reverse(_pipe@33), parse_blocks(_pipe@34) end} | Acc], lists:reverse(_pipe@35); {{unordered_list_builder, Item, Items, Tight, Marker, _}, []} -> _pipe@39 = [{unordered_list, begin _pipe@38 = [begin _pipe@36 = Item, _pipe@37 = lists:reverse(_pipe@36), parse_blocks(_pipe@37) end | Items], lists:reverse(_pipe@38) end, Tight andalso not gleam@list:any( gleam@list:drop(Item, 1), fun is_empty_line/1 ), commonmark@internal@parser@helpers:ul_marker(Marker)} | Acc], lists:reverse(_pipe@39); {{ordered_list_builder, Item@1, Items@1, Tight@1, Marker@1, Start, _}, []} -> _pipe@43 = [{ordered_list, begin _pipe@42 = [begin _pipe@40 = Item@1, _pipe@41 = lists:reverse(_pipe@40), parse_blocks(_pipe@41) end | Items@1], lists:reverse(_pipe@42) end, Start, Tight@1 andalso not gleam@list:any( gleam@list:drop(Item@1, 1), fun is_empty_line/1 ), commonmark@internal@parser@helpers:ol_marker(Marker@1)} | Acc], lists:reverse(_pipe@43); {outside_block, []} -> _pipe@44 = Acc, lists:reverse(_pipe@44); {{paragraph_builder, Bs@1}, [<<" "/utf8>> | Ls]} when Is_blank_line -> do_parse_blocks( outside_block, [{paragraph, begin _pipe@45 = lists:reverse(Bs@1), gleam@string:join(_pipe@45, <<"\n"/utf8>>) end} | Acc], Ls ); {{paragraph_builder, Bs@1}, [<<"\\"/utf8>> | Ls]} when Is_blank_line -> do_parse_blocks( outside_block, [{paragraph, begin _pipe@45 = lists:reverse(Bs@1), gleam@string:join(_pipe@45, <<"\n"/utf8>>) end} | Acc], Ls ); {{paragraph_builder, Bs@1}, [<<""/utf8>> | Ls]} when Is_blank_line -> do_parse_blocks( outside_block, [{paragraph, begin _pipe@45 = lists:reverse(Bs@1), gleam@string:join(_pipe@45, <<"\n"/utf8>>) end} | Acc], Ls ); {{paragraph_builder, Bs@1}, [_ | Ls]} when Is_blank_line -> do_parse_blocks( outside_block, [{paragraph, begin _pipe@45 = lists:reverse(Bs@1), gleam@string:join(_pipe@45, <<"\n"/utf8>>) end} | Acc], Ls ); {outside_block, [<<" "/utf8>> | Ls@1]} -> do_parse_blocks(outside_block, Acc, Ls@1); {outside_block, [<<"\\"/utf8>> | Ls@1]} -> do_parse_blocks(outside_block, Acc, Ls@1); {outside_block, [<<""/utf8>> | Ls@1]} -> do_parse_blocks(outside_block, Acc, Ls@1); {{paragraph_builder, Bs@2}, [_ | Ls@2]} when Is_setext_header -> case Setext_header_results of {ok, [{some, <<"="/utf8>>}]} -> do_parse_blocks( outside_block, [{heading, 1, {some, begin _pipe@46 = lists:reverse(Bs@2), gleam@string:join( _pipe@46, <<"\n"/utf8>> ) end}} | Acc], Ls@2 ); {ok, [{some, <<"-"/utf8>>}]} -> do_parse_blocks( outside_block, [{heading, 2, {some, begin _pipe@47 = lists:reverse(Bs@2), gleam@string:join( _pipe@47, <<"\n"/utf8>> ) end}} | Acc], Ls@2 ); _ -> erlang:error(#{gleam_error => panic, message => (<<"Invalid Setext header parser state: "/utf8, (gleam@string:inspect(Setext_header_results))/binary>>), module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 313}) end; {{paragraph_builder, Bs@3}, [_ | Ls@3]} when Is_hr -> do_parse_blocks( outside_block, [horizontal_break, {paragraph, begin _pipe@48 = lists:reverse(Bs@3), gleam@string:join(_pipe@48, <<"\n"/utf8>>) end} | Acc], Ls@3 ); {outside_block, [_ | Ls@4]} when Is_hr -> do_parse_blocks(outside_block, [horizontal_break | Acc], Ls@4); {{unordered_list_builder, Item@2, Items@2, Tight@2, Marker@2, Indent@2}, [L@1 | Ls@5]} when Is_list_continuation -> do_parse_blocks( {unordered_list_builder, [commonmark@internal@parser@helpers:trim_indent( L@1, Indent@2 ) | Item@2], Items@2, Tight@2, Marker@2, Indent@2}, Acc, Ls@5 ); {{unordered_list_builder, Item@3, Items@3, Tight@3, Marker@3, _}, [_ | Ls@6]} when Is_ul -> case Ul_results of {ok, [Leading, {some, New_marker}]} when Marker@3 =:= New_marker -> do_parse_blocks( {unordered_list_builder, [], [begin _pipe@49 = Item@3, _pipe@50 = lists:reverse(_pipe@49), parse_blocks(_pipe@50) end | Items@3], Tight@3 andalso not gleam@list:any( Item@3, fun is_empty_line/1 ), Marker@3, begin _pipe@51 = gleam@option:unwrap( Leading, <<""/utf8>> ), gleam@string:length(_pipe@51) end + 1}, Acc, Ls@6 ); {ok, [Leading@1, {some, New_marker@1}, {some, New_indent}, Rest]} when Marker@3 =:= New_marker@1 -> do_parse_blocks( {unordered_list_builder, [begin _pipe@52 = Rest, gleam@option:unwrap(_pipe@52, <<""/utf8>>) end], [begin _pipe@53 = Item@3, _pipe@54 = lists:reverse(_pipe@53), parse_blocks(_pipe@54) end | Items@3], Tight@3 andalso not gleam@list:any( Item@3, fun is_empty_line/1 ), Marker@3, (gleam@string:length(New_indent) + begin _pipe@55 = gleam@option:unwrap( Leading@1, <<""/utf8>> ), gleam@string:length(_pipe@55) end) + 1}, Acc, Ls@6 ); {ok, [Leading@2, {some, New_marker@2}]} -> do_parse_blocks( {unordered_list_builder, [], [], true, New_marker@2, begin _pipe@56 = gleam@option:unwrap( Leading@2, <<""/utf8>> ), gleam@string:length(_pipe@56) end + 1}, [{unordered_list, begin _pipe@59 = [begin _pipe@57 = Item@3, _pipe@58 = lists:reverse(_pipe@57), parse_blocks(_pipe@58) end | Items@3], lists:reverse(_pipe@59) end, Tight@3 andalso not gleam@list:any( gleam@list:drop(Item@3, 1), fun is_empty_line/1 ), commonmark@internal@parser@helpers:ul_marker( Marker@3 )} | Acc], Ls@6 ); {ok, [Leading@3, {some, New_marker@3}, {some, New_indent@1}, Rest@1]} -> do_parse_blocks( {unordered_list_builder, [begin _pipe@60 = Rest@1, gleam@option:unwrap(_pipe@60, <<""/utf8>>) end], [], true, New_marker@3, (gleam@string:length(New_indent@1) + begin _pipe@61 = gleam@option:unwrap( Leading@3, <<""/utf8>> ), gleam@string:length(_pipe@61) end) + 1}, [{unordered_list, begin _pipe@64 = [begin _pipe@62 = Item@3, _pipe@63 = lists:reverse(_pipe@62), parse_blocks(_pipe@63) end | Items@3], lists:reverse(_pipe@64) end, Tight@3 andalso not gleam@list:any( gleam@list:drop(Item@3, 1), fun is_empty_line/1 ), commonmark@internal@parser@helpers:ul_marker( Marker@3 )} | Acc], Ls@6 ); _ -> erlang:error(#{gleam_error => panic, message => (<<"Invalid unordered list parser state: "/utf8, (gleam@string:inspect(Ul_results))/binary>>), module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 417}) end; {{unordered_list_builder, Item@4, Items@4, Tight@4, Marker@4, _}, Ls@7} -> do_parse_blocks( outside_block, [{unordered_list, begin _pipe@67 = [begin _pipe@65 = Item@4, _pipe@66 = lists:reverse(_pipe@65), parse_blocks(_pipe@66) end | Items@4], lists:reverse(_pipe@67) end, Tight@4 andalso not gleam@list:any( gleam@list:drop(Item@4, 1), fun is_empty_line/1 ), commonmark@internal@parser@helpers:ul_marker(Marker@4)} | Acc], Ls@7 ); {outside_block, [_ | Ls@8]} when Is_ul -> case Ul_results of {ok, [Leading@4, {some, Marker@5}]} -> do_parse_blocks( {unordered_list_builder, [], [], true, Marker@5, begin _pipe@68 = gleam@option:unwrap( Leading@4, <<""/utf8>> ), gleam@string:length(_pipe@68) end + 1}, Acc, Ls@8 ); {ok, [Leading@5, {some, Marker@6}, {some, Indent@3}, Rest@2]} -> do_parse_blocks( {unordered_list_builder, [begin _pipe@69 = Rest@2, gleam@option:unwrap(_pipe@69, <<""/utf8>>) end], [], true, Marker@6, (gleam@string:length(Indent@3) + begin _pipe@70 = gleam@option:unwrap( Leading@5, <<""/utf8>> ), gleam@string:length(_pipe@70) end) + 1}, Acc, Ls@8 ); _ -> erlang:error(#{gleam_error => panic, message => (<<"Invalid unordered list parser state: "/utf8, (gleam@string:inspect(Ul_results))/binary>>), module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 464}) end; {{ordered_list_builder, Item@5, Items@5, Tight@5, Marker@7, Start@1, Indent@4}, [L@2 | Ls@9]} when Is_list_continuation -> do_parse_blocks( {ordered_list_builder, [commonmark@internal@parser@helpers:trim_indent( L@2, Indent@4 ) | Item@5], Items@5, Tight@5, Marker@7, Start@1, Indent@4}, Acc, Ls@9 ); {{ordered_list_builder, Item@6, Items@6, Tight@6, Marker@8, Start@2, _}, [_ | Ls@10]} when Is_ol -> case Ol_results of {ok, [Leading@6, _, {some, New_marker@4}]} when Marker@8 =:= New_marker@4 -> do_parse_blocks( {ordered_list_builder, [], [begin _pipe@71 = Item@6, _pipe@72 = lists:reverse(_pipe@71), parse_blocks(_pipe@72) end | Items@6], Tight@6 andalso not gleam@list:any( Item@6, fun is_empty_line/1 ), Marker@8, Start@2, begin _pipe@73 = gleam@option:unwrap( Leading@6, <<""/utf8>> ), gleam@string:length(_pipe@73) end + 1}, Acc, Ls@10 ); {ok, [Leading@7, {some, New_start}, {some, New_marker@5}, {some, New_indent@2}, Rest@3]} when Marker@8 =:= New_marker@5 -> do_parse_blocks( {ordered_list_builder, [begin _pipe@74 = Rest@3, gleam@option:unwrap(_pipe@74, <<""/utf8>>) end], [begin _pipe@75 = Item@6, _pipe@76 = lists:reverse(_pipe@75), parse_blocks(_pipe@76) end | Items@6], Tight@6 andalso not gleam@list:any( Item@6, fun is_empty_line/1 ), Marker@8, Start@2, ((gleam@string:length(New_indent@2) + gleam@string:length( New_start )) + begin _pipe@77 = gleam@option:unwrap( Leading@7, <<""/utf8>> ), gleam@string:length(_pipe@77) end) + 1}, Acc, Ls@10 ); {ok, [Leading@8, {some, New_start@1}, {some, New_marker@6}]} -> do_parse_blocks( {ordered_list_builder, [], [], true, New_marker@6, begin _pipe@78 = New_start@1, _pipe@79 = gleam@int:parse(_pipe@78), gleam@result:unwrap(_pipe@79, 1) end, (gleam@string:length(New_start@1) + begin _pipe@80 = gleam@option:unwrap( Leading@8, <<""/utf8>> ), gleam@string:length(_pipe@80) end) + 1}, [{ordered_list, begin _pipe@83 = [begin _pipe@81 = Item@6, _pipe@82 = lists:reverse(_pipe@81), parse_blocks(_pipe@82) end | Items@6], lists:reverse(_pipe@83) end, Start@2, Tight@6 andalso not gleam@list:any( gleam@list:drop(Item@6, 1), fun is_empty_line/1 ), commonmark@internal@parser@helpers:ol_marker( Marker@8 )} | Acc], Ls@10 ); {ok, [Leading@9, {some, New_start@2}, {some, New_marker@7}, {some, New_indent@3}, Rest@4]} -> do_parse_blocks( {ordered_list_builder, [begin _pipe@84 = Rest@4, gleam@option:unwrap(_pipe@84, <<""/utf8>>) end], [], true, New_marker@7, begin _pipe@85 = New_start@2, _pipe@86 = gleam@int:parse(_pipe@85), gleam@result:unwrap(_pipe@86, 1) end, ((gleam@string:length(New_indent@3) + gleam@string:length( New_start@2 )) + begin _pipe@87 = gleam@option:unwrap( Leading@9, <<""/utf8>> ), gleam@string:length(_pipe@87) end) + 1}, [{ordered_list, begin _pipe@90 = [begin _pipe@88 = Item@6, _pipe@89 = lists:reverse(_pipe@88), parse_blocks(_pipe@89) end | Items@6], lists:reverse(_pipe@90) end, Start@2, Tight@6 andalso not gleam@list:any( gleam@list:drop(Item@6, 1), fun is_empty_line/1 ), commonmark@internal@parser@helpers:ol_marker( Marker@8 )} | Acc], Ls@10 ); _ -> erlang:error(#{gleam_error => panic, message => (<<"Invalid ordered list parser state: "/utf8, (gleam@string:inspect(Ol_results))/binary>>), module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 568}) end; {{ordered_list_builder, Item@7, Items@7, Tight@7, Marker@9, Start@3, _}, Ls@11} -> do_parse_blocks( outside_block, [{ordered_list, begin _pipe@93 = [begin _pipe@91 = Item@7, _pipe@92 = lists:reverse(_pipe@91), parse_blocks(_pipe@92) end | Items@7], lists:reverse(_pipe@93) end, Start@3, Tight@7 andalso not gleam@list:any( gleam@list:drop(Item@7, 1), fun is_empty_line/1 ), commonmark@internal@parser@helpers:ol_marker(Marker@9)} | Acc], Ls@11 ); {outside_block, [_ | Ls@12]} when Is_ol -> case Ol_results of {ok, [Leading@10, {some, Start@4}, {some, Marker@10}]} -> do_parse_blocks( {ordered_list_builder, [], [], true, Marker@10, begin _pipe@94 = Start@4, _pipe@95 = gleam@int:parse(_pipe@94), gleam@result:unwrap(_pipe@95, 1) end, (gleam@string:length(Start@4) + begin _pipe@96 = gleam@option:unwrap( Leading@10, <<""/utf8>> ), gleam@string:length(_pipe@96) end) + 1}, Acc, Ls@12 ); {ok, [Leading@11, {some, Start@5}, {some, Marker@11}, {some, Indent@5}, Rest@5]} -> do_parse_blocks( {ordered_list_builder, [begin _pipe@97 = Rest@5, gleam@option:unwrap(_pipe@97, <<""/utf8>>) end], [], begin _pipe@98 = Rest@5, gleam@option:is_some(_pipe@98) end, Marker@11, begin _pipe@99 = Start@5, _pipe@100 = gleam@int:parse(_pipe@99), gleam@result:unwrap(_pipe@100, 1) end, ((gleam@string:length(Indent@5) + gleam@string:length( Start@5 )) + begin _pipe@101 = gleam@option:unwrap( Leading@11, <<""/utf8>> ), gleam@string:length(_pipe@101) end) + 1}, Acc, Ls@12 ); _ -> erlang:error(#{gleam_error => panic, message => (<<"Invalid ordered list parser state: "/utf8, (gleam@string:inspect(Ol_results))/binary>>), module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 620}) end; {outside_block, [L@3 | Ls@13]} when Is_indented_code_block -> case Is_blank_line of true -> do_parse_blocks(outside_block, Acc, Ls@13); false -> do_parse_blocks( {indented_code_block_builder, [L@3]}, Acc, Ls@13 ) end; {{indented_code_block_builder, Bs@4}, [L@4]} when Is_indented_code_block -> do_parse_blocks( {indented_code_block_builder, [L@4 | Bs@4]}, Acc, [] ); {{indented_code_block_builder, Bs@5}, [L@5 | Ls@14]} when Is_indented_code_block -> do_parse_blocks( {indented_code_block_builder, [L@5 | Bs@5]}, Acc, Ls@14 ); {{indented_code_block_builder, Bs@6}, Ls@15} -> do_parse_blocks( outside_block, [{code_block, none, none, begin _pipe@104 = [<<""/utf8>> | begin _pipe@102 = Bs@6, _pipe@103 = gleam@list:map( _pipe@102, fun(_capture@11) -> commonmark@internal@parser@helpers:trim_indent( _capture@11, 4 ) end ), gleam@list:drop_while( _pipe@103, fun(N@2) -> N@2 =:= <<""/utf8>> end ) end], _pipe@105 = lists:reverse(_pipe@104), _pipe@106 = gleam@list:drop_while( _pipe@105, fun(N@3) -> N@3 =:= <<""/utf8>> end ), gleam@string:join(_pipe@106, <<"\n"/utf8>>) end} | Acc], Ls@15 ); {{paragraph_builder, Bs@7}, [_ | Ls@16]} when Is_fenced_code_block -> case Fenced_code_results of {ok, [Indent@6, {some, Exit}]} -> do_parse_blocks( {fenced_code_block_builder, Exit, none, none, [], commonmark@internal@parser@helpers:determine_indent( Indent@6 )}, [{paragraph, begin _pipe@107 = lists:reverse(Bs@7), gleam@string:join(_pipe@107, <<"\n"/utf8>>) end} | Acc], Ls@16 ); {ok, [Indent@7, {some, Exit@1}, Full_info@1, Info@1]} -> do_parse_blocks( {fenced_code_block_builder, Exit@1, Info@1, Full_info@1, [], commonmark@internal@parser@helpers:determine_indent( Indent@7 )}, [{paragraph, begin _pipe@108 = lists:reverse(Bs@7), gleam@string:join(_pipe@108, <<"\n"/utf8>>) end} | Acc], Ls@16 ); _ -> erlang:error(#{gleam_error => panic, message => (<<"Invalid fenced code block parser state: "/utf8, (gleam@string:inspect(Fenced_code_results))/binary>>), module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 683}) end; {outside_block, [_ | Ls@17]} when Is_fenced_code_block -> case Fenced_code_results of {ok, [Indent@8, {some, Exit@2}]} -> do_parse_blocks( {fenced_code_block_builder, Exit@2, none, none, [], commonmark@internal@parser@helpers:determine_indent( Indent@8 )}, Acc, Ls@17 ); {ok, [Indent@9, {some, Exit@3}, Full_info@2, Info@2]} -> do_parse_blocks( {fenced_code_block_builder, Exit@3, Info@2, Full_info@2, [], commonmark@internal@parser@helpers:determine_indent( Indent@9 )}, Acc, Ls@17 ); _ -> erlang:error(#{gleam_error => panic, message => (<<"Invalid fenced code block parser state: "/utf8, (gleam@string:inspect(Fenced_code_results))/binary>>), module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 715}) end; {{fenced_code_block_builder, _, Info@3, Full_info@3, Bs@8, Indent@10}, [_ | Ls@18]} when Is_fenced_code_block -> do_parse_blocks( outside_block, [{code_block, Info@3, Full_info@3, begin _pipe@110 = lists:reverse( [<<""/utf8>> | begin _pipe@109 = Bs@8, gleam@list:map( _pipe@109, fun(_capture@12) -> commonmark@internal@parser@helpers:trim_indent( _capture@12, Indent@10 ) end ) end] ), gleam@string:join(_pipe@110, <<"\n"/utf8>>) end} | Acc], Ls@18 ); {{fenced_code_block_builder, Break@1, Info@4, Full_info@4, Bs@9, Indent@11}, [L@6 | Ls@19]} -> do_parse_blocks( {fenced_code_block_builder, Break@1, Info@4, Full_info@4, [L@6 | Bs@9], Indent@11}, Acc, Ls@19 ); {{block_quote_builder, Bs@10}, [_ | Ls@20]} when Is_block_quote -> case Block_quote_results of {ok, [none]} -> do_parse_blocks( {block_quote_builder, [<<""/utf8>> | Bs@10]}, Acc, Ls@20 ); {ok, []} -> do_parse_blocks( {block_quote_builder, [<<""/utf8>> | Bs@10]}, Acc, Ls@20 ); {ok, [{some, L@7}]} -> do_parse_blocks( {block_quote_builder, [L@7 | Bs@10]}, Acc, Ls@20 ); _ -> erlang:error(#{gleam_error => panic, message => (<<"Invalid block quote parser state: "/utf8, (gleam@string:inspect(Block_quote_results))/binary>>), module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 749}) end; {{block_quote_builder, Bs@11}, [L@8 | Ls@21]} -> case begin _pipe@111 = Bs@11, _pipe@112 = lists:reverse(_pipe@111), _pipe@113 = parse_blocks(_pipe@112), gleam@list:last(_pipe@113) end of {ok, {paragraph, _}} when Is_paragraph andalso not Is_blank_line -> do_parse_blocks( {block_quote_builder, [L@8 | Bs@11]}, Acc, Ls@21 ); {ok, {block_quote, _}} when Is_paragraph andalso not Is_blank_line -> do_parse_blocks( {block_quote_builder, [L@8 | Bs@11]}, Acc, Ls@21 ); _ -> do_parse_blocks( outside_block, [{block_quote, begin _pipe@114 = Bs@11, _pipe@115 = lists:reverse(_pipe@114), parse_blocks(_pipe@115) end} | Acc], [L@8 | Ls@21] ) end; {{paragraph_builder, Bs@12}, [_ | Ls@22]} when Is_block_quote -> case Block_quote_results of {ok, [none]} -> do_parse_blocks( {block_quote_builder, [<<""/utf8>>]}, [{paragraph, begin _pipe@116 = lists:reverse(Bs@12), gleam@string:join(_pipe@116, <<"\n"/utf8>>) end} | Acc], Ls@22 ); {ok, []} -> do_parse_blocks( {block_quote_builder, [<<""/utf8>>]}, [{paragraph, begin _pipe@116 = lists:reverse(Bs@12), gleam@string:join(_pipe@116, <<"\n"/utf8>>) end} | Acc], Ls@22 ); {ok, [{some, L@9}]} -> do_parse_blocks( {block_quote_builder, [L@9]}, [{paragraph, begin _pipe@117 = lists:reverse(Bs@12), gleam@string:join(_pipe@117, <<"\n"/utf8>>) end} | Acc], Ls@22 ); _ -> erlang:error(#{gleam_error => panic, message => (<<"Invalid block quote parser state: "/utf8, (gleam@string:inspect(Block_quote_results))/binary>>), module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 785}) end; {outside_block, [_ | Ls@23]} when Is_block_quote -> case Block_quote_results of {ok, [none]} -> do_parse_blocks( {block_quote_builder, [<<""/utf8>>]}, Acc, Ls@23 ); {ok, []} -> do_parse_blocks( {block_quote_builder, [<<""/utf8>>]}, Acc, Ls@23 ); {ok, [{some, L@10}]} -> do_parse_blocks({block_quote_builder, [L@10]}, Acc, Ls@23); _ -> erlang:error(#{gleam_error => panic, message => (<<"Invalid block quote parser state: "/utf8, (gleam@string:inspect(Block_quote_results))/binary>>), module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 795}) end; {outside_block, [_ | Ls@24]} when Is_atx_header -> case Atx_header_results of {ok, [{some, Heading}]} -> do_parse_blocks( outside_block, [{heading, gleam@string:length(Heading), none} | Acc], Ls@24 ); {ok, [{some, Heading@1}, {some, Contents@1}]} -> do_parse_blocks( outside_block, [{heading, gleam@string:length(Heading@1), {some, Contents@1}} | Acc], Ls@24 ); _ -> erlang:error(#{gleam_error => panic, message => (<<"Invalid ATX header parser state: "/utf8, (gleam@string:inspect(Atx_header_results))/binary>>), module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 816}) end; {{paragraph_builder, Bs@13}, [_ | Ls@25]} when Is_atx_header -> case Atx_header_results of {ok, [{some, Heading@2}]} -> do_parse_blocks( outside_block, [{heading, gleam@string:length(Heading@2), none}, {paragraph, begin _pipe@118 = lists:reverse(Bs@13), gleam@string:join(_pipe@118, <<"\n"/utf8>>) end} | Acc], Ls@25 ); {ok, [{some, Heading@3}, {some, Contents@2}]} -> do_parse_blocks( outside_block, [{heading, gleam@string:length(Heading@3), {some, Contents@2}}, {paragraph, begin _pipe@119 = lists:reverse(Bs@13), gleam@string:join(_pipe@119, <<"\n"/utf8>>) end} | Acc], Ls@25 ); _ -> erlang:error(#{gleam_error => panic, message => (<<"Invalid ATX header parser state: "/utf8, (gleam@string:inspect(Atx_header_results))/binary>>), module => <<"commonmark/internal/parser/block"/utf8>>, function => <<"do_parse_blocks"/utf8>>, line => 844}) end; {outside_block, [Line | Ls@26]} -> do_parse_blocks({paragraph_builder, [Line]}, Acc, Ls@26); {{paragraph_builder, Bs@14}, [Line@1 | Ls@27]} -> do_parse_blocks({paragraph_builder, [Line@1 | Bs@14]}, Acc, Ls@27) end. -spec parse_document(list(binary())) -> commonmark@ast:document(). parse_document(Lines) -> {Blocks, Refs} = begin _pipe = parse_blocks(Lines), _pipe@1 = gleam@list:map(_pipe, fun parse_block_state/1), _pipe@2 = gleam@list:unzip(_pipe@1), gleam@pair:map_second(_pipe@2, fun merge_references/1) end, {document, Blocks, Refs}.