Class CodeRay::Scanners::JavaScript
In: lib/coderay/scanners/java_script.rb
Parent: Scanner

Scanner for JavaScript.

Aliases: ecmascript, ecma_script, javascript

Methods

Protected Instance methods

[Source]

     # File lib/coderay/scanners/java_script.rb, line 201
201:     def reset_instance
202:       super
203:       @xml_scanner.reset if defined? @xml_scanner
204:     end

[Source]

     # File lib/coderay/scanners/java_script.rb, line 57
 57:     def scan_tokens encoder, options
 58:       
 59:       state = :initial
 60:       string_delimiter = nil
 61:       value_expected = true
 62:       key_expected = false
 63:       function_expected = false
 64:       
 65:       until eos?
 66:         
 67:         case state
 68:           
 69:         when :initial
 70:           
 71:           if match = scan(/ \s+ | \\\n /x)
 72:             value_expected = true if !value_expected && match.index(?\n)
 73:             encoder.text_token match, :space
 74:             
 75:           elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
 76:             value_expected = true
 77:             encoder.text_token match, :comment
 78:             
 79:           elsif check(/\.?\d/)
 80:             key_expected = value_expected = false
 81:             if match = scan(/0[xX][0-9A-Fa-f]+/)
 82:               encoder.text_token match, :hex
 83:             elsif match = scan(/(?>0[0-7]+)(?![89.eEfF])/)
 84:               encoder.text_token match, :octal
 85:             elsif match = scan(/\d+[fF]|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
 86:               encoder.text_token match, :float
 87:             elsif match = scan(/\d+/)
 88:               encoder.text_token match, :integer
 89:             end
 90:             
 91:           elsif value_expected && match = scan(/<([[:alpha:]]\w*) (?: [^\/>]*\/> | .*?<\/\1>)/xim)
 92:             # TODO: scan over nested tags
 93:             xml_scanner.tokenize match, :tokens => encoder
 94:             value_expected = false
 95:             next
 96:             
 97:           elsif match = scan(/ [-+*=<>?:;,!&^|(\[{~%]+ | \.(?!\d) /x)
 98:             value_expected = true
 99:             last_operator = match[-1]
100:             key_expected = (last_operator == ?{) || (last_operator == ?,)
101:             function_expected = false
102:             encoder.text_token match, :operator
103:             
104:           elsif match = scan(/ [)\]}]+ /x)
105:             function_expected = key_expected = value_expected = false
106:             encoder.text_token match, :operator
107:             
108:           elsif match = scan(/ [$a-zA-Z_][A-Za-z_0-9$]* /x)
109:             kind = IDENT_KIND[match]
110:             value_expected = (kind == :keyword) && KEYWORDS_EXPECTING_VALUE[match]
111:             # TODO: labels
112:             if kind == :ident
113:               if match.index(?$)  # $ allowed inside an identifier
114:                 kind = :predefined
115:               elsif function_expected
116:                 kind = :function
117:               elsif check(/\s*[=:]\s*function\b/)
118:                 kind = :function
119:               elsif key_expected && check(/\s*:/)
120:                 kind = :key
121:               end
122:             end
123:             function_expected = (kind == :keyword) && (match == 'function')
124:             key_expected = false
125:             encoder.text_token match, kind
126:             
127:           elsif match = scan(/["']/)
128:             if key_expected && check(KEY_CHECK_PATTERN[match])
129:               state = :key
130:             else
131:               state = :string
132:             end
133:             encoder.begin_group state
134:             string_delimiter = match
135:             encoder.text_token match, :delimiter
136:             
137:           elsif value_expected && (match = scan(/\//))
138:             encoder.begin_group :regexp
139:             state = :regexp
140:             string_delimiter = '/'
141:             encoder.text_token match, :delimiter
142:             
143:           elsif match = scan(/ \/ /x)
144:             value_expected = true
145:             key_expected = false
146:             encoder.text_token match, :operator
147:             
148:           else
149:             encoder.text_token getch, :error
150:             
151:           end
152:           
153:         when :string, :regexp, :key
154:           if match = scan(STRING_CONTENT_PATTERN[string_delimiter])
155:             encoder.text_token match, :content
156:           elsif match = scan(/["'\/]/)
157:             encoder.text_token match, :delimiter
158:             if state == :regexp
159:               modifiers = scan(/[gim]+/)
160:               encoder.text_token modifiers, :modifier if modifiers && !modifiers.empty?
161:             end
162:             encoder.end_group state
163:             string_delimiter = nil
164:             key_expected = value_expected = false
165:             state = :initial
166:           elsif state != :regexp && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox))
167:             if string_delimiter == "'" && !(match == "\\\\" || match == "\\'")
168:               encoder.text_token match, :content
169:             else
170:               encoder.text_token match, :char
171:             end
172:           elsif state == :regexp && match = scan(/ \\ (?: #{ESCAPE} | #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
173:             encoder.text_token match, :char
174:           elsif match = scan(/\\./m)
175:             encoder.text_token match, :content
176:           elsif match = scan(/ \\ | $ /x)
177:             encoder.end_group state
178:             encoder.text_token match, :error
179:             key_expected = value_expected = false
180:             state = :initial
181:           else
182:             raise_inspect "else case \" reached; %p not handled." % peek(1), encoder
183:           end
184:           
185:         else
186:           raise_inspect 'Unknown state', encoder
187:           
188:         end
189:         
190:       end
191:       
192:       if [:string, :regexp].include? state
193:         encoder.end_group state
194:       end
195:       
196:       encoder
197:     end

[Source]

     # File lib/coderay/scanners/java_script.rb, line 206
206:     def xml_scanner
207:       @xml_scanner ||= CodeRay.scanner :xml, :tokens => @tokens, :keep_tokens => true, :keep_state => false
208:     end

[Validate]