summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etc/0.8.1-vs-0.8.2.diff872
-rw-r--r--etc/0.8.2-vs-0.8.3.diff656
-rw-r--r--etc/check-coderay-gem-stats.sh1
-rw-r--r--etc/coderay-lib.tmproj8
-rw-r--r--etc/todo/scanners/sql.Keith.rb143
5 files changed, 1674 insertions, 6 deletions
diff --git a/etc/0.8.1-vs-0.8.2.diff b/etc/0.8.1-vs-0.8.2.diff
new file mode 100644
index 0000000..ea513de
--- /dev/null
+++ b/etc/0.8.1-vs-0.8.2.diff
@@ -0,0 +1,872 @@
+Index: coderay/encoders/html/numerization.rb
+===================================================================
+--- coderay/encoders/html/numerization.rb (.../tags/0.8.2/lib) (revision 302)
++++ coderay/encoders/html/numerization.rb (.../trunk/lib) (revision 302)
+@@ -32,9 +32,19 @@
+ #end
+
+ bold_every = options[:bold_every]
++ highlight_lines = options[:highlight_lines]
+ bolding =
+- if bold_every == false
++ if bold_every == false && highlight_lines == nil
+ proc { |line| line.to_s }
++ elsif highlight_lines.is_a? Enumerable
++ highlight_lines = highlight_lines.to_set
++ proc do |line|
++ if highlight_lines.include? line
++ "<strong class=\"highlighted\">#{line}</strong>" # highlighted line numbers in bold
++ else
++ line.to_s
++ end
++ end
+ elsif bold_every.is_a? Integer
+ raise ArgumentError, ":bolding can't be 0." if bold_every == 0
+ proc do |line|
+Index: coderay/encoders/html.rb
+===================================================================
+--- coderay/encoders/html.rb (.../tags/0.8.2/lib) (revision 302)
++++ coderay/encoders/html.rb (.../trunk/lib) (revision 302)
+@@ -56,6 +56,16 @@
+ #
+ # Default: 10
+ #
++ # === :highlight_lines
++ #
++ # Highlights certain line numbers now by using the :highlight_lines option.
++ # Can be any Enumerable, typically just an Array or Range, of numbers.
++ #
++ # Bolding is deactivated when :highlight_lines is set. It only makes sense
++ # in combination with :line_numbers.
++ #
++ # Default: nil
++ #
+ # === :hint
+ # Include some information into the output using the title attribute.
+ # Can be :info (show token type on mouse-over), :info_long (with full path)
+@@ -82,6 +92,7 @@
+ :line_numbers => nil,
+ :line_number_start => 1,
+ :bold_every => 10,
++ :highlight_lines => nil,
+
+ :hint => false,
+ }
+Index: coderay/helpers/plugin.rb
+===================================================================
+--- coderay/helpers/plugin.rb (.../tags/0.8.2/lib) (revision 302)
++++ coderay/helpers/plugin.rb (.../trunk/lib) (revision 302)
+@@ -303,9 +303,17 @@
+ #
+ # The above example loads the file myplugin/my_helper.rb relative to the
+ # file in which MyPlugin was defined.
++ #
++ # You can also load a helper from a different plugin:
++ #
++ # helper 'other_plugin/other_helper'
+ def helper *helpers
+ for helper in helpers
+- self::PLUGIN_HOST.require_helper plugin_id, helper.to_s
++ if helper.is_a?(String) && helper[/\//]
++ self::PLUGIN_HOST.require_helper $`, $'
++ else
++ self::PLUGIN_HOST.require_helper plugin_id, helper.to_s
++ end
+ end
+ end
+
+Index: coderay/helpers/file_type.rb
+===================================================================
+--- coderay/helpers/file_type.rb (.../tags/0.8.2/lib) (revision 302)
++++ coderay/helpers/file_type.rb (.../trunk/lib) (revision 302)
+@@ -87,6 +87,8 @@
+ 'mab' => :ruby,
+ 'cpp' => :c,
+ 'c' => :c,
++ 'gvy' => :groovy,
++ 'groovy' => :groovy,
+ 'h' => :c,
+ 'java' => :java,
+ 'js' => :java_script,
+Index: coderay/helpers/gzip_simple.rb
+===================================================================
+--- coderay/helpers/gzip_simple.rb (.../tags/0.8.2/lib) (revision 302)
++++ coderay/helpers/gzip_simple.rb (.../trunk/lib) (revision 302)
+@@ -2,7 +2,7 @@
+ #
+ # A simplified interface to the gzip library +zlib+ (from the Ruby Standard Library.)
+ #
+-# Author: murphy (mail to murphy cYcnus de)
++# Author: murphy (mail to murphy rubychan de)
+ #
+ # Version: 0.2 (2005.may.28)
+ #
+Index: coderay/styles/cycnus.rb
+===================================================================
+--- coderay/styles/cycnus.rb (.../tags/0.8.2/lib) (revision 302)
++++ coderay/styles/cycnus.rb (.../trunk/lib) (revision 302)
+@@ -8,7 +8,7 @@
+ code_background = '#f8f8f8'
+ numbers_background = '#def'
+ border_color = 'silver'
+- normal_color = '#100'
++ normal_color = '#000'
+
+ CSS_MAIN_STYLES = <<-MAIN
+ .CodeRay {
+@@ -32,6 +32,7 @@
+ text-align: right;
+ }
+ .CodeRay .line_numbers tt { font-weight: bold }
++.CodeRay .line_numbers .highlighted { color: red }
+ .CodeRay .no { padding: 0px 4px }
+ .CodeRay .code { width: 100% }
+
+@@ -50,7 +51,7 @@
+ .av { color:#700 }
+ .aw { color:#C00 }
+ .bi { color:#509; font-weight:bold }
+-.c { color:#666; }
++.c { color:#888; }
+
+ .ch { color:#04D }
+ .ch .k { color:#04D }
+@@ -77,10 +78,10 @@
+ .i { color:#00D; font-weight:bold }
+ .ic { color:#B44; font-weight:bold }
+
+-.il { background: #eee }
++.il { background: #eee; color: black }
+ .il .il { background: #ddd }
+ .il .il .il { background: #ccc }
+-.il .idl { font-weight: bold; color: #888 }
++.il .idl { font-weight: bold; color: #777 }
+
+ .im { color:#f00; }
+ .in { color:#B2B; font-weight:bold }
+@@ -94,7 +95,7 @@
+ .pd { color:#369; font-weight:bold }
+ .pp { color:#579; }
+ .ps { color:#00C; font-weight: bold; }
+-.pt { color:#339; font-weight:bold }
++.pt { color:#349; font-weight:bold }
+ .r, .kw { color:#080; font-weight:bold }
+
+ .ke { color: #808; }
+Index: coderay/for_redcloth.rb
+===================================================================
+--- coderay/for_redcloth.rb (.../tags/0.8.2/lib) (revision 302)
++++ coderay/for_redcloth.rb (.../trunk/lib) (revision 302)
+@@ -1,4 +1,4 @@
+-module CodeRay # :nodoc:
++module CodeRay
+
+ # A little hack to enable CodeRay highlighting in RedCloth.
+ #
+Index: coderay/scanners/ruby/patterns.rb
+===================================================================
+--- coderay/scanners/ruby/patterns.rb (.../tags/0.8.2/lib) (revision 302)
++++ coderay/scanners/ruby/patterns.rb (.../trunk/lib) (revision 302)
+@@ -81,25 +81,30 @@
+ /ox
+ METHOD_NAME_OR_SYMBOL = / #{METHOD_NAME_EX} | #{SYMBOL} /ox
+
+- # TODO investigste \M, \c and \C escape sequences
+- # (?: M-\\C-|C-\\M-|M-\\c|c\\M-|c|C-|M-)? (?: \\ (?: [0-7]{3} | x[0-9A-Fa-f]{2} | . ) )
+- # assert_equal(225, ?\M-a)
+- # assert_equal(129, ?\M-\C-a)
+- ESCAPE = /
++ SIMPLE_ESCAPE = /
+ [abefnrstv]
+- | M-\\C-|C-\\M-|M-\\c|c\\M-|c|C-|M-
+ | [0-7]{1,3}
+ | x[0-9A-Fa-f]{1,2}
+- | .
++ | .?
+ /mx
+-
++
++ CONTROL_META_ESCAPE = /
++ (?: M-|C-|c )
++ (?: \\ (?: M-|C-|c ) )*
++ (?: [^\\] | \\ #{SIMPLE_ESCAPE} )?
++ /mox
++
++ ESCAPE = /
++ #{CONTROL_META_ESCAPE} | #{SIMPLE_ESCAPE}
++ /mox
++
+ CHARACTER = /
+ \?
+ (?:
+ [^\s\\]
+ | \\ #{ESCAPE}
+ )
+- /mx
++ /mox
+
+ # NOTE: This is not completely correct, but
+ # nobody needs heredoc delimiters ending with \n.
+Index: coderay/scanners/java.rb
+===================================================================
+--- coderay/scanners/java.rb (.../tags/0.8.2/lib) (revision 302)
++++ coderay/scanners/java.rb (.../trunk/lib) (revision 302)
+@@ -30,12 +30,11 @@
+ add(KEYWORDS, :keyword).
+ add(MAGIC_VARIABLES, :local_variable).
+ add(TYPES, :type).
+- add(BuiltinTypes::List, :type).
++ add(BuiltinTypes::List, :pre_type).
+ add(DIRECTIVES, :directive)
+
+ ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x
+ UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x
+- REGEXP_ESCAPE = / [bBdDsSwW] /x
+ STRING_CONTENT_PATTERN = {
+ "'" => /[^\\']+/,
+ '"' => /[^\\"]+/,
+@@ -117,15 +116,11 @@
+
+ end
+
+- when :string, :regexp
++ when :string
+ if scan(STRING_CONTENT_PATTERN[string_delimiter])
+ kind = :content
+ elsif match = scan(/["'\/]/)
+ tokens << [match, :delimiter]
+- if state == :regexp
+- modifiers = scan(/[gim]+/)
+- tokens << [modifiers, :modifier] if modifiers && !modifiers.empty?
+- end
+ tokens << [:close, state]
+ string_delimiter = nil
+ state = :initial
+@@ -136,8 +131,6 @@
+ else
+ kind = :char
+ end
+- elsif state == :regexp && scan(/ \\ (?: #{ESCAPE} | #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
+- kind = :char
+ elsif scan(/\\./m)
+ kind = :content
+ elsif scan(/ \\ | $ /x)
+@@ -166,7 +159,7 @@
+
+ end
+
+- if [:string, :regexp].include? state
++ if state == :string
+ tokens << [:close, state]
+ end
+
+Index: coderay/scanners/ruby.rb
+===================================================================
+--- coderay/scanners/ruby.rb (.../tags/0.8.2/lib) (revision 302)
++++ coderay/scanners/ruby.rb (.../trunk/lib) (revision 302)
+@@ -147,6 +147,10 @@
+ tokens << [match, kind]
+ next
+
++ elsif bol? && match = scan(/\#!.*/)
++ tokens << [match, :doctype]
++ next
++
+ elsif match = scan(/\#.*/) or
+ ( bol? and match = scan(/#{patterns::RUBYDOC_OR_DATA}/o) )
+ kind = :comment
+@@ -191,6 +195,7 @@
+ depth -= 1
+ if depth == 0 # closing brace of inline block reached
+ state, depth, heredocs = inline_block_stack.pop
++ heredocs = nil if heredocs && heredocs.empty?
+ tokens << [match, :inline_delimiter]
+ kind = :inline
+ match = :close
+@@ -346,7 +351,7 @@
+ value_expected = value_expected == :set
+ last_token_dot = last_token_dot == :set
+ end
+-
++
+ if $DEBUG and not kind
+ raise_inspect 'Error token %p in line %d' %
+ [[match, kind], line], tokens, state
+Index: coderay/scanners/groovy.rb
+===================================================================
+--- coderay/scanners/groovy.rb (.../tags/0.8.2/lib) (revision 0)
++++ coderay/scanners/groovy.rb (.../trunk/lib) (revision 302)
+@@ -0,0 +1,271 @@
++module CodeRay
++module Scanners
++
++ load :java
++
++ class Groovy < Java
++
++ include Streamable
++ register_for :groovy
++
++ # TODO: Check this!
++ KEYWORDS = Java::KEYWORDS + %w[
++ as assert def in
++ ]
++ KEYWORDS_EXPECTING_VALUE = WordList.new.add %w[
++ case instanceof new return throw typeof while as assert in
++ ]
++
++ MAGIC_VARIABLES = Java::MAGIC_VARIABLES + %w[ it ]
++ # DIRECTIVES = %w[
++ # abstract extends final implements native private protected public
++ # static strictfp synchronized threadsafe throws transient volatile
++ # ]
++
++ IDENT_KIND = WordList.new(:ident).
++ add(KEYWORDS, :keyword).
++ add(MAGIC_VARIABLES, :local_variable).
++ add(TYPES, :type).
++ add(BuiltinTypes::List, :pre_type).
++ add(DIRECTIVES, :directive)
++
++ ESCAPE = / [bfnrtv$\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x
++ UNICODE_ESCAPE = / u[a-fA-F0-9]{4} /x # no 4-byte unicode chars? U[a-fA-F0-9]{8}
++ REGEXP_ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} | \d | [bBdDsSwW\/] /x
++
++ # TODO: interpretation inside ', ", /
++ STRING_CONTENT_PATTERN = {
++ "'" => /(?>\\[^\\'\n]+|[^\\'\n]+)+/,
++ '"' => /[^\\$"\n]+/,
++ "'''" => /(?>[^\\']+|'(?!''))+/,
++ '"""' => /(?>[^\\$"]+|"(?!""))+/,
++ '/' => /[^\\$\/\n]+/,
++ }
++
++ def scan_tokens tokens, options
++
++ state = :initial
++ inline_block_stack = []
++ inline_block_paren_depth = nil
++ string_delimiter = nil
++ import_clause = class_name_follows = last_token = after_def = false
++ value_expected = true
++
++ until eos?
++
++ kind = nil
++ match = nil
++
++ case state
++
++ when :initial
++
++ if match = scan(/ \s+ | \\\n /x)
++ tokens << [match, :space]
++ if match.index ?\n
++ import_clause = after_def = false
++ value_expected = true unless value_expected
++ end
++ next
++
++ elsif scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
++ value_expected = true
++ after_def = false
++ kind = :comment
++
++ elsif bol? && scan(/ \#!.* /x)
++ kind = :doctype
++
++ elsif import_clause && scan(/ (?!as) #{IDENT} (?: \. #{IDENT} )* (?: \.\* )? /ox)
++ after_def = value_expected = false
++ kind = :include
++
++ elsif match = scan(/ #{IDENT} | \[\] /ox)
++ kind = IDENT_KIND[match]
++ value_expected = (kind == :keyword) && KEYWORDS_EXPECTING_VALUE[match]
++ if last_token == '.'
++ kind = :ident
++ elsif class_name_follows
++ kind = :class
++ class_name_follows = false
++ elsif after_def && check(/\s*[({]/)
++ kind = :method
++ after_def = false
++ elsif kind == :ident && last_token != '?' && check(/:/)
++ kind = :key
++ else
++ class_name_follows = true if match == 'class' || (import_clause && match == 'as')
++ import_clause = match == 'import'
++ after_def = true if match == 'def'
++ end
++
++ elsif scan(/;/)
++ import_clause = after_def = false
++ value_expected = true
++ kind = :operator
++
++ elsif scan(/\{/)
++ class_name_follows = after_def = false
++ value_expected = true
++ kind = :operator
++ if !inline_block_stack.empty?
++ inline_block_paren_depth += 1
++ end
++
++ # TODO: ~'...', ~"..." and ~/.../ style regexps
++ elsif match = scan(/ \.\.<? | \*?\.(?!\d)@? | \.& | \?:? | [,?:(\[] | -[->] | \+\+ |
++ && | \|\| | \*\*=? | ==?~ | <=?>? | [-+*%^~&|>=!]=? | <<<?=? | >>>?=? /x)
++ value_expected = true
++ value_expected = :regexp if match == '~'
++ after_def = false
++ kind = :operator
++
++ elsif match = scan(/ [)\]}] /x)
++ value_expected = after_def = false
++ if !inline_block_stack.empty? && match == '}'
++ inline_block_paren_depth -= 1
++ if inline_block_paren_depth == 0 # closing brace of inline block reached
++ tokens << [match, :inline_delimiter]
++ tokens << [:close, :inline]
++ state, string_delimiter, inline_block_paren_depth = inline_block_stack.pop
++ next
++ end
++ end
++
++ elsif check(/[\d.]/)
++ after_def = value_expected = false
++ if scan(/0[xX][0-9A-Fa-f]+/)
++ kind = :hex
++ elsif scan(/(?>0[0-7]+)(?![89.eEfF])/)
++ kind = :oct
++ elsif scan(/\d+[fFdD]|\d*\.\d+(?:[eE][+-]?\d+)?[fFdD]?|\d+[eE][+-]?\d+[fFdD]?/)
++ kind = :float
++ elsif scan(/\d+[lLgG]?/)
++ kind = :integer
++ end
++
++ elsif match = scan(/'''|"""/)
++ after_def = value_expected = false
++ state = :multiline_string
++ tokens << [:open, :string]
++ string_delimiter = match
++ kind = :delimiter
++
++ # TODO: record.'name'
++ elsif match = scan(/["']/)
++ after_def = value_expected = false
++ state = match == '/' ? :regexp : :string
++ tokens << [:open, state]
++ string_delimiter = match
++ kind = :delimiter
++
++ elsif value_expected && (match = scan(/\//))
++ after_def = value_expected = false
++ tokens << [:open, :regexp]
++ state = :regexp
++ string_delimiter = '/'
++ kind = :delimiter
++
++ elsif scan(/ @ #{IDENT} /ox)
++ after_def = value_expected = false
++ kind = :annotation
++
++ elsif scan(/\//)
++ after_def = false
++ value_expected = true
++ kind = :operator
++
++ else
++ getch
++ kind = :error
++
++ end
++
++ when :string, :regexp, :multiline_string
++ if scan(STRING_CONTENT_PATTERN[string_delimiter])
++ kind = :content
++
++ elsif match = scan(state == :multiline_string ? /'''|"""/ : /["'\/]/)
++ tokens << [match, :delimiter]
++ if state == :regexp
++ # TODO: regexp modifiers? s, m, x, i?
++ modifiers = scan(/[ix]+/)
++ tokens << [modifiers, :modifier] if modifiers && !modifiers.empty?
++ end
++ state = :string if state == :multiline_string
++ tokens << [:close, state]
++ string_delimiter = nil
++ after_def = value_expected = false
++ state = :initial
++ next
++
++ elsif (state == :string || state == :multiline_string) &&
++ (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox))
++ if string_delimiter[0] == ?' && !(match == "\\\\" || match == "\\'")
++ kind = :content
++ else
++ kind = :char
++ end
++ elsif state == :regexp && scan(/ \\ (?: #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
++ kind = :char
++
++ elsif match = scan(/ \$ #{IDENT} /mox)
++ tokens << [:open, :inline]
++ tokens << ['$', :inline_delimiter]
++ match = match[1..-1]
++ tokens << [match, IDENT_KIND[match]]
++ tokens << [:close, :inline]
++ next
++ elsif match = scan(/ \$ \{ /x)
++ tokens << [:open, :inline]
++ tokens << ['${', :inline_delimiter]
++ inline_block_stack << [state, string_delimiter, inline_block_paren_depth]
++ inline_block_paren_depth = 1
++ state = :initial
++ next
++
++ elsif scan(/ \$ /mx)
++ kind = :content
++
++ elsif scan(/ \\. /mx)
++ kind = :content
++
++ elsif scan(/ \\ | \n /x)
++ tokens << [:close, state]
++ kind = :error
++ after_def = value_expected = false
++ state = :initial
++
++ else
++ raise_inspect "else case \" reached; %p not handled." % peek(1), tokens
++ end
++
++ else
++ raise_inspect 'Unknown state', tokens
++
++ end
++
++ match ||= matched
++ if $DEBUG and not kind
++ raise_inspect 'Error token %p in line %d' %
++ [[match, kind], line], tokens
++ end
++ raise_inspect 'Empty token', tokens unless match
++
++ last_token = match unless [:space, :comment, :doctype].include? kind
++
++ tokens << [match, kind]
++
++ end
++
++ if [:multiline_string, :string, :regexp].include? state
++ tokens << [:close, state]
++ end
++
++ tokens
++ end
++
++ end
++
++end
++end
+Index: coderay/scanners/css.rb
+===================================================================
+--- coderay/scanners/css.rb (.../tags/0.8.2/lib) (revision 302)
++++ coderay/scanners/css.rb (.../trunk/lib) (revision 302)
+@@ -38,6 +38,7 @@
+ Id = /##{Name}/
+ Class = /\.#{Name}/
+ PseudoClass = /:#{Name}/
++ AttributeSelector = /\[[^\]]*\]?/
+
+ end
+
+@@ -55,8 +56,8 @@
+ kind = :space
+
+ elsif case states.last
+- when :initial
+- if scan(/#{RE::Ident}|\*/ox)
++ when :initial, :media
++ if scan(/(?>#{RE::Ident})(?!\()|\*/ox)
+ kind = :keyword
+ elsif scan RE::Class
+ kind = :class
+@@ -64,10 +65,19 @@
+ kind = :constant
+ elsif scan RE::PseudoClass
+ kind = :pseudo_class
+- elsif scan RE::Name
+- kind = :identifier
++ elsif match = scan(RE::AttributeSelector)
++ # TODO: Improve highlighting inside of attribute selectors.
++ tokens << [:open, :string]
++ tokens << [match[0,1], :delimiter]
++ tokens << [match[1..-2], :content] if match.size > 2
++ tokens << [match[-1,1], :delimiter] if match[-1] == ?]
++ tokens << [:close, :string]
++ next
++ elsif match = scan(/@media/)
++ kind = :directive
++ states.push :media_before_name
+ end
+-
++
+ when :block
+ if scan(/(?>#{RE::Ident})(?!\()/ox)
+ if value_expected
+@@ -77,6 +87,18 @@
+ end
+ end
+
++ when :media_before_name
++ if scan RE::Ident
++ kind = :type
++ states[-1] = :media_after_name
++ end
++
++ when :media_after_name
++ if scan(/\{/)
++ kind = :operator
++ states[-1] = :media
++ end
++
+ when :comment
+ if scan(/(?:[^*\s]|\*(?!\/))+/)
+ kind = :comment
+@@ -103,7 +125,7 @@
+
+ elsif scan(/\}/)
+ value_expected = false
+- if states.last == :block
++ if states.last == :block || states.last == :media
+ kind = :operator
+ states.pop
+ else
+Index: coderay/scanners/java_script.rb
+===================================================================
+--- coderay/scanners/java_script.rb (.../tags/0.8.2/lib) (revision 302)
++++ coderay/scanners/java_script.rb (.../trunk/lib) (revision 302)
+@@ -94,13 +94,22 @@
+ kind = IDENT_KIND[match]
+ value_expected = (kind == :keyword) && KEYWORDS_EXPECTING_VALUE[match]
+ if kind == :ident
+- if match.index(?$)
++ if match.index(?$) # $ allowed inside an identifier
+ kind = :predefined
+ elsif key_expected && check(/\s*:/)
+ kind = :key
+ end
+ end
+ key_expected = false
++
++ # TODO: string key recognition
++ # There's a problem with expressions like: PAIRS: { 'slide': ['SlideDown','SlideUp'], ... }.
++ # The commas in the array are confusing the scanner here.
++ # elsif key_expected && match = scan(/["']/)
++ # tokens << [:open, :key]
++ # state = :key
++ # string_delimiter = match
++ # kind = :delimiter
+
+ elsif match = scan(/["']/)
+ tokens << [:open, :string]
+@@ -125,7 +134,7 @@
+
+ end
+
+- when :string, :regexp
++ when :string, :regexp, :key
+ if scan(STRING_CONTENT_PATTERN[string_delimiter])
+ kind = :content
+ elsif match = scan(/["'\/]/)
+@@ -139,7 +148,7 @@
+ key_expected = value_expected = false
+ state = :initial
+ next
+- elsif state == :string && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox))
++ elsif state != :regexp && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox))
+ if string_delimiter == "'" && !(match == "\\\\" || match == "\\'")
+ kind = :content
+ else
+@@ -150,7 +159,7 @@
+ elsif scan(/\\./m)
+ kind = :content
+ elsif scan(/ \\ | $ /x)
+- tokens << [:close, :delimiter]
++ tokens << [:close, state]
+ kind = :error
+ key_expected = value_expected = false
+ state = :initial
+Index: coderay/scanners/_map.rb
+===================================================================
+--- coderay/scanners/_map.rb (.../tags/0.8.2/lib) (revision 302)
++++ coderay/scanners/_map.rb (.../trunk/lib) (revision 302)
+@@ -7,6 +7,7 @@
+ :irb => :ruby,
+ :xhtml => :nitro_xhtml,
+ :javascript => :java_script,
++ :js => :java_script,
+ :nitro => :nitro_xhtml,
+ :yml => :yaml
+
+Index: coderay.rb
+===================================================================
+--- coderay.rb (.../tags/0.8.2/lib) (revision 302)
++++ coderay.rb (.../trunk/lib) (revision 302)
+@@ -130,11 +130,11 @@
+ module CodeRay
+
+ # Version: Major.Minor.Teeny[.Revision]
+- # Major: 0 for pre-release
+- # Minor: odd for beta, even for stable
+- # Teeny: development state
+- # Revision: Subversion Revision number (generated on rake)
+- VERSION = '0.8'
++ # Major: 0 for pre-stable, 1 for stable
++ # Minor: feature milestone
++ # Teeny: development state, 0 for pre-release
++ # Revision: Subversion Revision number (generated on rake gem:make)
++ VERSION = '0.9.0'
+
+ require 'coderay/tokens'
+ require 'coderay/scanner'
+Index: README
+===================================================================
+--- README (.../tags/0.8.2/lib) (revision 0)
++++ README (.../trunk/lib) (revision 302)
+@@ -0,0 +1,128 @@
++= CodeRay
++
++[- Tired of blue'n'gray? Try the original version of this documentation on
++coderay.rubychan.de[http://coderay.rubychan.de/doc/] (use Ctrl+Click to open it in its own frame.) -]
++
++== About
++CodeRay is a Ruby library for syntax highlighting.
++
++Syntax highlighting means: You put your code in, and you get it back colored;
++Keywords, strings, floats, comments - all in different colors.
++And with line numbers.
++
++*Syntax* *Highlighting*...
++* makes code easier to read and maintain
++* lets you detect syntax errors faster
++* helps you to understand the syntax of a language
++* looks nice
++* is what everybody should have on their website
++* solves all your problems and makes the girls run after you
++
++Version: 0.8.1
++Author:: murphy (Kornelius Kalnbach)
++Contact:: murphy rubychan de
++Website:: coderay.rubychan.de[http://coderay.rubychan.de]
++License:: GNU LGPL; see LICENSE file in the main directory.
++Subversion:: $Id$
++
++== Installation
++
++You need RubyGems[http://rubyforge.org/frs/?group_id=126].
++
++ % gem install coderay
++
++
++=== Dependencies
++
++CodeRay needs Ruby 1.8.6 or later. It should also run with Ruby 1.9 and JRuby.
++
++
++== Example Usage
++(Forgive me, but this is not highlighted.)
++
++ require 'coderay'
++
++ tokens = CodeRay.scan "puts 'Hello, world!'", :ruby
++ page = tokens.html :line_numbers => :inline, :wrap => :page
++ puts page
++
++
++== Documentation
++
++See CodeRay.
++
++Please report errors in this documentation to <murphy rubychan de>.
++
++
++== Credits
++
++=== Special Thanks to
++
++* licenser (Heinz N. Gies) for ending my QBasic career, inventing the Coder
++ project and the input/output plugin system.
++ CodeRay would not exist without him.
++* bovi (Daniel Bovensiepen) for helping me out on various occasions.
++
++=== Thanks to
++
++* Caleb Clausen for writing RubyLexer (see
++ http://rubyforge.org/projects/rubylexer) and lots of very interesting mail
++ traffic
++* birkenfeld (Georg Brandl) and mitsuhiku (Arnim Ronacher) for PyKleur, now pygments.
++ You guys rock!
++* Jamis Buck for writing Syntax (see http://rubyforge.org/projects/syntax)
++ I got some useful ideas from it.
++* Doug Kearns and everyone else who worked on ruby.vim - it not only helped me
++ coding CodeRay, but also gave me a wonderful target to reach for the Ruby
++ scanner.
++* everyone who uses CodeBB on http://www.rubyforen.de and http://www.python-forum.de
++* iGEL, magichisoka, manveru, WoNáDo and everyone I forgot from rubyforen.de
++* Dethix from ruby-mine.de
++* zickzackw
++* Dookie (who is no longer with us...) and Leonidas from http://www.python-forum.de
++* Andreas Schwarz for finding out that CaseIgnoringWordList was not case
++ ignoring! Such things really make you write tests.
++* closure for the first version of the Scheme scanner.
++* Stefan Walk for the first version of the JavaScript scanner.
++* Josh Goebel for another version of the JavaScript scanner and a Diff scanner.
++* Jonathan Younger for pointing out the licence confusion caused by wrong LICENSE file.
++* Jeremy Hinegardner for finding the shebang-on-empty-file bug in FileType.
++* Charles Oliver Nutter and Yehuda Katz for helping me benchmark CodeRay on JRuby.
++* The folks at redmine.org - thank you for using and fixing CodeRay!
++* matz and all Ruby gods and gurus
++* The inventors of: the computer, the internet, the true color display, HTML &
++ CSS, VIM, RUBY, pizza, microwaves, guitars, scouting, programming, anime,
++ manga, coke and green ice tea.
++
++Where would we be without all those people?
++
++=== Created using
++
++* Ruby[http://ruby-lang.org/]
++* Chihiro (my Sony VAIO laptop); Henrietta (my old MacBook);
++ Triella, born Rico (my new MacBook); as well as
++ Seras and Hikari (my PCs)
++* RDE[http://homepage2.nifty.com/sakazuki/rde_e.html],
++ VIM[http://vim.org] and TextMate[http://macromates.com]
++* Subversion[http://subversion.tigris.org/]
++* Redmine[http://redmine.org/]
++* Firefox[http://www.mozilla.org/products/firefox/],
++ Firebug[http://getfirebug.com/], and
++ Thunderbird[http://www.mozilla.org/products/thunderbird/]
++* RubyGems[http://docs.rubygems.org/] and Rake[http://rake.rubyforge.org/]
++* TortoiseSVN[http://tortoisesvn.tigris.org/] using Apache via
++ XAMPP[http://www.apachefriends.org/en/xampp.html]
++* RDoc (though I'm quite unsatisfied with it)
++* Microsoft Windows (yes, I confess!) and MacOS X
++* GNUWin32, MinGW and some other tools to make the shell under windows a bit
++ less useless
++* Term::ANSIColor[http://term-ansicolor.rubyforge.org/]
++* PLEAC[http://pleac.sourceforge.net/] code examples
++
++=== Free
++
++* As you can see, CodeRay was created under heavy use of *free* software.
++* So CodeRay is also *free*.
++* If you use CodeRay to create software, think about making this software
++ *free*, too.
++* Thanks :)
+
+Property changes on: README
+___________________________________________________________________
+Added: svn:keywords
+ + Id
+Added: svn:mergeinfo
+
diff --git a/etc/0.8.2-vs-0.8.3.diff b/etc/0.8.2-vs-0.8.3.diff
new file mode 100644
index 0000000..a3d19ca
--- /dev/null
+++ b/etc/0.8.2-vs-0.8.3.diff
@@ -0,0 +1,656 @@
+Index: test/functional/basic.rb
+===================================================================
+--- test/functional/basic.rb (revision 308)
++++ test/functional/basic.rb (working copy)
+@@ -48,11 +48,30 @@
+ <div lang="ruby" class="CodeRay">
+ <div class="code"><pre>puts <span style="background-color:#fff0f0;color:#D20"><span style="color:#710">&quot;</span><span style="">Hello, World!</span><span style="color:#710">&quot;</span></span></pre></div>
+ </div>
+-</pre>
+ BLOCKCODE
+ RedCloth.new('bc[ruby]. puts "Hello, World!"').to_html
+ end
+
++ def test_for_redcloth_no_lang
++ require 'rubygems'
++ require 'coderay/for_redcloth'
++ assert_equal "<p><code>puts \"Hello, World!\"</code></p>",
++ RedCloth.new('@puts "Hello, World!"@').to_html
++ assert_equal <<-BLOCKCODE.chomp,
++<pre><code>puts \"Hello, World!\"</code></pre>
++ BLOCKCODE
++ RedCloth.new('bc. puts "Hello, World!"').to_html
++ end
++
++ def test_for_redcloth_style
++ require 'rubygems'
++ require 'coderay/for_redcloth'
++ assert_equal <<-BLOCKCODE.chomp,
++<pre style=\"color: red;\"><code style=\"color: red;\">puts \"Hello, World!\"</code></pre>
++ BLOCKCODE
++ RedCloth.new('bc{color: red}. puts "Hello, World!"').to_html
++ end
++
+ def test_for_redcloth_escapes
+ require 'rubygems'
+ require 'coderay/for_redcloth'
+@@ -62,7 +81,6 @@
+ <div lang="ruby" class="CodeRay">
+ <div class="code"><pre>&amp;</pre></div>
+ </div>
+-</pre>
+ BLOCKCODE
+ RedCloth.new('bc[ruby]. &').to_html
+ end
+Index: test/scanners/java/jruby.expected.raydebug
+===================================================================
+--- test/scanners/java/jruby.expected.raydebug (revision 308)
++++ test/scanners/java/jruby.expected.raydebug (working copy)
+@@ -50,7 +50,7 @@
+ * @author pldms
+ *
+ */)
+-directive(public) type(interface) ident(Finalizable) operator({)
++directive(public) type(interface) class(Finalizable) operator({)
+ directive(public) type(void) ident(finalize)operator(()operator(\))operator(;)
+ operator(})
+ comment(/***** BEGIN LICENSE BLOCK *****
+@@ -91,7 +91,7 @@
+ * The purpose of this class it to help implement the Errno module which in turn in needed by rubicon.
+ * @author Benoit Cerrina
+ **/)
+-directive(public) type(interface) ident(IErrno)
++directive(public) type(interface) class(IErrno)
+ operator({)
+ type(int) ident(EPERM) operator(=) integer(1)operator(;)
+ type(int) ident(ENOENT) operator(=) integer(2)operator(;)
+@@ -590,7 +590,7 @@
+ directive(private) pre_type(Graphics) ident(backBufferGraphics)operator(;)
+ directive(private) ident(Facade) ident(facade)operator(;)
+
+- directive(private) type(interface) ident(Facade) operator({)
++ directive(private) type(interface) class(Facade) operator({)
+ directive(public) pre_type(InputStream) ident(getInputStream)operator(()operator(\))operator(;)
+ directive(public) pre_type(PrintStream) ident(getOutputStream)operator(()operator(\))operator(;)
+ directive(public) pre_type(PrintStream) ident(getErrorStream)operator(()operator(\))operator(;)
+@@ -1742,7 +1742,7 @@
+ comment(/**
+ * @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
+ */)
+-directive(public) type(interface) ident(Profile) operator({)
++directive(public) type(interface) class(Profile) operator({)
+ ident(Profile) ident(ALL) operator(=) keyword(new) ident(Profile)operator(()operator(\)) operator({)
+ directive(public) type(boolean) ident(allowBuiltin)operator(()pre_type(String) ident(name)operator(\)) operator({) keyword(return) keyword(true)operator(;) operator(})
+ directive(public) type(boolean) ident(allowClass)operator(()pre_type(String) ident(name)operator(\)) operator({) keyword(return) keyword(true)operator(;) operator(})
+@@ -21557,7 +21557,7 @@
+ directive(public) directive(static) type(boolean) ident(nativeEnabled) operator(=) keyword(true)operator(;)
+
+
+- directive(public) directive(static) type(interface) ident(LoadServiceCreator) operator({)
++ directive(public) directive(static) type(interface) class(LoadServiceCreator) operator({)
+ ident(LoadService) ident(create)operator(()ident(Ruby) ident(runtime)operator(\))operator(;)
+
+ ident(LoadServiceCreator) ident(DEFAULT) operator(=) keyword(new) ident(LoadServiceCreator)operator(()operator(\)) operator({)
+@@ -36946,7 +36946,7 @@
+ *
+ * @author nicksieger
+ */)
+-directive(public) type(interface) ident(RubyObjectAdapter) operator({)
++directive(public) type(interface) class(RubyObjectAdapter) operator({)
+
+ type(boolean) ident(isKindOf)operator(()ident(IRubyObject) ident(value)operator(,) ident(RubyModule) ident(rubyModule)operator(\))operator(;)
+
+@@ -40779,7 +40779,7 @@
+ *
+ * @author nicksieger
+ */)
+-directive(public) type(interface) ident(RubyRuntimeAdapter) operator({)
++directive(public) type(interface) class(RubyRuntimeAdapter) operator({)
+ ident(IRubyObject) ident(eval)operator(()ident(Ruby) ident(runtime)operator(,) pre_type(String) ident(script)operator(\))operator(;)
+ operator(})
+ comment(/***** BEGIN LICENSE BLOCK *****
+Index: test/scanners/javascript/script.aculo.us.expected.raydebug
+===================================================================
+--- test/scanners/javascript/script.aculo.us.expected.raydebug (revision 308)
++++ test/scanners/javascript/script.aculo.us.expected.raydebug (working copy)
+@@ -2083,9 +2083,9 @@
+ operator(}\))operator(;)
+ operator(})operator(,)
+ key(PAIRS)operator(:) operator({)
+- string<delimiter(')content(slide)delimiter(')>operator(:) operator([)string<delimiter(')content(SlideDown)delimiter(')>operator(,)string<delimiter(')content(SlideUp)delimiter(')>operator(])operator(,)
+- string<delimiter(')content(blind)delimiter(')>operator(:) operator([)string<delimiter(')content(BlindDown)delimiter(')>operator(,)string<delimiter(')content(BlindUp)delimiter(')>operator(])operator(,)
+- string<delimiter(')content(appear)delimiter(')>operator(:) operator([)string<delimiter(')content(Appear)delimiter(')>operator(,)string<delimiter(')content(Fade)delimiter(')>operator(])
++ key<delimiter(')content(slide)delimiter(')>operator(:) operator([)string<delimiter(')content(SlideDown)delimiter(')>operator(,)string<delimiter(')content(SlideUp)delimiter(')>operator(])operator(,)
++ key<delimiter(')content(blind)delimiter(')>operator(:) operator([)string<delimiter(')content(BlindDown)delimiter(')>operator(,)string<delimiter(')content(BlindUp)delimiter(')>operator(])operator(,)
++ key<delimiter(')content(appear)delimiter(')>operator(:) operator([)string<delimiter(')content(Appear)delimiter(')>operator(,)string<delimiter(')content(Fade)delimiter(')>operator(])
+ operator(})operator(,)
+ key(toggle)operator(:) keyword(function)operator(()ident(element)operator(,) ident(effect)operator(\)) operator({)
+ ident(element) operator(=) predefined($)operator(()ident(element)operator(\))operator(;)
+@@ -3378,12 +3378,12 @@
+ keyword(return) ident(value) operator(==) keyword(null) operator(?) string<delimiter(')delimiter(')> operator(:) ident(String)operator(()ident(value)operator(\))operator(;)
+ operator(})operator(,)
+ key(specialChar)operator(:) operator({)
+- string<delimiter(')content(\\b)delimiter(')>operator(:) string<delimiter(')char(\\\\)content(b)delimiter(')>operator(,)
+- string<delimiter(')content(\\t)delimiter(')>operator(:) string<delimiter(')char(\\\\)content(t)delimiter(')>operator(,)
+- string<delimiter(')content(\\n)delimiter(')>operator(:) string<delimiter(')char(\\\\)content(n)delimiter(')>operator(,)
+- string<delimiter(')content(\\f)delimiter(')>operator(:) string<delimiter(')char(\\\\)content(f)delimiter(')>operator(,)
+- string<delimiter(')content(\\r)delimiter(')>operator(:) string<delimiter(')char(\\\\)content(r)delimiter(')>operator(,)
+- string<delimiter(')char(\\\\)delimiter(')>operator(:) string<delimiter(')char(\\\\)char(\\\\)delimiter(')>
++ key<delimiter(')content(\\b)delimiter(')>operator(:) string<delimiter(')char(\\\\)content(b)delimiter(')>operator(,)
++ key<delimiter(')content(\\t)delimiter(')>operator(:) string<delimiter(')char(\\\\)content(t)delimiter(')>operator(,)
++ key<delimiter(')content(\\n)delimiter(')>operator(:) string<delimiter(')char(\\\\)content(n)delimiter(')>operator(,)
++ key<delimiter(')content(\\f)delimiter(')>operator(:) string<delimiter(')char(\\\\)content(f)delimiter(')>operator(,)
++ key<delimiter(')content(\\r)delimiter(')>operator(:) string<delimiter(')char(\\\\)content(r)delimiter(')>operator(,)
++ key<delimiter(')char(\\\\)delimiter(')>operator(:) string<delimiter(')char(\\\\)char(\\\\)delimiter(')>
+ operator(})
+ operator(}\))operator(;)
+
+@@ -4296,9 +4296,9 @@
+
+ key(setRequestHeaders)operator(:) keyword(function)operator(()operator(\)) operator({)
+ keyword(var) ident(headers) operator(=) operator({)
+- string<delimiter(')content(X-Requested-With)delimiter(')>operator(:) string<delimiter(')content(XMLHttpRequest)delimiter(')>operator(,)
+- string<delimiter(')content(X-Prototype-Version)delimiter(')>operator(:) ident(Prototype)operator(.)ident(Version)operator(,)
+- string<delimiter(')content(Accept)delimiter(')>operator(:) string<delimiter(')content(text/javascript, text/html, application/xml, text/xml, */*)delimiter(')>
++ key<delimiter(')content(X-Requested-With)delimiter(')>operator(:) string<delimiter(')content(XMLHttpRequest)delimiter(')>operator(,)
++ key<delimiter(')content(X-Prototype-Version)delimiter(')>operator(:) ident(Prototype)operator(.)ident(Version)operator(,)
++ key<delimiter(')content(Accept)delimiter(')>operator(:) string<delimiter(')content(text/javascript, text/html, application/xml, text/xml, */*)delimiter(')>
+ operator(})operator(;)
+
+ keyword(if) operator(()local_variable(this)operator(.)ident(method) operator(==) string<delimiter(')content(post)delimiter(')>operator(\)) operator({)
+@@ -4705,7 +4705,7 @@
+ key(inspect)operator(:) keyword(function)operator(()ident(element)operator(\)) operator({)
+ ident(element) operator(=) predefined($)operator(()ident(element)operator(\))operator(;)
+ keyword(var) ident(result) operator(=) string<delimiter(')content(<)delimiter(')> operator(+) ident(element)operator(.)ident(tagName)operator(.)ident(toLowerCase)operator(()operator(\))operator(;)
+- predefined($H)operator(({)string<delimiter(')content(id)delimiter(')>operator(:) string<delimiter(')content(id)delimiter(')>operator(,) string<delimiter(')content(className)delimiter(')>operator(:) string<delimiter(')content(class)delimiter(')>operator(}\))operator(.)ident(each)operator(()keyword(function)operator(()ident(pair)operator(\)) operator({)
++ predefined($H)operator(({)key<delimiter(')content(id)delimiter(')>operator(:) string<delimiter(')content(id)delimiter(')>operator(,) key<delimiter(')content(className)delimiter(')>operator(:) string<delimiter(')content(class)delimiter(')>operator(}\))operator(.)ident(each)operator(()keyword(function)operator(()ident(pair)operator(\)) operator({)
+ keyword(var) ident(property) operator(=) ident(pair)operator(.)ident(first)operator(()operator(\))operator(,) ident(attribute) operator(=) ident(pair)operator(.)ident(last)operator(()operator(\))operator(;)
+ keyword(var) ident(value) operator(=) operator(()ident(element)operator([)ident(property)operator(]) operator(||) string<delimiter(')delimiter(')>operator(\))operator(.)ident(toString)operator(()operator(\))operator(;)
+ keyword(if) operator(()ident(value)operator(\)) ident(result) operator(+=) string<delimiter(')content( )delimiter(')> operator(+) ident(attribute) operator(+) string<delimiter(')content(=)delimiter(')> operator(+) ident(value)operator(.)ident(inspect)operator(()keyword(true)operator(\))operator(;)
+@@ -5352,8 +5352,8 @@
+ ident(Element)operator(.)ident(_attributeTranslations) operator(=) operator({)
+ key(read)operator(:) operator({)
+ key(names)operator(:) operator({)
+- string<delimiter(')content(class)delimiter(')>operator(:) string<delimiter(')content(className)delimiter(')>operator(,)
+- string<delimiter(')content(for)delimiter(')>operator(:) string<delimiter(')content(htmlFor)delimiter(')>
++ key<delimiter(')content(class)delimiter(')>operator(:) string<delimiter(')content(className)delimiter(')>operator(,)
++ key<delimiter(')content(for)delimiter(')>operator(:) string<delimiter(')content(htmlFor)delimiter(')>
+ operator(})operator(,)
+ key(values)operator(:) operator({)
+ key(_getAttr)operator(:) keyword(function)operator(()ident(element)operator(,) ident(attribute)operator(\)) operator({)
+@@ -5667,10 +5667,10 @@
+ ident(Object)operator(.)ident(extend)operator(()ident(Form)operator(,) ident(Form)operator(.)ident(Methods)operator(\))operator(;)
+ ident(Object)operator(.)ident(extend)operator(()ident(Form)operator(.)ident(Element)operator(,) ident(Form)operator(.)ident(Element)operator(.)ident(Methods)operator(\))operator(;)
+ ident(Object)operator(.)ident(extend)operator(()ident(Element)operator(.)ident(Methods)operator(.)ident(ByTag)operator(,) operator({)
+- string<delimiter(")content(FORM)delimiter(")>operator(:) ident(Object)operator(.)ident(clone)operator(()ident(Form)operator(.)ident(Methods)operator(\))operator(,)
+- string<delimiter(")content(INPUT)delimiter(")>operator(:) ident(Object)operator(.)ident(clone)operator(()ident(Form)operator(.)ident(Element)operator(.)ident(Methods)operator(\))operator(,)
+- string<delimiter(")content(SELECT)delimiter(")>operator(:) ident(Object)operator(.)ident(clone)operator(()ident(Form)operator(.)ident(Element)operator(.)ident(Methods)operator(\))operator(,)
+- string<delimiter(")content(TEXTAREA)delimiter(")>operator(:) ident(Object)operator(.)ident(clone)operator(()ident(Form)operator(.)ident(Element)operator(.)ident(Methods)operator(\))
++ key<delimiter(")content(FORM)delimiter(")>operator(:) ident(Object)operator(.)ident(clone)operator(()ident(Form)operator(.)ident(Methods)operator(\))operator(,)
++ key<delimiter(")content(INPUT)delimiter(")>operator(:) ident(Object)operator(.)ident(clone)operator(()ident(Form)operator(.)ident(Element)operator(.)ident(Methods)operator(\))operator(,)
++ key<delimiter(")content(SELECT)delimiter(")>operator(:) ident(Object)operator(.)ident(clone)operator(()ident(Form)operator(.)ident(Element)operator(.)ident(Methods)operator(\))operator(,)
++ key<delimiter(")content(TEXTAREA)delimiter(")>operator(:) ident(Object)operator(.)ident(clone)operator(()ident(Form)operator(.)ident(Element)operator(.)ident(Methods)operator(\))
+ operator(}\))operator(;)
+ operator(})
+
+@@ -5705,15 +5705,15 @@
+ keyword(function) ident(findDOMClass)operator(()ident(tagName)operator(\)) operator({)
+ keyword(var) ident(klass)operator(;)
+ keyword(var) ident(trans) operator(=) operator({)
+- string<delimiter(")content(OPTGROUP)delimiter(")>operator(:) string<delimiter(")content(OptGroup)delimiter(")>operator(,) string<delimiter(")content(TEXTAREA)delimiter(")>operator(:) string<delimiter(")content(TextArea)delimiter(")>operator(,) string<delimiter(")content(P)delimiter(")>operator(:) string<delimiter(")content(Paragraph)delimiter(")>operator(,)
+- string<delimiter(")content(FIELDSET)delimiter(")>operator(:) string<delimiter(")content(FieldSet)delimiter(")>operator(,) string<delimiter(")content(UL)delimiter(")>operator(:) string<delimiter(")content(UList)delimiter(")>operator(,) string<delimiter(")content(OL)delimiter(")>operator(:) string<delimiter(")content(OList)delimiter(")>operator(,) string<delimiter(")content(DL)delimiter(")>operator(:) string<delimiter(")content(DList)delimiter(")>operator(,)
+- string<delimiter(")content(DIR)delimiter(")>operator(:) string<delimiter(")content(Directory)delimiter(")>operator(,) string<delimiter(")content(H1)delimiter(")>operator(:) string<delimiter(")content(Heading)delimiter(")>operator(,) string<delimiter(")content(H2)delimiter(")>operator(:) string<delimiter(")content(Heading)delimiter(")>operator(,) string<delimiter(")content(H3)delimiter(")>operator(:) string<delimiter(")content(Heading)delimiter(")>operator(,)
+- string<delimiter(")content(H4)delimiter(")>operator(:) string<delimiter(")content(Heading)delimiter(")>operator(,) string<delimiter(")content(H5)delimiter(")>operator(:) string<delimiter(")content(Heading)delimiter(")>operator(,) string<delimiter(")content(H6)delimiter(")>operator(:) string<delimiter(")content(Heading)delimiter(")>operator(,) string<delimiter(")content(Q)delimiter(")>operator(:) string<delimiter(")content(Quote)delimiter(")>operator(,)
+- string<delimiter(")content(INS)delimiter(")>operator(:) string<delimiter(")content(Mod)delimiter(")>operator(,) string<delimiter(")content(DEL)delimiter(")>operator(:) string<delimiter(")content(Mod)delimiter(")>operator(,) string<delimiter(")content(A)delimiter(")>operator(:) string<delimiter(")content(Anchor)delimiter(")>operator(,) string<delimiter(")content(IMG)delimiter(")>operator(:) string<delimiter(")content(Image)delimiter(")>operator(,) string<delimiter(")content(CAPTION)delimiter(")>operator(:)
+- string<delimiter(")content(TableCaption)delimiter(")>operator(,) string<delimiter(")content(COL)delimiter(")>operator(:) string<delimiter(")content(TableCol)delimiter(")>operator(,) string<delimiter(")content(COLGROUP)delimiter(")>operator(:) string<delimiter(")content(TableCol)delimiter(")>operator(,) string<delimiter(")content(THEAD)delimiter(")>operator(:)
+- string<delimiter(")content(TableSection)delimiter(")>operator(,) string<delimiter(")content(TFOOT)delimiter(")>operator(:) string<delimiter(")content(TableSection)delimiter(")>operator(,) string<delimiter(")content(TBODY)delimiter(")>operator(:) string<delimiter(")content(TableSection)delimiter(")>operator(,) string<delimiter(")content(TR)delimiter(")>operator(:)
+- string<delimiter(")content(TableRow)delimiter(")>operator(,) string<delimiter(")content(TH)delimiter(")>operator(:) string<delimiter(")content(TableCell)delimiter(")>operator(,) string<delimiter(")content(TD)delimiter(")>operator(:) string<delimiter(")content(TableCell)delimiter(")>operator(,) string<delimiter(")content(FRAMESET)delimiter(")>operator(:)
+- string<delimiter(")content(FrameSet)delimiter(")>operator(,) string<delimiter(")content(IFRAME)delimiter(")>operator(:) string<delimiter(")content(IFrame)delimiter(")>
++ key<delimiter(")content(OPTGROUP)delimiter(")>operator(:) string<delimiter(")content(OptGroup)delimiter(")>operator(,) key<delimiter(")content(TEXTAREA)delimiter(")>operator(:) string<delimiter(")content(TextArea)delimiter(")>operator(,) key<delimiter(")content(P)delimiter(")>operator(:) string<delimiter(")content(Paragraph)delimiter(")>operator(,)
++ key<delimiter(")content(FIELDSET)delimiter(")>operator(:) string<delimiter(")content(FieldSet)delimiter(")>operator(,) key<delimiter(")content(UL)delimiter(")>operator(:) string<delimiter(")content(UList)delimiter(")>operator(,) key<delimiter(")content(OL)delimiter(")>operator(:) string<delimiter(")content(OList)delimiter(")>operator(,) key<delimiter(")content(DL)delimiter(")>operator(:) string<delimiter(")content(DList)delimiter(")>operator(,)
++ key<delimiter(")content(DIR)delimiter(")>operator(:) string<delimiter(")content(Directory)delimiter(")>operator(,) key<delimiter(")content(H1)delimiter(")>operator(:) string<delimiter(")content(Heading)delimiter(")>operator(,) key<delimiter(")content(H2)delimiter(")>operator(:) string<delimiter(")content(Heading)delimiter(")>operator(,) key<delimiter(")content(H3)delimiter(")>operator(:) string<delimiter(")content(Heading)delimiter(")>operator(,)
++ key<delimiter(")content(H4)delimiter(")>operator(:) string<delimiter(")content(Heading)delimiter(")>operator(,) key<delimiter(")content(H5)delimiter(")>operator(:) string<delimiter(")content(Heading)delimiter(")>operator(,) key<delimiter(")content(H6)delimiter(")>operator(:) string<delimiter(")content(Heading)delimiter(")>operator(,) key<delimiter(")content(Q)delimiter(")>operator(:) string<delimiter(")content(Quote)delimiter(")>operator(,)
++ key<delimiter(")content(INS)delimiter(")>operator(:) string<delimiter(")content(Mod)delimiter(")>operator(,) key<delimiter(")content(DEL)delimiter(")>operator(:) string<delimiter(")content(Mod)delimiter(")>operator(,) key<delimiter(")content(A)delimiter(")>operator(:) string<delimiter(")content(Anchor)delimiter(")>operator(,) key<delimiter(")content(IMG)delimiter(")>operator(:) string<delimiter(")content(Image)delimiter(")>operator(,) key<delimiter(")content(CAPTION)delimiter(")>operator(:)
++ string<delimiter(")content(TableCaption)delimiter(")>operator(,) key<delimiter(")content(COL)delimiter(")>operator(:) string<delimiter(")content(TableCol)delimiter(")>operator(,) key<delimiter(")content(COLGROUP)delimiter(")>operator(:) string<delimiter(")content(TableCol)delimiter(")>operator(,) key<delimiter(")content(THEAD)delimiter(")>operator(:)
++ string<delimiter(")content(TableSection)delimiter(")>operator(,) key<delimiter(")content(TFOOT)delimiter(")>operator(:) string<delimiter(")content(TableSection)delimiter(")>operator(,) key<delimiter(")content(TBODY)delimiter(")>operator(:) string<delimiter(")content(TableSection)delimiter(")>operator(,) key<delimiter(")content(TR)delimiter(")>operator(:)
++ string<delimiter(")content(TableRow)delimiter(")>operator(,) key<delimiter(")content(TH)delimiter(")>operator(:) string<delimiter(")content(TableCell)delimiter(")>operator(,) key<delimiter(")content(TD)delimiter(")>operator(:) string<delimiter(")content(TableCell)delimiter(")>operator(,) key<delimiter(")content(FRAMESET)delimiter(")>operator(:)
++ string<delimiter(")content(FrameSet)delimiter(")>operator(,) key<delimiter(")content(IFRAME)delimiter(")>operator(:) string<delimiter(")content(IFrame)delimiter(")>
+ operator(})operator(;)
+ keyword(if) operator(()ident(trans)operator([)ident(tagName)operator(]\)) ident(klass) operator(=) string<delimiter(')content(HTML)delimiter(')> operator(+) ident(trans)operator([)ident(tagName)operator(]) operator(+) string<delimiter(')content(Element)delimiter(')>operator(;)
+ keyword(if) operator(()ident(window)operator([)ident(klass)operator(]\)) keyword(return) ident(window)operator([)ident(klass)operator(])operator(;)
+@@ -5941,23 +5941,23 @@
+ keyword(return) keyword(new) ident(Template)operator(()ident(Selector)operator(.)ident(xpath)operator(.)ident(pseudos)operator([)ident(m)operator([)integer(1)operator(]]\))operator(.)ident(evaluate)operator(()ident(m)operator(\))operator(;)
+ operator(})operator(,)
+ key(operators)operator(:) operator({)
+- string<delimiter(')content(=)delimiter(')>operator(:) string<delimiter(")content([@#{1}='#{3}'])delimiter(")>operator(,)
+- string<delimiter(')content(!=)delimiter(')>operator(:) string<delimiter(")content([@#{1}!='#{3}'])delimiter(")>operator(,)
+- string<delimiter(')content(^=)delimiter(')>operator(:) string<delimiter(")content([starts-with(@#{1}, '#{3}'\)])delimiter(")>operator(,)
+- string<delimiter(')content($=)delimiter(')>operator(:) string<delimiter(")content([substring(@#{1}, (string-length(@#{1}\) - string-length('#{3}'\) + 1\)\)='#{3}'])delimiter(")>operator(,)
+- string<delimiter(')content(*=)delimiter(')>operator(:) string<delimiter(")content([contains(@#{1}, '#{3}'\)])delimiter(")>operator(,)
+- string<delimiter(')content(~=)delimiter(')>operator(:) string<delimiter(")content([contains(concat(' ', @#{1}, ' '\), ' #{3} '\)])delimiter(")>operator(,)
+- string<delimiter(')content(|=)delimiter(')>operator(:) string<delimiter(")content([contains(concat('-', @#{1}, '-'\), '-#{3}-'\)])delimiter(")>
++ key<delimiter(')content(=)delimiter(')>operator(:) string<delimiter(")content([@#{1}='#{3}'])delimiter(")>operator(,)
++ key<delimiter(')content(!=)delimiter(')>operator(:) string<delimiter(")content([@#{1}!='#{3}'])delimiter(")>operator(,)
++ key<delimiter(')content(^=)delimiter(')>operator(:) string<delimiter(")content([starts-with(@#{1}, '#{3}'\)])delimiter(")>operator(,)
++ key<delimiter(')content($=)delimiter(')>operator(:) string<delimiter(")content([substring(@#{1}, (string-length(@#{1}\) - string-length('#{3}'\) + 1\)\)='#{3}'])delimiter(")>operator(,)
++ key<delimiter(')content(*=)delimiter(')>operator(:) string<delimiter(")content([contains(@#{1}, '#{3}'\)])delimiter(")>operator(,)
++ key<delimiter(')content(~=)delimiter(')>operator(:) string<delimiter(")content([contains(concat(' ', @#{1}, ' '\), ' #{3} '\)])delimiter(")>operator(,)
++ key<delimiter(')content(|=)delimiter(')>operator(:) string<delimiter(")content([contains(concat('-', @#{1}, '-'\), '-#{3}-'\)])delimiter(")>
+ operator(})operator(,)
+ key(pseudos)operator(:) operator({)
+- string<delimiter(')content(first-child)delimiter(')>operator(:) string<delimiter(')content([not(preceding-sibling::*\)])delimiter(')>operator(,)
+- string<delimiter(')content(last-child)delimiter(')>operator(:) string<delimiter(')content([not(following-sibling::*\)])delimiter(')>operator(,)
+- string<delimiter(')content(only-child)delimiter(')>operator(:) string<delimiter(')content([not(preceding-sibling::* or following-sibling::*\)])delimiter(')>operator(,)
+- string<delimiter(')content(empty)delimiter(')>operator(:) string<delimiter(")content([count(*\) = 0 and (count(text(\)\) = 0 or translate(text(\), ' )char(\\t)char(\\r)char(\\n)content(', ''\) = ''\)])delimiter(")>operator(,)
+- string<delimiter(')content(checked)delimiter(')>operator(:) string<delimiter(")content([@checked])delimiter(")>operator(,)
+- string<delimiter(')content(disabled)delimiter(')>operator(:) string<delimiter(")content([@disabled])delimiter(")>operator(,)
+- string<delimiter(')content(enabled)delimiter(')>operator(:) string<delimiter(")content([not(@disabled\)])delimiter(")>operator(,)
+- string<delimiter(')content(not)delimiter(')>operator(:) keyword(function)operator(()ident(m)operator(\)) operator({)
++ key<delimiter(')content(first-child)delimiter(')>operator(:) string<delimiter(')content([not(preceding-sibling::*\)])delimiter(')>operator(,)
++ key<delimiter(')content(last-child)delimiter(')>operator(:) string<delimiter(')content([not(following-sibling::*\)])delimiter(')>operator(,)
++ key<delimiter(')content(only-child)delimiter(')>operator(:) string<delimiter(')content([not(preceding-sibling::* or following-sibling::*\)])delimiter(')>operator(,)
++ key<delimiter(')content(empty)delimiter(')>operator(:) string<delimiter(")content([count(*\) = 0 and (count(text(\)\) = 0 or translate(text(\), ' )char(\\t)char(\\r)char(\\n)content(', ''\) = ''\)])delimiter(")>operator(,)
++ key<delimiter(')content(checked)delimiter(')>operator(:) string<delimiter(")content([@checked])delimiter(")>operator(,)
++ key<delimiter(')content(disabled)delimiter(')>operator(:) string<delimiter(")content([@disabled])delimiter(")>operator(,)
++ key<delimiter(')content(enabled)delimiter(')>operator(:) string<delimiter(")content([not(@disabled\)])delimiter(")>operator(,)
++ key<delimiter(')content(not)delimiter(')>operator(:) keyword(function)operator(()ident(m)operator(\)) operator({)
+ keyword(var) ident(e) operator(=) ident(m)operator([)integer(6)operator(])operator(,) ident(p) operator(=) ident(Selector)operator(.)ident(patterns)operator(,)
+ ident(x) operator(=) ident(Selector)operator(.)ident(xpath)operator(,) ident(le)operator(,) ident(v)operator(;)
+
+@@ -5975,25 +5975,25 @@
+ operator(})
+ keyword(return) string<delimiter(")content([not()delimiter(")> operator(+) ident(exclusion)operator(.)ident(join)operator(()string<delimiter(")content( and )delimiter(")>operator(\)) operator(+) string<delimiter(")content(\)])delimiter(")>operator(;)
+ operator(})operator(,)
+- string<delimiter(')content(nth-child)delimiter(')>operator(:) keyword(function)operator(()ident(m)operator(\)) operator({)
++ key<delimiter(')content(nth-child)delimiter(')>operator(:) keyword(function)operator(()ident(m)operator(\)) operator({)
+ keyword(return) ident(Selector)operator(.)ident(xpath)operator(.)ident(pseudos)operator(.)ident(nth)operator(()string<delimiter(")content((count(./preceding-sibling::*\) + 1\) )delimiter(")>operator(,) ident(m)operator(\))operator(;)
+ operator(})operator(,)
+- string<delimiter(')content(nth-last-child)delimiter(')>operator(:) keyword(function)operator(()ident(m)operator(\)) operator({)
++ key<delimiter(')content(nth-last-child)delimiter(')>operator(:) keyword(function)operator(()ident(m)operator(\)) operator({)
+ keyword(return) ident(Selector)operator(.)ident(xpath)operator(.)ident(pseudos)operator(.)ident(nth)operator(()string<delimiter(")content((count(./following-sibling::*\) + 1\) )delimiter(")>operator(,) ident(m)operator(\))operator(;)
+ operator(})operator(,)
+- string<delimiter(')content(nth-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(m)operator(\)) operator({)
++ key<delimiter(')content(nth-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(m)operator(\)) operator({)
+ keyword(return) ident(Selector)operator(.)ident(xpath)operator(.)ident(pseudos)operator(.)ident(nth)operator(()string<delimiter(")content(position(\) )delimiter(")>operator(,) ident(m)operator(\))operator(;)
+ operator(})operator(,)
+- string<delimiter(')content(nth-last-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(m)operator(\)) operator({)
++ key<delimiter(')content(nth-last-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(m)operator(\)) operator({)
+ keyword(return) ident(Selector)operator(.)ident(xpath)operator(.)ident(pseudos)operator(.)ident(nth)operator(()string<delimiter(")content((last(\) + 1 - position(\)\) )delimiter(")>operator(,) ident(m)operator(\))operator(;)
+ operator(})operator(,)
+- string<delimiter(')content(first-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(m)operator(\)) operator({)
++ key<delimiter(')content(first-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(m)operator(\)) operator({)
+ ident(m)operator([)integer(6)operator(]) operator(=) string<delimiter(")content(1)delimiter(")>operator(;) keyword(return) ident(Selector)operator(.)ident(xpath)operator(.)ident(pseudos)operator([)string<delimiter(')content(nth-of-type)delimiter(')>operator(])operator(()ident(m)operator(\))operator(;)
+ operator(})operator(,)
+- string<delimiter(')content(last-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(m)operator(\)) operator({)
++ key<delimiter(')content(last-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(m)operator(\)) operator({)
+ ident(m)operator([)integer(6)operator(]) operator(=) string<delimiter(")content(1)delimiter(")>operator(;) keyword(return) ident(Selector)operator(.)ident(xpath)operator(.)ident(pseudos)operator([)string<delimiter(')content(nth-last-of-type)delimiter(')>operator(])operator(()ident(m)operator(\))operator(;)
+ operator(})operator(,)
+- string<delimiter(')content(only-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(m)operator(\)) operator({)
++ key<delimiter(')content(only-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(m)operator(\)) operator({)
+ keyword(var) ident(p) operator(=) ident(Selector)operator(.)ident(xpath)operator(.)ident(pseudos)operator(;) keyword(return) ident(p)operator([)string<delimiter(')content(first-of-type)delimiter(')>operator(])operator(()ident(m)operator(\)) operator(+) ident(p)operator([)string<delimiter(')content(last-of-type)delimiter(')>operator(])operator(()ident(m)operator(\))operator(;)
+ operator(})operator(,)
+ key(nth)operator(:) keyword(function)operator(()ident(fragment)operator(,) ident(m)operator(\)) operator({)
+@@ -6258,46 +6258,46 @@
+ operator(})operator(,)
+
+ key(pseudos)operator(:) operator({)
+- string<delimiter(')content(first-child)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(value)operator(,) ident(root)operator(\)) operator({)
++ key<delimiter(')content(first-child)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(value)operator(,) ident(root)operator(\)) operator({)
+ keyword(for) operator(()keyword(var) ident(i) operator(=) integer(0)operator(,) ident(results) operator(=) operator([)operator(])operator(,) ident(node)operator(;) ident(node) operator(=) ident(nodes)operator([)ident(i)operator(])operator(;) ident(i)operator(++)operator(\)) operator({)
+ keyword(if) operator(()ident(Selector)operator(.)ident(handlers)operator(.)ident(previousElementSibling)operator(()ident(node)operator(\)\)) keyword(continue)operator(;)
+ ident(results)operator(.)ident(push)operator(()ident(node)operator(\))operator(;)
+ operator(})
+ keyword(return) ident(results)operator(;)
+ operator(})operator(,)
+- string<delimiter(')content(last-child)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(value)operator(,) ident(root)operator(\)) operator({)
++ key<delimiter(')content(last-child)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(value)operator(,) ident(root)operator(\)) operator({)
+ keyword(for) operator(()keyword(var) ident(i) operator(=) integer(0)operator(,) ident(results) operator(=) operator([)operator(])operator(,) ident(node)operator(;) ident(node) operator(=) ident(nodes)operator([)ident(i)operator(])operator(;) ident(i)operator(++)operator(\)) operator({)
+ keyword(if) operator(()ident(Selector)operator(.)ident(handlers)operator(.)ident(nextElementSibling)operator(()ident(node)operator(\)\)) keyword(continue)operator(;)
+ ident(results)operator(.)ident(push)operator(()ident(node)operator(\))operator(;)
+ operator(})
+ keyword(return) ident(results)operator(;)
+ operator(})operator(,)
+- string<delimiter(')content(only-child)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(value)operator(,) ident(root)operator(\)) operator({)
++ key<delimiter(')content(only-child)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(value)operator(,) ident(root)operator(\)) operator({)
+ keyword(var) ident(h) operator(=) ident(Selector)operator(.)ident(handlers)operator(;)
+ keyword(for) operator(()keyword(var) ident(i) operator(=) integer(0)operator(,) ident(results) operator(=) operator([)operator(])operator(,) ident(node)operator(;) ident(node) operator(=) ident(nodes)operator([)ident(i)operator(])operator(;) ident(i)operator(++)operator(\))
+ keyword(if) operator((!)ident(h)operator(.)ident(previousElementSibling)operator(()ident(node)operator(\)) operator(&&) operator(!)ident(h)operator(.)ident(nextElementSibling)operator(()ident(node)operator(\)\))
+ ident(results)operator(.)ident(push)operator(()ident(node)operator(\))operator(;)
+ keyword(return) ident(results)operator(;)
+ operator(})operator(,)
+- string<delimiter(')content(nth-child)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(\)) operator({)
++ key<delimiter(')content(nth-child)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(\)) operator({)
+ keyword(return) ident(Selector)operator(.)ident(pseudos)operator(.)ident(nth)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(\))operator(;)
+ operator(})operator(,)
+- string<delimiter(')content(nth-last-child)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(\)) operator({)
++ key<delimiter(')content(nth-last-child)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(\)) operator({)
+ keyword(return) ident(Selector)operator(.)ident(pseudos)operator(.)ident(nth)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(,) keyword(true)operator(\))operator(;)
+ operator(})operator(,)
+- string<delimiter(')content(nth-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(\)) operator({)
++ key<delimiter(')content(nth-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(\)) operator({)
+ keyword(return) ident(Selector)operator(.)ident(pseudos)operator(.)ident(nth)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(,) keyword(false)operator(,) keyword(true)operator(\))operator(;)
+ operator(})operator(,)
+- string<delimiter(')content(nth-last-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(\)) operator({)
++ key<delimiter(')content(nth-last-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(\)) operator({)
+ keyword(return) ident(Selector)operator(.)ident(pseudos)operator(.)ident(nth)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(,) keyword(true)operator(,) keyword(true)operator(\))operator(;)
+ operator(})operator(,)
+- string<delimiter(')content(first-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(\)) operator({)
++ key<delimiter(')content(first-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(\)) operator({)
+ keyword(return) ident(Selector)operator(.)ident(pseudos)operator(.)ident(nth)operator(()ident(nodes)operator(,) string<delimiter(")content(1)delimiter(")>operator(,) ident(root)operator(,) keyword(false)operator(,) keyword(true)operator(\))operator(;)
+ operator(})operator(,)
+- string<delimiter(')content(last-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(\)) operator({)
++ key<delimiter(')content(last-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(\)) operator({)
+ keyword(return) ident(Selector)operator(.)ident(pseudos)operator(.)ident(nth)operator(()ident(nodes)operator(,) string<delimiter(")content(1)delimiter(")>operator(,) ident(root)operator(,) keyword(true)operator(,) keyword(true)operator(\))operator(;)
+ operator(})operator(,)
+- string<delimiter(')content(only-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(\)) operator({)
++ key<delimiter(')content(only-of-type)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(\)) operator({)
+ keyword(var) ident(p) operator(=) ident(Selector)operator(.)ident(pseudos)operator(;)
+ keyword(return) ident(p)operator([)string<delimiter(')content(last-of-type)delimiter(')>operator(])operator(()ident(p)operator([)string<delimiter(')content(first-of-type)delimiter(')>operator(])operator(()ident(nodes)operator(,) ident(formula)operator(,) ident(root)operator(\))operator(,) ident(formula)operator(,) ident(root)operator(\))operator(;)
+ operator(})operator(,)
+@@ -6343,7 +6343,7 @@
+ keyword(return) ident(results)operator(;)
+ operator(})operator(,)
+
+- string<delimiter(')content(empty)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(value)operator(,) ident(root)operator(\)) operator({)
++ key<delimiter(')content(empty)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(value)operator(,) ident(root)operator(\)) operator({)
+ keyword(for) operator(()keyword(var) ident(i) operator(=) integer(0)operator(,) ident(results) operator(=) operator([)operator(])operator(,) ident(node)operator(;) ident(node) operator(=) ident(nodes)operator([)ident(i)operator(])operator(;) ident(i)operator(++)operator(\)) operator({)
+ comment(// IE treats comments as element nodes)
+ keyword(if) operator(()ident(node)operator(.)ident(tagName) operator(==) string<delimiter(')content(!)delimiter(')> operator(||) operator(()ident(node)operator(.)ident(firstChild) operator(&&) operator(!)ident(node)operator(.)ident(innerHTML)operator(.)ident(match)operator(()regexp<delimiter(/)content(^)char(\\s)content(*$)delimiter(/)>operator(\)\)\)) keyword(continue)operator(;)
+@@ -6352,7 +6352,7 @@
+ keyword(return) ident(results)operator(;)
+ operator(})operator(,)
+
+- string<delimiter(')content(not)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(selector)operator(,) ident(root)operator(\)) operator({)
++ key<delimiter(')content(not)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(selector)operator(,) ident(root)operator(\)) operator({)
+ keyword(var) ident(h) operator(=) ident(Selector)operator(.)ident(handlers)operator(,) ident(selectorType)operator(,) ident(m)operator(;)
+ keyword(var) ident(exclusions) operator(=) keyword(new) ident(Selector)operator(()ident(selector)operator(\))operator(.)ident(findElements)operator(()ident(root)operator(\))operator(;)
+ ident(h)operator(.)ident(mark)operator(()ident(exclusions)operator(\))operator(;)
+@@ -6362,19 +6362,19 @@
+ keyword(return) ident(results)operator(;)
+ operator(})operator(,)
+
+- string<delimiter(')content(enabled)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(value)operator(,) ident(root)operator(\)) operator({)
++ key<delimiter(')content(enabled)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(value)operator(,) ident(root)operator(\)) operator({)
+ keyword(for) operator(()keyword(var) ident(i) operator(=) integer(0)operator(,) ident(results) operator(=) operator([)operator(])operator(,) ident(node)operator(;) ident(node) operator(=) ident(nodes)operator([)ident(i)operator(])operator(;) ident(i)operator(++)operator(\))
+ keyword(if) operator((!)ident(node)operator(.)ident(disabled)operator(\)) ident(results)operator(.)ident(push)operator(()ident(node)operator(\))operator(;)
+ keyword(return) ident(results)operator(;)
+ operator(})operator(,)
+
+- string<delimiter(')content(disabled)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(value)operator(,) ident(root)operator(\)) operator({)
++ key<delimiter(')content(disabled)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(value)operator(,) ident(root)operator(\)) operator({)
+ keyword(for) operator(()keyword(var) ident(i) operator(=) integer(0)operator(,) ident(results) operator(=) operator([)operator(])operator(,) ident(node)operator(;) ident(node) operator(=) ident(nodes)operator([)ident(i)operator(])operator(;) ident(i)operator(++)operator(\))
+ keyword(if) operator(()ident(node)operator(.)ident(disabled)operator(\)) ident(results)operator(.)ident(push)operator(()ident(node)operator(\))operator(;)
+ keyword(return) ident(results)operator(;)
+ operator(})operator(,)
+
+- string<delimiter(')content(checked)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(value)operator(,) ident(root)operator(\)) operator({)
++ key<delimiter(')content(checked)delimiter(')>operator(:) keyword(function)operator(()ident(nodes)operator(,) ident(value)operator(,) ident(root)operator(\)) operator({)
+ keyword(for) operator(()keyword(var) ident(i) operator(=) integer(0)operator(,) ident(results) operator(=) operator([)operator(])operator(,) ident(node)operator(;) ident(node) operator(=) ident(nodes)operator([)ident(i)operator(])operator(;) ident(i)operator(++)operator(\))
+ keyword(if) operator(()ident(node)operator(.)ident(checked)operator(\)) ident(results)operator(.)ident(push)operator(()ident(node)operator(\))operator(;)
+ keyword(return) ident(results)operator(;)
+@@ -6382,13 +6382,13 @@
+ operator(})operator(,)
+
+ key(operators)operator(:) operator({)
+- string<delimiter(')content(=)delimiter(')>operator(:) keyword(function)operator(()ident(nv)operator(,) ident(v)operator(\)) operator({) keyword(return) ident(nv) operator(==) ident(v)operator(;) operator(})operator(,)
+- string<delimiter(')content(!=)delimiter(')>operator(:) keyword(function)operator(()ident(nv)operator(,) ident(v)operator(\)) operator({) keyword(return) ident(nv) operator(!=) ident(v)operator(;) operator(})operator(,)
+- string<delimiter(')content(^=)delimiter(')>operator(:) keyword(function)operator(()ident(nv)operator(,) ident(v)operator(\)) operator({) keyword(return) ident(nv)operator(.)ident(startsWith)operator(()ident(v)operator(\))operator(;) operator(})operator(,)
+- string<delimiter(')content($=)delimiter(')>operator(:) keyword(function)operator(()ident(nv)operator(,) ident(v)operator(\)) operator({) keyword(return) ident(nv)operator(.)ident(endsWith)operator(()ident(v)operator(\))operator(;) operator(})operator(,)
+- string<delimiter(')content(*=)delimiter(')>operator(:) keyword(function)operator(()ident(nv)operator(,) ident(v)operator(\)) operator({) keyword(return) ident(nv)operator(.)ident(include)operator(()ident(v)operator(\))operator(;) operator(})operator(,)
+- string<delimiter(')content(~=)delimiter(')>operator(:) keyword(function)operator(()ident(nv)operator(,) ident(v)operator(\)) operator({) keyword(return) operator(()string<delimiter(')content( )delimiter(')> operator(+) ident(nv) operator(+) string<delimiter(')content( )delimiter(')>operator(\))operator(.)ident(include)operator(()string<delimiter(')content( )delimiter(')> operator(+) ident(v) operator(+) string<delimiter(')content( )delimiter(')>operator(\))operator(;) operator(})operator(,)
+- string<delimiter(')content(|=)delimiter(')>operator(:) keyword(function)operator(()ident(nv)operator(,) ident(v)operator(\)) operator({) keyword(return) operator(()string<delimiter(')content(-)delimiter(')> operator(+) ident(nv)operator(.)ident(toUpperCase)operator(()operator(\)) operator(+) string<delimiter(')content(-)delimiter(')>operator(\))operator(.)ident(include)operator(()string<delimiter(')content(-)delimiter(')> operator(+) ident(v)operator(.)ident(toUpperCase)operator(()operator(\)) operator(+) string<delimiter(')content(-)delimiter(')>operator(\))operator(;) operator(})
++ key<delimiter(')content(=)delimiter(')>operator(:) keyword(function)operator(()ident(nv)operator(,) ident(v)operator(\)) operator({) keyword(return) ident(nv) operator(==) ident(v)operator(;) operator(})operator(,)
++ key<delimiter(')content(!=)delimiter(')>operator(:) keyword(function)operator(()ident(nv)operator(,) ident(v)operator(\)) operator({) keyword(return) ident(nv) operator(!=) ident(v)operator(;) operator(})operator(,)
++ key<delimiter(')content(^=)delimiter(')>operator(:) keyword(function)operator(()ident(nv)operator(,) ident(v)operator(\)) operator({) keyword(return) ident(nv)operator(.)ident(startsWith)operator(()ident(v)operator(\))operator(;) operator(})operator(,)
++ key<delimiter(')content($=)delimiter(')>operator(:) keyword(function)operator(()ident(nv)operator(,) ident(v)operator(\)) operator({) keyword(return) ident(nv)operator(.)ident(endsWith)operator(()ident(v)operator(\))operator(;) operator(})operator(,)
++ key<delimiter(')content(*=)delimiter(')>operator(:) keyword(function)operator(()ident(nv)operator(,) ident(v)operator(\)) operator({) keyword(return) ident(nv)operator(.)ident(include)operator(()ident(v)operator(\))operator(;) operator(})operator(,)
++ key<delimiter(')content(~=)delimiter(')>operator(:) keyword(function)operator(()ident(nv)operator(,) ident(v)operator(\)) operator({) keyword(return) operator(()string<delimiter(')content( )delimiter(')> operator(+) ident(nv) operator(+) string<delimiter(')content( )delimiter(')>operator(\))operator(.)ident(include)operator(()string<delimiter(')content( )delimiter(')> operator(+) ident(v) operator(+) string<delimiter(')content( )delimiter(')>operator(\))operator(;) operator(})operator(,)
++ key<delimiter(')content(|=)delimiter(')>operator(:) keyword(function)operator(()ident(nv)operator(,) ident(v)operator(\)) operator({) keyword(return) operator(()string<delimiter(')content(-)delimiter(')> operator(+) ident(nv)operator(.)ident(toUpperCase)operator(()operator(\)) operator(+) string<delimiter(')content(-)delimiter(')>operator(\))operator(.)ident(include)operator(()string<delimiter(')content(-)delimiter(')> operator(+) ident(v)operator(.)ident(toUpperCase)operator(()operator(\)) operator(+) string<delimiter(')content(-)delimiter(')>operator(\))operator(;) operator(})
+ operator(})operator(,)
+
+ key(matchElements)operator(:) keyword(function)operator(()ident(elements)operator(,) ident(expression)operator(\)) operator({)
+Index: Rakefile
+===================================================================
+--- Rakefile (revision 308)
++++ Rakefile (working copy)
+@@ -44,10 +44,12 @@
+ task 'jruby' do
+ RUBY.replace 'jruby'
+ end
++task :j => :jruby
+
+ task 'jruby19' do
+ RUBY.replace 'jruby --1.9'
+ end
++task :j19 => :jruby19
+
+ task 'rubinius' do
+ RUBY.replace 'rbx'
+Index: lib/coderay/helpers/plugin.rb
+===================================================================
+--- lib/coderay/helpers/plugin.rb (revision 308)
++++ lib/coderay/helpers/plugin.rb (working copy)
+@@ -2,8 +2,6 @@
+
+ # = PluginHost
+ #
+-# $Id$
+-#
+ # A simple subclass plugin system.
+ #
+ # Example:
+Index: lib/coderay/duo.rb
+===================================================================
+--- lib/coderay/duo.rb (revision 308)
++++ lib/coderay/duo.rb (working copy)
+@@ -2,8 +2,6 @@
+
+ # = Duo
+ #
+- # $Id: scanner.rb 123 2006-03-21 14:46:34Z murphy $
+- #
+ # A Duo is a convenient way to use CodeRay. You just create a Duo,
+ # giving it a lang (language of the input code) and a format (desired
+ # output format), and call Duo#highlight with the code.
+Index: lib/coderay/scanner.rb
+===================================================================
+--- lib/coderay/scanner.rb (revision 308)
++++ lib/coderay/scanner.rb (working copy)
+@@ -4,8 +4,6 @@
+
+ # = Scanners
+ #
+- # $Id$
+- #
+ # This module holds the Scanner class and its subclasses.
+ # For example, the Ruby scanner is named CodeRay::Scanners::Ruby
+ # can be found in coderay/scanners/ruby.
+Index: lib/coderay/scanners/java.rb
+===================================================================
+--- lib/coderay/scanners/java.rb (revision 308)
++++ lib/coderay/scanners/java.rb (working copy)
+@@ -76,7 +76,7 @@
+ class_name_follows = false
+ else
+ import_clause = true if match == 'import'
+- class_name_follows = true if match == 'class'
++ class_name_follows = true if match == 'class' || match == 'interface'
+ end
+
+ elsif scan(/ \.(?!\d) | [,?:(\[)\]}] | -- | \+\+ | && | \|\| | \*\*=? | [-+*\/%^~&|<>=!]=? | <<<?=? | >>>?=? /x)
+Index: lib/coderay/scanners/rhtml.rb
+===================================================================
+--- lib/coderay/scanners/rhtml.rb (revision 308)
++++ lib/coderay/scanners/rhtml.rb (working copy)
+@@ -5,8 +5,6 @@
+ load :ruby
+
+ # RHTML Scanner
+- #
+- # $Id$
+ class RHTML < Scanner
+
+ include Streamable
+Index: lib/coderay/scanners/xml.rb
+===================================================================
+--- lib/coderay/scanners/xml.rb (revision 308)
++++ lib/coderay/scanners/xml.rb (working copy)
+@@ -5,8 +5,6 @@
+
+ # XML Scanner
+ #
+- # $Id$
+- #
+ # Currently this is the same scanner as Scanners::HTML.
+ class XML < HTML
+
+Index: lib/coderay/scanners/java_script.rb
+===================================================================
+--- lib/coderay/scanners/java_script.rb (revision 308)
++++ lib/coderay/scanners/java_script.rb (working copy)
+@@ -42,6 +42,10 @@
+ '"' => /[^\\"]+/,
+ '/' => /[^\\\/]+/,
+ }
++ KEY_CHECK_PATTERN = {
++ "'" => / [^\\']* (?: \\.? [^\\']* )* '? \s* : /x,
++ '"' => / [^\\"]* (?: \\.? [^\\"]* )* "? \s* : /x,
++ }
+
+ def scan_tokens tokens, options
+
+@@ -103,8 +107,12 @@
+ key_expected = false
+
+ elsif match = scan(/["']/)
+- tokens << [:open, :string]
+- state = :string
++ if key_expected && check(KEY_CHECK_PATTERN[match])
++ state = :key
++ else
++ state = :string
++ end
++ tokens << [:open, state]
+ string_delimiter = match
+ kind = :delimiter
+
+@@ -125,7 +133,7 @@
+
+ end
+
+- when :string, :regexp
++ when :string, :regexp, :key
+ if scan(STRING_CONTENT_PATTERN[string_delimiter])
+ kind = :content
+ elsif match = scan(/["'\/]/)
+@@ -139,7 +147,7 @@
+ key_expected = value_expected = false
+ state = :initial
+ next
+- elsif state == :string && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox))
++ elsif state != :regexp && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox))
+ if string_delimiter == "'" && !(match == "\\\\" || match == "\\'")
+ kind = :content
+ else
+@@ -155,20 +163,20 @@
+ key_expected = value_expected = false
+ state = :initial
+ else
+- raise_inspect "else case \" reached; %p not handled." % peek(1), tokens
++ raise_inspect "else case \" reached; %p not handled." % peek(1), tokens, state
+ end
+
+ else
+- raise_inspect 'Unknown state', tokens
++ raise_inspect 'Unknown state', tokens, state
+
+ end
+
+ match ||= matched
+ if $DEBUG and not kind
+ raise_inspect 'Error token %p in line %d' %
+- [[match, kind], line], tokens
++ [[match, kind], line], tokens, state
+ end
+- raise_inspect 'Empty token', tokens unless match
++ raise_inspect 'Empty token', tokens, state unless match
+
+ tokens << [match, kind]
+
+Index: lib/coderay/scanners/nitro_xhtml.rb
+===================================================================
+--- lib/coderay/scanners/nitro_xhtml.rb (revision 308)
++++ lib/coderay/scanners/nitro_xhtml.rb (working copy)
+@@ -5,8 +5,6 @@
+ load :ruby
+
+ # Nitro XHTML Scanner
+- #
+- # $Id$
+ class NitroXHTML < Scanner
+
+ include Streamable
+Index: lib/coderay/for_redcloth.rb
+===================================================================
+--- lib/coderay/for_redcloth.rb (revision 308)
++++ lib/coderay/for_redcloth.rb (working copy)
+@@ -48,6 +48,7 @@
+ opts[:lang] ? '' : "<pre#{pba(opts)}>"
+ end
+ def bc_close(opts) # :nodoc:
++ opts = @in_bc
+ @in_bc = nil
+ opts[:lang] ? '' : "</pre>\n"
+ end
+Index: lib/README
+===================================================================
+--- lib/README (revision 308)
++++ lib/README (working copy)
+@@ -87,6 +87,7 @@
+ * Jonathan Younger for pointing out the licence confusion caused by wrong LICENSE file.
+ * Jeremy Hinegardner for finding the shebang-on-empty-file bug in FileType.
+ * Charles Oliver Nutter and Yehuda Katz for helping me benchmark CodeRay on JRuby.
++* Andreas Neuhaus for pointing out a markup bug in coderay/for_redcloth.
+ * The folks at redmine.org - thank you for using and fixing CodeRay!
+ * matz and all Ruby gods and gurus
+ * The inventors of: the computer, the internet, the true color display, HTML &
+Index: rake_tasks/test.rake
+===================================================================
+--- rake_tasks/test.rake (revision 308)
++++ rake_tasks/test.rake (working copy)
+@@ -9,6 +9,22 @@
+ ruby "./test/functional/suite.rb"
+ end
+
++ namespace :functional do
++ desc 'run all functional tests on all supported Ruby platforms'
++ task :all do
++ $stdout.sync = true
++ for task in %w(test:functional 19 test:functional jruby test:functional ee test:functional)
++ if task == 'test:functional'
++ puts "\n\nTesting with #{RUBY}..."
++ Rake::Task['test:functional'].reenable
++ Rake::Task['test:functional'].invoke
++ else
++ Rake::Task[task].invoke
++ end
++ end
++ end
++ end
++
+ desc 'run all scanner tests'
+ task :scanners do
+ ruby "./test/scanners/suite.rb"
+Index: rake_tasks/documentation.rake
+===================================================================
+--- rake_tasks/documentation.rake (revision 308)
++++ rake_tasks/documentation.rake (working copy)
+@@ -7,7 +7,7 @@
+ rd.main = 'lib/README'
+ rd.title = "CodeRay Documentation"
+ rd.options << '--line-numbers' << '--inline-source' << '--tab-width' << '2'
+- # rd.options << '--format' << ENV.fetch('format', 'html_coderay')
++ rd.options << '--fmt' << ENV.fetch('format', 'html_coderay')
+ rd.options << '--all'
+
+ rd.template = ENV.fetch('template', CODERAY_TEMPLATE)
diff --git a/etc/check-coderay-gem-stats.sh b/etc/check-coderay-gem-stats.sh
new file mode 100644
index 0000000..a889e40
--- /dev/null
+++ b/etc/check-coderay-gem-stats.sh
@@ -0,0 +1 @@
+curl http://gems.rubyforge.org/stats.html 2>/dev/null | grep -n ">coderay<"
diff --git a/etc/coderay-lib.tmproj b/etc/coderay-lib.tmproj
index 8aba341..8b6a722 100644
--- a/etc/coderay-lib.tmproj
+++ b/etc/coderay-lib.tmproj
@@ -5,8 +5,6 @@
<key>documents</key>
<array>
<dict>
- <key>expanded</key>
- <true/>
<key>name</key>
<string>lib</string>
<key>regexFolderFilter</key>
@@ -88,9 +86,7 @@
<key>filename</key>
<string>../diff</string>
<key>lastUsed</key>
- <date>2009-02-06T00:14:22Z</date>
- <key>selected</key>
- <true/>
+ <date>2009-04-20T20:13:43Z</date>
</dict>
<dict>
<key>filename</key>
@@ -110,7 +106,7 @@
<key>filename</key>
<string>../test/scanners/coderay_suite.rb</string>
<key>lastUsed</key>
- <date>2009-01-22T13:52:45Z</date>
+ <date>2009-04-15T08:56:45Z</date>
</dict>
<dict>
<key>filename</key>
diff --git a/etc/todo/scanners/sql.Keith.rb b/etc/todo/scanners/sql.Keith.rb
new file mode 100644
index 0000000..a889902
--- /dev/null
+++ b/etc/todo/scanners/sql.Keith.rb
@@ -0,0 +1,143 @@
+module CodeRay
+module Scanners
+
+ # by Keith Pitt
+ class SQL < Scanner
+
+ register_for :sql
+
+ include Streamable
+
+ RESERVED_WORDS = %w(
+ all alter and any as asc at authid avg begin between
+ body bulk by case char check close cluster coalesce
+ collect comment commit compress connect constant create
+ current currval cursor day declare default delete
+ desc distinct do drop else elsif end exception exclusive
+ execute exists exit extends extract fetch for forall
+ from function goto group having heap hour if immediate in
+ index indicator insert interface intersect
+ interval into is isolation java level like limited lock
+ loop max min minus minute mlslabel mod mode month natural
+ naturaln new nextval nocopy not nowait null nullif
+ number_base ocirowid of on opaque open operator option or
+ order organization others out package partition pctfree
+ pls_integer positive positiven pragma prior private procedure
+ public raise range raw real record ref release return reverse
+ rollback row rowid rownum rowtype savepoint second select
+ separate set share space sql sqlcode sqlerrm start
+ stddev subtype successful sum synonym sysdate table then
+ timezone_region timezone_abbr timezone_minute
+ to trigger true type uid union unique update
+ use user validate values variance view when
+ whenever where while with work write year zone
+ )
+
+ PREDEFINED_TYPES = %w(
+ array bigint bit binary blob boolean binary_integer char
+ character clob date decimal double float char_base
+ int integer nchar nclob smallint timestamp long number
+ timestamp_hour timestamp_minute varchar varying smallint
+ varchar2 nvarchar money time
+ )
+
+ PREDEFINED_CONSTANTS = %w(
+ NULL true false
+ )
+
+ IDENT_KIND = CaseIgnoringWordList.new(:ident).
+ add(RESERVED_WORDS, :reserved).
+ add(PREDEFINED_TYPES, :pre_type).
+ add(PREDEFINED_CONSTANTS, :pre_constant)
+
+ def scan_tokens tokens, options
+
+ state = :initial
+
+ until eos?
+
+ kind = nil
+ match = nil
+
+ case state
+
+ when :initial
+
+ if scan(/ \s+ | \\\n /x)
+ kind = :space
+
+ elsif scan(%r! -- [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
+ kind = :comment
+
+ elsif scan(/ [-+*\/=<>?:;,!&^|()~%]+ | \.(?!\d) /x)
+ kind = :operator
+
+ elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
+ kind = IDENT_KIND[match]
+ if kind == :ident and check(/:(?!:)/)
+ match << scan(/:/)
+ kind = :label
+ end
+
+ elsif match = scan(/'/)
+ tokens << [:open, :string]
+ state = :string
+ kind = :delimiter
+
+ elsif scan(/(?:\d+)(?![.eEfF])/)
+ kind = :integer
+
+ elsif scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
+ kind = :float
+
+ else
+ getch
+ kind = :error
+
+ end
+
+ when :string
+ if scan(/[^\\\n']+/)
+ kind = :content
+ elsif scan(/'/)
+ tokens << ["'", :delimiter]
+ tokens << [:close, :string]
+ state = :initial
+ next
+ elsif scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
+ kind = :char
+ elsif scan(/ \\ | $ /x)
+ tokens << [:close, :string]
+ kind = :error
+ state = :initial
+ else
+ raise_inspect "else case \" reached; %p not handled." % peek(1), tokens
+ end
+
+ else
+ raise_inspect 'Unknown state', tokens
+
+ end
+
+ match ||= matched
+ if $DEBUG and not kind
+ raise_inspect 'Error token %p in line %d' %
+ [[match, kind], line], tokens
+ end
+ raise_inspect 'Empty token', tokens unless match
+
+ tokens << [match, kind]
+
+ end
+
+ if state == :string
+ tokens << [:close, :string]
+ end
+
+ tokens
+ end
+
+ end
+
+end
+end