-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]*\\g{1}){2,}[ \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 => 156}) 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 => 157}) 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 => 159}) 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})(([~`])\\g{3}{2,})[ \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 => 161}) 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 => 166}) 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 => 168}) 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 => 169}) 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 => 171}) 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 => 209}) 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 => 209}) 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 => 322}) end; {{unordered_list_builder, Item@2, Items@2, Tight@2, Marker@2, _}, [_ | Ls@3]} when Is_hr -> do_parse_blocks( outside_block, [horizontal_break, {unordered_list, begin _pipe@50 = [begin _pipe@48 = Item@2, _pipe@49 = lists:reverse(_pipe@48), parse_blocks(_pipe@49) end | Items@2], lists:reverse(_pipe@50) end, Tight@2 andalso not gleam@list:any( gleam@list:drop(Item@2, 1), fun is_empty_line/1 ), commonmark@internal@parser@helpers:ul_marker(Marker@2)} | Acc], Ls@3 ); {{ordered_list_builder, Item@3, Items@3, Tight@3, Marker@3, Start@1, _}, [_ | Ls@4]} when Is_hr -> do_parse_blocks( outside_block, [horizontal_break, {ordered_list, begin _pipe@53 = [begin _pipe@51 = Item@3, _pipe@52 = lists:reverse(_pipe@51), parse_blocks(_pipe@52) end | Items@3], lists:reverse(_pipe@53) end, Start@1, Tight@3 andalso not gleam@list:any( gleam@list:drop(Item@3, 1), fun is_empty_line/1 ), commonmark@internal@parser@helpers:ol_marker(Marker@3)} | Acc], Ls@4 ); {{paragraph_builder, Bs@3}, [_ | Ls@5]} when Is_hr -> do_parse_blocks( outside_block, [horizontal_break, {paragraph, begin _pipe@54 = lists:reverse(Bs@3), gleam@string:join(_pipe@54, <<"\n"/utf8>>) end} | Acc], Ls@5 ); {outside_block, [_ | Ls@6]} when Is_hr -> do_parse_blocks(outside_block, [horizontal_break | Acc], Ls@6); {{unordered_list_builder, Item@4, Items@4, Tight@4, Marker@4, Indent@2}, [L@1 | Ls@7]} when Is_list_continuation -> do_parse_blocks( {unordered_list_builder, [commonmark@internal@parser@helpers:trim_indent( L@1, Indent@2 ) | Item@4], Items@4, Tight@4, Marker@4, Indent@2}, Acc, Ls@7 ); {{unordered_list_builder, Item@5, Items@5, Tight@5, Marker@5, _}, [_ | Ls@8]} when Is_ul -> case Ul_results of {ok, [Leading, {some, New_marker}]} when Marker@5 =:= New_marker -> do_parse_blocks( {unordered_list_builder, [], [begin _pipe@55 = Item@5, _pipe@56 = lists:reverse(_pipe@55), parse_blocks(_pipe@56) end | Items@5], Tight@5 andalso not gleam@list:any( Item@5, fun is_empty_line/1 ), Marker@5, begin _pipe@57 = gleam@option:unwrap( Leading, <<""/utf8>> ), gleam@string:length(_pipe@57) end + 1}, Acc, Ls@8 ); {ok, [Leading@1, {some, New_marker@1}, {some, New_indent}, Rest]} when Marker@5 =:= New_marker@1 -> do_parse_blocks( {unordered_list_builder, [begin _pipe@58 = Rest, gleam@option:unwrap(_pipe@58, <<""/utf8>>) end], [begin _pipe@59 = Item@5, _pipe@60 = lists:reverse(_pipe@59), parse_blocks(_pipe@60) end | Items@5], Tight@5 andalso not gleam@list:any( Item@5, fun is_empty_line/1 ), Marker@5, (gleam@string:length(New_indent) + begin _pipe@61 = gleam@option:unwrap( Leading@1, <<""/utf8>> ), gleam@string:length(_pipe@61) end) + 1}, Acc, Ls@8 ); {ok, [Leading@2, {some, New_marker@2}]} -> do_parse_blocks( {unordered_list_builder, [], [], true, New_marker@2, begin _pipe@62 = gleam@option:unwrap( Leading@2, <<""/utf8>> ), gleam@string:length(_pipe@62) end + 1}, [{unordered_list, begin _pipe@65 = [begin _pipe@63 = Item@5, _pipe@64 = lists:reverse(_pipe@63), parse_blocks(_pipe@64) end | Items@5], lists:reverse(_pipe@65) end, Tight@5 andalso not gleam@list:any( gleam@list:drop(Item@5, 1), fun is_empty_line/1 ), commonmark@internal@parser@helpers:ul_marker( Marker@5 )} | Acc], Ls@8 ); {ok, [Leading@3, {some, New_marker@3}, {some, New_indent@1}, Rest@1]} -> do_parse_blocks( {unordered_list_builder, [begin _pipe@66 = Rest@1, gleam@option:unwrap(_pipe@66, <<""/utf8>>) end], [], true, New_marker@3, (gleam@string:length(New_indent@1) + begin _pipe@67 = gleam@option:unwrap( Leading@3, <<""/utf8>> ), gleam@string:length(_pipe@67) end) + 1}, [{unordered_list, begin _pipe@70 = [begin _pipe@68 = Item@5, _pipe@69 = lists:reverse(_pipe@68), parse_blocks(_pipe@69) end | Items@5], lists:reverse(_pipe@70) end, Tight@5 andalso not gleam@list:any( gleam@list:drop(Item@5, 1), fun is_empty_line/1 ), commonmark@internal@parser@helpers:ul_marker( Marker@5 )} | 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 => 457}) end; {{unordered_list_builder, Item@6, Items@6, Tight@6, Marker@6, _}, Ls@9} -> do_parse_blocks( outside_block, [{unordered_list, begin _pipe@73 = [begin _pipe@71 = Item@6, _pipe@72 = lists:reverse(_pipe@71), parse_blocks(_pipe@72) end | Items@6], lists:reverse(_pipe@73) end, Tight@6 andalso not gleam@list:any( gleam@list:drop(Item@6, 1), fun is_empty_line/1 ), commonmark@internal@parser@helpers:ul_marker(Marker@6)} | Acc], Ls@9 ); {outside_block, [_ | Ls@10]} when Is_ul -> case Ul_results of {ok, [Leading@4, {some, Marker@7}]} -> do_parse_blocks( {unordered_list_builder, [], [], true, Marker@7, begin _pipe@74 = gleam@option:unwrap( Leading@4, <<""/utf8>> ), gleam@string:length(_pipe@74) end + 1}, Acc, Ls@10 ); {ok, [Leading@5, {some, Marker@8}, {some, Indent@3}, Rest@2]} -> do_parse_blocks( {unordered_list_builder, [begin _pipe@75 = Rest@2, gleam@option:unwrap(_pipe@75, <<""/utf8>>) end], [], true, Marker@8, (gleam@string:length(Indent@3) + begin _pipe@76 = gleam@option:unwrap( Leading@5, <<""/utf8>> ), gleam@string:length(_pipe@76) end) + 1}, Acc, Ls@10 ); _ -> 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 => 504}) end; {{ordered_list_builder, Item@7, Items@7, Tight@7, Marker@9, Start@2, Indent@4}, [L@2 | Ls@11]} when Is_list_continuation -> do_parse_blocks( {ordered_list_builder, [commonmark@internal@parser@helpers:trim_indent( L@2, Indent@4 ) | Item@7], Items@7, Tight@7, Marker@9, Start@2, Indent@4}, Acc, Ls@11 ); {{ordered_list_builder, Item@8, Items@8, Tight@8, Marker@10, Start@3, _}, [_ | Ls@12]} when Is_ol -> case Ol_results of {ok, [Leading@6, _, {some, New_marker@4}]} when Marker@10 =:= New_marker@4 -> do_parse_blocks( {ordered_list_builder, [], [begin _pipe@77 = Item@8, _pipe@78 = lists:reverse(_pipe@77), parse_blocks(_pipe@78) end | Items@8], Tight@8 andalso not gleam@list:any( Item@8, fun is_empty_line/1 ), Marker@10, Start@3, begin _pipe@79 = gleam@option:unwrap( Leading@6, <<""/utf8>> ), gleam@string:length(_pipe@79) end + 1}, Acc, Ls@12 ); {ok, [Leading@7, {some, New_start}, {some, New_marker@5}, {some, New_indent@2}, Rest@3]} when Marker@10 =:= New_marker@5 -> do_parse_blocks( {ordered_list_builder, [begin _pipe@80 = Rest@3, gleam@option:unwrap(_pipe@80, <<""/utf8>>) end], [begin _pipe@81 = Item@8, _pipe@82 = lists:reverse(_pipe@81), parse_blocks(_pipe@82) end | Items@8], Tight@8 andalso not gleam@list:any( Item@8, fun is_empty_line/1 ), Marker@10, Start@3, ((gleam@string:length(New_indent@2) + gleam@string:length( New_start )) + begin _pipe@83 = gleam@option:unwrap( Leading@7, <<""/utf8>> ), gleam@string:length(_pipe@83) end) + 1}, Acc, Ls@12 ); {ok, [Leading@8, {some, New_start@1}, {some, New_marker@6}]} -> do_parse_blocks( {ordered_list_builder, [], [], true, New_marker@6, begin _pipe@84 = New_start@1, _pipe@85 = gleam@int:parse(_pipe@84), gleam@result:unwrap(_pipe@85, 1) end, (gleam@string:length(New_start@1) + begin _pipe@86 = gleam@option:unwrap( Leading@8, <<""/utf8>> ), gleam@string:length(_pipe@86) end) + 1}, [{ordered_list, begin _pipe@89 = [begin _pipe@87 = Item@8, _pipe@88 = lists:reverse(_pipe@87), parse_blocks(_pipe@88) end | Items@8], lists:reverse(_pipe@89) end, Start@3, Tight@8 andalso not gleam@list:any( gleam@list:drop(Item@8, 1), fun is_empty_line/1 ), commonmark@internal@parser@helpers:ol_marker( Marker@10 )} | Acc], Ls@12 ); {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@90 = Rest@4, gleam@option:unwrap(_pipe@90, <<""/utf8>>) end], [], true, New_marker@7, begin _pipe@91 = New_start@2, _pipe@92 = gleam@int:parse(_pipe@91), gleam@result:unwrap(_pipe@92, 1) end, ((gleam@string:length(New_indent@3) + gleam@string:length( New_start@2 )) + begin _pipe@93 = gleam@option:unwrap( Leading@9, <<""/utf8>> ), gleam@string:length(_pipe@93) end) + 1}, [{ordered_list, begin _pipe@96 = [begin _pipe@94 = Item@8, _pipe@95 = lists:reverse(_pipe@94), parse_blocks(_pipe@95) end | Items@8], lists:reverse(_pipe@96) end, Start@3, Tight@8 andalso not gleam@list:any( gleam@list:drop(Item@8, 1), fun is_empty_line/1 ), commonmark@internal@parser@helpers:ol_marker( Marker@10 )} | 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 => 608}) end; {{ordered_list_builder, Item@9, Items@9, Tight@9, Marker@11, Start@4, _}, Ls@13} -> do_parse_blocks( outside_block, [{ordered_list, begin _pipe@99 = [begin _pipe@97 = Item@9, _pipe@98 = lists:reverse(_pipe@97), parse_blocks(_pipe@98) end | Items@9], lists:reverse(_pipe@99) end, Start@4, Tight@9 andalso not gleam@list:any( gleam@list:drop(Item@9, 1), fun is_empty_line/1 ), commonmark@internal@parser@helpers:ol_marker(Marker@11)} | Acc], Ls@13 ); {outside_block, [_ | Ls@14]} when Is_ol -> case Ol_results of {ok, [Leading@10, {some, Start@5}, {some, Marker@12}]} -> do_parse_blocks( {ordered_list_builder, [], [], true, Marker@12, begin _pipe@100 = Start@5, _pipe@101 = gleam@int:parse(_pipe@100), gleam@result:unwrap(_pipe@101, 1) end, (gleam@string:length(Start@5) + begin _pipe@102 = gleam@option:unwrap( Leading@10, <<""/utf8>> ), gleam@string:length(_pipe@102) end) + 1}, Acc, Ls@14 ); {ok, [Leading@11, {some, Start@6}, {some, Marker@13}, {some, Indent@5}, Rest@5]} -> do_parse_blocks( {ordered_list_builder, [begin _pipe@103 = Rest@5, gleam@option:unwrap(_pipe@103, <<""/utf8>>) end], [], begin _pipe@104 = Rest@5, gleam@option:is_some(_pipe@104) end, Marker@13, begin _pipe@105 = Start@6, _pipe@106 = gleam@int:parse(_pipe@105), gleam@result:unwrap(_pipe@106, 1) end, ((gleam@string:length(Indent@5) + gleam@string:length( Start@6 )) + begin _pipe@107 = gleam@option:unwrap( Leading@11, <<""/utf8>> ), gleam@string:length(_pipe@107) end) + 1}, Acc, Ls@14 ); _ -> 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 => 660}) end; {outside_block, [L@3 | Ls@15]} when Is_indented_code_block -> case Is_blank_line of true -> do_parse_blocks(outside_block, Acc, Ls@15); false -> do_parse_blocks( {indented_code_block_builder, [L@3]}, Acc, Ls@15 ) 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@16]} when Is_indented_code_block -> do_parse_blocks( {indented_code_block_builder, [L@5 | Bs@5]}, Acc, Ls@16 ); {{indented_code_block_builder, Bs@6}, Ls@17} -> do_parse_blocks( outside_block, [{code_block, none, none, begin _pipe@110 = [<<""/utf8>> | begin _pipe@108 = Bs@6, _pipe@109 = gleam@list:map( _pipe@108, fun(_capture@11) -> commonmark@internal@parser@helpers:trim_indent( _capture@11, 4 ) end ), gleam@list:drop_while( _pipe@109, fun(N@2) -> N@2 =:= <<""/utf8>> end ) end], _pipe@111 = lists:reverse(_pipe@110), _pipe@112 = gleam@list:drop_while( _pipe@111, fun(N@3) -> N@3 =:= <<""/utf8>> end ), gleam@string:join(_pipe@112, <<"\n"/utf8>>) end} | Acc], Ls@17 ); {{paragraph_builder, Bs@7}, [_ | Ls@18]} 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@113 = lists:reverse(Bs@7), gleam@string:join(_pipe@113, <<"\n"/utf8>>) end} | Acc], Ls@18 ); {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@114 = lists:reverse(Bs@7), gleam@string:join(_pipe@114, <<"\n"/utf8>>) end} | Acc], Ls@18 ); _ -> 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 => 723}) end; {outside_block, [_ | Ls@19]} 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@19 ); {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@19 ); _ -> 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 => 755}) end; {{fenced_code_block_builder, _, Info@3, Full_info@3, Bs@8, Indent@10}, [_ | Ls@20]} when Is_fenced_code_block -> do_parse_blocks( outside_block, [{code_block, Info@3, Full_info@3, begin _pipe@116 = lists:reverse( [<<""/utf8>> | begin _pipe@115 = Bs@8, gleam@list:map( _pipe@115, fun(_capture@12) -> commonmark@internal@parser@helpers:trim_indent( _capture@12, Indent@10 ) end ) end] ), gleam@string:join(_pipe@116, <<"\n"/utf8>>) end} | Acc], Ls@20 ); {{fenced_code_block_builder, Break@1, Info@4, Full_info@4, Bs@9, Indent@11}, [L@6 | Ls@21]} -> do_parse_blocks( {fenced_code_block_builder, Break@1, Info@4, Full_info@4, [L@6 | Bs@9], Indent@11}, Acc, Ls@21 ); {{block_quote_builder, Bs@10}, [_ | Ls@22]} when Is_block_quote -> case Block_quote_results of {ok, [none]} -> do_parse_blocks( {block_quote_builder, [<<""/utf8>> | Bs@10]}, Acc, Ls@22 ); {ok, []} -> do_parse_blocks( {block_quote_builder, [<<""/utf8>> | Bs@10]}, Acc, Ls@22 ); {ok, [{some, L@7}]} -> do_parse_blocks( {block_quote_builder, [L@7 | Bs@10]}, 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 => 789}) end; {{block_quote_builder, Bs@11}, [L@8 | Ls@23]} -> case begin _pipe@117 = Bs@11, _pipe@118 = lists:reverse(_pipe@117), _pipe@119 = parse_blocks(_pipe@118), gleam@list:last(_pipe@119) end of {ok, {paragraph, _}} when Is_paragraph andalso not Is_blank_line -> do_parse_blocks( {block_quote_builder, [L@8 | Bs@11]}, Acc, Ls@23 ); {ok, {block_quote, _}} when Is_paragraph andalso not Is_blank_line -> do_parse_blocks( {block_quote_builder, [L@8 | Bs@11]}, Acc, Ls@23 ); _ -> do_parse_blocks( outside_block, [{block_quote, begin _pipe@120 = Bs@11, _pipe@121 = lists:reverse(_pipe@120), parse_blocks(_pipe@121) end} | Acc], [L@8 | Ls@23] ) end; {{paragraph_builder, Bs@12}, [_ | Ls@24]} when Is_block_quote -> case Block_quote_results of {ok, [none]} -> do_parse_blocks( {block_quote_builder, [<<""/utf8>>]}, [{paragraph, begin _pipe@122 = lists:reverse(Bs@12), gleam@string:join(_pipe@122, <<"\n"/utf8>>) end} | Acc], Ls@24 ); {ok, []} -> do_parse_blocks( {block_quote_builder, [<<""/utf8>>]}, [{paragraph, begin _pipe@122 = lists:reverse(Bs@12), gleam@string:join(_pipe@122, <<"\n"/utf8>>) end} | Acc], Ls@24 ); {ok, [{some, L@9}]} -> do_parse_blocks( {block_quote_builder, [L@9]}, [{paragraph, begin _pipe@123 = lists:reverse(Bs@12), gleam@string:join(_pipe@123, <<"\n"/utf8>>) end} | Acc], Ls@24 ); _ -> 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 => 825}) end; {outside_block, [_ | Ls@25]} when Is_block_quote -> case Block_quote_results of {ok, [none]} -> do_parse_blocks( {block_quote_builder, [<<""/utf8>>]}, Acc, Ls@25 ); {ok, []} -> do_parse_blocks( {block_quote_builder, [<<""/utf8>>]}, Acc, Ls@25 ); {ok, [{some, L@10}]} -> do_parse_blocks({block_quote_builder, [L@10]}, Acc, Ls@25); _ -> 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 => 835}) end; {outside_block, [_ | Ls@26]} 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@26 ); {ok, [{some, Heading@1}, {some, Contents@1}]} -> do_parse_blocks( outside_block, [{heading, gleam@string:length(Heading@1), {some, Contents@1}} | Acc], Ls@26 ); _ -> 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 => 856}) end; {{paragraph_builder, Bs@13}, [_ | Ls@27]} 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@124 = lists:reverse(Bs@13), gleam@string:join(_pipe@124, <<"\n"/utf8>>) end} | Acc], Ls@27 ); {ok, [{some, Heading@3}, {some, Contents@2}]} -> do_parse_blocks( outside_block, [{heading, gleam@string:length(Heading@3), {some, Contents@2}}, {paragraph, begin _pipe@125 = lists:reverse(Bs@13), gleam@string:join(_pipe@125, <<"\n"/utf8>>) end} | Acc], Ls@27 ); _ -> 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 => 884}) end; {outside_block, [Line | Ls@28]} -> do_parse_blocks({paragraph_builder, [Line]}, Acc, Ls@28); {{paragraph_builder, Bs@14}, [Line@1 | Ls@29]} -> do_parse_blocks({paragraph_builder, [Line@1 | Bs@14]}, Acc, Ls@29) 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}.