Class | CodeRay::Scanners::CSS |
In: |
lib/coderay/scanners/css.rb
|
Parent: | Scanner |
KINDS_NOT_LOC | = | [ :comment, :class, :pseudo_class, :type, :constant, :directive, :key, :value, :operator, :color, :float, :error, :important, ] |
# File lib/coderay/scanners/css.rb, line 52 52: def scan_tokens tokens, options 53: 54: value_expected = nil 55: states = [:initial] 56: 57: until eos? 58: 59: kind = nil 60: match = nil 61: 62: if scan(/\s+/) 63: kind = :space 64: 65: elsif case states.last 66: when :initial, :media 67: if scan(/(?>#{RE::Ident})(?!\()|\*/ox) 68: kind = :type 69: elsif scan RE::Class 70: kind = :class 71: elsif scan RE::Id 72: kind = :constant 73: elsif scan RE::PseudoClass 74: kind = :pseudo_class 75: elsif match = scan(RE::AttributeSelector) 76: # TODO: Improve highlighting inside of attribute selectors. 77: tokens << [:open, :string] 78: tokens << [match[0,1], :delimiter] 79: tokens << [match[1..-2], :content] if match.size > 2 80: tokens << [match[-1,1], :delimiter] if match[-1] == ?] 81: tokens << [:close, :string] 82: next 83: elsif match = scan(/@media/) 84: kind = :directive 85: states.push :media_before_name 86: end 87: 88: when :block 89: if scan(/(?>#{RE::Ident})(?!\()/ox) 90: if value_expected 91: kind = :value 92: else 93: kind = :key 94: end 95: end 96: 97: when :media_before_name 98: if scan RE::Ident 99: kind = :type 100: states[-1] = :media_after_name 101: end 102: 103: when :media_after_name 104: if scan(/\{/) 105: kind = :operator 106: states[-1] = :media 107: end 108: 109: when :comment 110: if scan(/(?:[^*\s]|\*(?!\/))+/) 111: kind = :comment 112: elsif scan(/\*\//) 113: kind = :comment 114: states.pop 115: elsif scan(/\s+/) 116: kind = :space 117: end 118: 119: else 120: raise_inspect 'Unknown state', tokens 121: 122: end 123: 124: elsif scan(/\/\*/) 125: kind = :comment 126: states.push :comment 127: 128: elsif scan(/\{/) 129: value_expected = false 130: kind = :operator 131: states.push :block 132: 133: elsif scan(/\}/) 134: value_expected = false 135: if states.last == :block || states.last == :media 136: kind = :operator 137: states.pop 138: else 139: kind = :error 140: end 141: 142: elsif match = scan(/#{RE::String}/o) 143: tokens << [:open, :string] 144: tokens << [match[0, 1], :delimiter] 145: tokens << [match[1..-2], :content] if match.size > 2 146: tokens << [match[-1, 1], :delimiter] if match.size >= 2 147: tokens << [:close, :string] 148: next 149: 150: elsif match = scan(/#{RE::Function}/o) 151: tokens << [:open, :string] 152: start = match[/^\w+\(/] 153: tokens << [start, :delimiter] 154: if match[-1] == ?) 155: tokens << [match[start.size..-2], :content] 156: tokens << [')', :delimiter] 157: else 158: tokens << [match[start.size..-1], :content] 159: end 160: tokens << [:close, :string] 161: next 162: 163: elsif scan(/(?: #{RE::Dimension} | #{RE::Percentage} | #{RE::Num} )/ox) 164: kind = :float 165: 166: elsif scan(/#{RE::Color}/o) 167: kind = :color 168: 169: elsif scan(/! *important/) 170: kind = :important 171: 172: elsif scan(/rgb\([^()\n]*\)?/) 173: kind = :color 174: 175: elsif scan(/#{RE::AtKeyword}/o) 176: kind = :directive 177: 178: elsif match = scan(/ [+>:;,.=()\/] /x) 179: if match == ':' 180: value_expected = true 181: elsif match == ';' 182: value_expected = false 183: end 184: kind = :operator 185: 186: else 187: getch 188: kind = :error 189: 190: end 191: 192: match ||= matched 193: if $CODERAY_DEBUG and not kind 194: raise_inspect 'Error token %p in line %d' % 195: [[match, kind], line], tokens 196: end 197: raise_inspect 'Empty token', tokens unless match 198: 199: tokens << [match, kind] 200: 201: end 202: 203: tokens 204: end