The base class for Inversion tags that parse the body section of the tag using a Ruby parser.
It provides a tag_pattern declarative method that is used to specify a pattern of tokens to match, and a block for handling tag instances that match the pattern.
class Inversion::Template::MyTag < Inversion::Template::CodeTag # Match a tag that looks like: <?my "string of stuff" ?> tag_pattern 'tstring_beg $(tstring_content) tstring_end' do |tag, match| tag.string = match.string( 1 ) end end
The tokens in the tag_pattern are Ruby token names used by the parser. If you're creating your own tag, you can dump the tokens for a particular snippet using the 'inversion' command-line tool that comes with the gem:
$ inversion tagtokens 'attr.dump! {|thing| thing.length }' ident<"attr"> period<"."> ident<"dump!"> sp<" "> lbrace<"{"> op<"|"> \ ident<"thing"> op<"|"> sp<" "> ident<"thing"> period<"."> \ ident<"length"> sp<" "> rbrace<"}">
:todo: Finish the tag_pattern docs: placeholders, regex limitations, etc.
Declare a token_pattern for tag bodies along with a callback that will be called when a tag matching the pattern is instantiated.
# File lib/inversion/template/codetag.rb, line 95 def self::tag_pattern( token_pattern, &callback ) #:yield: pattern = TokenPattern.compile( token_pattern ) @tag_patterns = [] unless defined?( @tag_patterns ) @tag_patterns << [ pattern, callback ] end
Initialize a new tag that expects Ruby code in its body. Calls the tag's parse_pi_body method with the specified body.
# File lib/inversion/template/codetag.rb, line 108 def initialize( body, linenum=nil, colnum=nil ) # :notnew: super @body = body.strip @identifiers = [] @matched_pattern = self.match_tag_pattern( body ) end
Match the given body against one of the tag's tag patterns, calling the block associated with the first one that matches and returning the matching pattern.
# File lib/inversion/template/codetag.rb, line 140 def match_tag_pattern( body ) self.class.tag_patterns.each do |tp, callback| if match = tp.match( body.strip ) self.log.debug "Matched tag pattern: %p, match is: %p" % [ tp, match ] callback.call( self, match ) return tp end end self.log.error "Failed to match %p with %d patterns." % [ body, self.class.tag_patterns.length ] valid_patterns = self.class.tag_patterns.map( &:first ).map( &:source ).join( "\n ") tokenized_src = Ripper.lex( body ).collect do |tok| self.log.debug " lexed token: #{tok.inspect}" "%s<%s>" % [ tok[1].to_s[3..-1], tok[2] ] end.join(' ') raise Inversion::ParseError, "malformed %s: expected one of:\n %s\ngot:\n %s" % [ self.tagname, valid_patterns, tokenized_src ] end
Generated with the Darkfish Rdoc Generator 2.