subroutineexpand_file_includesrecursiveprivate
recursive subroutine expand_file_includes(lines, options, depth)
Replace file include directives by the contents of the file.
Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
| lines | type(string_t) | inout | allocatabledimension(:) | the lines |
| options | type(markdown_options_t) | in | what rendering depends on | |
| depth | integer | in | how many includes deep this is |
Calls
Source
Show the code
recursive subroutine expand_file_includes(lines, options, depth)
type(string_t), allocatable, intent(inout) :: lines(:) !! the lines
type(markdown_options_t), intent(in) :: options !! what rendering depends on
integer, intent(in) :: depth !! how many includes deep this is
type(string_t), allocatable :: out(:), included(:)
character(len=:), allocatable :: contents, msg, path, before, after
integer :: k, a, b, stat, j
if (depth > 16) return
if (.not. allocated(options%base_path)) return
if (.not. any([(index(lines(k)%s, '{!') > 0, k=1, size(lines))])) return
allocate (out(0))
do k = 1, size(lines)
a = index(lines(k)%s, '{!')
b = 0
if (a > 0) b = index(lines(k)%s(a + 2:), '!}')
if (a == 0 .or. b == 0) then
call push(out, lines(k)%s)
cycle
end if
! not `join_path`, which returns a deferred-length string
path = strip(lines(k)%s(a + 2:a + b))
if (.not. starts_with(path, '/')) path = options%base_path//'/'//path
call read_whole_file(path, contents, stat, msg)
if (stat /= 0) then
call warn('could not include '//path)
call push(out, lines(k)%s)
cycle
end if
included = split_lines(contents)
call normalize_lines(included)
call expand_file_includes(included, options, depth + 1)
before = lines(k)%s(:a - 1)
after = lines(k)%s(a + b + 3:)
if (size(included) == 0) then
call push(out, before//after)
cycle
end if
included(1)%s = before//included(1)%s
included(size(included))%s = included(size(included))%s//after
do j = 1, size(included)
call push(out, included(j)%s)
end do
end do
call move_alloc(out, lines)
end subroutine expand_file_includes