lib/erbook/document.rb in erbook-7.0.0 vs lib/erbook/document.rb in erbook-7.1.0
- old
+ new
@@ -1,8 +1,8 @@
#--
-# Copyright 2008 Suraj N. Kurapati
-# See the LICENSE file for details.
+# Copyright protects this work.
+# See LICENSE file for details.
#++
require 'yaml'
require 'erbook/template'
require 'digest/sha1'
@@ -39,11 +39,11 @@
# [:unindent]
# If true, all node content is unindented hierarchically.
#
def initialize format_name, input_text, input_file, options = {}
# process format specification
- @format_file = format_name.to_s
+ @format_file = format_name.to_s
File.file? @format_file or
@format_file = File.join(ERBook::FORMATS_DIR, @format_file + '.yaml')
begin
@@ -60,164 +60,167 @@
end
@node_defs = @format['nodes']
# process input document
- begin
- # create sandbox for input evaluation
- template = Template.new(input_file, input_text, options[:unindent])
- sandbox = template.sandbox
+ begin
+ # create sandbox for input evaluation
+ template = Template.new(input_file, input_text, options[:unindent])
+ sandbox = template.sandbox
- @template_vars = {
- :@format => @format,
- :@roots => @roots = [], # root nodes of all trees
- :@nodes => @nodes = [], # all nodes in the forest
- :@nodes_by_type => @nodes_by_type = Hash.new {|h,k| h[k] = [] },
- :@stack => [], # stack for all nodes
- }.each_pair {|k,v| sandbox.instance_variable_set(k, v) }
+ @template_vars = {
+ :@format => @format,
+ :@roots => @roots = [], # root nodes of all trees
+ :@nodes => @nodes = [], # all nodes in the forest
+ :@nodes_by_type => @nodes_by_type = Hash.new {|h,k| h[k] = [] },
+ :@stack => [], # stack for all nodes
+ }.each_pair {|k,v| sandbox.instance_variable_set(k, v) }
- # Handles the method call from a node
- # placeholder in the input document.
- def sandbox.__node_impl__ node_type, *node_args, &node_content
- node = Node.new(
- :type => node_type,
- :defn => @format['nodes'][node_type],
- :args => node_args,
- :children => [],
+ ##
+ # Handles the method call from a node
+ # placeholder in the input document.
+ #
+ def sandbox.__node_impl__ node_type, *node_args, &node_content
+ node = Node.new(
+ :type => node_type,
+ :defn => @format['nodes'][node_type],
+ :args => node_args,
+ :children => [],
- # omit erbook internals from the stack trace
- :trace => caller.reject {|t|
- [$0, ERBook::INSTALL].any? {|f| t.index(f) == 0 }
- }
- )
- @nodes << node
- @nodes_by_type[node.type] << node
+ # omit erbook internals from the stack trace
+ :trace => caller.reject {|t|
+ [$0, ERBook::INSTALL].any? {|f| t.index(f) == 0 }
+ }
+ )
+ @nodes << node
+ @nodes_by_type[node.type] << node
- # calculate occurrence number for this node
- if node.defn['number']
- @count ||= Hash.new {|h,k| h[k] = []}
- node.number = (@count[node.type] << node).length
- end
+ # calculate occurrence number for this node
+ if node.defn['number']
+ @count ||= Hash.new {|h,k| h[k] = []}
+ node.number = (@count[node.type] << node).length
+ end
- # assign node family
- if parent = @stack.last
- parent.children << node
- node.parent = parent
- node.depth = parent.depth
- node.depth += 1 if node.defn['depth']
+ # assign node family
+ if parent = @stack.last
+ parent.children << node
+ node.parent = parent
+ node.depth = parent.depth
+ node.depth += 1 if node.defn['depth']
- # calculate latex-style index number for this node
- if node.defn['index']
- ancestry = @stack.reverse.find {|n| n.defn['index'] }.index
- branches = node.parent.children.select {|n| n.index }
+ # calculate latex-style index number for this node
+ if node.defn['index']
+ ancestry = @stack.reverse.find {|n| n.defn['index'] }.index
+ branches = node.parent.children.select {|n| n.index }
- node.index = [ancestry, branches.length + 1].join('.')
- end
- else
- @roots << node
- node.parent = nil
- node.depth = 0
-
- # calculate latex-style index number for this node
- if node.defn['index']
- branches = @roots.select {|n| n.index }
- node.index = (branches.length + 1).to_s
- end
+ node.index = [ancestry, branches.length + 1].join('.')
end
+ else
+ @roots << node
+ node.parent = nil
+ node.depth = 0
- # assign node content
- if block_given?
- @stack.push node
- node.content = __block_content__(node, &node_content)
- @stack.pop
+ # calculate latex-style index number for this node
+ if node.defn['index']
+ branches = @roots.select {|n| n.index }
+ node.index = (branches.length + 1).to_s
end
-
- @buffer << node
-
- nil
end
- @node_defs.each_key do |type|
- # XXX: using a string because define_method()
- # does not accept a block until Ruby 1.9
- file, line = __FILE__, __LINE__; eval %{
- def sandbox.#{type} *node_args, &node_content
- __node_impl__ #{type.inspect}, *node_args, &node_content
- end
- }, binding, file, line
+ # assign node content
+ if block_given?
+ @stack.push node
+ node.content = __block_content__(node, &node_content)
+ @stack.pop
end
- # evaluate the input & build the document tree
- template.render
- @processed_document = template.buffer
+ @buffer << node
- # chain block-level nodes together for local navigation
- block_nodes = @nodes.reject {|n| n.defn['bypass'] ||
- n.defn['inline'] }
+ nil
+ end
- require 'enumerator'
- block_nodes.each_cons(2) do |a, b|
- a.next_node = b
- b.prev_node = a
- end
+ @node_defs.each_key do |type|
+ # XXX: using a string because define_method()
+ # does not accept a block until Ruby 1.9
+ file, line = __FILE__, __LINE__; eval %{
+ def sandbox.#{type} *node_args, &node_content
+ __node_impl__ #{type.inspect}, *node_args, &node_content
+ end
+ }, binding, file, line
+ end
- # calculate output for all nodes
- actual_output_by_node = {}
+ # evaluate the input & build the document tree
+ template.render
+ @processed_document = template.buffer
- visitor = lambda do |n|
- #
- # allow child nodes to calculate their actual
- # output and to set their identifier as Node#output
- #
- # we do this nodes first because this node's
- # content contains the child nodes' output
- #
- n.children.each {|c| visitor.call c }
+ # chain block-level nodes together for local navigation
+ block_nodes = @nodes.reject do |n|
+ n.defn['bypass'] || n.defn['inline']
+ end
- # calculate the output for this node
- actual_output = Template.new(
- "#{@format_file}:nodes:#{n.type}:output",
- n.defn['output'].to_s.chomp
- ).render_with(@template_vars.merge(:@node => n))
+ require 'enumerator'
+ block_nodes.each_cons(2) do |a, b|
+ a.next_node = b
+ b.prev_node = a
+ end
- # reveal child nodes' actual output in this node's actual output
- n.children.each do |c|
- if c.defn['inline'] && !c.defn['bypass']
- actual_output[c.output] = actual_output_by_node[c]
+ # calculate output for all nodes
+ actual_output_by_node = {}
- else
- # pull block-level node out of paragraph tag added by Maruku
- actual_output.sub! %r/(<p>\s*)?#{Regexp.quote c.output}/ do
- actual_output_by_node[c] + $1.to_s
- end
+ visitor = lambda do |n|
+ #
+ # allow child nodes to calculate their actual
+ # output and to set their identifier as Node#output
+ #
+ # we do this nodes first because this node's
+ # content contains the child nodes' output
+ #
+ n.children.each {|c| visitor.call c }
+
+ # calculate the output for this node
+ actual_output = Template.new(
+ "#{@format_file}:nodes:#{n.type}:output",
+ n.defn['output'].to_s.chomp
+ ).render_with(@template_vars.merge(:@node => n))
+
+ # reveal child nodes' actual output in this node's actual output
+ n.children.each do |c|
+ if c.defn['inline'] && !c.defn['bypass']
+ actual_output[c.output] = actual_output_by_node[c]
+
+ else
+ # pull block-level node out of paragraph tag added by Maruku
+ actual_output.sub! %r/(<p>\s*)?#{Regexp.quote c.output}/ do
+ actual_output_by_node[c] + $1.to_s
end
end
+ end
- actual_output_by_node[n] = actual_output
+ actual_output_by_node[n] = actual_output
- #
- # allow the parent node to calculate its actual
- # output without interference from the output of
- # this node (Node#to_s is aliased to Node#output)
- #
- # this assumes that having this node's string
- # representation be a consecutive sequence of digits
- # will not interfere with the text-to-whatever
- # transformation defined by the format specification
- #
- n.output = Digest::SHA1.digest(n.object_id.to_s).unpack('I*').join
- end
+ #
+ # allow the parent node to calculate its actual
+ # output without interference from the output of
+ # this node (Node#to_s is aliased to Node#output)
+ #
+ # this assumes that having this node's string
+ # representation be a consecutive sequence of digits
+ # will not interfere with the text-to-whatever
+ # transformation defined by the format specification
+ #
+ n.output = Digest::SHA1.digest(n.object_id.to_s).unpack('I*').join
+ end
- @roots.each {|n| visitor.call n }
+ @roots.each {|n| visitor.call n }
- # replace the temporary identifier with each node's actual output
- @nodes.each {|n| n.output = actual_output_by_node[n] }
+ # replace the temporary identifier with each node's actual output
+ @nodes.each {|n| n.output = actual_output_by_node[n] }
- rescue Exception
- puts input_text # so the user can debug line numbers in stack trace
- error "Could not process input document #{input_file.inspect}"
- end
+ rescue Exception
+ puts input_text # so the user can debug line numbers in stack trace
+ error "Could not process input document #{input_file.inspect}"
+ end
end
##
# Returns the output of this document.
#
@@ -230,10 +233,12 @@
class Node < OpenStruct
# deprecated in Ruby 1.8; removed in Ruby 1.9
undef id if respond_to? :id
undef type if respond_to? :type
+ ##
# Returns the output of this node.
+ #
def to_s
defn['silent'] ? '' : output
end
end