subroutineparse_blockrecursiveprivate
recursive subroutine parse_block(t, parent, block, stack, n)
Find the block processor for block and run it.
Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
| t | type(tree_t) | inout | the conversion | |
| parent | integer | in | the node | |
| block | character(len=:) | inout | allocatable | the chunk |
| stack | type(string_t) | inout | allocatabledimension(:) | the chunks left, the next one last |
| n | integer | inout | how many there are |
Calls
- last_child
- push_back
- starts_with
- in_state
- list_indent
- is_list
- code_block
- admonition_block
- find_hash_header
- hash_header
- is_setext
- setext_header
- find_rule
- parse_one
- trimmed_end
- new_node
- is_ordered_item
- list_block
- is_bullet_item
- find_quote
- quote_block
- is_table
- find_definition
- definition_block
- paragraph
Source
Show the code
recursive subroutine parse_block(t, parent, block, stack, n)
type(tree_t), intent(inout) :: t !! the conversion
integer, intent(in) :: parent !! the node
character(len=:), allocatable, intent(inout) :: block !! the chunk
type(string_t), allocatable, intent(inout) :: stack(:) !! the chunks left, the next one last
integer, intent(inout) :: n !! how many there are
character(len=:), allocatable :: tag
integer :: sibling, at, stop_at
logical :: code_sibling
sibling = last_child(t, parent)
code_sibling = .false.
if (sibling > 0) code_sibling = t%nodes(sibling)%tag == 'code'
! empty
if (len(block) == 0) then
if (code_sibling) t%nodes(sibling)%text = t%nodes(sibling)%text//NL//NL
return
end if
if (block(1:1) == NL) then
if (code_sibling) t%nodes(sibling)%text = t%nodes(sibling)%text//NL
if (len(block) > 1) call push_back(stack, n, block(2:))
return
end if
tag = t%nodes(parent)%tag
! list indent
if (starts_with(block, ' ') .and. .not. in_state(t, 'detabbed')) then
if (tag == 'li' .or. tag == 'dd') then
call list_indent(t, parent, block)
return
end if
if (sibling > 0) then
if (is_list(t%nodes(sibling)%tag)) then
call list_indent(t, parent, block)
return
end if
end if
end if
! code
if (starts_with(block, ' ')) then
call code_block(t, parent, block, stack, n)
return
end if
! admonition
if (starts_with(block, '@note ')) then
call admonition_block(t, parent, block, stack, n)
return
end if
! headers
call find_hash_header(block, at, stop_at)
if (at > 0) then
call hash_header(t, parent, block, at, stop_at, stack, n)
return
end if
if (is_setext(block)) then
call setext_header(t, parent, block, stack, n)
return
end if
! horizontal rule
call find_rule(block, at, stop_at)
if (at > 0) then
if (at > 1) call parse_one(t, parent, trimmed_end(block(:at - 1)))
call new_node(t, parent, 'hr', sibling)
if (stop_at < len(block)) call push_back(stack, n, block(stop_at + 2:))
return
end if
! lists
if (is_ordered_item(block)) then
call list_block(t, parent, block, 'ol')
return
end if
if (is_bullet_item(block)) then
call list_block(t, parent, block, 'ul')
return
end if
! block quote
call find_quote(block, at)
if (at > 0) then
call quote_block(t, parent, block, at)
return
end if
! tables, definition lists, paragraphs
if (is_table(block)) then
call new_node(t, parent, 'table', sibling)
t%nodes(sibling)%text = block
return
end if
call find_definition(block, at)
if (at > 0) then
call definition_block(t, parent, block, at, stack, n)
return
end if
call paragraph(t, parent, block)
end subroutine parse_block