lib/rouge/lexers/css.rb
# -*- coding: utf-8 -*- # # frozen_string_literal: true module Rouge module Lexers class CSS < RegexLexer title "CSS" desc "Cascading Style Sheets, used to style web pages" tag 'css' filenames '*.css' mimetypes 'text/css' # Documentation: https://www.w3.org/TR/CSS21/syndata.html#characters identifier = /[\p{L}_-][\p{Word}\p{Cf}-]*/ number = /-?(?:[0-9]+(\.[0-9]+)?|\.[0-9]+)/ def self.attributes @attributes ||= Set.new %w( align-content align-items align-self alignment-adjust alignment-baseline all anchor-point animation animation-delay animation-direction animation-duration animation-fill-mode animation-iteration-count animation-name animation-play-state animation-timing-function appearance azimuth backface-visibility background background-attachment background-clip background-color background-image background-origin background-position background-repeat background-size baseline-shift binding bleed bookmark-label bookmark-level bookmark-state bookmark-target border border-bottom border-bottom-color border-bottom-left-radius border-bottom-right-radius border-bottom-style border-bottom-width border-collapse border-color border-image border-image-outset border-image-repeat border-image-slice border-image-source border-image-width border-left border-left-color border-left-style border-left-width border-radius border-right border-right-color border-right-style border-right-width border-spacing border-style border-top border-top-color border-top-left-radius border-top-right-radius border-top-style border-top-width border-width bottom box-align box-decoration-break box-direction box-flex box-flex-group box-lines box-ordinal-group box-orient box-pack box-shadow box-sizing break-after break-before break-inside caption-side clear clip clip-path clip-rule color color-profile columns column-count column-fill column-gap column-rule column-rule-color column-rule-style column-rule-width column-span column-width content counter-increment counter-reset crop cue cue-after cue-before cursor direction display dominant-baseline drop-initial-after-adjust drop-initial-after-align drop-initial-before-adjust drop-initial-before-align drop-initial-size drop-initial-value elevation empty-cells filter fit fit-position flex flex-basis flex-direction flex-flow flex-grow flex-shrink flex-wrap float float-offset font font-family font-feature-settings font-kerning font-language-override font-size font-size-adjust font-stretch font-style font-synthesis font-variant font-variant-alternates font-variant-caps font-variant-east-asian font-variant-ligatures font-variant-numeric font-variant-position font-weight grid-cell grid-column grid-column-align grid-column-sizing grid-column-span grid-columns grid-flow grid-row grid-row-align grid-row-sizing grid-row-span grid-rows grid-template hanging-punctuation height hyphenate-after hyphenate-before hyphenate-character hyphenate-lines hyphenate-resource hyphens icon image-orientation image-rendering image-resolution ime-mode inline-box-align justify-content left letter-spacing line-break line-height line-stacking line-stacking-ruby line-stacking-shift line-stacking-strategy list-style list-style-image list-style-position list-style-type margin margin-bottom margin-left margin-right margin-top mark marker-offset marks mark-after mark-before marquee-direction marquee-loop marquee-play-count marquee-speed marquee-style mask max-height max-width min-height min-width move-to nav-down nav-index nav-left nav-right nav-up object-fit object-position opacity order orphans outline outline-color outline-offset outline-style outline-width overflow overflow-style overflow-wrap overflow-x overflow-y padding padding-bottom padding-left padding-right padding-top page page-break-after page-break-before page-break-inside page-policy pause pause-after pause-before perspective perspective-origin phonemes pitch pitch-range play-during pointer-events position presentation-level punctuation-trim quotes rendering-intent resize rest rest-after rest-before richness right rotation rotation-point ruby-align ruby-overhang ruby-position ruby-span size speak speak-as speak-header speak-numeral speak-punctuation speech-rate src stress string-set tab-size table-layout target target-name target-new target-position text-align text-align-last text-combine-horizontal text-decoration text-decoration-color text-decoration-line text-decoration-skip text-decoration-style text-emphasis text-emphasis-color text-emphasis-position text-emphasis-style text-height text-indent text-justify text-orientation text-outline text-overflow text-rendering text-shadow text-space-collapse text-transform text-underline-position text-wrap top transform transform-origin transform-style transition transition-delay transition-duration transition-property transition-timing-function unicode-bidi vertical-align visibility voice-balance voice-duration voice-family voice-pitch voice-pitch-range voice-range voice-rate voice-stress voice-volume volume white-space widows width word-break word-spacing word-wrap writing-mode z-index ) end def self.builtins @builtins ||= Set.new %w( above absolute always armenian aural auto avoid left bottom baseline behind below bidi-override blink block bold bolder both bottom capitalize center center-left center-right circle cjk-ideographic close-quote collapse condensed continuous crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double e-resize embed expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed georgian groove hebrew help hidden hide high higher hiragana hiragana-iroha icon inherit inline inline-table inset inside invert italic justify katakana katakana-iroha landscape large larger left left-side leftwards level lighter line-through list-item loud low lower lower-alpha lower-greek lower-roman lowercase ltr medium message-box middle mix monospace n-resize narrower ne-resize no-close-quote no-open-quote no-repeat none normal nowrap nw-resize oblique once open-quote outset outside overline pointer portrait px relative repeat repeat-x repeat-y rgb ridge right right-side rightwards s-resize sans-serif scroll se-resize semi-condensed semi-expanded separate serif show silent slow slower small-caps small-caption smaller soft solid spell-out square static status-bar super sw-resize table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group text text-bottom text-top thick thin top transparent ultra-condensed ultra-expanded underline upper-alpha upper-latin upper-roman uppercase url visible w-resize wait wider x-fast x-high x-large x-loud x-low x-small x-soft xx-large xx-small yes ) end def self.constants @constants ||= Set.new %w( indigo gold firebrick indianred yellow darkolivegreen darkseagreen mediumvioletred mediumorchid chartreuse mediumslateblue black springgreen crimson lightsalmon brown turquoise olivedrab cyan silver skyblue gray darkturquoise goldenrod darkgreen darkviolet darkgray lightpink teal darkmagenta lightgoldenrodyellow lavender yellowgreen thistle violet navy orchid blue ghostwhite honeydew cornflowerblue darkblue darkkhaki mediumpurple cornsilk red bisque slategray darkcyan khaki wheat deepskyblue darkred steelblue aliceblue gainsboro mediumturquoise floralwhite coral purple lightgrey lightcyan darksalmon beige azure lightsteelblue oldlace greenyellow royalblue lightseagreen mistyrose sienna lightcoral orangered navajowhite lime palegreen burlywood seashell mediumspringgreen fuchsia papayawhip blanchedalmond peru aquamarine white darkslategray ivory dodgerblue lemonchiffon chocolate orange forestgreen slateblue olive mintcream antiquewhite darkorange cadetblue moccasin limegreen saddlebrown darkslateblue lightskyblue deeppink plum aqua darkgoldenrod maroon sandybrown magenta tan rosybrown pink lightblue palevioletred mediumseagreen dimgray powderblue seagreen snow mediumblue midnightblue paleturquoise palegoldenrod whitesmoke darkorchid salmon lightslategray lawngreen lightgreen tomato hotpink lightyellow lavenderblush linen mediumaquamarine green blueviolet peachpuff ) end # source: http://www.w3.org/TR/CSS21/syndata.html#vendor-keyword-history def self.vendor_prefixes @vendor_prefixes ||= Set.new %w( -ah- -atsc- -hp- -khtml- -moz- -ms- -o- -rim- -ro- -tc- -wap- -webkit- -xv- mso- prince- ) end state :root do mixin :basics rule %r/{/, Punctuation, :stanza rule %r/:[:]?#{identifier}/, Name::Decorator rule %r/\.#{identifier}/, Name::Class rule %r/##{identifier}/, Name::Function rule %r/@#{identifier}/, Keyword, :at_rule rule identifier, Name::Tag rule %r([~^*!%&\[\]()<>|+=@:;,./?-]), Operator rule %r/"(\\\\|\\"|[^"])*"/, Str::Single rule %r/'(\\\\|\\'|[^'])*'/, Str::Double end state :value do mixin :basics rule %r/url\(.*?\)/, Str::Other rule %r/#[0-9a-f]{1,6}/i, Num # colors rule %r/#{number}(?:%|(?:em|px|pt|pc|in|mm|cm|ex|rem|ch|vw|vh|vmin|vmax|dpi|dpcm|dppx|deg|grad|rad|turn|s|ms|Hz|kHz)\b)?/, Num rule %r/[\[\]():\/.,]/, Punctuation rule %r/"(\\\\|\\"|[^"])*"/, Str::Single rule %r/'(\\\\|\\'|[^'])*'/, Str::Double rule(identifier) do |m| if self.class.constants.include? m[0] token Name::Constant elsif self.class.builtins.include? m[0] token Name::Builtin else token Name end end end state :at_rule do rule %r/{(?=\s*#{identifier}\s*:)/m, Punctuation, :at_stanza rule %r/{/, Punctuation, :at_body rule %r/;/, Punctuation, :pop! mixin :value end state :at_body do mixin :at_content mixin :root end state :at_stanza do mixin :at_content mixin :stanza end state :at_content do rule %r/}/ do token Punctuation pop! 2 end end state :basics do rule %r/\s+/m, Text rule %r(/\*(?:.*?)\*/)m, Comment end state :stanza do mixin :basics rule %r/}/, Punctuation, :pop! rule %r/(#{identifier})(\s*)(:)/m do |m| name_tok = if self.class.attributes.include? m[1] Name::Label elsif self.class.vendor_prefixes.any? { |p| m[1].start_with?(p) } Name::Label else Name::Property end groups name_tok, Text, Punctuation push :stanza_value end end state :stanza_value do rule %r/;/, Punctuation, :pop! rule(/(?=})/) { pop! } rule %r/!\s*important\b/, Comment::Preproc rule %r/^@.*?$/, Comment::Preproc mixin :value end end end end