Subversion Info

Rev
437
Last Checked In
2008-03-28 00:49:20 (2 weeks ago)
Checked in by
deveiant

Parent

Included Modules

Class Index

Quicksearch

Arrow::Template::Parser

Default parser object class — parses template source into template objects.

Constants

SVNRev
SVN Revision
SVNId
SVN Id
Defaults
Default configuration hash

Attributes

config[R]
The configuration object which contains the parser‘s config.

Public Class Methods

new( config={} ) click to toggle source

Create a new parser using the specified config. The config can contain one or more of the following keys:

:strict_end_tags
Raise an error if the optional name associated with an <?end?> tag doesn‘t match the directive it closes. Defaults to false.
:ignore_unknown_PIs
When this is set to true, any processing instructions found in a template that don‘t parse will be kept as-is in the output. If this is false, unrecognized PIs will raise an error at parse time. Defaults to true.

     # File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 264
264:     def initialize( config={} )
265:         @config = Defaults.merge( config, &Arrow::HashMergeFunction )
266:     end

Public Instance Methods

initialize_copy( original ) click to toggle source

Initialize a duplicate of the original parser.

     # File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 270
270:     def initialize_copy( original )
271:         super
272:         @config = original.config.dup
273:     end
parse( string, template, initialData={} ) click to toggle source

Parse and return a template syntax tree from the given string.

     # File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 285
285:     def parse( string, template, initialData={} )
286: 
287:         # Create a new parse state and build the parse tree with it.
288:         begin
289:             state = State.new( string, template, initialData )
290:             syntax_tree = self.scan_for_nodes( state )
291:         
292:         rescue Arrow::TemplateError => err
293:             Kernel.raise( err ) unless defined? state
294:             state.scanner.unscan if state.scanner.matched? #<- segfaults
295:             
296:             # Get the linecount and chunk of erroring content
297:             errorContent = get_parse_context( state.scanner )
298:             
299:             msg = err.message.split( /:/ ).uniq.join( ':' ) +
300:                 %{ at line %d of %s: %s...} %
301:                 [ state.line, template._file, errorContent ]
302:             Kernel.raise( err.class, msg )
303:         end
304: 
305:         return syntax_tree
306:     end
scan_directive( state, context=nil ) click to toggle source

Given the specified parse state which is pointing past the opening of a directive tag, parse the directive.

     # File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 356
356:     def scan_directive( state, context=nil )
357:         scanner = state.scanner
358: 
359:         # Set the patterns in the parse state to compliment the
360:         # opening tag.
361:         state.set_tag_patterns( scanner.matched )
362:         tag_begin = state.line
363: 
364:         # Scan for the directive name; if no valid name can be
365:         # found, handle an unknown PI/directive.
366:         scanner.skip( WHITESPACE )
367:         unless (( tag = scanner.scan( IDENTIFIER ) ))
368:             #self.log.debug "No identifier at '%s...'" % scanner.rest[0,20]
369: 
370:             # If the tag_open is <?, then this is a PI that we don't
371:             # grok. The reaction to this is configurable, so decide what to
372:             # do.
373:             if state.tag_open == '<?'
374:                 return handle_unknown_pi( state )
375: 
376:             # ...otherwise, it's just a malformed non-PI tag, which
377:             # is always an error.
378:             else
379:                 raise Arrow::ParseError, "malformed directive name"
380:             end
381:         end
382: 
383:         # If it's anything but an 'end' tag, create a directive object.
384:         unless tag == 'end'
385:             begin
386:                 node = Arrow::Template::Directive.create( tag, self, state )
387:             rescue ::FactoryError => err
388:                 return self.handle_unknown_pi( state, tag )
389:             end
390: 
391:         # If it's an 'end', 
392:         else
393:             #self.log.debug "Found end tag."
394: 
395:             # If this scan is occuring in a recursive parse, make sure the
396:             # 'end' is closing the correct thing and break out of the node
397:             # search. Note that the trailing '?>' is left in the scanner to
398:             # match at the end of the loop that opened this recursion.
399:             if context
400:                 scanner.skip( WHITESPACE )
401:                 closed_tag = scanner.scan( IDENTIFIER )
402:                 #self.log.debug "End found for #{closed_tag}"
403: 
404:                 # If strict end tags is turned on, check to be sure we
405:                 # got the correct 'end'.
406:                 if @config[:strict_end_tags]
407:                     raise Arrow::ParseError,
408:                         "missing or malformed closing tag name" if
409:                         closed_tag.nil?
410:                     raise Arrow::ParseError,
411:                         "mismatched closing tag name '#{closed_tag}'" unless
412:                         closed_tag.downcase == context.downcase
413:                 end
414: 
415:                 # Jump out of the loop in #scan_for_nodes...
416:                 throw :endscan 
417:             else
418:                 raise Arrow::ParseError, "dangling end"
419:             end
420:         end
421: 
422:         # Skip to the end of the tag
423:         self.scan_for_tag_ending( state ) or
424:             raise Arrow::ParseError,
425:                 "malformed tag starting at line %d: no closing tag "\
426:                 "delimiters %p found" % [ tag_begin, state.tag_close ]
427: 
428:         return node
429:     end
scan_for_arglist( state, skip_whitespace=true ) click to toggle source

Given the specified state (an Arrow::Template::Parser::State object), scan for and return two Arrays of identifiers. The first is the list of parsed arguments as they appeared in the source, and the second is the same list with all non-word characters removed. Given an arglist like:

  foo, bar=baz, *bim, &boozle

the returned arrays will contain:

  ["foo", "bar=baz", "*bim", "&boozle"]

and

  ["foo", "bar", "bim", "boozle"]

respectively.

     # File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 511
511:     def scan_for_arglist( state, skip_whitespace=true )
512:         scanner = state.scanner
513:         #self.log.debug "Scanning for arglist at %p" %
514:         # scanner.rest[0,20]
515: 
516:         args = []
517:         pureargs = []
518:         scanner.skip( WHITESPACE ) if skip_whitespace
519:         while (( rval = scanner.scan(ARGUMENT) ))
520:             args << rval
521:             pureargs << rval.gsub( /\W+/, '' )
522:             scanner.skip( WHITESPACE )
523:             if (( rval = scanner.scan(ARGDEFAULT) ))
524:                 args.last << rval
525:             end
526:             break unless scanner.skip( WHITESPACE + COMMA + WHITESPACE )
527:         end
528: 
529:         return nil if args.empty?
530: 
531:         #self.log.debug "Found args: %p, pureargs: %p" %
532:         # [ args, pureargs ]
533:         return args, pureargs
534:     end
scan_for_identifier( state, skip_whitespace=true ) click to toggle source

Given the specified state (an Arrow::Template::Parser::State object), scan for and return an indentifier. If skip_whitespace is true, any leading whitespace characters will be skipped. Returns nil if no identifier is found.

     # File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 436
436:     def scan_for_identifier( state, skip_whitespace=true )
437:         #self.log.debug "Scanning for identifier at %p" %
438:         # state.scanner.rest[0,20]
439: 
440:         state.scanner.skip( WHITESPACE ) if skip_whitespace
441:         rval = state.scanner.scan( IDENTIFIER ) or return nil
442: 
443:         #self.log.debug "Found identifier %p" % rval
444:         return rval
445:     end
scan_for_methodchain( state ) click to toggle source

Given the specified state (an Arrow::Template::Parser::State object), scan for and return a methodchain. Returns nil if no methodchain is found.

     # File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 469
469:     def scan_for_methodchain( state )
470:         scanner = state.scanner
471:         #self.log.debug "Scanning for methodchain at %p" %
472:         # scanner.rest[0,20]
473: 
474:         rval = scanner.scan( INFIX ) || ''
475:         rval << (scanner.scan( WHITESPACE ) || '')
476:         rval << (scanner.scan( state.tag_middle ) || '')
477: 
478:         #self.log.debug "Found methodchain %p" % rval
479:         return rval
480:     end
scan_for_nodes( state, context=nil, node=nil ) click to toggle source

Use the specified state (a StringScanner object) to scan for directive and plain-text nodes. The context argument, if set, indicates a recursive call for the directive named. The node will be used as the branch node in the parse state.

     # File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 313
313:     def scan_for_nodes( state, context=nil, node=nil )
314:         return state.branch( node ) do
315:             scanner = state.scanner
316: 
317:             # Scan until the scanner reaches the end of its string. Early exits
318:             # 'break' of this loop.
319:             catch( :endscan ) {
320:                 until scanner.eos?
321:                     startpos = scanner.pos
322:                     #self.log.debug %{Scanning from %d:%p} %
323:                     #  [ scanner.pos, scanner.rest[0,20] + '..' ]
324:                 
325:                     # Scan for the next directive. When the scanner reaches
326:                     # the end of the parsed string, just append any plain
327:                     # text that's left and stop scanning.
328:                     if scanner.skip_until( TAGOPEN )
329: 
330:                         # Add the literal String node leading up to the tag
331:                         # as a text node :FIXME: Have to do it this way
332:                         # because StringScanner#pre_match does weird crap if
333:                         # skip_until skips only one or no character/s.
334:                         if ( scanner.pos - startpos > scanner.matched.length )
335:                             offset = scanner.pos - scanner.matched.length - 1
336:                             state << Arrow::Template::TextNode.
337:                                 new( scanner.string[startpos..offset] )
338:                             #self.log.debug "Added text node %p" %
339:                             #    scanner.string[startpos..offset]
340:                         end
341: 
342:                         # Now scan the directive that was found
343:                         state << self.scan_directive( state, context )
344:                     else
345:                         state << Arrow::Template::TextNode.new( scanner.rest )
346:                         scanner.terminate
347:                     end
348:                 end
349:             }
350:         end
351:     end
scan_for_pathname( state, skip_whitespace=true ) click to toggle source

Given the specified state (an Arrow::Template::Parser::State object), scan for and return a valid-looking file pathname.

     # File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 539
539:     def scan_for_pathname( state, skip_whitespace=true )
540:         scanner = state.scanner
541:         #self.log.debug "Scanning for file path at %p" %
542:         # scanner.rest[0,20]
543: 
544:         scanner.skip( WHITESPACE ) if skip_whitespace
545:         rval = scanner.scan( PATHNAME ) or
546:             return nil
547: 
548:         #self.log.debug "Found path: %p" % rval
549:         return rval
550:     end
scan_for_quoted_string( state, skip_whitespace=true ) click to toggle source

Given the specified state (an Arrow::Template::Parser::State object), scan for and return a quoted string, including the quotes. If skip_whitespace is true, any leading whitespace characters will be skipped. Returns nil if no quoted string is found.

     # File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 453
453:     def scan_for_quoted_string( state, skip_whitespace=true )
454:         #self.log.debug "Scanning for quoted string at %p" %
455:         # state.scanner.rest[0,20]
456: 
457:         state.scanner.skip( WHITESPACE ) if skip_whitespace
458: 
459:         rval = state.scanner.scan( QUOTEDSTRING ) or return nil
460: 
461:         #self.log.debug "Found quoted string %p" % rval
462:         return rval
463:     end
scan_for_tag_ending( state, skip_whitespace=true ) click to toggle source

Given the specified state (an Arrow::Template::Parser::State object), scan for and return the current tag ending. Returns nil if no tag ending is found.

     # File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 486
486:     def scan_for_tag_ending( state, skip_whitespace=true )
487:         scanner = state.scanner
488:         #self.log.debug "Scanning for tag ending at %p" %
489:         # scanner.rest[0,20]
490: 
491:         scanner.skip( WHITESPACE ) if skip_whitespace
492:         rval = scanner.scan( state.tag_close ) or
493:             return nil
494: 
495:         #self.log.debug "Found tag ending %p" % rval
496:         return rval
497:     end

Protected Instance Methods

get_parse_context( scanner ) click to toggle source

Return a string showing the given scanner‘s context in the string being parsed.

     # File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 578
578:     def get_parse_context( scanner )
579:         str = scanner.string
580:         
581:         pre = str[ scanner.pos < 40 ? 0 : scanner.pos - 40, 39 ]
582:         post = scanner.rest[ 0, 40 ]
583:         
584:         return "#{pre}[*** ERROR ***]#{post}"
585:     end
handle_unknown_pi( state, tag="" ) click to toggle source

Handle an unknown ProcessingInstruction.

     # File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 559
559:     def handle_unknown_pi( state, tag="" )
560:         
561:         # If the configuration doesn't say to ignore unknown PIs or it's an
562:         # [?alternate-synax?] directive, raise an error.
563:         if state.tag_open == '[?' || !@config[:ignore_unknown_PIs]
564:             raise Arrow::ParseError, "unknown directive"
565:         end
566: 
567:         remainder = state.scanner.scan( %r{(?:[^?]|\?(?!>))*\?>} ) or
568:             raise Arrow::ParseError, "failed to skip unknown PI"
569: 
570:         pi = state.tag_open + tag + remainder
571:         self.log.info( "Ignoring unknown PI (to = #{state.tag_open.inspect}) '#{pi}'" )
572:         return Arrow::Template::TextNode.new( pi )
573:     end

secsequence

--- SEC00160

seccomment

--- ""

classlist

--- |
Module <a href="Parser/Patterns.html" class="link">Arrow::Template::Parser::Patterns</a><br />
Class <a href="Parser/State.html" class="link">Arrow::Template::Parser::State</a><br />

attributes

--- 
- name: config
  rw: R
  a_desc: |+
    
    The configuration object which contains the parser&#8216;s config.
    

method_list

--- 
- methods: 
  - visibility: public
    aref: M000149
    name: new
    sourcecode: "     <span class=\"ruby-comment cmt\"># File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 264</span>\n\
      264:     <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">initialize</span>( <span class=\"ruby-identifier\">config</span>={} )\n\
      265:         <span class=\"ruby-ivar\">@config</span> = <span class=\"ruby-constant\">Defaults</span>.<span class=\"ruby-identifier\">merge</span>( <span class=\"ruby-identifier\">config</span>, <span class=\"ruby-operator\">&amp;</span><span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">HashMergeFunction</span> )\n\
      266:     <span class=\"ruby-keyword kw\">end</span>"
    m_desc: |-
      <p>
      Create a <a href="Parser.html#M000149">new</a> parser using the specified
      <tt>config</tt>. The <tt>config</tt> can contain one or more of the
      following keys:
      </p>
      <dl>
      <dt><b>:strict_end_tags</b></dt><dd>Raise an error if the optional name associated with an &lt;?end?&gt; tag
      doesn&#8216;t match the directive it closes. Defaults to <tt>false</tt>.
      
      </dd>
      <dt><b>:ignore_unknown_PIs</b></dt><dd>When this is set to <tt>true</tt>, any processing instructions found in a
      template that don&#8216;t <a href="Parser.html#M000151">parse</a> will be
      kept as-is in the output. If this is <tt>false</tt>, unrecognized PIs will
      raise an error at <a href="Parser.html#M000151">parse</a> time. Defaults to
      <tt>true</tt>.
      
      </dd>
      </dl>
    params: ( config={} )
  category: Class
  type: Public
- methods: 
  - visibility: public
    aref: M000150
    name: initialize_copy
    sourcecode: "     <span class=\"ruby-comment cmt\"># File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 270</span>\n\
      270:     <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">initialize_copy</span>( <span class=\"ruby-identifier\">original</span> )\n\
      271:         <span class=\"ruby-keyword kw\">super</span>\n\
      272:         <span class=\"ruby-ivar\">@config</span> = <span class=\"ruby-identifier\">original</span>.<span class=\"ruby-identifier\">config</span>.<span class=\"ruby-identifier\">dup</span>\n\
      273:     <span class=\"ruby-keyword kw\">end</span>"
    m_desc: |-
      <p>
      Initialize a duplicate of the <tt>original</tt> parser.
      </p>
    params: ( original )
  - visibility: public
    aref: M000151
    name: parse
    sourcecode: "     <span class=\"ruby-comment cmt\"># File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 285</span>\n\
      285:     <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">parse</span>( <span class=\"ruby-identifier\">string</span>, <span class=\"ruby-identifier\">template</span>, <span class=\"ruby-identifier\">initialData</span>={} )\n\
      286: \n\
      287:         <span class=\"ruby-comment cmt\"># Create a new parse state and build the parse tree with it.</span>\n\
      288:         <span class=\"ruby-keyword kw\">begin</span>\n\
      289:             <span class=\"ruby-identifier\">state</span> = <span class=\"ruby-constant\">State</span>.<span class=\"ruby-identifier\">new</span>( <span class=\"ruby-identifier\">string</span>, <span class=\"ruby-identifier\">template</span>, <span class=\"ruby-identifier\">initialData</span> )\n\
      290:             <span class=\"ruby-identifier\">syntax_tree</span> = <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">scan_for_nodes</span>( <span class=\"ruby-identifier\">state</span> )\n\
      291:         \n\
      292:         <span class=\"ruby-keyword kw\">rescue</span> <span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">TemplateError</span> =<span class=\"ruby-operator\">&gt;</span> <span class=\"ruby-identifier\">err</span>\n\
      293:             <span class=\"ruby-constant\">Kernel</span>.<span class=\"ruby-identifier\">raise</span>( <span class=\"ruby-identifier\">err</span> ) <span class=\"ruby-keyword kw\">unless</span> <span class=\"ruby-keyword kw\">defined?</span> <span class=\"ruby-identifier\">state</span>\n\
      294:             <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">unscan</span> <span class=\"ruby-keyword kw\">if</span> <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">matched?</span> <span class=\"ruby-comment cmt\">#&lt;- segfaults</span>\n\
      295:             \n\
      296:             <span class=\"ruby-comment cmt\"># Get the linecount and chunk of erroring content</span>\n\
      297:             <span class=\"ruby-identifier\">errorContent</span> = <span class=\"ruby-identifier\">get_parse_context</span>( <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">scanner</span> )\n\
      298:             \n\
      299:             <span class=\"ruby-identifier\">msg</span> = <span class=\"ruby-identifier\">err</span>.<span class=\"ruby-identifier\">message</span>.<span class=\"ruby-identifier\">split</span>( <span class=\"ruby-regexp re\">/:/</span> ).<span class=\"ruby-identifier\">uniq</span>.<span class=\"ruby-identifier\">join</span>( <span class=\"ruby-value str\">':'</span> ) <span class=\"ruby-operator\">+</span>\n\
      300:                 <span class=\"ruby-value str\">%{ at line %d of %s: %s...}</span> <span class=\"ruby-operator\">%</span>\n\
      301:                 [ <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">line</span>, <span class=\"ruby-identifier\">template</span>.<span class=\"ruby-identifier\">_file</span>, <span class=\"ruby-identifier\">errorContent</span> ]\n\
      302:             <span class=\"ruby-constant\">Kernel</span>.<span class=\"ruby-identifier\">raise</span>( <span class=\"ruby-identifier\">err</span>.<span class=\"ruby-identifier\">class</span>, <span class=\"ruby-identifier\">msg</span> )\n\
      303:         <span class=\"ruby-keyword kw\">end</span>\n\
      304: \n\
      305:         <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-identifier\">syntax_tree</span>\n\
      306:     <span class=\"ruby-keyword kw\">end</span>"
    m_desc: |-
      <p>
      Parse and return a template syntax tree from the given <tt>string</tt>.
      </p>
    params: ( string, template, initialData={} )
  - visibility: public
    aref: M000153
    name: scan_directive
    sourcecode: "     <span class=\"ruby-comment cmt\"># File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 356</span>\n\
      356:     <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">scan_directive</span>( <span class=\"ruby-identifier\">state</span>, <span class=\"ruby-identifier\">context</span>=<span class=\"ruby-keyword kw\">nil</span> )\n\
      357:         <span class=\"ruby-identifier\">scanner</span> = <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">scanner</span>\n\
      358: \n\
      359:         <span class=\"ruby-comment cmt\"># Set the patterns in the parse state to compliment the</span>\n\
      360:         <span class=\"ruby-comment cmt\"># opening tag.</span>\n\
      361:         <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">set_tag_patterns</span>( <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">matched</span> )\n\
      362:         <span class=\"ruby-identifier\">tag_begin</span> = <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">line</span>\n\
      363: \n\
      364:         <span class=\"ruby-comment cmt\"># Scan for the directive name; if no valid name can be</span>\n\
      365:         <span class=\"ruby-comment cmt\"># found, handle an unknown PI/directive.</span>\n\
      366:         <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">skip</span>( <span class=\"ruby-constant\">WHITESPACE</span> )\n\
      367:         <span class=\"ruby-keyword kw\">unless</span> (( <span class=\"ruby-identifier\">tag</span> = <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">scan</span>( <span class=\"ruby-constant\">IDENTIFIER</span> ) ))\n\
      368:             <span class=\"ruby-comment cmt\">#self.log.debug &quot;No identifier at '%s...'&quot; % scanner.rest[0,20]</span>\n\
      369: \n\
      370:             <span class=\"ruby-comment cmt\"># If the tag_open is &lt;?, then this is a PI that we don't</span>\n\
      371:             <span class=\"ruby-comment cmt\"># grok. The reaction to this is configurable, so decide what to</span>\n\
      372:             <span class=\"ruby-comment cmt\"># do.</span>\n\
      373:             <span class=\"ruby-keyword kw\">if</span> <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">tag_open</span> <span class=\"ruby-operator\">==</span> <span class=\"ruby-value str\">'&lt;?'</span>\n\
      374:                 <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-identifier\">handle_unknown_pi</span>( <span class=\"ruby-identifier\">state</span> )\n\
      375: \n\
      376:             <span class=\"ruby-comment cmt\"># ...otherwise, it's just a malformed non-PI tag, which</span>\n\
      377:             <span class=\"ruby-comment cmt\"># is always an error.</span>\n\
      378:             <span class=\"ruby-keyword kw\">else</span>\n\
      379:                 <span class=\"ruby-identifier\">raise</span> <span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">ParseError</span>, <span class=\"ruby-value str\">&quot;malformed directive name&quot;</span>\n\
      380:             <span class=\"ruby-keyword kw\">end</span>\n\
      381:         <span class=\"ruby-keyword kw\">end</span>\n\
      382: \n\
      383:         <span class=\"ruby-comment cmt\"># If it's anything but an 'end' tag, create a directive object.</span>\n\
      384:         <span class=\"ruby-keyword kw\">unless</span> <span class=\"ruby-identifier\">tag</span> <span class=\"ruby-operator\">==</span> <span class=\"ruby-value str\">'end'</span>\n\
      385:             <span class=\"ruby-keyword kw\">begin</span>\n\
      386:                 <span class=\"ruby-identifier\">node</span> = <span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">Template</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">Directive</span>.<span class=\"ruby-identifier\">create</span>( <span class=\"ruby-identifier\">tag</span>, <span class=\"ruby-keyword kw\">self</span>, <span class=\"ruby-identifier\">state</span> )\n\
      387:             <span class=\"ruby-keyword kw\">rescue</span> <span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">FactoryError</span> =<span class=\"ruby-operator\">&gt;</span> <span class=\"ruby-identifier\">err</span>\n\
      388:                 <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">handle_unknown_pi</span>( <span class=\"ruby-identifier\">state</span>, <span class=\"ruby-identifier\">tag</span> )\n\
      389:             <span class=\"ruby-keyword kw\">end</span>\n\
      390: \n\
      391:         <span class=\"ruby-comment cmt\"># If it's an 'end', </span>\n\
      392:         <span class=\"ruby-keyword kw\">else</span>\n\
      393:             <span class=\"ruby-comment cmt\">#self.log.debug &quot;Found end tag.&quot;</span>\n\
      394: \n\
      395:             <span class=\"ruby-comment cmt\"># If this scan is occuring in a recursive parse, make sure the</span>\n\
      396:             <span class=\"ruby-comment cmt\"># 'end' is closing the correct thing and break out of the node</span>\n\
      397:             <span class=\"ruby-comment cmt\"># search. Note that the trailing '?&gt;' is left in the scanner to</span>\n\
      398:             <span class=\"ruby-comment cmt\"># match at the end of the loop that opened this recursion.</span>\n\
      399:             <span class=\"ruby-keyword kw\">if</span> <span class=\"ruby-identifier\">context</span>\n\
      400:                 <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">skip</span>( <span class=\"ruby-constant\">WHITESPACE</span> )\n\
      401:                 <span class=\"ruby-identifier\">closed_tag</span> = <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">scan</span>( <span class=\"ruby-constant\">IDENTIFIER</span> )\n\
      402:                 <span class=\"ruby-comment cmt\">#self.log.debug &quot;End found for #{closed_tag}&quot;</span>\n\
      403: \n\
      404:                 <span class=\"ruby-comment cmt\"># If strict end tags is turned on, check to be sure we</span>\n\
      405:                 <span class=\"ruby-comment cmt\"># got the correct 'end'.</span>\n\
      406:                 <span class=\"ruby-keyword kw\">if</span> <span class=\"ruby-ivar\">@config</span>[<span class=\"ruby-identifier\">:strict_end_tags</span>]\n\
      407:                     <span class=\"ruby-identifier\">raise</span> <span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">ParseError</span>,\n\
      408:                         <span class=\"ruby-value str\">&quot;missing or malformed closing tag name&quot;</span> <span class=\"ruby-keyword kw\">if</span>\n\
      409:                         <span class=\"ruby-identifier\">closed_tag</span>.<span class=\"ruby-identifier\">nil?</span>\n\
      410:                     <span class=\"ruby-identifier\">raise</span> <span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">ParseError</span>,\n\
      411:                         <span class=\"ruby-node\">&quot;mismatched closing tag name '#{closed_tag}'&quot;</span> <span class=\"ruby-keyword kw\">unless</span>\n\
      412:                         <span class=\"ruby-identifier\">closed_tag</span>.<span class=\"ruby-identifier\">downcase</span> <span class=\"ruby-operator\">==</span> <span class=\"ruby-identifier\">context</span>.<span class=\"ruby-identifier\">downcase</span>\n\
      413:                 <span class=\"ruby-keyword kw\">end</span>\n\
      414: \n\
      415:                 <span class=\"ruby-comment cmt\"># Jump out of the loop in #scan_for_nodes...</span>\n\
      416:                 <span class=\"ruby-identifier\">throw</span> <span class=\"ruby-identifier\">:endscan</span> \n\
      417:             <span class=\"ruby-keyword kw\">else</span>\n\
      418:                 <span class=\"ruby-identifier\">raise</span> <span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">ParseError</span>, <span class=\"ruby-value str\">&quot;dangling end&quot;</span>\n\
      419:             <span class=\"ruby-keyword kw\">end</span>\n\
      420:         <span class=\"ruby-keyword kw\">end</span>\n\
      421: \n\
      422:         <span class=\"ruby-comment cmt\"># Skip to the end of the tag</span>\n\
      423:         <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">scan_for_tag_ending</span>( <span class=\"ruby-identifier\">state</span> ) <span class=\"ruby-keyword kw\">or</span>\n\
      424:             <span class=\"ruby-identifier\">raise</span> <span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">ParseError</span>,\n\
      425:                 <span class=\"ruby-value str\">&quot;malformed tag starting at line %d: no closing tag &quot;</span>\\\n\
      426:                 <span class=\"ruby-value str\">&quot;delimiters %p found&quot;</span> <span class=\"ruby-operator\">%</span> [ <span class=\"ruby-identifier\">tag_begin</span>, <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">tag_close</span> ]\n\
      427: \n\
      428:         <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-identifier\">node</span>\n\
      429:     <span class=\"ruby-keyword kw\">end</span>"
    m_desc: |-
      <p>
      Given the specified <a href="Parser.html#M000151">parse</a> <tt>state</tt>
      which is pointing past the opening of a directive tag, <a
      href="Parser.html#M000151">parse</a> the directive.
      </p>
    params: ( state, context=nil )
  - visibility: public
    aref: M000158
    name: scan_for_arglist
    sourcecode: "     <span class=\"ruby-comment cmt\"># File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 511</span>\n\
      511:     <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">scan_for_arglist</span>( <span class=\"ruby-identifier\">state</span>, <span class=\"ruby-identifier\">skip_whitespace</span>=<span class=\"ruby-keyword kw\">true</span> )\n\
      512:         <span class=\"ruby-identifier\">scanner</span> = <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">scanner</span>\n\
      513:         <span class=\"ruby-comment cmt\">#self.log.debug &quot;Scanning for arglist at %p&quot; %</span>\n\
      514:         <span class=\"ruby-comment cmt\"># scanner.rest[0,20]</span>\n\
      515: \n\
      516:         <span class=\"ruby-identifier\">args</span> = []\n\
      517:         <span class=\"ruby-identifier\">pureargs</span> = []\n\
      518:         <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">skip</span>( <span class=\"ruby-constant\">WHITESPACE</span> ) <span class=\"ruby-keyword kw\">if</span> <span class=\"ruby-identifier\">skip_whitespace</span>\n\
      519:         <span class=\"ruby-keyword kw\">while</span> (( <span class=\"ruby-identifier\">rval</span> = <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">scan</span>(<span class=\"ruby-constant\">ARGUMENT</span>) ))\n\
      520:             <span class=\"ruby-identifier\">args</span> <span class=\"ruby-operator\">&lt;&lt;</span> <span class=\"ruby-identifier\">rval</span>\n\
      521:             <span class=\"ruby-identifier\">pureargs</span> <span class=\"ruby-operator\">&lt;&lt;</span> <span class=\"ruby-identifier\">rval</span>.<span class=\"ruby-identifier\">gsub</span>( <span class=\"ruby-regexp re\">/\\W+/</span>, <span class=\"ruby-value str\">''</span> )\n\
      522:             <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">skip</span>( <span class=\"ruby-constant\">WHITESPACE</span> )\n\
      523:             <span class=\"ruby-keyword kw\">if</span> (( <span class=\"ruby-identifier\">rval</span> = <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">scan</span>(<span class=\"ruby-constant\">ARGDEFAULT</span>) ))\n\
      524:                 <span class=\"ruby-identifier\">args</span>.<span class=\"ruby-identifier\">last</span> <span class=\"ruby-operator\">&lt;&lt;</span> <span class=\"ruby-identifier\">rval</span>\n\
      525:             <span class=\"ruby-keyword kw\">end</span>\n\
      526:             <span class=\"ruby-keyword kw\">break</span> <span class=\"ruby-keyword kw\">unless</span> <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">skip</span>( <span class=\"ruby-constant\">WHITESPACE</span> <span class=\"ruby-operator\">+</span> <span class=\"ruby-constant\">COMMA</span> <span class=\"ruby-operator\">+</span> <span class=\"ruby-constant\">WHITESPACE</span> )\n\
      527:         <span class=\"ruby-keyword kw\">end</span>\n\
      528: \n\
      529:         <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-keyword kw\">nil</span> <span class=\"ruby-keyword kw\">if</span> <span class=\"ruby-identifier\">args</span>.<span class=\"ruby-identifier\">empty?</span>\n\
      530: \n\
      531:         <span class=\"ruby-comment cmt\">#self.log.debug &quot;Found args: %p, pureargs: %p&quot; %</span>\n\
      532:         <span class=\"ruby-comment cmt\"># [ args, pureargs ]</span>\n\
      533:         <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-identifier\">args</span>, <span class=\"ruby-identifier\">pureargs</span>\n\
      534:     <span class=\"ruby-keyword kw\">end</span>"
    m_desc: |-
      <p>
      Given the specified <tt>state</tt> (an <a
      href="Parser/State.html">Arrow::Template::Parser::State</a> object), scan
      for and return two Arrays of identifiers. The first is the list of parsed
      arguments as they appeared in the source, and the second is the same list
      with all non-word characters removed. Given an arglist like:
      </p>
      <pre>
        foo, bar=baz, *bim, &amp;boozle
      </pre>
      <p>
      the returned arrays will contain:
      </p>
      <pre>
        [&quot;foo&quot;, &quot;bar=baz&quot;, &quot;*bim&quot;, &quot;&amp;boozle&quot;]
      </pre>
      <p>
      and
      </p>
      <pre>
        [&quot;foo&quot;, &quot;bar&quot;, &quot;bim&quot;, &quot;boozle&quot;]
      </pre>
      <p>
      respectively.
      </p>
    params: ( state, skip_whitespace=true )
  - visibility: public
    aref: M000154
    name: scan_for_identifier
    sourcecode: "     <span class=\"ruby-comment cmt\"># File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 436</span>\n\
      436:     <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">scan_for_identifier</span>( <span class=\"ruby-identifier\">state</span>, <span class=\"ruby-identifier\">skip_whitespace</span>=<span class=\"ruby-keyword kw\">true</span> )\n\
      437:         <span class=\"ruby-comment cmt\">#self.log.debug &quot;Scanning for identifier at %p&quot; %</span>\n\
      438:         <span class=\"ruby-comment cmt\"># state.scanner.rest[0,20]</span>\n\
      439: \n\
      440:         <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">skip</span>( <span class=\"ruby-constant\">WHITESPACE</span> ) <span class=\"ruby-keyword kw\">if</span> <span class=\"ruby-identifier\">skip_whitespace</span>\n\
      441:         <span class=\"ruby-identifier\">rval</span> = <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">scan</span>( <span class=\"ruby-constant\">IDENTIFIER</span> ) <span class=\"ruby-keyword kw\">or</span> <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-keyword kw\">nil</span>\n\
      442: \n\
      443:         <span class=\"ruby-comment cmt\">#self.log.debug &quot;Found identifier %p&quot; % rval</span>\n\
      444:         <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-identifier\">rval</span>\n\
      445:     <span class=\"ruby-keyword kw\">end</span>"
    m_desc: |-
      <p>
      Given the specified <tt>state</tt> (an <a
      href="Parser/State.html">Arrow::Template::Parser::State</a> object), scan
      for and return an indentifier. If <tt>skip_whitespace</tt> is
      <tt>true</tt>, any leading whitespace characters will be skipped. Returns
      <tt>nil</tt> if no identifier is found.
      </p>
    params: ( state, skip_whitespace=true )
  - visibility: public
    aref: M000156
    name: scan_for_methodchain
    sourcecode: "     <span class=\"ruby-comment cmt\"># File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 469</span>\n\
      469:     <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">scan_for_methodchain</span>( <span class=\"ruby-identifier\">state</span> )\n\
      470:         <span class=\"ruby-identifier\">scanner</span> = <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">scanner</span>\n\
      471:         <span class=\"ruby-comment cmt\">#self.log.debug &quot;Scanning for methodchain at %p&quot; %</span>\n\
      472:         <span class=\"ruby-comment cmt\"># scanner.rest[0,20]</span>\n\
      473: \n\
      474:         <span class=\"ruby-identifier\">rval</span> = <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">scan</span>( <span class=\"ruby-constant\">INFIX</span> ) <span class=\"ruby-operator\">||</span> <span class=\"ruby-value str\">''</span>\n\
      475:         <span class=\"ruby-identifier\">rval</span> <span class=\"ruby-operator\">&lt;&lt;</span> (<span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">scan</span>( <span class=\"ruby-constant\">WHITESPACE</span> ) <span class=\"ruby-operator\">||</span> <span class=\"ruby-value str\">''</span>)\n\
      476:         <span class=\"ruby-identifier\">rval</span> <span class=\"ruby-operator\">&lt;&lt;</span> (<span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">scan</span>( <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">tag_middle</span> ) <span class=\"ruby-operator\">||</span> <span class=\"ruby-value str\">''</span>)\n\
      477: \n\
      478:         <span class=\"ruby-comment cmt\">#self.log.debug &quot;Found methodchain %p&quot; % rval</span>\n\
      479:         <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-identifier\">rval</span>\n\
      480:     <span class=\"ruby-keyword kw\">end</span>"
    m_desc: |-
      <p>
      Given the specified <tt>state</tt> (an <a
      href="Parser/State.html">Arrow::Template::Parser::State</a> object), scan
      for and return a methodchain. Returns <tt>nil</tt> if no methodchain is
      found.
      </p>
    params: ( state )
  - visibility: public
    aref: M000152
    name: scan_for_nodes
    sourcecode: "     <span class=\"ruby-comment cmt\"># File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 313</span>\n\
      313:     <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">scan_for_nodes</span>( <span class=\"ruby-identifier\">state</span>, <span class=\"ruby-identifier\">context</span>=<span class=\"ruby-keyword kw\">nil</span>, <span class=\"ruby-identifier\">node</span>=<span class=\"ruby-keyword kw\">nil</span> )\n\
      314:         <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">branch</span>( <span class=\"ruby-identifier\">node</span> ) <span class=\"ruby-keyword kw\">do</span>\n\
      315:             <span class=\"ruby-identifier\">scanner</span> = <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">scanner</span>\n\
      316: \n\
      317:             <span class=\"ruby-comment cmt\"># Scan until the scanner reaches the end of its string. Early exits</span>\n\
      318:             <span class=\"ruby-comment cmt\"># 'break' of this loop.</span>\n\
      319:             <span class=\"ruby-identifier\">catch</span>( <span class=\"ruby-identifier\">:endscan</span> ) {\n\
      320:                 <span class=\"ruby-keyword kw\">until</span> <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">eos?</span>\n\
      321:                     <span class=\"ruby-identifier\">startpos</span> = <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">pos</span>\n\
      322:                     <span class=\"ruby-comment cmt\">#self.log.debug %{Scanning from %d:%p} %</span>\n\
      323:                     <span class=\"ruby-comment cmt\">#  [ scanner.pos, scanner.rest[0,20] + '..' ]</span>\n\
      324:                 \n\
      325:                     <span class=\"ruby-comment cmt\"># Scan for the next directive. When the scanner reaches</span>\n\
      326:                     <span class=\"ruby-comment cmt\"># the end of the parsed string, just append any plain</span>\n\
      327:                     <span class=\"ruby-comment cmt\"># text that's left and stop scanning.</span>\n\
      328:                     <span class=\"ruby-keyword kw\">if</span> <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">skip_until</span>( <span class=\"ruby-constant\">TAGOPEN</span> )\n\
      329: \n\
      330:                         <span class=\"ruby-comment cmt\"># Add the literal String node leading up to the tag</span>\n\
      331:                         <span class=\"ruby-comment cmt\"># as a text node :FIXME: Have to do it this way</span>\n\
      332:                         <span class=\"ruby-comment cmt\"># because StringScanner#pre_match does weird crap if</span>\n\
      333:                         <span class=\"ruby-comment cmt\"># skip_until skips only one or no character/s.</span>\n\
      334:                         <span class=\"ruby-keyword kw\">if</span> ( <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">pos</span> <span class=\"ruby-operator\">-</span> <span class=\"ruby-identifier\">startpos</span> <span class=\"ruby-operator\">&gt;</span> <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">matched</span>.<span class=\"ruby-identifier\">length</span> )\n\
      335:                             <span class=\"ruby-identifier\">offset</span> = <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">pos</span> <span class=\"ruby-operator\">-</span> <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">matched</span>.<span class=\"ruby-identifier\">length</span> <span class=\"ruby-operator\">-</span> <span class=\"ruby-value\">1</span>\n\
      336:                             <span class=\"ruby-identifier\">state</span> <span class=\"ruby-operator\">&lt;&lt;</span> <span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">Template</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">TextNode</span>.\n\
      337:                                 <span class=\"ruby-identifier\">new</span>( <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">string</span>[<span class=\"ruby-identifier\">startpos</span><span class=\"ruby-operator\">..</span><span class=\"ruby-identifier\">offset</span>] )\n\
      338:                             <span class=\"ruby-comment cmt\">#self.log.debug &quot;Added text node %p&quot; %</span>\n\
      339:                             <span class=\"ruby-comment cmt\">#    scanner.string[startpos..offset]</span>\n\
      340:                         <span class=\"ruby-keyword kw\">end</span>\n\
      341: \n\
      342:                         <span class=\"ruby-comment cmt\"># Now scan the directive that was found</span>\n\
      343:                         <span class=\"ruby-identifier\">state</span> <span class=\"ruby-operator\">&lt;&lt;</span> <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">scan_directive</span>( <span class=\"ruby-identifier\">state</span>, <span class=\"ruby-identifier\">context</span> )\n\
      344:                     <span class=\"ruby-keyword kw\">else</span>\n\
      345:                         <span class=\"ruby-identifier\">state</span> <span class=\"ruby-operator\">&lt;&lt;</span> <span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">Template</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">TextNode</span>.<span class=\"ruby-identifier\">new</span>( <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">rest</span> )\n\
      346:                         <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">terminate</span>\n\
      347:                     <span class=\"ruby-keyword kw\">end</span>\n\
      348:                 <span class=\"ruby-keyword kw\">end</span>\n\
      349:             }\n\
      350:         <span class=\"ruby-keyword kw\">end</span>\n\
      351:     <span class=\"ruby-keyword kw\">end</span>"
    m_desc: |-
      <p>
      Use the specified <tt>state</tt> (a StringScanner object) to scan for
      directive and plain-text nodes. The <tt>context</tt> argument, if set,
      indicates a recursive call for the directive named. The <tt>node</tt> will
      be used as the branch node in the <a href="Parser.html#M000151">parse</a>
      state.
      </p>
    params: ( state, context=nil, node=nil )
  - visibility: public
    aref: M000159
    name: scan_for_pathname
    sourcecode: "     <span class=\"ruby-comment cmt\"># File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 539</span>\n\
      539:     <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">scan_for_pathname</span>( <span class=\"ruby-identifier\">state</span>, <span class=\"ruby-identifier\">skip_whitespace</span>=<span class=\"ruby-keyword kw\">true</span> )\n\
      540:         <span class=\"ruby-identifier\">scanner</span> = <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">scanner</span>\n\
      541:         <span class=\"ruby-comment cmt\">#self.log.debug &quot;Scanning for file path at %p&quot; %</span>\n\
      542:         <span class=\"ruby-comment cmt\"># scanner.rest[0,20]</span>\n\
      543: \n\
      544:         <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">skip</span>( <span class=\"ruby-constant\">WHITESPACE</span> ) <span class=\"ruby-keyword kw\">if</span> <span class=\"ruby-identifier\">skip_whitespace</span>\n\
      545:         <span class=\"ruby-identifier\">rval</span> = <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">scan</span>( <span class=\"ruby-constant\">PATHNAME</span> ) <span class=\"ruby-keyword kw\">or</span>\n\
      546:             <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-keyword kw\">nil</span>\n\
      547: \n\
      548:         <span class=\"ruby-comment cmt\">#self.log.debug &quot;Found path: %p&quot; % rval</span>\n\
      549:         <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-identifier\">rval</span>\n\
      550:     <span class=\"ruby-keyword kw\">end</span>"
    m_desc: |-
      <p>
      Given the specified <tt>state</tt> (an <a
      href="Parser/State.html">Arrow::Template::Parser::State</a> object), scan
      for and return a valid-looking file pathname.
      </p>
    params: ( state, skip_whitespace=true )
  - visibility: public
    aref: M000155
    name: scan_for_quoted_string
    sourcecode: "     <span class=\"ruby-comment cmt\"># File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 453</span>\n\
      453:     <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">scan_for_quoted_string</span>( <span class=\"ruby-identifier\">state</span>, <span class=\"ruby-identifier\">skip_whitespace</span>=<span class=\"ruby-keyword kw\">true</span> )\n\
      454:         <span class=\"ruby-comment cmt\">#self.log.debug &quot;Scanning for quoted string at %p&quot; %</span>\n\
      455:         <span class=\"ruby-comment cmt\"># state.scanner.rest[0,20]</span>\n\
      456: \n\
      457:         <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">skip</span>( <span class=\"ruby-constant\">WHITESPACE</span> ) <span class=\"ruby-keyword kw\">if</span> <span class=\"ruby-identifier\">skip_whitespace</span>\n\
      458: \n\
      459:         <span class=\"ruby-identifier\">rval</span> = <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">scan</span>( <span class=\"ruby-constant\">QUOTEDSTRING</span> ) <span class=\"ruby-keyword kw\">or</span> <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-keyword kw\">nil</span>\n\
      460: \n\
      461:         <span class=\"ruby-comment cmt\">#self.log.debug &quot;Found quoted string %p&quot; % rval</span>\n\
      462:         <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-identifier\">rval</span>\n\
      463:     <span class=\"ruby-keyword kw\">end</span>"
    m_desc: |-
      <p>
      Given the specified <tt>state</tt> (an <a
      href="Parser/State.html">Arrow::Template::Parser::State</a> object), scan
      for and return a quoted string, including the quotes. If
      <tt>skip_whitespace</tt> is <tt>true</tt>, any leading whitespace
      characters will be skipped. Returns <tt>nil</tt> if no quoted string is
      found.
      </p>
    params: ( state, skip_whitespace=true )
  - visibility: public
    aref: M000157
    name: scan_for_tag_ending
    sourcecode: "     <span class=\"ruby-comment cmt\"># File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 486</span>\n\
      486:     <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">scan_for_tag_ending</span>( <span class=\"ruby-identifier\">state</span>, <span class=\"ruby-identifier\">skip_whitespace</span>=<span class=\"ruby-keyword kw\">true</span> )\n\
      487:         <span class=\"ruby-identifier\">scanner</span> = <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">scanner</span>\n\
      488:         <span class=\"ruby-comment cmt\">#self.log.debug &quot;Scanning for tag ending at %p&quot; %</span>\n\
      489:         <span class=\"ruby-comment cmt\"># scanner.rest[0,20]</span>\n\
      490: \n\
      491:         <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">skip</span>( <span class=\"ruby-constant\">WHITESPACE</span> ) <span class=\"ruby-keyword kw\">if</span> <span class=\"ruby-identifier\">skip_whitespace</span>\n\
      492:         <span class=\"ruby-identifier\">rval</span> = <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">scan</span>( <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">tag_close</span> ) <span class=\"ruby-keyword kw\">or</span>\n\
      493:             <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-keyword kw\">nil</span>\n\
      494: \n\
      495:         <span class=\"ruby-comment cmt\">#self.log.debug &quot;Found tag ending %p&quot; % rval</span>\n\
      496:         <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-identifier\">rval</span>\n\
      497:     <span class=\"ruby-keyword kw\">end</span>"
    m_desc: |-
      <p>
      Given the specified <tt>state</tt> (an <a
      href="Parser/State.html">Arrow::Template::Parser::State</a> object), scan
      for and return the current tag ending. Returns <tt>nil</tt> if no tag
      ending is found.
      </p>
    params: ( state, skip_whitespace=true )
  category: Instance
  type: Public
- methods: 
  - visibility: protected
    aref: M000161
    name: get_parse_context
    sourcecode: "     <span class=\"ruby-comment cmt\"># File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 578</span>\n\
      578:     <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">get_parse_context</span>( <span class=\"ruby-identifier\">scanner</span> )\n\
      579:         <span class=\"ruby-identifier\">str</span> = <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">string</span>\n\
      580:         \n\
      581:         <span class=\"ruby-identifier\">pre</span> = <span class=\"ruby-identifier\">str</span>[ <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">pos</span> <span class=\"ruby-operator\">&lt;</span> <span class=\"ruby-value\">40</span> <span class=\"ruby-operator\">?</span> <span class=\"ruby-value\">0</span> <span class=\"ruby-operator\">:</span> <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">pos</span> <span class=\"ruby-operator\">-</span> <span class=\"ruby-value\">40</span>, <span class=\"ruby-value\">39</span> ]\n\
      582:         <span class=\"ruby-identifier\">post</span> = <span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">rest</span>[ <span class=\"ruby-value\">0</span>, <span class=\"ruby-value\">40</span> ]\n\
      583:         \n\
      584:         <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-node\">&quot;#{pre}[*** ERROR ***]#{post}&quot;</span>\n\
      585:     <span class=\"ruby-keyword kw\">end</span>"
    m_desc: |-
      <p>
      Return a string showing the given <tt>scanner</tt>&#8216;s context in the
      string being parsed.
      </p>
    params: ( scanner )
  - visibility: protected
    aref: M000160
    name: handle_unknown_pi
    sourcecode: "     <span class=\"ruby-comment cmt\"># File /Users/ged/source/ruby/Arrow/lib/arrow/template/parser.rb, line 559</span>\n\
      559:     <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">handle_unknown_pi</span>( <span class=\"ruby-identifier\">state</span>, <span class=\"ruby-identifier\">tag</span>=<span class=\"ruby-value str\">&quot;&quot;</span> )\n\
      560:         \n\
      561:         <span class=\"ruby-comment cmt\"># If the configuration doesn't say to ignore unknown PIs or it's an</span>\n\
      562:         <span class=\"ruby-comment cmt\"># [?alternate-synax?] directive, raise an error.</span>\n\
      563:         <span class=\"ruby-keyword kw\">if</span> <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">tag_open</span> <span class=\"ruby-operator\">==</span> <span class=\"ruby-value str\">'[?'</span> <span class=\"ruby-operator\">||</span> <span class=\"ruby-operator\">!</span><span class=\"ruby-ivar\">@config</span>[<span class=\"ruby-identifier\">:ignore_unknown_PIs</span>]\n\
      564:             <span class=\"ruby-identifier\">raise</span> <span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">ParseError</span>, <span class=\"ruby-value str\">&quot;unknown directive&quot;</span>\n\
      565:         <span class=\"ruby-keyword kw\">end</span>\n\
      566: \n\
      567:         <span class=\"ruby-identifier\">remainder</span> = <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">scanner</span>.<span class=\"ruby-identifier\">scan</span>( <span class=\"ruby-regexp re\">%r{(?:[^?]|\\?(?!&gt;))*\\?&gt;}</span> ) <span class=\"ruby-keyword kw\">or</span>\n\
      568:             <span class=\"ruby-identifier\">raise</span> <span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">ParseError</span>, <span class=\"ruby-value str\">&quot;failed to skip unknown PI&quot;</span>\n\
      569: \n\
      570:         <span class=\"ruby-identifier\">pi</span> = <span class=\"ruby-identifier\">state</span>.<span class=\"ruby-identifier\">tag_open</span> <span class=\"ruby-operator\">+</span> <span class=\"ruby-identifier\">tag</span> <span class=\"ruby-operator\">+</span> <span class=\"ruby-identifier\">remainder</span>\n\
      571:         <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">log</span>.<span class=\"ruby-identifier\">info</span>( <span class=\"ruby-node\">&quot;Ignoring unknown PI (to = #{state.tag_open.inspect}) '#{pi}'&quot;</span> )\n\
      572:         <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">Template</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">TextNode</span>.<span class=\"ruby-identifier\">new</span>( <span class=\"ruby-identifier\">pi</span> )\n\
      573:     <span class=\"ruby-keyword kw\">end</span>"
    m_desc: |-
      <p>
      Handle an unknown ProcessingInstruction.
      </p>
    params: ( state, tag=&quot;&quot; )
  category: Instance
  type: Protected

sectitle

--- 

constants

--- 
- name: SVNRev
  desc: |+
    
    SVN Revision
    
  value: "%q$Rev: 437 $"
- name: SVNId
  desc: |+
    
    SVN Id
    
  value: "%q$Id: parser.rb 437 2008-03-28 00:49:20Z deveiant $"
- name: Defaults
  desc: |+
    
    Default configuration hash
    
  value: "{         :strict_end_tags          =&gt; false,         :ignore_unknown_PIs       =&gt; true,     }"

[Validate]

Generated with the Darkfish Rdoc Generator.