Class: CodeRay::Scanners::YAML

Inherits:
Scanner
  • Object
show all
Defined in:
vendor/plugins/coderay-0.9.2/lib/coderay/scanners/yaml.rb

Overview

YAML Scanner

Based on the YAML scanner from Syntax by Jamis Buck.

Constant Summary

KINDS_NOT_LOC =
:all

Constants inherited from Scanner

DEFAULT_OPTIONS, KINDS_NOT_LOC, ScanError

Instance Method Summary

Methods inherited from Scanner

#column, #each, file_extension, #initialize, #line, #marshal_dump, #marshal_load, normify, #reset, streamable?, #streaming?, #string=, #tokenize, #tokens

Methods included from CodeRay::Plugin

#helper, #included, #plugin_host, #plugin_id, #register_for, #title

Constructor Details

This class inherits a constructor from CodeRay::Scanners::Scanner

Instance Method Details

- (Object) scan_tokens(tokens, options)



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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'vendor/plugins/coderay-0.9.2/lib/coderay/scanners/yaml.rb', line 14

def scan_tokens tokens, options
  
  value_expected = nil
  state = :initial
  key_indent = indent = 0
  
  until eos?
    
    kind = nil
    match = nil
    key_indent = nil if bol?
    
    if match = scan(/ +[\t ]*/)
      kind = :space
      
    elsif match = scan(/\n+/)
      kind = :space
      state = :initial if match.index(?\n)
      
    elsif match = scan(/#.*/)
      kind = :comment
      
    elsif bol? and case
      when match = scan(/---|\.\.\./)
        tokens << [:open, :head]
        tokens << [match, :head]
        tokens << [:close, :head]
        next
      when match = scan(/%.*/)
        tokens << [match, :doctype]
        next
      end
    
    elsif state == :value and case
      when !check(/(?:"[^"]*")(?=: |:$)/) && scan(/"/)
        tokens << [:open, :string]
        tokens << [matched, :delimiter]
        tokens << [matched, :content] if scan(/ [^"\\]* (?: \\. [^"\\]* )* /mx)
        tokens << [matched, :delimiter] if scan(/"/)
        tokens << [:close, :string]
        next
      when match = scan(/[|>][-+]?/)
        tokens << [:open, :string]
        tokens << [match, :delimiter]
        string_indent = key_indent || column(pos - match.size - 1)
        tokens << [matched, :content] if scan(/(?:\n+ {#{string_indent + 1}}.*)+/)
        tokens << [:close, :string]
        next
      when match = scan(/(?![!"*&]).+?(?=$|\s+#)/)
        tokens << [match, :string]
        string_indent = key_indent || column(pos - match.size - 1)
        tokens << [matched, :string] if scan(/(?:\n+ {#{string_indent + 1}}.*)+/)
        next
      end
      
    elsif case
      when match = scan(/[-:](?= |$)/)
        state = :value if state == :colon && (match == ':' || match == '-')
        state = :value if state == :initial && match == '-'
        kind = :operator
      when match = scan(/[,{}\[\]]/)
        kind = :operator
      when state == :initial && match = scan(/[\w.() ]*\S(?=: |:$)/)
        kind = :key
        key_indent = column(pos - match.size - 1)
        # tokens << [key_indent.inspect, :debug]
        state = :colon
      when match = scan(/(?:"[^"\n]*"|'[^'\n]*')(?=: |:$)/)
        tokens << [:open, :key]
        tokens << [match[0,1], :delimiter]
        tokens << [match[1..-2], :content]
        tokens << [match[-1,1], :delimiter]
        tokens << [:close, :key]
        key_indent = column(pos - match.size - 1)
        # tokens << [key_indent.inspect, :debug]
        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(/<</)
        kind = :class_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]+(:(?! |$)[^:\s]*)* .*/)
        kind = :error
      when scan(/[^:\s]+(:(?! |$)[^:\s]*)*/)
        kind = :error
      end
      
    else
      getch
      kind = :error
      
    end
    
    match ||= matched
    
    if $CODERAY_DEBUG and not kind
      raise_inspect 'Error token %p in line %d' %
        [[match, kind], line], tokens, state
    end
    raise_inspect 'Empty token', tokens, state unless match
    
    tokens << [match, kind]
    
  end
  
  tokens
end