Inversion::Parser::

State

class
Superclass
Object
Extended With
Loggability

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

anchor
new( template, options={} )

Create a new State object

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

Public Instance Methods

anchor
<<( node )

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

# File lib/inversion/parser.rb, line 210
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
anchor
append_tree( newtree )

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

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

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

# File lib/inversion/parser.rb, line 278
def clear_nodes
        @tree       = []
        @node_stack = [ @tree ]
end
anchor
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 272
def current_node
        return self.node_stack.last
end
anchor
initialize_copy( original )

Copy constructor – duplicate inner structures.

# File lib/inversion/parser.rb, line 183
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
anchor
is_well_formed?()

Check to see if all open tags have been closed.

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

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

# File lib/inversion/parser.rb, line 285
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
anchor
pop()

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

# File lib/inversion/parser.rb, line 256
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
anchor
tree()

Returns the tree if it's well formed.

# File lib/inversion/parser.rb, line 239
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
anchor
well_formed?()
Alias for: is_well_formed?