diff options
Diffstat (limited to 'lib/coderay/scanners/css2.rb')
-rw-r--r-- | lib/coderay/scanners/css2.rb | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/lib/coderay/scanners/css2.rb b/lib/coderay/scanners/css2.rb new file mode 100644 index 0000000..0c0d4a0 --- /dev/null +++ b/lib/coderay/scanners/css2.rb @@ -0,0 +1,90 @@ +module CodeRay +module Scanners + + class CSS2 < RuleBasedScanner + + register_for :css2 + + KINDS_NOT_LOC = [ + :comment, + :class, :pseudo_class, :tag, + :id, :directive, + :key, :value, :operator, :color, :float, :string, + :error, :important, :type, + ] # :nodoc: + + module RE # :nodoc: + Hex = /[0-9a-fA-F]/ + Unicode = /\\#{Hex}{1,6}\b/ # differs from standard because it allows uppercase hex too + Escape = /#{Unicode}|\\[^\n0-9a-fA-F]/ + NMChar = /[-_a-zA-Z0-9]/ + NMStart = /[_a-zA-Z]/ + String1 = /(")((?:[^\n\\"]+|\\\n|#{Escape})+)?(")?/ # TODO: buggy regexp + String2 = /(')((?:[^\n\\']+|\\\n|#{Escape})+)?(')?/ # TODO: buggy regexp + String = /#{String1}|#{String2}/ + + HexColor = /#(?:#{Hex}{6}|#{Hex}{3})/ + + Num = /-?(?:[0-9]*\.[0-9]+|[0-9]+)n?/ + Name = /#{NMChar}+/ + Ident = /-?#{NMStart}#{NMChar}*/ + AtKeyword = /@#{Ident}/ + Percentage = /#{Num}%/ + + reldimensions = %w[em ex px] + absdimensions = %w[in cm mm pt pc] + Unit = Regexp.union(*(reldimensions + absdimensions + %w[s dpi dppx deg])) + + Dimension = /#{Num}#{Unit}/ + + Function = /((?:url|alpha|attr|counters?)\()((?:[^)\n]|\\\))+)?(\))?/ + + Id = /(?!#{HexColor}\b(?!-))##{Name}/ + Class = /\.#{Name}/ + PseudoClass = /::?#{Ident}/ + AttributeSelector = /(\[)([^\]]+)?(\])?/ + end + + state :initial do + on %r/\s+/, :space + + on check_if(:block), check_if(:value_expected), %r/(?>#{RE::Ident})(?!\()/x, :value + on check_if(:block), %r/(?>#{RE::Ident})(?!\()/x, :key + + on check_unless(:block), %r/(?>#{RE::Ident})(?!\()|\*/x, :tag + on check_unless(:block), RE::Class, :class + on check_unless(:block), RE::Id, :id + on check_unless(:block), RE::PseudoClass, :pseudo_class + # TODO: Improve highlighting inside of attribute selectors. + on check_unless(:block), RE::AttributeSelector, groups(:operator, :attribute_name, :operator) + on check_unless(:block), %r/(@media)(\s+)?(#{RE::Ident})?(\s+)?(\{)?/, groups(:directive, :space, :type, :space, :operator) + + on %r/\/\*(?:.*?\*\/|\z)/m, :comment + on %r/\{/, :operator, flag_off(:value_expected), flag_on(:block) + on %r/\}/, :operator, flag_off(:value_expected), flag_off(:block) + on RE::String1, push(:string), groups(:delimiter, :content, :delimiter), pop + on RE::String2, push(:string), groups(:delimiter, :content, :delimiter), pop + on RE::Function, push(:function), groups(:delimiter, :content, :delimiter), pop + on %r/(?: #{RE::Dimension} | #{RE::Percentage} | #{RE::Num} )/x, :float + on RE::HexColor, :color + on %r/! *important/, :important + on %r/(?:rgb|hsl)a?\([^()\n]*\)?/, :color + on RE::AtKeyword, :directive + on %r/:/, :operator, flag_on(:value_expected) + on %r/;/, :operator, flag_off(:value_expected) + on %r/ [+>~,.=()\/] /x, :operator + end + + protected + + def setup + super + + @value_expected = false + @block = false + end + + end + +end +end |