summaryrefslogtreecommitdiff
path: root/lib/coderay/scanners/yaml.rb
blob: 06da9070fd2ad78f1215cdc0e519e84272c6fa86 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
module CodeRay
module Scanners
  
  # YAML Scanner
  #
  # Based on the YAML scanner from Syntax by Jamis Buck.
  class XML < Scanner
    
    register_for :yaml
    file_extension 'yml'
    
    def scan_tokens tokens, options
      
      value_expected = nil
      states = :initial
      
      until eos?
        
        kind = nil
        match = nil
        
        if match = scan(/\s+/)
          kind = :space
          state = :initial if match.index(?\n)
          
        elsif match = scan(/#.*/)
          kind = :comment
          
        elsif bol? and case
          when scan(/---/)
            kind = :tag
          end
        
        elsif state == :value and case
          when scan(/(?![!*&]).+(?=$|\s+#)/)
            kind = :string
          end
          
        elsif case
          when match = scan(/[-:](?= )/)
            state = :value if state == :colon && (match == ':' || match == '-')
            kind = :operator
          when match = scan(/[,{}\[\]]/)
            kind = :operator
          when state == :initial && scan(/\w+(?=:)/)
            kind = :key
            state = :colon
          when state == :initial && match = scan(/(?:"[^"]*"|'[^']*')(?=:)/)
            tokens << [:open, :key]
            tokens << [match[0,1], :delimiter]
            tokens << [match[1..-2], :content]
            tokens << [match[-1,1], :delimiter]
            tokens << [:close, :key]
            state = :colon
            next
          when scan(/(![\w\/]+)(:([\w:]+))?/)
            tokens << [self[1], :type]
            if self[2]
              tokens << [':', :operator]
              tokens << [self[3], :class]
            end
            next
          when scan(/&\S+/)
            kind = :variable
          when scan(/\*\w+/)
            kind = :global_variable
          when scan(/\d\d:\d\d:\d\d/)
            kind = :oct
          when scan(/\d\d\d\d-\d\d-\d\d\s\d\d:\d\d:\d\d(\.\d+)? [-+]\d\d:\d\d/)
            kind = :oct
          when scan(/:\w+/)
            kind = :symbol
          when scan(/[^:\s]+/)
            kind = :string
          # when scan(/>-?/)
          #   kind = :punct
          #   kind = :normal, scan(/.*$/)
          #   append getch until eos? || bol?
          #   return if eos?
          #   indent = check(/ */)
          #   kind = :string
          #   loop do
          #     line = check_until(/[\n\r]|\Z/)
          #     break if line.nil?
          #     if line.chomp.length > 0
          #       this_indent = line.chomp.match( /^\s*/ )[0]
          #       break if this_indent.length < indent.length
          #     end
          #     append scan_until(/[\n\r]|\Z/)
          #   end
          end
          
        else
          getch
          kind = :error
          
        end
        
        match ||= matched
        
        raise_inspect 'Error token %p in line %d' % [[match, kind], line], tokens if $DEBUG && !kind
        raise_inspect 'Empty token', tokens unless match
        
        tokens << [match, kind]
        
      end
      
      tokens
    end
    
  end
  
end
end