To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / .svn / pristine / 04 / 04bd6b422ff086dcb557f90d7ba79b9553b3ae87.svn-base @ 1297:0a574315af3e

History | View | Annotate | Download (2.07 KB)

1
# encoding: utf-8
2
module CodeRay
3
module Scanners
4
  
5
  class Ruby
6
    
7
    class StringState < Struct.new :type, :interpreted, :delim, :heredoc,
8
      :opening_paren, :paren_depth, :pattern, :next_state  # :nodoc: all
9
      
10
      CLOSING_PAREN = Hash[ *%w[
11
        ( )
12
        [ ]
13
        < >
14
        { }
15
      ] ].each { |k,v| k.freeze; v.freeze }  # debug, if I try to change it with <<
16
      
17
      STRING_PATTERN = Hash.new do |h, k|
18
        delim, interpreted = *k
19
        # delim = delim.dup  # workaround for old Ruby
20
        delim_pattern = Regexp.escape(delim)
21
        if closing_paren = CLOSING_PAREN[delim]
22
          delim_pattern << Regexp.escape(closing_paren)
23
        end
24
        delim_pattern << '\\\\' unless delim == '\\'
25
        
26
        # special_escapes =
27
        #   case interpreted
28
        #   when :regexp_symbols
29
        #     '| [|?*+(){}\[\].^$]'
30
        #   end
31
        
32
        h[k] =
33
          if interpreted && delim != '#'
34
            / (?= [#{delim_pattern}] | \# [{$@] ) /mx
35
          else
36
            / (?= [#{delim_pattern}] ) /mx
37
          end
38
      end
39
      
40
      def initialize kind, interpreted, delim, heredoc = false
41
        if heredoc
42
          pattern = heredoc_pattern delim, interpreted, heredoc == :indented
43
          delim = nil
44
        else
45
          pattern = STRING_PATTERN[ [delim, interpreted] ]
46
          if closing_paren = CLOSING_PAREN[delim]
47
            opening_paren = delim
48
            delim = closing_paren
49
            paren_depth = 1
50
          end
51
        end
52
        super kind, interpreted, delim, heredoc, opening_paren, paren_depth, pattern, :initial
53
      end
54
      
55
      def heredoc_pattern delim, interpreted, indented
56
        # delim = delim.dup  # workaround for old Ruby
57
        delim_pattern = Regexp.escape(delim)
58
        delim_pattern = / (?:\A|\n) #{ '(?>[ \t]*)' if indented } #{ Regexp.new delim_pattern } $ /x
59
        if interpreted
60
          / (?= #{delim_pattern}() | \\ | \# [{$@] ) /mx  # $1 set == end of heredoc
61
        else
62
          / (?= #{delim_pattern}() | \\ ) /mx
63
        end
64
      end
65
      
66
    end
67
    
68
  end
69
  
70
end
71
end