annotate vendor/plugins/coderay-0.9.2/lib/coderay/scanners/nitro_xhtml.rb @ 874:12771bc38f20 feature_123

Close obsolete branch feature_123
author Chris Cannam
date Sat, 02 Apr 2011 09:37:51 +0100
parents 513646585e45
children
rev   line source
Chris@0 1 module CodeRay
Chris@0 2 module Scanners
Chris@0 3
Chris@0 4 load :html
Chris@0 5 load :ruby
Chris@0 6
Chris@0 7 # Nitro XHTML Scanner
Chris@0 8 class NitroXHTML < Scanner
Chris@0 9
Chris@0 10 include Streamable
Chris@0 11 register_for :nitro_xhtml
Chris@0 12 file_extension :xhtml
Chris@0 13 title 'Nitro XHTML'
Chris@0 14
Chris@0 15 KINDS_NOT_LOC = HTML::KINDS_NOT_LOC
Chris@0 16
Chris@0 17 NITRO_RUBY_BLOCK = /
Chris@0 18 <\?r
Chris@0 19 (?>
Chris@0 20 [^\?]*
Chris@0 21 (?> \?(?!>) [^\?]* )*
Chris@0 22 )
Chris@0 23 (?: \?> )?
Chris@0 24 |
Chris@0 25 <ruby>
Chris@0 26 (?>
Chris@0 27 [^<]*
Chris@0 28 (?> <(?!\/ruby>) [^<]* )*
Chris@0 29 )
Chris@0 30 (?: <\/ruby> )?
Chris@0 31 |
Chris@0 32 <%
Chris@0 33 (?>
Chris@0 34 [^%]*
Chris@0 35 (?> %(?!>) [^%]* )*
Chris@0 36 )
Chris@0 37 (?: %> )?
Chris@0 38 /mx
Chris@0 39
Chris@0 40 NITRO_VALUE_BLOCK = /
Chris@0 41 \#
Chris@0 42 (?:
Chris@0 43 \{
Chris@0 44 [^{}]*
Chris@0 45 (?>
Chris@0 46 \{ [^}]* \}
Chris@0 47 (?> [^{}]* )
Chris@0 48 )*
Chris@0 49 \}?
Chris@0 50 | \| [^|]* \|?
Chris@0 51 | \( [^)]* \)?
Chris@0 52 | \[ [^\]]* \]?
Chris@0 53 | \\ [^\\]* \\?
Chris@0 54 )
Chris@0 55 /x
Chris@0 56
Chris@0 57 NITRO_ENTITY = /
Chris@0 58 % (?: \#\d+ | \w+ ) ;
Chris@0 59 /
Chris@0 60
Chris@0 61 START_OF_RUBY = /
Chris@0 62 (?=[<\#%])
Chris@0 63 < (?: \?r | % | ruby> )
Chris@0 64 | \# [{(|]
Chris@0 65 | % (?: \#\d+ | \w+ ) ;
Chris@0 66 /x
Chris@0 67
Chris@0 68 CLOSING_PAREN = Hash.new do |h, p|
Chris@0 69 h[p] = p
Chris@0 70 end.update( {
Chris@0 71 '(' => ')',
Chris@0 72 '[' => ']',
Chris@0 73 '{' => '}',
Chris@0 74 } )
Chris@0 75
Chris@0 76 private
Chris@0 77
Chris@0 78 def setup
Chris@0 79 @ruby_scanner = CodeRay.scanner :ruby, :tokens => @tokens, :keep_tokens => true
Chris@0 80 @html_scanner = CodeRay.scanner :html, :tokens => @tokens, :keep_tokens => true, :keep_state => true
Chris@0 81 end
Chris@0 82
Chris@0 83 def reset_instance
Chris@0 84 super
Chris@0 85 @html_scanner.reset
Chris@0 86 end
Chris@0 87
Chris@0 88 def scan_tokens tokens, options
Chris@0 89
Chris@0 90 until eos?
Chris@0 91
Chris@0 92 if (match = scan_until(/(?=#{START_OF_RUBY})/o) || scan_until(/\z/)) and not match.empty?
Chris@0 93 @html_scanner.tokenize match
Chris@0 94
Chris@0 95 elsif match = scan(/#{NITRO_VALUE_BLOCK}/o)
Chris@0 96 start_tag = match[0,2]
Chris@0 97 delimiter = CLOSING_PAREN[start_tag[1,1]]
Chris@0 98 end_tag = match[-1,1] == delimiter ? delimiter : ''
Chris@0 99 tokens << [:open, :inline]
Chris@0 100 tokens << [start_tag, :inline_delimiter]
Chris@0 101 code = match[start_tag.size .. -1 - end_tag.size]
Chris@0 102 @ruby_scanner.tokenize code
Chris@0 103 tokens << [end_tag, :inline_delimiter] unless end_tag.empty?
Chris@0 104 tokens << [:close, :inline]
Chris@0 105
Chris@0 106 elsif match = scan(/#{NITRO_RUBY_BLOCK}/o)
Chris@0 107 start_tag = '<?r'
Chris@0 108 end_tag = match[-2,2] == '?>' ? '?>' : ''
Chris@0 109 tokens << [:open, :inline]
Chris@0 110 tokens << [start_tag, :inline_delimiter]
Chris@0 111 code = match[start_tag.size .. -(end_tag.size)-1]
Chris@0 112 @ruby_scanner.tokenize code
Chris@0 113 tokens << [end_tag, :inline_delimiter] unless end_tag.empty?
Chris@0 114 tokens << [:close, :inline]
Chris@0 115
Chris@0 116 elsif entity = scan(/#{NITRO_ENTITY}/o)
Chris@0 117 tokens << [entity, :entity]
Chris@0 118
Chris@0 119 elsif scan(/%/)
Chris@0 120 tokens << [matched, :error]
Chris@0 121
Chris@0 122 else
Chris@0 123 raise_inspect 'else-case reached!', tokens
Chris@0 124
Chris@0 125 end
Chris@0 126
Chris@0 127 end
Chris@0 128
Chris@0 129 tokens
Chris@0 130
Chris@0 131 end
Chris@0 132
Chris@0 133 end
Chris@0 134
Chris@0 135 end
Chris@0 136 end