coderay 0.7.4.215 → 0.8.260
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +421 -257
- data/README +24 -13
- data/bin/coderay +9 -4
- data/lib/coderay.rb +19 -17
- data/lib/coderay/duo.rb +67 -9
- data/lib/coderay/encoder.rb +18 -9
- data/lib/coderay/encoders/_map.rb +2 -1
- data/lib/coderay/encoders/debug.rb +14 -11
- data/lib/coderay/encoders/html.rb +44 -17
- data/lib/coderay/encoders/html/css.rb +13 -8
- data/lib/coderay/encoders/html/numerization.rb +8 -6
- data/lib/coderay/encoders/html/output.rb +3 -1
- data/lib/coderay/encoders/statistic.rb +2 -6
- data/lib/coderay/encoders/text.rb +2 -3
- data/lib/coderay/encoders/tokens.rb +3 -3
- data/lib/coderay/encoders/xml.rb +1 -2
- data/lib/coderay/for_redcloth.rb +72 -0
- data/lib/coderay/helpers/file_type.rb +38 -9
- data/lib/coderay/helpers/gzip_simple.rb +1 -0
- data/lib/coderay/helpers/plugin.rb +15 -8
- data/lib/coderay/helpers/word_list.rb +4 -0
- data/lib/coderay/scanner.rb +30 -13
- data/lib/coderay/scanners/_map.rb +1 -1
- data/lib/coderay/scanners/c.rb +3 -1
- data/lib/coderay/scanners/css.rb +181 -0
- data/lib/coderay/scanners/debug.rb +1 -0
- data/lib/coderay/scanners/delphi.rb +1 -0
- data/lib/coderay/scanners/diff.rb +104 -0
- data/lib/coderay/scanners/java.rb +179 -0
- data/lib/coderay/scanners/java/builtin_types.rb +419 -0
- data/lib/coderay/scanners/java_script.rb +187 -0
- data/lib/coderay/scanners/json.rb +106 -0
- data/lib/coderay/scanners/nitro_xhtml.rb +5 -4
- data/lib/coderay/scanners/plaintext.rb +2 -0
- data/lib/coderay/scanners/rhtml.rb +2 -2
- data/lib/coderay/scanners/ruby.rb +64 -50
- data/lib/coderay/scanners/ruby/patterns.rb +15 -19
- data/lib/coderay/scanners/scheme.rb +142 -0
- data/lib/coderay/scanners/sql.Keith.rb +143 -0
- data/lib/coderay/scanners/sql.rb +154 -0
- data/lib/coderay/scanners/xml.rb +1 -0
- data/lib/coderay/styles/cycnus.rb +30 -9
- data/lib/coderay/styles/murphy.rb +15 -2
- data/lib/coderay/{encoders/html/classes.rb → token_classes.rb} +14 -9
- data/lib/coderay/tokens.rb +33 -14
- data/lib/term/ansicolor.rb +220 -0
- metadata +62 -44
| @@ -0,0 +1,106 @@ | |
| 1 | 
            +
            module CodeRay
         | 
| 2 | 
            +
            module Scanners
         | 
| 3 | 
            +
              
         | 
| 4 | 
            +
              class JSON < Scanner
         | 
| 5 | 
            +
                
         | 
| 6 | 
            +
                include Streamable
         | 
| 7 | 
            +
                
         | 
| 8 | 
            +
                register_for :json
         | 
| 9 | 
            +
                
         | 
| 10 | 
            +
                CONSTANTS = %w( true false null )
         | 
| 11 | 
            +
                IDENT_KIND = WordList.new(:key).add(CONSTANTS, :reserved)
         | 
| 12 | 
            +
                
         | 
| 13 | 
            +
                ESCAPE = / [bfnrt\\"\/] /x
         | 
| 14 | 
            +
                UNICODE_ESCAPE =  / u[a-fA-F0-9]{4} /x
         | 
| 15 | 
            +
                
         | 
| 16 | 
            +
                def scan_tokens tokens, options
         | 
| 17 | 
            +
                  
         | 
| 18 | 
            +
                  state = :initial
         | 
| 19 | 
            +
                  stack = []
         | 
| 20 | 
            +
                  string_delimiter = nil
         | 
| 21 | 
            +
                  key_expected = false
         | 
| 22 | 
            +
                  
         | 
| 23 | 
            +
                  until eos?
         | 
| 24 | 
            +
                    
         | 
| 25 | 
            +
                    kind = nil
         | 
| 26 | 
            +
                    match = nil
         | 
| 27 | 
            +
                    
         | 
| 28 | 
            +
                    case state
         | 
| 29 | 
            +
                    
         | 
| 30 | 
            +
                    when :initial
         | 
| 31 | 
            +
                      if match = scan(/ \s+ | \\\n /x)
         | 
| 32 | 
            +
                        tokens << [match, :space]
         | 
| 33 | 
            +
                        next
         | 
| 34 | 
            +
                      elsif match = scan(/ [:,\[{\]}] /x)
         | 
| 35 | 
            +
                        kind = :operator
         | 
| 36 | 
            +
                        case match
         | 
| 37 | 
            +
                        when '{': stack << :object; key_expected = true
         | 
| 38 | 
            +
                        when '[': stack << :array
         | 
| 39 | 
            +
                        when ':': key_expected = false
         | 
| 40 | 
            +
                        when ',': key_expected = true if stack.last == :object
         | 
| 41 | 
            +
                        when '}', ']': stack.pop  # no error recovery, but works for valid JSON
         | 
| 42 | 
            +
                        end
         | 
| 43 | 
            +
                      elsif match = scan(/ true | false | null /x)
         | 
| 44 | 
            +
                        kind = IDENT_KIND[match]
         | 
| 45 | 
            +
                      elsif match = scan(/-?(?:0|[1-9]\d*)/)
         | 
| 46 | 
            +
                        kind = :integer
         | 
| 47 | 
            +
                        if scan(/\.\d+(?:[eE][-+]?\d+)?|[eE][-+]?\d+/)
         | 
| 48 | 
            +
                          match << matched
         | 
| 49 | 
            +
                          kind = :float
         | 
| 50 | 
            +
                        end
         | 
| 51 | 
            +
                      elsif match = scan(/"/)
         | 
| 52 | 
            +
                        state = key_expected ? :key : :string
         | 
| 53 | 
            +
                        tokens << [:open, state]
         | 
| 54 | 
            +
                        kind = :delimiter
         | 
| 55 | 
            +
                      else
         | 
| 56 | 
            +
                        getch
         | 
| 57 | 
            +
                        kind = :error
         | 
| 58 | 
            +
                      end
         | 
| 59 | 
            +
                      
         | 
| 60 | 
            +
                    when :string, :key
         | 
| 61 | 
            +
                      if scan(/[^\\"]+/)
         | 
| 62 | 
            +
                        kind = :content
         | 
| 63 | 
            +
                      elsif scan(/"/)
         | 
| 64 | 
            +
                        tokens << ['"', :delimiter]
         | 
| 65 | 
            +
                        tokens << [:close, state]
         | 
| 66 | 
            +
                        state = :initial
         | 
| 67 | 
            +
                        next
         | 
| 68 | 
            +
                      elsif scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
         | 
| 69 | 
            +
                        kind = :char
         | 
| 70 | 
            +
                      elsif scan(/\\./m)
         | 
| 71 | 
            +
                        kind = :content
         | 
| 72 | 
            +
                      elsif scan(/ \\ | $ /x)
         | 
| 73 | 
            +
                        tokens << [:close, :delimiter]
         | 
| 74 | 
            +
                        kind = :error
         | 
| 75 | 
            +
                        state = :initial
         | 
| 76 | 
            +
                      else
         | 
| 77 | 
            +
                        raise_inspect "else case \" reached; %p not handled." % peek(1), tokens
         | 
| 78 | 
            +
                      end
         | 
| 79 | 
            +
                      
         | 
| 80 | 
            +
                    else
         | 
| 81 | 
            +
                      raise_inspect 'Unknown state', tokens
         | 
| 82 | 
            +
                      
         | 
| 83 | 
            +
                    end
         | 
| 84 | 
            +
                    
         | 
| 85 | 
            +
                    match ||= matched
         | 
| 86 | 
            +
                    if $DEBUG and not kind
         | 
| 87 | 
            +
                      raise_inspect 'Error token %p in line %d' %
         | 
| 88 | 
            +
                        [[match, kind], line], tokens
         | 
| 89 | 
            +
                    end
         | 
| 90 | 
            +
                    raise_inspect 'Empty token', tokens unless match
         | 
| 91 | 
            +
                    
         | 
| 92 | 
            +
                    tokens << [match, kind]
         | 
| 93 | 
            +
                    
         | 
| 94 | 
            +
                  end
         | 
| 95 | 
            +
                  
         | 
| 96 | 
            +
                  if [:string, :key].include? state
         | 
| 97 | 
            +
                    tokens << [:close, state]
         | 
| 98 | 
            +
                  end
         | 
| 99 | 
            +
                  
         | 
| 100 | 
            +
                  tokens
         | 
| 101 | 
            +
                end
         | 
| 102 | 
            +
                
         | 
| 103 | 
            +
              end
         | 
| 104 | 
            +
              
         | 
| 105 | 
            +
            end
         | 
| 106 | 
            +
            end
         | 
| @@ -11,6 +11,7 @@ module Scanners | |
| 11 11 |  | 
| 12 12 | 
             
                include Streamable
         | 
| 13 13 | 
             
                register_for :nitro_xhtml
         | 
| 14 | 
            +
                file_extension :xhtml
         | 
| 14 15 |  | 
| 15 16 | 
             
                NITRO_RUBY_BLOCK = /
         | 
| 16 17 | 
             
                  <\?r
         | 
| @@ -95,20 +96,20 @@ module Scanners | |
| 95 96 | 
             
                      delimiter = CLOSING_PAREN[start_tag[1,1]]
         | 
| 96 97 | 
             
                      end_tag = match[-1,1] == delimiter ? delimiter : ''
         | 
| 97 98 | 
             
                      tokens << [:open, :inline]
         | 
| 98 | 
            -
                      tokens << [start_tag, : | 
| 99 | 
            +
                      tokens << [start_tag, :inline_delimiter]
         | 
| 99 100 | 
             
                      code = match[start_tag.size .. -1 - end_tag.size]
         | 
| 100 101 | 
             
                      @ruby_scanner.tokenize code
         | 
| 101 | 
            -
                      tokens << [end_tag, : | 
| 102 | 
            +
                      tokens << [end_tag, :inline_delimiter] unless end_tag.empty?
         | 
| 102 103 | 
             
                      tokens << [:close, :inline]
         | 
| 103 104 |  | 
| 104 105 | 
             
                    elsif match = scan(/#{NITRO_RUBY_BLOCK}/o)
         | 
| 105 106 | 
             
                      start_tag = '<?r'
         | 
| 106 107 | 
             
                      end_tag = match[-2,2] == '?>' ? '?>' : ''
         | 
| 107 108 | 
             
                      tokens << [:open, :inline]
         | 
| 108 | 
            -
                      tokens << [start_tag, : | 
| 109 | 
            +
                      tokens << [start_tag, :inline_delimiter]
         | 
| 109 110 | 
             
                      code = match[start_tag.size .. -(end_tag.size)-1]
         | 
| 110 111 | 
             
                      @ruby_scanner.tokenize code
         | 
| 111 | 
            -
                      tokens << [end_tag, : | 
| 112 | 
            +
                      tokens << [end_tag, :inline_delimiter] unless end_tag.empty?
         | 
| 112 113 | 
             
                      tokens << [:close, :inline]
         | 
| 113 114 |  | 
| 114 115 | 
             
                    elsif entity = scan(/#{NITRO_ENTITY}/o)
         | 
| @@ -51,10 +51,10 @@ module Scanners | |
| 51 51 | 
             
                      start_tag = match[/\A<%[-=]?/]
         | 
| 52 52 | 
             
                      end_tag = match[/-?%?>?\z/]
         | 
| 53 53 | 
             
                      tokens << [:open, :inline]
         | 
| 54 | 
            -
                      tokens << [start_tag, : | 
| 54 | 
            +
                      tokens << [start_tag, :inline_delimiter]
         | 
| 55 55 | 
             
                      code = match[start_tag.size .. -1 - end_tag.size]
         | 
| 56 56 | 
             
                      @ruby_scanner.tokenize code
         | 
| 57 | 
            -
                      tokens << [end_tag, : | 
| 57 | 
            +
                      tokens << [end_tag, :inline_delimiter] unless end_tag.empty?
         | 
| 58 58 | 
             
                      tokens << [:close, :inline]
         | 
| 59 59 |  | 
| 60 60 | 
             
                    else
         | 
| @@ -18,6 +18,7 @@ module Scanners | |
| 18 18 | 
             
                include Streamable
         | 
| 19 19 |  | 
| 20 20 | 
             
                register_for :ruby
         | 
| 21 | 
            +
                file_extension 'rb'
         | 
| 21 22 |  | 
| 22 23 | 
             
                helper :patterns
         | 
| 23 24 |  | 
| @@ -90,15 +91,15 @@ module Scanners | |
| 90 91 | 
             
                        end
         | 
| 91 92 |  | 
| 92 93 | 
             
                      when '#'
         | 
| 93 | 
            -
                        case peek(1) | 
| 94 | 
            -
                        when  | 
| 94 | 
            +
                        case peek(1)
         | 
| 95 | 
            +
                        when '{'
         | 
| 95 96 | 
             
                          inline_block_stack << [state, depth, heredocs]
         | 
| 96 97 | 
             
                          value_expected = true
         | 
| 97 98 | 
             
                          state = :initial
         | 
| 98 99 | 
             
                          depth = 1
         | 
| 99 100 | 
             
                          tokens << [:open, :inline]
         | 
| 100 101 | 
             
                          tokens << [match + getch, :inline_delimiter]
         | 
| 101 | 
            -
                        when  | 
| 102 | 
            +
                        when '$', '@'
         | 
| 102 103 | 
             
                          tokens << [match, :escape]
         | 
| 103 104 | 
             
                          last_state = state  # scan one token as normal code, then return here
         | 
| 104 105 | 
             
                          state = :initial
         | 
| @@ -121,36 +122,37 @@ module Scanners | |
| 121 122 | 
             
            # }}}
         | 
| 122 123 | 
             
                    else
         | 
| 123 124 | 
             
            # {{{
         | 
| 124 | 
            -
                      if match = scan(/ | 
| 125 | 
            -
                         | 
| 126 | 
            -
                         | 
| 127 | 
            -
                         | 
| 128 | 
            -
             | 
| 129 | 
            -
             | 
| 130 | 
            -
                         | 
| 131 | 
            -
             | 
| 132 | 
            -
             | 
| 133 | 
            -
             | 
| 134 | 
            -
             | 
| 135 | 
            -
                           | 
| 136 | 
            -
             | 
| 137 | 
            -
             | 
| 138 | 
            -
             | 
| 139 | 
            -
             | 
| 140 | 
            -
             | 
| 141 | 
            -
             | 
| 142 | 
            -
                           | 
| 143 | 
            -
                            match << scan(/\s*/) unless eos?
         | 
| 144 | 
            -
                          end
         | 
| 145 | 
            -
                        when ?#, ?=, ?_
         | 
| 146 | 
            -
                          kind = :comment
         | 
| 147 | 
            -
                          value_expected = true
         | 
| 125 | 
            +
                      if match = scan(/[ \t\f]+/)
         | 
| 126 | 
            +
                        kind = :space
         | 
| 127 | 
            +
                        match << scan(/\s*/) unless eos? || heredocs
         | 
| 128 | 
            +
                        value_expected = true if match.index(?\n) # FIXME not quite true
         | 
| 129 | 
            +
                        tokens << [match, kind]
         | 
| 130 | 
            +
                        next
         | 
| 131 | 
            +
                        
         | 
| 132 | 
            +
                      elsif match = scan(/\\?\n/)
         | 
| 133 | 
            +
                        kind = :space
         | 
| 134 | 
            +
                        if match == "\n"
         | 
| 135 | 
            +
                          value_expected = true  # FIXME not quite true
         | 
| 136 | 
            +
                          state = :initial if state == :undef_comma_expected
         | 
| 137 | 
            +
                        end
         | 
| 138 | 
            +
                        if heredocs
         | 
| 139 | 
            +
                          unscan  # heredoc scanning needs \n at start
         | 
| 140 | 
            +
                          state = heredocs.shift
         | 
| 141 | 
            +
                          tokens << [:open, state.type]
         | 
| 142 | 
            +
                          heredocs = nil if heredocs.empty?
         | 
| 143 | 
            +
                          next
         | 
| 148 144 | 
             
                        else
         | 
| 149 | 
            -
                           | 
| 150 | 
            -
                            not handled' % [matched[0].chr], tokens
         | 
| 145 | 
            +
                          match << scan(/\s*/) unless eos?
         | 
| 151 146 | 
             
                        end
         | 
| 152 147 | 
             
                        tokens << [match, kind]
         | 
| 153 148 | 
             
                        next
         | 
| 149 | 
            +
                      
         | 
| 150 | 
            +
                      elsif match = scan(/\#.*/) or
         | 
| 151 | 
            +
                        ( bol? and match = scan(/#{patterns::RUBYDOC_OR_DATA}/o) )
         | 
| 152 | 
            +
                          kind = :comment
         | 
| 153 | 
            +
                          value_expected = true
         | 
| 154 | 
            +
                          tokens << [match, kind]
         | 
| 155 | 
            +
                          next
         | 
| 154 156 |  | 
| 155 157 | 
             
                      elsif state == :initial
         | 
| 156 158 |  | 
| @@ -167,19 +169,19 @@ module Scanners | |
| 167 169 | 
             
                            end
         | 
| 168 170 | 
             
                          end
         | 
| 169 171 | 
             
                          ## experimental!
         | 
| 170 | 
            -
                          value_expected = :set if
         | 
| 171 | 
            -
                            patterns::REGEXP_ALLOWED[match] or check(/#{patterns::VALUE_FOLLOWS}/o)
         | 
| 172 | 
            +
                          value_expected = :set if check(/#{patterns::VALUE_FOLLOWS}/o)
         | 
| 172 173 |  | 
| 173 174 | 
             
                        elsif last_token_dot and match = scan(/#{patterns::METHOD_NAME_OPERATOR}/o)
         | 
| 174 175 | 
             
                          kind = :ident
         | 
| 175 176 | 
             
                          value_expected = :set if check(/#{patterns::VALUE_FOLLOWS}/o)
         | 
| 176 177 |  | 
| 177 178 | 
             
                        # OPERATORS #
         | 
| 178 | 
            -
                         | 
| 179 | 
            +
                        # TODO: match (), [], {} as one single operator
         | 
| 180 | 
            +
                        elsif not last_token_dot and match = scan(/ \.\.\.? | (?:\.|::)() | [,\(\)\[\]\{\}] | ==?=? /x)
         | 
| 179 181 | 
             
                          if match !~ / [.\)\]\}] /x or match =~ /\.\.\.?/
         | 
| 180 182 | 
             
                            value_expected = :set
         | 
| 181 183 | 
             
                          end
         | 
| 182 | 
            -
                          last_token_dot = :set if  | 
| 184 | 
            +
                          last_token_dot = :set if self[1]
         | 
| 183 185 | 
             
                          kind = :operator
         | 
| 184 186 | 
             
                          unless inline_block_stack.empty?
         | 
| 185 187 | 
             
                            case match
         | 
| @@ -210,8 +212,9 @@ module Scanners | |
| 210 212 | 
             
                          interpreted = true
         | 
| 211 213 | 
             
                          state = patterns::StringState.new :regexp, interpreted, match
         | 
| 212 214 |  | 
| 213 | 
            -
                        elsif match = scan( | 
| 214 | 
            -
             | 
| 215 | 
            +
                        # elsif match = scan(/[-+]?#{patterns::NUMERIC}/o)
         | 
| 216 | 
            +
                        elsif match = value_expected ? scan(/[-+]?#{patterns::NUMERIC}/o) : scan(/#{patterns::NUMERIC}/o)
         | 
| 217 | 
            +
                          kind = self[1] ? :float : :integer
         | 
| 215 218 |  | 
| 216 219 | 
             
                        elsif match = scan(/#{patterns::SYMBOL}/o)
         | 
| 217 220 | 
             
                          case delim = match[1]
         | 
| @@ -285,6 +288,18 @@ module Scanners | |
| 285 288 | 
             
                          next
         | 
| 286 289 | 
             
                        end
         | 
| 287 290 |  | 
| 291 | 
            +
                      elsif state == :module_expected
         | 
| 292 | 
            +
                        if match = scan(/<</)
         | 
| 293 | 
            +
                          kind = :operator
         | 
| 294 | 
            +
                        else
         | 
| 295 | 
            +
                          state = :initial
         | 
| 296 | 
            +
                          if match = scan(/ (?:#{patterns::IDENT}::)* #{patterns::IDENT} /ox)
         | 
| 297 | 
            +
                            kind = :class
         | 
| 298 | 
            +
                          else
         | 
| 299 | 
            +
                            next
         | 
| 300 | 
            +
                          end
         | 
| 301 | 
            +
                        end
         | 
| 302 | 
            +
             | 
| 288 303 | 
             
                      elsif state == :undef_expected
         | 
| 289 304 | 
             
                        state = :undef_comma_expected
         | 
| 290 305 | 
             
                        if match = scan(/#{patterns::METHOD_NAME_EX}/o)
         | 
| @@ -306,6 +321,15 @@ module Scanners | |
| 306 321 | 
             
                          next
         | 
| 307 322 | 
             
                        end
         | 
| 308 323 |  | 
| 324 | 
            +
                      elsif state == :alias_expected
         | 
| 325 | 
            +
                        if match = scan(/(#{patterns::METHOD_NAME_OR_SYMBOL})([ \t]+)(#{patterns::METHOD_NAME_OR_SYMBOL})/o)
         | 
| 326 | 
            +
                          tokens << [self[1], (self[1][0] == ?: ? :symbol : :method)]
         | 
| 327 | 
            +
                          tokens << [self[2], :space]
         | 
| 328 | 
            +
                          tokens << [self[3], (self[3][0] == ?: ? :symbol : :method)]
         | 
| 329 | 
            +
                        end
         | 
| 330 | 
            +
                        state = :initial
         | 
| 331 | 
            +
                        next
         | 
| 332 | 
            +
             | 
| 309 333 | 
             
                      elsif state == :undef_comma_expected
         | 
| 310 334 | 
             
                        if match = scan(/,/)
         | 
| 311 335 | 
             
                          kind = :operator
         | 
| @@ -315,23 +339,13 @@ module Scanners | |
| 315 339 | 
             
                          next
         | 
| 316 340 | 
             
                        end
         | 
| 317 341 |  | 
| 318 | 
            -
                      elsif state == :module_expected
         | 
| 319 | 
            -
                        if match = scan(/<</)
         | 
| 320 | 
            -
                          kind = :operator
         | 
| 321 | 
            -
                        else
         | 
| 322 | 
            -
                          state = :initial
         | 
| 323 | 
            -
                          if match = scan(/ (?:#{patterns::IDENT}::)* #{patterns::IDENT} /ox)
         | 
| 324 | 
            -
                            kind = :class
         | 
| 325 | 
            -
                          else
         | 
| 326 | 
            -
                            next
         | 
| 327 | 
            -
                          end
         | 
| 328 | 
            -
                        end
         | 
| 329 | 
            -
             | 
| 330 342 | 
             
                      end
         | 
| 331 343 | 
             
            # }}}
         | 
| 332 | 
            -
             | 
| 333 | 
            -
                       | 
| 334 | 
            -
             | 
| 344 | 
            +
                      
         | 
| 345 | 
            +
                      unless kind == :error
         | 
| 346 | 
            +
                        value_expected = value_expected == :set
         | 
| 347 | 
            +
                        last_token_dot = last_token_dot == :set
         | 
| 348 | 
            +
                      end
         | 
| 335 349 |  | 
| 336 350 | 
             
                      if $DEBUG and not kind
         | 
| 337 351 | 
             
                        raise_inspect 'Error token %p in line %d' %
         | 
| @@ -14,19 +14,14 @@ module Scanners | |
| 14 14 |  | 
| 15 15 | 
             
                DEF_KEYWORDS = %w[ def ]
         | 
| 16 16 | 
             
                UNDEF_KEYWORDS = %w[ undef ]
         | 
| 17 | 
            +
                ALIAS_KEYWORDS = %w[ alias ]
         | 
| 17 18 | 
             
                MODULE_KEYWORDS = %w[class module]
         | 
| 18 19 | 
             
                DEF_NEW_STATE = WordList.new(:initial).
         | 
| 19 20 | 
             
                  add(DEF_KEYWORDS, :def_expected).
         | 
| 20 21 | 
             
                  add(UNDEF_KEYWORDS, :undef_expected).
         | 
| 22 | 
            +
                  add(ALIAS_KEYWORDS, :alias_expected).
         | 
| 21 23 | 
             
                  add(MODULE_KEYWORDS, :module_expected)
         | 
| 22 24 |  | 
| 23 | 
            -
                IDENTS_ALLOWING_REGEXP = %w[
         | 
| 24 | 
            -
                  and or not while until unless if then elsif when sub sub! gsub gsub!
         | 
| 25 | 
            -
                  scan slice slice! split
         | 
| 26 | 
            -
                ]
         | 
| 27 | 
            -
                REGEXP_ALLOWED = WordList.new(false).
         | 
| 28 | 
            -
                  add(IDENTS_ALLOWING_REGEXP, :set)
         | 
| 29 | 
            -
             | 
| 30 25 | 
             
                PREDEFINED_CONSTANTS = %w[
         | 
| 31 26 | 
             
                  nil true false self
         | 
| 32 27 | 
             
                  DATA ARGV ARGF __FILE__ __LINE__
         | 
| @@ -41,19 +36,20 @@ module Scanners | |
| 41 36 | 
             
                METHOD_NAME = / #{IDENT} [?!]? /ox
         | 
| 42 37 | 
             
                METHOD_NAME_OPERATOR = /
         | 
| 43 38 | 
             
                  \*\*?           # multiplication and power
         | 
| 44 | 
            -
                  | [ | 
| 45 | 
            -
                  | [ | 
| 39 | 
            +
                  | [-+~]@?       # plus, minus, tilde with and without @
         | 
| 40 | 
            +
                  | [\/%&|^`]     # division, modulo or format strings, &and, |or, ^xor, `system`
         | 
| 46 41 | 
             
                  | \[\]=?        # array getter and setter
         | 
| 47 42 | 
             
                  | << | >>       # append or shift left, shift right
         | 
| 48 43 | 
             
                  | <=?>? | >=?   # comparison, rocket operator
         | 
| 49 | 
            -
                  | ===? | 
| 44 | 
            +
                  | ===? | =~     # simple equality, case equality, match
         | 
| 45 | 
            +
                  | ![~=@]?       # negation with and without @, not-equal and not-match
         | 
| 50 46 | 
             
                /ox
         | 
| 51 47 | 
             
                METHOD_NAME_EX = / #{IDENT} (?:[?!]|=(?!>))? | #{METHOD_NAME_OPERATOR} /ox
         | 
| 52 48 | 
             
                INSTANCE_VARIABLE = / @ #{IDENT} /ox
         | 
| 53 49 | 
             
                CLASS_VARIABLE = / @@ #{IDENT} /ox
         | 
| 54 50 | 
             
                OBJECT_VARIABLE = / @@? #{IDENT} /ox
         | 
| 55 51 | 
             
                GLOBAL_VARIABLE = / \$ (?: #{IDENT} | [1-9]\d* | 0\w* | [~&+`'=\/,;_.<>!@$?*":\\] | -[a-zA-Z_0-9] ) /ox
         | 
| 56 | 
            -
                PREFIX_VARIABLE = / #{GLOBAL_VARIABLE}  | 
| 52 | 
            +
                PREFIX_VARIABLE = / #{GLOBAL_VARIABLE} | #{OBJECT_VARIABLE} /ox
         | 
| 57 53 | 
             
                VARIABLE = / @?@? #{IDENT} | #{GLOBAL_VARIABLE} /ox
         | 
| 58 54 |  | 
| 59 55 | 
             
                QUOTE_TO_TYPE = {
         | 
| @@ -73,7 +69,7 @@ module Scanners | |
| 73 69 | 
             
                EXPONENT = / [eE] [+-]? #{DECIMAL} /ox
         | 
| 74 70 | 
             
                FLOAT_SUFFIX = / #{EXPONENT} | \. #{DECIMAL} #{EXPONENT}? /ox
         | 
| 75 71 | 
             
                FLOAT_OR_INT = / #{DECIMAL} (?: #{FLOAT_SUFFIX} () )? /ox
         | 
| 76 | 
            -
                NUMERIC = /  | 
| 72 | 
            +
                NUMERIC = / (?: (?=0) (?: #{OCTAL} | #{HEXADECIMAL} | #{BINARY} ) | #{FLOAT_OR_INT} ) /ox
         | 
| 77 73 |  | 
| 78 74 | 
             
                SYMBOL = /
         | 
| 79 75 | 
             
                  :
         | 
| @@ -83,6 +79,7 @@ module Scanners | |
| 83 79 | 
             
                  | ['"]
         | 
| 84 80 | 
             
                  )
         | 
| 85 81 | 
             
                /ox
         | 
| 82 | 
            +
                METHOD_NAME_OR_SYMBOL = / #{METHOD_NAME_EX} | #{SYMBOL} /ox
         | 
| 86 83 |  | 
| 87 84 | 
             
                # TODO investigste \M, \c and \C escape sequences
         | 
| 88 85 | 
             
                # (?: M-\\C-|C-\\M-|M-\\c|c\\M-|c|C-|M-)? (?: \\ (?: [0-7]{3} | x[0-9A-Fa-f]{2} | . ) )
         | 
| @@ -111,7 +108,7 @@ module Scanners | |
| 111 108 | 
             
                  (?:
         | 
| 112 109 | 
             
                    ( [A-Za-z_0-9]+ )  # $2 = delim
         | 
| 113 110 | 
             
                  |
         | 
| 114 | 
            -
                    ( ["' | 
| 111 | 
            +
                    ( ["'`\/] )        # $3 = quote, type
         | 
| 115 112 | 
             
                    ( [^\n]*? ) \3     # $4 = delim
         | 
| 116 113 | 
             
                  )
         | 
| 117 114 | 
             
                /mx
         | 
| @@ -129,15 +126,14 @@ module Scanners | |
| 129 126 | 
             
                /mx
         | 
| 130 127 |  | 
| 131 128 | 
             
                # Checks for a valid value to follow. This enables
         | 
| 132 | 
            -
                #  | 
| 129 | 
            +
                # value_expected in method calls without parentheses.
         | 
| 133 130 | 
             
                VALUE_FOLLOWS = /
         | 
| 134 | 
            -
                  \ | 
| 131 | 
            +
                  (?>[ \t\f\v]+)
         | 
| 135 132 | 
             
                  (?:
         | 
| 136 133 | 
             
                    [%\/][^\s=]
         | 
| 137 | 
            -
                  |
         | 
| 138 | 
            -
             | 
| 139 | 
            -
                  |
         | 
| 140 | 
            -
                    #{CHARACTER}
         | 
| 134 | 
            +
                  | <<-?\S
         | 
| 135 | 
            +
                  | [-+] \d
         | 
| 136 | 
            +
                  | #{CHARACTER}
         | 
| 141 137 | 
             
                  )
         | 
| 142 138 | 
             
                /x
         | 
| 143 139 |  | 
| @@ -0,0 +1,142 @@ | |
| 1 | 
            +
            module CodeRay
         | 
| 2 | 
            +
              module Scanners
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                # Scheme scanner for CodeRay (by closure).
         | 
| 5 | 
            +
                # Thanks to murphy for putting CodeRay into public.
         | 
| 6 | 
            +
                class Scheme < Scanner
         | 
| 7 | 
            +
                  
         | 
| 8 | 
            +
                  register_for :scheme
         | 
| 9 | 
            +
                  file_extension 'scm'
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  CORE_FORMS = %w[
         | 
| 12 | 
            +
                    lambda let let* letrec syntax-case define-syntax let-syntax
         | 
| 13 | 
            +
                    letrec-syntax begin define quote if or and cond case do delay
         | 
| 14 | 
            +
                    quasiquote set! cons force call-with-current-continuation call/cc
         | 
| 15 | 
            +
                  ]
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  IDENT_KIND = CaseIgnoringWordList.new(:ident).
         | 
| 18 | 
            +
                    add(CORE_FORMS, :reserved)
         | 
| 19 | 
            +
                  
         | 
| 20 | 
            +
                  #IDENTIFIER_INITIAL = /[a-z!@\$%&\*\/\:<=>\?~_\^]/i
         | 
| 21 | 
            +
                  #IDENTIFIER_SUBSEQUENT = /#{IDENTIFIER_INITIAL}|\d|\.|\+|-/
         | 
| 22 | 
            +
                  #IDENTIFIER = /#{IDENTIFIER_INITIAL}#{IDENTIFIER_SUBSEQUENT}*|\+|-|\.{3}/
         | 
| 23 | 
            +
                  IDENTIFIER = /[a-zA-Z!@$%&*\/:<=>?~_^][\w!@$%&*\/:<=>?~^.+\-]*|[+-]|\.\.\./
         | 
| 24 | 
            +
                  DIGIT = /\d/
         | 
| 25 | 
            +
                  DIGIT10 = DIGIT
         | 
| 26 | 
            +
                  DIGIT16 = /[0-9a-f]/i
         | 
| 27 | 
            +
                  DIGIT8 = /[0-7]/
         | 
| 28 | 
            +
                  DIGIT2 = /[01]/
         | 
| 29 | 
            +
                  RADIX16 = /\#x/i
         | 
| 30 | 
            +
                  RADIX8 = /\#o/i
         | 
| 31 | 
            +
                  RADIX2 = /\#b/i
         | 
| 32 | 
            +
                  RADIX10 = /\#d/i
         | 
| 33 | 
            +
                  EXACTNESS = /#i|#e/i
         | 
| 34 | 
            +
                  SIGN = /[\+-]?/
         | 
| 35 | 
            +
                  EXP_MARK = /[esfdl]/i
         | 
| 36 | 
            +
                  EXP = /#{EXP_MARK}#{SIGN}#{DIGIT}+/
         | 
| 37 | 
            +
                  SUFFIX = /#{EXP}?/
         | 
| 38 | 
            +
                  PREFIX10 = /#{RADIX10}?#{EXACTNESS}?|#{EXACTNESS}?#{RADIX10}?/
         | 
| 39 | 
            +
                  PREFIX16 = /#{RADIX16}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX16}/
         | 
| 40 | 
            +
                  PREFIX8 = /#{RADIX8}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX8}/
         | 
| 41 | 
            +
                  PREFIX2 = /#{RADIX2}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX2}/
         | 
| 42 | 
            +
                  UINT10 = /#{DIGIT10}+#*/
         | 
| 43 | 
            +
                  UINT16 = /#{DIGIT16}+#*/
         | 
| 44 | 
            +
                  UINT8 = /#{DIGIT8}+#*/
         | 
| 45 | 
            +
                  UINT2 = /#{DIGIT2}+#*/
         | 
| 46 | 
            +
                  DECIMAL = /#{DIGIT10}+#+\.#*#{SUFFIX}|#{DIGIT10}+\.#{DIGIT10}*#*#{SUFFIX}|\.#{DIGIT10}+#*#{SUFFIX}|#{UINT10}#{EXP}/
         | 
| 47 | 
            +
                  UREAL10 = /#{UINT10}\/#{UINT10}|#{DECIMAL}|#{UINT10}/
         | 
| 48 | 
            +
                  UREAL16 = /#{UINT16}\/#{UINT16}|#{UINT16}/
         | 
| 49 | 
            +
                  UREAL8 = /#{UINT8}\/#{UINT8}|#{UINT8}/
         | 
| 50 | 
            +
                  UREAL2 = /#{UINT2}\/#{UINT2}|#{UINT2}/
         | 
| 51 | 
            +
                  REAL10 = /#{SIGN}#{UREAL10}/
         | 
| 52 | 
            +
                  REAL16 = /#{SIGN}#{UREAL16}/
         | 
| 53 | 
            +
                  REAL8 = /#{SIGN}#{UREAL8}/
         | 
| 54 | 
            +
                  REAL2 = /#{SIGN}#{UREAL2}/
         | 
| 55 | 
            +
                  IMAG10 = /i|#{UREAL10}i/
         | 
| 56 | 
            +
                  IMAG16 = /i|#{UREAL16}i/
         | 
| 57 | 
            +
                  IMAG8 = /i|#{UREAL8}i/
         | 
| 58 | 
            +
                  IMAG2 = /i|#{UREAL2}i/
         | 
| 59 | 
            +
                  COMPLEX10 = /#{REAL10}@#{REAL10}|#{REAL10}\+#{IMAG10}|#{REAL10}-#{IMAG10}|\+#{IMAG10}|-#{IMAG10}|#{REAL10}/
         | 
| 60 | 
            +
                  COMPLEX16 = /#{REAL16}@#{REAL16}|#{REAL16}\+#{IMAG16}|#{REAL16}-#{IMAG16}|\+#{IMAG16}|-#{IMAG16}|#{REAL16}/
         | 
| 61 | 
            +
                  COMPLEX8 = /#{REAL8}@#{REAL8}|#{REAL8}\+#{IMAG8}|#{REAL8}-#{IMAG8}|\+#{IMAG8}|-#{IMAG8}|#{REAL8}/
         | 
| 62 | 
            +
                  COMPLEX2 = /#{REAL2}@#{REAL2}|#{REAL2}\+#{IMAG2}|#{REAL2}-#{IMAG2}|\+#{IMAG2}|-#{IMAG2}|#{REAL2}/
         | 
| 63 | 
            +
                  NUM10 = /#{PREFIX10}?#{COMPLEX10}/
         | 
| 64 | 
            +
                  NUM16 = /#{PREFIX16}#{COMPLEX16}/
         | 
| 65 | 
            +
                  NUM8 = /#{PREFIX8}#{COMPLEX8}/
         | 
| 66 | 
            +
                  NUM2 = /#{PREFIX2}#{COMPLEX2}/
         | 
| 67 | 
            +
                  NUM = /#{NUM10}|#{NUM16}|#{NUM8}|#{NUM2}/
         | 
| 68 | 
            +
                
         | 
| 69 | 
            +
                private
         | 
| 70 | 
            +
                  def scan_tokens tokens,options
         | 
| 71 | 
            +
                    
         | 
| 72 | 
            +
                    state = :initial
         | 
| 73 | 
            +
                    ident_kind = IDENT_KIND
         | 
| 74 | 
            +
                    
         | 
| 75 | 
            +
                    until eos?
         | 
| 76 | 
            +
                      kind = match = nil
         | 
| 77 | 
            +
                      
         | 
| 78 | 
            +
                      case state
         | 
| 79 | 
            +
                      when :initial
         | 
| 80 | 
            +
                        if scan(/ \s+ | \\\n /x)
         | 
| 81 | 
            +
                          kind = :space
         | 
| 82 | 
            +
                        elsif scan(/['\(\[\)\]]|#\(/)
         | 
| 83 | 
            +
                          kind = :operator_fat
         | 
| 84 | 
            +
                        elsif scan(/;.*/)
         | 
| 85 | 
            +
                          kind = :comment
         | 
| 86 | 
            +
                        elsif scan(/#\\(?:newline|space|.?)/)
         | 
| 87 | 
            +
                          kind = :char
         | 
| 88 | 
            +
                        elsif scan(/#[ft]/)
         | 
| 89 | 
            +
                          kind = :pre_constant
         | 
| 90 | 
            +
                        elsif scan(/#{IDENTIFIER}/o)
         | 
| 91 | 
            +
                          kind = ident_kind[matched]
         | 
| 92 | 
            +
                        elsif scan(/\./)
         | 
| 93 | 
            +
                          kind = :operator
         | 
| 94 | 
            +
                        elsif scan(/"/)
         | 
| 95 | 
            +
                          tokens << [:open, :string]
         | 
| 96 | 
            +
                          state = :string
         | 
| 97 | 
            +
                          tokens << ['"', :delimiter]
         | 
| 98 | 
            +
                          next
         | 
| 99 | 
            +
                        elsif scan(/#{NUM}/o) and not matched.empty?
         | 
| 100 | 
            +
                          kind = :integer
         | 
| 101 | 
            +
                        elsif getch
         | 
| 102 | 
            +
                          kind = :error
         | 
| 103 | 
            +
                        end
         | 
| 104 | 
            +
                        
         | 
| 105 | 
            +
                      when :string
         | 
| 106 | 
            +
                        if scan(/[^"\\]+/) or scan(/\\.?/)
         | 
| 107 | 
            +
                          kind = :content
         | 
| 108 | 
            +
                        elsif scan(/"/)
         | 
| 109 | 
            +
                          tokens << ['"', :delimiter]
         | 
| 110 | 
            +
                          tokens << [:close, :string]
         | 
| 111 | 
            +
                          state = :initial
         | 
| 112 | 
            +
                          next
         | 
| 113 | 
            +
                        else
         | 
| 114 | 
            +
                          raise_inspect "else case \" reached; %p not handled." % peek(1),
         | 
| 115 | 
            +
                            tokens, state
         | 
| 116 | 
            +
                        end
         | 
| 117 | 
            +
                        
         | 
| 118 | 
            +
                      else
         | 
| 119 | 
            +
                        raise "else case reached"
         | 
| 120 | 
            +
                      end
         | 
| 121 | 
            +
                      
         | 
| 122 | 
            +
                      match ||= matched
         | 
| 123 | 
            +
                      if $DEBUG and not kind
         | 
| 124 | 
            +
                        raise_inspect 'Error token %p in line %d' %
         | 
| 125 | 
            +
                        [[match, kind], line], tokens
         | 
| 126 | 
            +
                      end
         | 
| 127 | 
            +
                      raise_inspect 'Empty token', tokens, state unless match
         | 
| 128 | 
            +
                      
         | 
| 129 | 
            +
                      tokens << [match, kind]
         | 
| 130 | 
            +
                      
         | 
| 131 | 
            +
                    end  # until eos
         | 
| 132 | 
            +
                    
         | 
| 133 | 
            +
                    if state == :string
         | 
| 134 | 
            +
                      tokens << [:close, :string]
         | 
| 135 | 
            +
                    end
         | 
| 136 | 
            +
                    
         | 
| 137 | 
            +
                    tokens
         | 
| 138 | 
            +
                    
         | 
| 139 | 
            +
                  end #scan_tokens
         | 
| 140 | 
            +
                end #class
         | 
| 141 | 
            +
              end #module scanners
         | 
| 142 | 
            +
            end #module coderay
         |