Method: Asciidoctor::PreprocessorReader#push_include

Defined in:
lib/asciidoctor/reader.rb

#push_include(data, file = nil, path = nil, lineno = 1, attributes = {}) ⇒ Object

Push source onto the front of the reader and switch the context based on the file, document-relative path and line information given.

This method is typically used in an IncludeProcessor to add source read from the target specified.

Examples:

path = 'partial.adoc'
file = File.expand_path path
data = File.read file
reader.push_include data, file, path

Returns:

  • this Reader object.



686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
# File 'lib/asciidoctor/reader.rb', line 686

def push_include data, file = nil, path = nil, lineno = 1, attributes = {}
  @include_stack << [@lines, @file, @dir, @path, @lineno, @maxdepth, @process_lines]
  if (@file = file)
    # NOTE if file is not a string, assume it's a URI
    if ::String === file
      @dir = ::File.dirname file
    elsif RUBY_ENGINE_OPAL
      @dir = ::URI.parse ::File.dirname(file = file.to_s)
    else
      # NOTE this intentionally throws an error if URI has no path
      (@dir = file.dup).path = (dir = ::File.dirname file.path) == '/' ? '' : dir
      file = file.to_s
    end
    @path = (path ||= ::File.basename file)
    # only process lines in AsciiDoc files
    if (@process_lines = file.end_with?(*ASCIIDOC_EXTENSIONS.keys))
      # NOTE registering the include with a nil value tracks it while not making it visible to interdocument xrefs
      @includes[path.slice 0, (path.rindex '.')] ||= attributes['partial-option'] ? nil : true
    end
  else
    @dir = '.'
    # we don't know what file type we have, so assume AsciiDoc
    @process_lines = true
    if (@path = path)
      # NOTE registering the include with a nil value tracks it while not making it visible to interdocument xrefs
      @includes[Helpers.rootname path] ||= attributes['partial-option'] ? nil : true
    else
      @path = '<stdin>'
    end
  end

  @lineno = lineno

  if @maxdepth && (attributes.key? 'depth')
    if (rel_maxdepth = attributes['depth'].to_i) > 0
      if (curr_maxdepth = @include_stack.size + rel_maxdepth) > (abs_maxdepth = @maxdepth[:abs])
        # if relative depth exceeds absolute max depth, effectively ignore relative depth request
        curr_maxdepth = rel_maxdepth = abs_maxdepth
      end
      @maxdepth = { abs: abs_maxdepth, curr: curr_maxdepth, rel: rel_maxdepth }
    else
      @maxdepth = { abs: @maxdepth[:abs], curr: @include_stack.size, rel: 0 }
    end
  end

  # effectively fill the buffer
  if (@lines = prepare_lines data, normalize: @process_lines || :chomp, condense: false, indent: attributes['indent']).empty?
    pop_include
  else
    # FIXME we eventually want to handle leveloffset without affecting the lines
    if attributes.key? 'leveloffset'
      @lines = [((leveloffset = @document.attr 'leveloffset') ? %(:leveloffset: #{leveloffset}) : ':leveloffset!:'), ''] + @lines.reverse + ['', %(:leveloffset: #{attributes['leveloffset']})]
      # compensate for these extra lines at the top
      @lineno -= 2
    else
      @lines.reverse!
    end

    # FIXME kind of a hack
    #Document::AttributeEntry.new('infile', @file).save_to_next_block @document
    #Document::AttributeEntry.new('indir', @dir).save_to_next_block @document
    @look_ahead = 0
  end
  self
end