def matchTagged( prefix, ldel, rdel, failmode, bad, ignore )
failmode = failmode.to_s.intern if failmode
startPos = self.pointer
debugMsg 2, "matchTagged starting at pos = %d: prefix = %s, "\
"ldel = %s, rdel = %s, failmode = %s, bad = %s, ignore = %s",
startPos, prefix.inspect, ldel.inspect, rdel.inspect,
failmode.inspect, bad.inspect, ignore.inspect
rdelspec = ''
openTagPos, textPos, paraPos, closeTagPos, endPos = ([nil] * 5)
match = nil
raise MatchFailure, "Did not find prefix: /#{prefix.inspect}/" unless
self.skip( prefix )
openTagPos = self.pointer
debugMsg 3, "Found prefix. Pointer now at offset %d" % self.pointer
unless (( match = self.scan(ldel) ))
raise MatchFailure, "Did not find opening tag %s at offset %d" %
[ ldel.inspect, self.pointer ]
end
textPos = self.pointer
debugMsg 3, "Found left delimiter '%s': offset now %d" % [ match, textPos ]
if rdel.nil?
rdelspec = makeClosingTag( match )
debugMsg 3, "Generated right-delimiting tag: %s" % rdelspec.inspect
else
rdelspec = rdel.gsub( /(\A|[^\\])\$([1-9])/, '\1self[\2]' ).interpolate( binding )
debugMsg 3, "Right delimiter (after interpolation) is: %s" % rdelspec.inspect
end
while self.rest? && closeTagPos.nil?
if (( self.skip( /^\\./ ) ))
debugMsg 4, "Skipping backslashed literal at offset %d" % self.pointer
next
elsif (( matchlength = self.skip( /^(\n[ \t]*\n)/ ) ))
paraPos ||= self.pointer - matchlength
debugMsg 4, "Found paragraph position at offset %d" % paraPos
elsif (( matchlength = self.skip( rdelspec ) ))
closeTagPos = self.pointer - matchlength
debugMsg 3, "Found closing tag at offset %d" % closeTagPos
elsif ignore && !ignore.empty? && self.skip(ignore)
debugMsg 3, "Skipping ignored text '%s' at offset %d" %
[ self.matched, self.pointer - self.matched_size ]
next
elsif bad && !bad.empty? && self.match?( bad )
if failmode == :para || failmode == :max
break
else
raise MatchFailure, "Found invalid nested tag '%s' at offset %d" %
[ match, self.pointer ]
end
elsif (( match = self.scan( ldel ) ))
tag = match
self.unscan
unless self.matchTagged( prefix, ldel, rdel, failmode, bad, ignore )
break if failmode == :para || failmode == :max
raise MatchFailure, "Found unbalanced nested tag '%s' at offset %d" %
[ tag, self.pointer ]
end
else
self.pointer += 1
debugMsg 5, "Advanced scan pointer to offset %d" % self.pointer
end
end
unless closeTagPos
debugMsg 3, "No close tag position found. "
if failmode == :max || failmode == :para
closeTagPos = self.pointer - 1
debugMsg 4, "Failmode %s tolerates no closing tag. Close tag position set to %d" %
[ failmode.inspect, closeTagPos ]
if failmode == :para && paraPos
self.pointer = paraPos + 1
end
else
raise MatchFailure, "No closing tag found."
end
end
rval = {
:match => self.string[ openTagPos .. (self.pointer - 1) ],
:prefix => self.string[ startPos, (openTagPos-startPos) ],
:suffix => self.string[ self.pointer..-1 ],
}
debugMsg 1, "matchTagged succeeded: %s" % rval.inspect
return rval
end