summaryrefslogtreecommitdiff
path: root/lib/coderay/scanners/css2.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/coderay/scanners/css2.rb')
-rw-r--r--lib/coderay/scanners/css2.rb90
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