diff options
author | murphy <murphy@rubychan.de> | 2011-03-07 22:36:53 +0000 |
---|---|---|
committer | murphy <murphy@rubychan.de> | 2011-03-07 22:36:53 +0000 |
commit | c6baf98c3e5ce3fdc9884968ba1a06fbe29ce49f (patch) | |
tree | 107a5193117263bb4e265ab4b4780eade3e73818 /lib/coderay | |
parent | fc3fb2ed266bf01fdac54cd4abcc346559159cbe (diff) | |
download | coderay-c6baf98c3e5ce3fdc9884968ba1a06fbe29ce49f.tar.gz |
lots of fixes and improvements to the Ruby scanner
Diffstat (limited to 'lib/coderay')
-rw-r--r-- | lib/coderay/scanners/ruby/patterns.rb | 97 | ||||
-rw-r--r-- | lib/coderay/scanners/ruby/string_state.rb | 71 |
2 files changed, 86 insertions, 82 deletions
diff --git a/lib/coderay/scanners/ruby/patterns.rb b/lib/coderay/scanners/ruby/patterns.rb index 0388bde..9effc9a 100644 --- a/lib/coderay/scanners/ruby/patterns.rb +++ b/lib/coderay/scanners/ruby/patterns.rb @@ -65,7 +65,6 @@ module Scanners QUOTE_TO_TYPE.default = :string REGEXP_MODIFIERS = /[mousenix]*/ - REGEXP_SYMBOLS = /[|?*+(){}\[\].^$]/ DECIMAL = /\d+(?:_\d+)*/ OCTAL = /0_?[0-7]+(?:_[0-7]+)*/ @@ -91,7 +90,7 @@ module Scanners [abefnrstv] | [0-7]{1,3} | x[0-9A-Fa-f]{1,2} - | .? + | . /mx CONTROL_META_ESCAPE = / @@ -157,86 +156,20 @@ module Scanners while elsif if not return yield ]) - - FANCY_START = / % ( [qQwWxsr] | (?![a-zA-Z0-9]) ) ([^a-zA-Z0-9]) /mx - - FancyStringType = { - 'q' => [:string, false], - 'Q' => [:string, true], - 'r' => [:regexp, true], - 's' => [:symbol, false], - 'x' => [:shell, true] - } - FancyStringType['w'] = FancyStringType['q'] - FancyStringType['W'] = FancyStringType[''] = FancyStringType['Q'] - - class StringState < Struct.new :type, :interpreted, :delim, :heredoc, - :opening_paren, :paren_depth, :pattern, :next_state - - CLOSING_PAREN = Hash[ *%w[ - ( ) - [ ] - < > - { } - ] ] - - CLOSING_PAREN.each { |k,v| k.freeze; v.freeze } # debug, if I try to change it with << - OPENING_PAREN = CLOSING_PAREN.invert - - STRING_PATTERN = Hash.new do |h, k| - delim, interpreted = *k - delim_pattern = Regexp.escape(delim.dup) # dup: workaround for old Ruby - if closing_paren = CLOSING_PAREN[delim] - delim_pattern = delim_pattern[0..-1] if defined? JRUBY_VERSION # JRuby fix - delim_pattern << Regexp.escape(closing_paren) - end - delim_pattern << '\\\\' unless delim == '\\' - - special_escapes = - case interpreted - when :regexp_symbols - '| ' + REGEXP_SYMBOLS.source - when :words - '| \s' - end - - h[k] = - if interpreted and not delim == '#' - / (?= [#{delim_pattern}] | \# [{$@] #{special_escapes} ) /mx - else - / (?= [#{delim_pattern}] #{special_escapes} ) /mx - end - end - - HEREDOC_PATTERN = Hash.new do |h, k| - delim, interpreted, indented = *k - delim_pattern = Regexp.escape(delim.dup) # dup: workaround for old Ruby - delim_pattern = / \n #{ '(?>[\ \t]*)' if indented } #{ Regexp.new delim_pattern } $ /x - h[k] = - if interpreted - / (?= #{delim_pattern}() | \\ | \# [{$@] ) /mx # $1 set == end of heredoc - else - / (?= #{delim_pattern}() | \\ ) /mx - end - end - - def initialize kind, interpreted, delim, heredoc = false - if heredoc - pattern = HEREDOC_PATTERN[ [delim, interpreted, heredoc == :indented] ] - delim = nil - else - pattern = STRING_PATTERN[ [delim, interpreted] ] - if closing_paren = CLOSING_PAREN[delim] - opening_paren = delim - delim = closing_paren - paren_depth = 1 - end - end - super kind, interpreted, delim, heredoc, opening_paren, paren_depth, pattern, :initial - end - end unless defined? StringState - + + FANCY_STRING_START = / % ( [QqrsWwx] | (?![a-zA-Z0-9]) ) ([^a-zA-Z0-9]) /x + FANCY_STRING_KIND = Hash.new(:string).merge({ + 'r' => :regexp, + 's' => :symbol, + 'x' => :shell, + }) + FANCY_STRING_INTERPRETED = Hash.new(true).merge({ + 'q' => false, + 's' => false, + 'w' => false, + }) + end - + end end diff --git a/lib/coderay/scanners/ruby/string_state.rb b/lib/coderay/scanners/ruby/string_state.rb new file mode 100644 index 0000000..14127c6 --- /dev/null +++ b/lib/coderay/scanners/ruby/string_state.rb @@ -0,0 +1,71 @@ +# encoding: utf-8 +module CodeRay +module Scanners + + class Ruby + + class StringState < Struct.new :type, :interpreted, :delim, :heredoc, + :opening_paren, :paren_depth, :pattern, :next_state # :nodoc: all + + CLOSING_PAREN = Hash[ *%w[ + ( ) + [ ] + < > + { } + ] ].each { |k,v| k.freeze; v.freeze } # debug, if I try to change it with << + + STRING_PATTERN = Hash.new do |h, k| + delim, interpreted = *k + # delim = delim.dup # workaround for old Ruby + delim_pattern = Regexp.escape(delim) + if closing_paren = CLOSING_PAREN[delim] + delim_pattern << Regexp.escape(closing_paren) + end + delim_pattern << '\\\\' unless delim == '\\' + + # special_escapes = + # case interpreted + # when :regexp_symbols + # '| [|?*+(){}\[\].^$]' + # end + + h[k] = + if interpreted && delim != '#' + / (?= [#{delim_pattern}] | \# [{$@] ) /mx + else + / (?= [#{delim_pattern}] ) /mx + end + end + + def initialize kind, interpreted, delim, heredoc = false + if heredoc + pattern = heredoc_pattern delim, interpreted, heredoc == :indented + delim = nil + else + pattern = STRING_PATTERN[ [delim, interpreted] ] + if closing_paren = CLOSING_PAREN[delim] + opening_paren = delim + delim = closing_paren + paren_depth = 1 + end + end + super kind, interpreted, delim, heredoc, opening_paren, paren_depth, pattern, :initial + end + + def heredoc_pattern delim, interpreted, indented + # delim = delim.dup # workaround for old Ruby + delim_pattern = Regexp.escape(delim) + delim_pattern = / \n #{ '(?>[ \t]*)' if indented } #{ Regexp.new delim_pattern } $ /x + if interpreted + / (?= #{delim_pattern}() | \\ | \# [{$@] ) /mx # $1 set == end of heredoc + else + / (?= #{delim_pattern}() | \\ ) /mx + end + end + + end + + end + +end +end |