summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Allen <dan.j.allen@gmail.com>2013-08-22 03:08:28 -0600
committerDan Allen <dan.j.allen@gmail.com>2013-08-22 03:08:28 -0600
commitc0db091965fa01f10c5c2f5b27e6cde492b91b60 (patch)
treea5262527a213a832d088281eb174196a172c4021
parent2d26e534c05464af7a0703951b4567b2e3945fa3 (diff)
extension improvements
- make Preprocessor operate on Reader instead of just lines - add template_name to Inline; make property writable for all node types - add a finalize_header method to handle preparing to parse body - spec out idea for preserialize processor - update tests
-rw-r--r--lib/asciidoctor/abstract_block.rb11
-rw-r--r--lib/asciidoctor/document.rb25
-rw-r--r--lib/asciidoctor/extensions.rb16
-rw-r--r--lib/asciidoctor/inline.rb6
-rw-r--r--lib/asciidoctor/lexer.rb12
-rw-r--r--lib/asciidoctor/reader.rb16
-rw-r--r--test/extensions_test.rb6
-rw-r--r--test/paths_test.rb12
8 files changed, 62 insertions, 42 deletions
diff --git a/lib/asciidoctor/abstract_block.rb b/lib/asciidoctor/abstract_block.rb
index 7110a4ef..707b64ba 100644
--- a/lib/asciidoctor/abstract_block.rb
+++ b/lib/asciidoctor/abstract_block.rb
@@ -3,8 +3,8 @@ class AbstractBlock < AbstractNode
# Public: The types of content that this block can accomodate
attr_accessor :content_model
- # Public: Get the String name of the render template
- attr_reader :template_name
+ # Public: Get/Set the String name of the render template
+ attr_accessor :template_name
# Public: Get the Array of Asciidoctor::AbstractBlock sub-blocks for this block
attr_reader :blocks
@@ -102,12 +102,7 @@ class AbstractBlock < AbstractNode
# Public: Determine whether this Block contains block content
#
- # returns Whether this Block has block content
- #
- #--
- # TODO we still need another method that answers
- # whether this Block *can* have block content
- # that should be the option 'sectionbody'
+ # Returns A Boolean indicating whether this Block has block content
def blocks?
!@blocks.empty?
end
diff --git a/lib/asciidoctor/document.rb b/lib/asciidoctor/document.rb
index dcbbf69c..ec241ee3 100644
--- a/lib/asciidoctor/document.rb
+++ b/lib/asciidoctor/document.rb
@@ -314,9 +314,10 @@ class Document < AbstractBlock
@extensions = initialize_extensions ? Extensions::Registry.new(self) : nil
@reader = PreprocessorReader.new self, data, Asciidoctor::Reader::Cursor.new(@attributes['docfile'], @base_dir)
- # TODO needs review
if @extensions && @extensions.preprocessors?
- @reader.invoke_preprocessors @extensions.load_preprocessors(self)
+ @extensions.load_preprocessors(self).each do |processor|
+ @reader = processor.process(@reader, @reader.lines) || @reader
+ end
end
else
# don't need to do the extra processing within our own document
@@ -517,6 +518,18 @@ class Document < AbstractBlock
assign_index block
end
end
+
+ # Internal: called after the header has been parsed and before the content
+ # will be parsed.
+ #--
+ # QUESTION should we invoke the Treeprocessors here, passing in a phase?
+ # QUESTION is finalize_header the right name?
+ def finalize_header unrooted_attributes, header_valid = true
+ clear_playback_attributes unrooted_attributes
+ save_attributes
+ unrooted_attributes['invalid-header'] = true unless header_valid
+ unrooted_attributes
+ end
# Internal: Branch the attributes so that the original state can be restored
# at a future time.
@@ -724,6 +737,14 @@ class Document < AbstractBlock
def render(opts = {})
restore_attributes
r = renderer(opts)
+
+ # QUESTION should we add Preserializeprocessors? is it the right name?
+ #if !@parent_document && @extensions && @extensions.preserializeprocessors?
+ # @extensions.load_preserializeprocessors(self).each do |processor|
+ # processor.process r
+ # end
+ #end
+
if doctype == 'inline'
# QUESTION should we warn if @blocks.size > 0 and the first block is not a paragraph?
if !(block = @blocks.first).nil? && block.content_model != :compound
diff --git a/lib/asciidoctor/extensions.rb b/lib/asciidoctor/extensions.rb
index 32250a74..877d2f89 100644
--- a/lib/asciidoctor/extensions.rb
+++ b/lib/asciidoctor/extensions.rb
@@ -245,19 +245,19 @@ module Extensions
# lines and normalizes them. The normalize process strips trailing whitespace
# from each line and leaves behind a line-feed character (i.e., "\n").
#
- # Asciidoctor passes a reference to the resulting lines Array to the process
- # method of an instance of each registered Preprocessor. The Preprocessor
- # modifies the Array as necessary and either returns a reference to the same
- # Array or a reference to a new one.
+ # Asciidoctor passes a reference to the Reader and a copy of the lines Array
+ # to the process method of an instance of each registered Preprocessor. The
+ # Preprocessor modifies the Array as necessary and either returns a reference
+ # to the same Reader or a reference to a new one.
#
# Preprocessors must extend Asciidoctor::Extensions::Preprocessor.
class Preprocessor < Processor
- # Public: Accepts an Array of lines, modifies it as needed, then returns
- # the Array or a reference to a new one.
+ # Public: Accepts the Reader and an Array of lines, modifies them as
+ # needed, then returns the Reader or a reference to a new one.
#
# Each subclass of Preprocessor should override this method.
- def process lines
- lines
+ def process reader, lines
+ reader
end
end
diff --git a/lib/asciidoctor/inline.rb b/lib/asciidoctor/inline.rb
index 1f06f253..508cfd7d 100644
--- a/lib/asciidoctor/inline.rb
+++ b/lib/asciidoctor/inline.rb
@@ -1,6 +1,9 @@
module Asciidoctor
# Public: Methods for managing inline elements in AsciiDoc block
class Inline < AbstractNode
+ # Public: Get/Set the String name of the render template
+ attr_accessor :template_name
+
# Public: Get the text of this inline element
attr_reader :text
@@ -12,6 +15,7 @@ class Inline < AbstractNode
def initialize(parent, context, text = nil, opts = {})
super(parent, context)
+ @template_name = "inline_#{context}"
@text = text
@@ -25,7 +29,7 @@ class Inline < AbstractNode
end
def render
- renderer.render("inline_#{@context}", self).chomp
+ renderer.render(@template_name, self).chomp
end
end
diff --git a/lib/asciidoctor/lexer.rb b/lib/asciidoctor/lexer.rb
index f6d5b159..56dc5b14 100644
--- a/lib/asciidoctor/lexer.rb
+++ b/lib/asciidoctor/lexer.rb
@@ -77,10 +77,7 @@ class Lexer
# special case, block title is not allowed above document title,
# carry attributes over to the document body
if block_attributes.has_key?('title')
- document.clear_playback_attributes block_attributes
- document.save_attributes
- block_attributes['invalid-header'] = true
- return block_attributes
+ return document.finalize_header block_attributes, false
end
# yep, document title logic in AsciiDoc is just insanity
@@ -122,12 +119,9 @@ class Lexer
# parse title and consume name section of manpage document
parse_manpage_header(reader, document) if document.doctype == 'manpage'
- document.clear_playback_attributes block_attributes
- document.save_attributes
-
- # NOTE these are the block-level attributes (not document attributes) that
+ # NOTE block_attributes are the block-level attributes (not document attributes) that
# precede the first line of content (document title, first section or first block)
- block_attributes
+ document.finalize_header block_attributes
end
# Public: Parses the manpage header of the AsciiDoc source read from the Reader
diff --git a/lib/asciidoctor/reader.rb b/lib/asciidoctor/reader.rb
index ef1126ea..31ac3595 100644
--- a/lib/asciidoctor/reader.rb
+++ b/lib/asciidoctor/reader.rb
@@ -65,7 +65,7 @@ class Reader
@unescape_next_line = false
end
- # Protected: Prepare the lines from the provided data
+ # Internal: Prepare the lines from the provided data
#
# This method strips whitespace from the end of every line of
# the source data and appends a LF (i.e., Unix endline). This
@@ -84,7 +84,7 @@ class Reader
data.is_a?(String) ? data.each_line.to_a : data.dup
end
- # Protected: Processes a previously unvisited line
+ # Internal: Processes a previously unvisited line
#
# By default, this method marks the line as processed
# by incrementing the look_ahead counter and returns
@@ -456,14 +456,14 @@ class Reader
result
end
- # Protected: Shift the line off the stack and increment the lineno
+ # Internal: Shift the line off the stack and increment the lineno
def shift
@lineno += 1
@look_ahead -= 1 unless @look_ahead == 0
@lines.shift
end
- # Protected: Restore the line to the stack and decrement the lineno
+ # Internal: Restore the line to the stack and decrement the lineno
def unshift line
@lineno -= 1
@look_ahead += 1
@@ -568,14 +568,6 @@ class PreprocessorReader < Reader
result
end
- # FIXME need to deal with cursor info
- def invoke_preprocessors preprocessors
- preprocessors.each do |processor|
- #@lines = processor.process self, @lines
- @lines = processor.process @lines
- end
- end
-
def process_line line
return line unless @process_lines
diff --git a/test/extensions_test.rb b/test/extensions_test.rb
index b983ca6e..50a1ff92 100644
--- a/test/extensions_test.rb
+++ b/test/extensions_test.rb
@@ -20,11 +20,13 @@ class SampleInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
end
class ScrubHeaderPreprocessor < Asciidoctor::Extensions::Preprocessor
- def process lines
+ def process reader, lines
while !lines.empty? && !lines.first.start_with?('=')
lines.shift
+ reader.advance
end
- lines
+ #lines
+ reader
end
end
diff --git a/test/paths_test.rb b/test/paths_test.rb
index 35e84ec1..acb24602 100644
--- a/test/paths_test.rb
+++ b/test/paths_test.rb
@@ -181,4 +181,16 @@ context 'Path Resolver' do
assert_equal 'part1/chapter1/section1.adoc', @resolver.relative_path(filename, JAIL)
end
end
+
+ context 'Helpers' do
+ test 'rootname should return file name without extension' do
+ assert_equal 'master', Asciidoctor::Helpers.rootname('master.adoc')
+ assert_equal 'docs/master', Asciidoctor::Helpers.rootname('docs/master.adoc')
+ end
+
+ test 'rootname should file name if it has no extension' do
+ assert_equal 'master', Asciidoctor::Helpers.rootname('master')
+ assert_equal 'docs/master', Asciidoctor::Helpers.rootname('docs/master')
+ end
+ end
end