Administrator
|
While playing around with extension points in Asciidoctor, I hacked together these two classes that walk the Asciidoctor document tree. The NodeVisitor simply visits each node, whereas the NodeTransformer allows the node to be removed or replaced. I though these might come in handy while shaving your docs. Enjoy!
require 'asciidoctor'
source_file = ARGV.first
doc = Asciidoctor.load_file(source_file, :safe => :safe, :header_footer => true)
class NodeTransformer def traverse node
if node.is_a? Asciidoctor::AbstractBlock context = node.context dispatch = "visit_#{context}".to_sym
if respond_to? dispatch result = send dispatch, node else
result = visit node end
if result.nil? node.parent.blocks.delete node return elsif result != node index = node.parent.blocks.find_index node node.parent.blocks.delete_at index
node.parent.blocks.insert index, result return end
if node.blocks? node.blocks.each do |child| traverse child end end end end
def visit node node end end
class NodeVisitor def traverse node if node.is_a? Asciidoctor::AbstractBlock context = node.context dispatch = "visit_#{context}".to_sym
if respond_to? dispatch send dispatch, node else visit node end
if node.blocks? node.blocks.each do |child| traverse child end
end end end
def visit node node end end
class SampleNodeTransformer < NodeTransformer def visit_image node # keep node: #node
# delete node:
# nil
# replace node: Asciidoctor::Block.new(node.parent, :paragraph, :source => 'This image has been replaced!') end end
SampleNodeTransformer.new().traverse(doc)
puts doc.render
-Dan p.s. I'm considering adding these two classes into the Asciidoctor Extensions package once I refine them a bit. They will be essential when implementing a Treeprocessor.
|