Inversion::Parser::

State class

Parse state object class. State objects keep track of where in the parse tree new nodes should be appended, and manages inclusion.

Attributes

include_stack R

The stack of templates that have been loaded for this state; for loop detection.

node_stack R

The stack of containers

options R

The parse options in effect for this parse state

template RW

The template object for this parser state

Public Class Methods

new( template, options={} )

Create a new State object

# File lib/inversion/parser.rb, line 172
def initialize( template, options={} )
        @template      = template
        @options       = options.dup
        @tree          = []
        @node_stack    = [ @tree ]
        @include_stack = []
end

Public Instance Methods

<<( node )

Append operator: add nodes to the correct part of the parse tree.

# File lib/inversion/parser.rb, line 209
def <<( node )
        # self.log.debug "Appending %p" % [ node ]

        node.before_appending( self )
        self.node_stack.last << node

        if node.is_container?
                # Containers get pushed onto the stack so they get appended to
                self.node_stack.push( node )
        else
                # Container nodes' #after_appending gets called in #pop
                node.after_appending( self )
        end

        return self
rescue Inversion::ParseError => err
        raise err, "%s at %s" % [ err.message, node.location ]
end
append_tree( newtree )

Append another Array of nodes onto this state’s node tree.

# File lib/inversion/parser.rb, line 230
def append_tree( newtree )
        newtree.each do |node|
                self.node_stack.last << node
        end
end
clear_nodes()

Clear any parsed nodes from the state, leaving the options and include_stack intact.

# File lib/inversion/parser.rb, line 277
def clear_nodes
        @tree       = []
        @node_stack = [ @tree ]
end
current_node()

Return the node that is currently being appended to, or ‘nil` if there aren’t any opened container nodes.

# File lib/inversion/parser.rb, line 271
def current_node
        return self.node_stack.last
end
initialize_copy( original )

Copy constructor – duplicate inner structures.

# File lib/inversion/parser.rb, line 182
def initialize_copy( original )
        @template      = original.template
        @options       = original.options.dup
        @tree          = @tree.map( &:dup )
        @node_stack    = [ @tree ]
        @include_stack = original.include_stack.dup
end
is_well_formed?()

Check to see if all open tags have been closed.

# File lib/inversion/parser.rb, line 248
def is_well_formed?
        return self.node_stack.length == 1
end
Also aliased as: well_formed?
load_subtemplate( path )

Load a subtemplate from the specified ‘path`, checking for recursive-dependency.

# File lib/inversion/parser.rb, line 284
def load_subtemplate( path )
        if self.include_stack.include?( path )
                stack_desc = ( self.include_stack + [path] ).join( ' --> ' )
                msg = "Recursive load of %p detected: from %s" % [ path, stack_desc ]

                self.log.error( msg )
                raise Inversion::StackError, msg
        end

        # self.log.debug "Include stack is: %p" % [ self.include_stack ]

        substate = self.dup
        substate.clear_nodes
        substate.include_stack.push( path )

        return Inversion::Template.load( path, substate, self.options )
end
pop()

Pop one level off of the node stack and return it.

# File lib/inversion/parser.rb, line 255
def pop
        closed_node = self.node_stack.pop

        # If there's nothing on the node stack, we've popped the top-level
        # Array, which means there wasn't an opening container.
        raise Inversion::ParseError, "unbalanced end: no open tag" if
                self.node_stack.empty?

        closed_node.after_appending( self )

        return closed_node
end
tree()

Returns the tree if it’s well formed.

# File lib/inversion/parser.rb, line 238
def tree
        unless self.is_well_formed?
                raise Inversion::ParseError, "Unclosed container tag: %s, from %s" %
                        [ self.node_stack.last.tagname, self.node_stack.last.location ]
        end
        return @tree
end
well_formed?()
Alias for: is_well_formed?