class Asciidoctor::PreprocessorReader
Public: Methods for retrieving lines from AsciiDoc source files, evaluating preprocessor directives as each line is read off the Array
of lines.
Attributes
Public Class Methods
Public: Initialize the PreprocessorReader
object
Asciidoctor::Reader::new
# File lib/asciidoctor/reader.rb, line 616 def initialize document, data = nil, cursor = nil, opts = {} @document = document super data, cursor, opts if (default_include_depth = (document.attributes['max-include-depth'] || 64).to_i) > 0 # track absolute max depth, current max depth for comparing to include stack size, and relative max depth for reporting @maxdepth = { abs: default_include_depth, curr: default_include_depth, rel: default_include_depth } else # if @maxdepth is not set, built-in include functionality is disabled @maxdepth = nil end @include_stack = [] @includes = document.catalog[:includes] @skipping = false @conditional_stack = [] @include_processor_extensions = nil end
Public Instance Methods
# File lib/asciidoctor/reader.rb, line 779 def create_include_cursor file, path, lineno if ::String === file dir = ::File.dirname file elsif RUBY_ENGINE_OPAL dir = ::File.dirname(file = file.to_s) else dir = (dir = ::File.dirname file.path) == '' ? '/' : dir file = file.to_s end Cursor.new file, dir, path, lineno end
(see Reader#empty?
)
# File lib/asciidoctor/reader.rb, line 639 def empty? peek_line ? false : true end
Public: Reports whether pushing an include on the include stack exceeds the max include depth.
Returns nil if no max depth is set and includes are disabled (max-include-depth=0), false if the current max depth will not be exceeded, and the relative max include depth if the current max depth will be exceed.
# File lib/asciidoctor/reader.rb, line 750 def exceeds_max_depth? @maxdepth && @include_stack.size >= @maxdepth[:curr] && @maxdepth[:rel] end
(see Reader#has_more_lines?
)
# File lib/asciidoctor/reader.rb, line 634 def has_more_lines? peek_line ? true : false end
# File lib/asciidoctor/reader.rb, line 742 def include_depth @include_stack.size end
# File lib/asciidoctor/reader.rb, line 767 def include_processors? if @include_processor_extensions.nil? if @document.extensions? && @document.extensions.include_processors? !!(@include_processor_extensions = @document.extensions.include_processors) else @include_processor_extensions = false end else @include_processor_extensions != false end end
Public: Override the Reader#peek_line
method to pop the include stack if the last line has been reached and there’s at least one include on the stack.
Returns the next line of the source data as a String
if there are lines remaining in the current include context or a parent include context. Returns nothing if there are no more lines remaining and the include stack is empty.
Asciidoctor::Reader#peek_line
# File lib/asciidoctor/reader.rb, line 651 def peek_line direct = false if (line = super) line elsif @include_stack.empty? nil else pop_include peek_line direct end end
Public: 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.
# File lib/asciidoctor/reader.rb, line 676 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
TODO Document
this override also, we now have the field in the super class, so perhaps just implement the logic there?
Asciidoctor::Reader#shift
# File lib/asciidoctor/reader.rb, line 758 def shift if @unescape_next_line @unescape_next_line = false (line = super).slice 1, line.length else super end end
# File lib/asciidoctor/reader.rb, line 791 def to_s %(#<#{self.class}@#{object_id} {path: #{@path.inspect}, line: #{@lineno}, include depth: #{@include_stack.size}, include stack: [#{@include_stack.map {|inc| inc.to_s }.join ', '}]}>) end