[gtksourceview/gnome-3-24] language-specs: sync all *.lang files from GtkSourceView 4



commit 0ebeb0662d6c07f4044d095182ab617f526514ce
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sun Jun 17 11:43:00 2018 +0200

    language-specs: sync all *.lang files from GtkSourceView 4

 data/language-specs/Makefile.am     |    2 +
 data/language-specs/css.lang        | 1950 +++++++++++++++++++++++++++++------
 data/language-specs/julia.lang      |    3 +-
 data/language-specs/less.lang       |  793 ++++++++++++++
 data/language-specs/rust.lang       |    6 +-
 data/language-specs/scss.lang       |  878 ++++++++++++++++
 data/language-specs/xml.lang        |    4 +-
 po/POTFILES.skip                    |    2 +
 tests/syntax-highlighting/file.css  |  369 ++++++-
 tests/syntax-highlighting/file.less |  779 ++++++++++++++
 tests/syntax-highlighting/file.scss |  805 +++++++++++++++
 11 files changed, 5277 insertions(+), 314 deletions(-)
---
diff --git a/data/language-specs/Makefile.am b/data/language-specs/Makefile.am
index aea1b608..6428f830 100644
--- a/data/language-specs/Makefile.am
+++ b/data/language-specs/Makefile.am
@@ -65,6 +65,7 @@ LANGUAGES =                   \
        julia.lang              \
        kotlin.lang             \
        latex.lang              \
+       less.lang               \
        lex.lang                \
        libtool.lang            \
        llvm.lang               \
@@ -110,6 +111,7 @@ LANGUAGES =                 \
        scala.lang              \
        scheme.lang             \
        scilab.lang             \
+       scss.lang               \
        sh.lang                 \
        sml.lang                \
        sparql.lang             \
diff --git a/data/language-specs/css.lang b/data/language-specs/css.lang
index f191d349..c992eb4a 100644
--- a/data/language-specs/css.lang
+++ b/data/language-specs/css.lang
@@ -7,6 +7,7 @@
  Copyright (C) 2004 Scott Martin <scott coffeeblack org>
  Copyright (C) 2010 Patryk Zawadzki <patrys pld-linux org>
  Copyright (C) 2016 Tobias Schönberg <tobias47n9e gmail com>
+ Copyright (C) 2018 Jeffery To <jeffery to gmail com>
 
  GtkSourceView is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
@@ -22,19 +23,6 @@
  along with this library; if not, see <http://www.gnu.org/licenses/>.
 
 -->
-<!--
-       Proposed language specification for CSS (Cascading Style Sheet) files.
-
-       Reference used:
-               http://www.w3.org/TR/CSS2/
-
-       Tested with:
-               http://www.simplebits.com/css/simple.css
-
-       Submitted by
-
-        Converted to new format with convert.py
--->
 <language id="css" name="CSS" version="2.0" _section="Other">
   <metadata>
     <property name="mimetypes">text/css</property>
@@ -44,104 +32,367 @@
   </metadata>
 
   <styles>
-    <style id="error"                 name="Error"                 map-to="def:error"/>
-    <style id="others-2"              name="Others 2"/>
-    <style id="string"                name="String"                map-to="def:string"/>
-    <style id="color"                 name="Color"                 map-to="def:base-n-integer"/>
-    <style id="others-3"              name="Others 3"/>
-    <style id="function"              name="Function"              map-to="def:function"/>
-    <style id="decimal"               name="Decimal"               map-to="def:decimal"/>
-    <style id="dimension"             name="Dimension"             map-to="def:floating-point"/>
-    <style id="property-values"       name="Property Value"        map-to="def:constant"/>
-    <style id="at-rules"              name="at-rules"              map-to="def:preprocessor"/>
-    <style id="keyword"               name="Keyword"               map-to="def:keyword"/>
-    <style id="selector-id"           name="ID Selector"           map-to="def:statement"/>
-    <style id="selector-class"        name="Class Selector"        map-to="def:identifier"/>
-    <style id="selector-tagname"      name="Tag Name Selector"     map-to="def:type"/>
+
+    <!-- global -->
+    <style id="error"                       name="Error"                       map-to="def:error"/>
+    <style id="vendor-specific"             name="Vendor Specific"             map-to="def:warning"/>
+    <style id="keyword"                     name="Keyword"                     map-to="def:constant"/>
+    <style id="namespace"                   name="Namespace"                   map-to="def:keyword"/>
+    <style id="symbol"                      name="Symbol"/>
+    <style id="delimiter"                   name="Delimiter"/>
+    <style id="block-delimiter"             name="Block Delimiter"             map-to="css:delimiter"/>
+    <style id="test-delimiter"              name="Test Delimiter"              map-to="css:delimiter"/>
+
+    <!-- data types -->
+    <style id="name"                        name="Name"/>
+    <style id="escape"                      name="Escape Sequence"             map-to="def:special-char"/>
+    <style id="string"                      name="String"                      map-to="def:string"/>
+    <style id="color"                       name="Color"                       map-to="def:base-n-integer"/>
+    <style id="number"                      name="Number"                      map-to="def:number"/>
+    <style id="integer"                     name="Integer"                     map-to="def:decimal"/>
+    <style id="dimension"                   name="Dimension"                   map-to="def:floating-point"/>
+    <style id="expression"                  name="Expression"                  map-to="def:complex"/>
+    <style id="unicode-range"               name="Unicode Range"/>
+
+    <!-- functions -->
+    <style id="function"                    name="Function"                    map-to="def:function"/>
+
+    <!-- style properties -->
+    <style id="property-name"               name="Property Name"               map-to="def:keyword"/>
+
+    <!-- modifiers -->
+    <style id="modifier"                    name="Modifier"                    map-to="def:keyword"/>
+
+    <!-- at-rules -->
+    <style id="at-rule"                     name="At-rule"                     map-to="def:preprocessor"/>
+    <style id="at-rule-operator"            name="At-rule Operator"            map-to="css:at-rule"/>
+    <style id="at-rule-inner-selector"      name="At-rule Inner Selector"      map-to="def:identifier"/>
+
+    <!-- media queries -->
+    <style id="media-query-operator"        name="Media Query Operator"        
map-to="css:at-rule-operator"/>
+    <style id="media-type"                  name="Media Type"                  map-to="css:property-name"/>
+    <style id="media-feature"               name="Media Feature"               map-to="css:property-name"/>
+    <style id="media-feature-value"         name="Media Feature Value"         map-to="css:keyword"/>
+
+    <!-- selectors -->
+    <style id="selector-symbol"             name="Selector Symbol"             map-to="css:symbol"/>
+    <style id="namespace-qualifier"         name="Namespace Qualifier"         map-to="css:selector-symbol"/>
+    <style id="id-selector"                 name="ID Selector"                 map-to="def:statement"/>
+    <style id="class-selector"              name="Class Selector"              map-to="def:identifier"/>
+    <style id="type-selector"               name="Type Selector"               map-to="def:type"/>
+    <style id="universal-selector"          name="Universal Selector"          map-to="css:selector-symbol"/>
+    <style id="attribute-selector"          name="Attribute Selector"          map-to="css:selector-symbol"/>
+    <style id="attribute-selector-operator" name="Attribute Selector Operator" map-to="css:selector-symbol"/>
+    <style id="attribute-selector-name"     name="Attribute Selector Name"     map-to="def:type"/>
+    <style id="combinator"                  name="Combinator"                  map-to="css:selector-symbol"/>
+    <style id="pseudo-element"              name="Pseudo-element"              map-to="def:function"/>
+    <style id="pseudo-class"                name="Pseudo-class"                map-to="def:function"/>
+
   </styles>
 
+  <default-regex-options case-sensitive="false"/>
+
+  <keyword-char-class>[a-z0-9_-]</keyword-char-class>
+
   <definitions>
 
-    <context id="unicode-character-reference" style-ref="others-2">
-      <match>\\([a-fA-F0-9]{1,5}[ \t]|[a-fA-F0-9]{6})</match>
+    <!-- global -->
+
+    <!-- https://drafts.csswg.org/css-syntax/#escaping -->
+    <define-regex id="escape-regex" extended="true">
+      (?:
+        \\                   # backslash
+        (?:
+          [^\n\r\f0-9a-f] |  # not newline or hex digit; or
+          [0-9a-f]{1,6} \s?  # 1-6 hex digits, trailing whitespace (not necessary in some cases)
+        )
+      )
+    </define-regex>
+
+    <!-- https://drafts.csswg.org/css-syntax/#non-ascii-code-point -->
+    <define-regex id="non-ascii-regex">[\x{80}-\x{10ffff}]</define-regex>
+
+    <!--
+    a combination of name-start code point and escape
+    https://drafts.csswg.org/css-syntax/#name-start-code-point
+    https://www.w3.org/TR/selectors-3/#lex
+    -->
+    <define-regex id="identifier-start-char-regex" extended="true">
+      (?:
+        [a-z_] |
+        \%{non-ascii-regex} |
+        \%{escape-regex}
+      )
+    </define-regex>
+
+    <!--
+    a combination of name code point and escape
+    https://drafts.csswg.org/css-syntax/#name-code-point
+    https://www.w3.org/TR/selectors-3/#lex
+    -->
+    <define-regex id="identifier-chars-regex" extended="true">
+      (?&gt;
+        (?:
+          [a-z0-9_-]+ |
+          \%{non-ascii-regex}+ |
+          \%{escape-regex}+
+        )+
+      )
+    </define-regex>
+
+    <!-- for lookbehinds (and lookaheads) -->
+    <define-regex id="single-identifier-char-regex" extended="true">
+      (?:
+        [a-z0-9_-] |
+        \%{non-ascii-regex}
+      )
+    </define-regex>
+
+    <!-- https://drafts.csswg.org/css-syntax/#ident-token-diagram -->
+    <define-regex id="identifier-regex" extended="true">
+      (?:
+        (?:
+          -- |
+          -? \%{identifier-start-char-regex}
+        )
+        \%{identifier-chars-regex}?
+      )
+    </define-regex>
+
+    <!--
+    https://www.w3.org/TR/CSS21/syndata.html#vendor-keywords
+    https://en.wikipedia.org/wiki/CSS_hack#List_of_prefixes
+    -->
+    <define-regex id="vendor-specific-prefix-regex" extended="true">
+      (?:
+        (?:
+          [_-] \%{identifier-start-char-regex}+ |
+          mso |
+          prince
+        )
+        -
+      )
+    </define-regex>
+
+    <define-regex id="vendor-specific-identifier-regex" extended="true">
+      (?:
+        (?&lt;! \%{single-identifier-char-regex} )
+        \%{vendor-specific-prefix-regex} \%{identifier-chars-regex}
+      )
+    </define-regex>
+
+    <define-regex id="declaration-value-end">(?=[!;}])</define-regex>
+
+    <define-regex id="test-value-end">(?=\))</define-regex>
+
+    <context id="comment">
+      <include>
+        <context ref="def:c-like-comment-multiline"/>
+        <context ref="def:c-like-close-comment-outside-comment"/>
+      </include>
     </context>
 
-    <context id="selector-pseudo-elements" style-ref="function">
-      <prefix>:</prefix>
-      <keyword>first-line</keyword>
-      <keyword>first-letter</keyword>
-      <keyword>before</keyword>
-      <keyword>after</keyword>
+    <context id="slash" style-ref="symbol">
+      <match>/</match>
     </context>
 
-    <context id="selector-pseudo-classes" style-ref="function">
-      <prefix>:</prefix>
-      <keyword>enabled</keyword>
-      <keyword>disabled</keyword>
-      <keyword>checked</keyword>
-      <keyword>indeterminate</keyword>
-      <keyword>root</keyword>
-      <keyword>nth-child</keyword>
-      <keyword>nth-last-child</keyword>
-      <keyword>nth-of-type</keyword>
-      <keyword>nth-last-of-type</keyword>
-      <keyword>first-child</keyword>
-      <keyword>last-child</keyword>
-      <keyword>first-of-type</keyword>
-      <keyword>last-of-type</keyword>
-      <keyword>only-child</keyword>
-      <keyword>only-of-type</keyword>
-      <keyword>empty</keyword>
-      <keyword>not</keyword>
-      <keyword>link</keyword>
-      <keyword>visited</keyword>
-      <keyword>hover</keyword>
-      <keyword>active</keyword>
-      <keyword>focus</keyword>
-      <keyword>target</keyword>
-      <keyword>lang</keyword>
+    <context id="comma" style-ref="delimiter">
+      <match>,</match>
     </context>
 
-    <context id="css3-at-rules" style-ref="at-rules">
-      <prefix>^[ \t]*@</prefix>
-      <keyword>annotation</keyword>
-      <keyword>character-variant</keyword>
-      <keyword>font-face</keyword>
-      <keyword>font-feature-values</keyword>
-      <keyword>keyframes</keyword>
-      <keyword>ornaments</keyword>
-      <keyword>styleset</keyword>
-      <keyword>stylistic</keyword>
-      <keyword>swash</keyword>
+    <context id="colon" style-ref="delimiter">
+      <match>:</match>
     </context>
 
-    <context id="at-rules" style-ref="at-rules">
-      <prefix>^[ \t]*@</prefix>
-      <keyword>charset</keyword>
-      <keyword>import</keyword>
-      <keyword>media</keyword>
-      <keyword>page</keyword>
+    <context id="semicolon" style-ref="delimiter">
+      <match>;</match>
+    </context>
+
+
+    <!-- data types -->
+
+    <!-- custom identifier -->
+    <context id="name" style-ref="name">
+      <match>\%{identifier-regex}</match>
     </context>
 
-    <context id="selector-id" style-ref="selector-id">
-      <match>#[a-zA-Z][a-zA-Z0-9_-]*\b</match>
+    <context id="vendor-specific-name" style-ref="vendor-specific">
+      <match>\%{vendor-specific-identifier-regex}</match>
     </context>
 
-    <context id="selector-class" style-ref="selector-class">
-      <match>\.[a-zA-Z][a-zA-Z0-9_-]*\b</match>
+    <context id="escape" style-ref="escape">
+      <match>\%{escape-regex}</match>
     </context>
 
-    <context id="selector-tagname" style-ref="selector-tagname">
-      <match>\b[a-zA-Z][a-zA-Z0-9_-]*\b</match>
+    <context id="string-content">
+      <include>
+        <context ref="escape"/>
+        <context ref="def:line-continue"/>
+      </include>
+    </context>
+
+    <context id="double-quoted-string" style-ref="string" end-at-line-end="true" class="string" 
class-disabled="no-spell-check">
+      <start>"</start>
+      <end>"</end>
+      <include>
+        <context ref="string-content"/>
+      </include>
+    </context>
+
+    <context id="single-quoted-string" style-ref="string" end-at-line-end="true" class="string" 
class-disabled="no-spell-check">
+      <start>'</start>
+      <end>'</end>
+      <include>
+        <context ref="string-content"/>
+      </include>
+    </context>
+
+    <context id="string">
+      <include>
+        <context ref="double-quoted-string"/>
+        <context ref="single-quoted-string"/>
+      </include>
     </context>
 
     <context id="hexadecimal-color" style-ref="color">
-      <match>#([a-fA-F0-9]{8}|[a-fA-F0-9]{6}|[a-fA-F0-9]{4}|[a-fA-F0-9]{3})\b</match>
+      <match>#([a-f0-9]{8}|[a-f0-9]{6}|[a-f0-9]{4}|[a-f0-9]{3})\%]</match>
+    </context>
+
+    <context id="css3-named-color" style-ref="color">
+      <keyword>aliceblue</keyword>
+      <keyword>antiquewhite</keyword>
+      <keyword>aquamarine</keyword>
+      <keyword>azure</keyword>
+      <keyword>beige</keyword>
+      <keyword>bisque</keyword>
+      <keyword>blanchedalmond</keyword>
+      <keyword>blueviolet</keyword>
+      <keyword>brown</keyword>
+      <keyword>burlywood</keyword>
+      <keyword>cadetblue</keyword>
+      <keyword>chartreuse</keyword>
+      <keyword>chocolate</keyword>
+      <keyword>coral</keyword>
+      <keyword>cornflowerblue</keyword>
+      <keyword>cornsilk</keyword>
+      <keyword>crimson</keyword>
+      <keyword>cyan</keyword>
+      <keyword>darkblue</keyword>
+      <keyword>darkcyan</keyword>
+      <keyword>darkgoldenrod</keyword>
+      <keyword>darkgray</keyword>
+      <keyword>darkgreen</keyword>
+      <keyword>darkgrey</keyword>
+      <keyword>darkkhaki</keyword>
+      <keyword>darkmagenta</keyword>
+      <keyword>darkolivegreen</keyword>
+      <keyword>darkorange</keyword>
+      <keyword>darkorchid</keyword>
+      <keyword>darkred</keyword>
+      <keyword>darksalmon</keyword>
+      <keyword>darkseagreen</keyword>
+      <keyword>darkslateblue</keyword>
+      <keyword>darkslategray</keyword>
+      <keyword>darkslategrey</keyword>
+      <keyword>darkturquoise</keyword>
+      <keyword>darkviolet</keyword>
+      <keyword>deeppink</keyword>
+      <keyword>deepskyblue</keyword>
+      <keyword>dimgray</keyword>
+      <keyword>dimgrey</keyword>
+      <keyword>dodgerblue</keyword>
+      <keyword>firebrick</keyword>
+      <keyword>floralwhite</keyword>
+      <keyword>forestgreen</keyword>
+      <keyword>gainsboro</keyword>
+      <keyword>ghostwhite</keyword>
+      <keyword>goldenrod</keyword>
+      <keyword>gold</keyword>
+      <keyword>greenyellow</keyword>
+      <keyword>grey</keyword>
+      <keyword>honeydew</keyword>
+      <keyword>hotpink</keyword>
+      <keyword>indianred</keyword>
+      <keyword>indigo</keyword>
+      <keyword>ivory</keyword>
+      <keyword>khaki</keyword>
+      <keyword>lavenderblush</keyword>
+      <keyword>lavender</keyword>
+      <keyword>lawngreen</keyword>
+      <keyword>lemonchiffon</keyword>
+      <keyword>lightblue</keyword>
+      <keyword>lightcoral</keyword>
+      <keyword>lightcyan</keyword>
+      <keyword>lightgoldenrodyellow</keyword>
+      <keyword>lightgray</keyword>
+      <keyword>lightgreen</keyword>
+      <keyword>lightgrey</keyword>
+      <keyword>lightpink</keyword>
+      <keyword>lightsalmon</keyword>
+      <keyword>lightseagreen</keyword>
+      <keyword>lightskyblue</keyword>
+      <keyword>lightslategray</keyword>
+      <keyword>lightslategrey</keyword>
+      <keyword>lightsteelblue</keyword>
+      <keyword>lightyellow</keyword>
+      <keyword>limegreen</keyword>
+      <keyword>linen</keyword>
+      <keyword>magenta</keyword>
+      <keyword>mediumaquamarine</keyword>
+      <keyword>mediumblue</keyword>
+      <keyword>mediumorchid</keyword>
+      <keyword>mediumpurple</keyword>
+      <keyword>mediumseagreen</keyword>
+      <keyword>mediumslateblue</keyword>
+      <keyword>mediumspringgreen</keyword>
+      <keyword>mediumturquoise</keyword>
+      <keyword>mediumvioletred</keyword>
+      <keyword>midnightblue</keyword>
+      <keyword>mintcream</keyword>
+      <keyword>mistyrose</keyword>
+      <keyword>moccasin</keyword>
+      <keyword>navajowhite</keyword>
+      <keyword>oldlace</keyword>
+      <keyword>olivedrab</keyword>
+      <keyword>orangered</keyword>
+      <keyword>orchid</keyword>
+      <keyword>palegoldenrod</keyword>
+      <keyword>palegreen</keyword>
+      <keyword>paleturquoise</keyword>
+      <keyword>palevioletred</keyword>
+      <keyword>papayawhip</keyword>
+      <keyword>peachpuff</keyword>
+      <keyword>peru</keyword>
+      <keyword>pink</keyword>
+      <keyword>plum</keyword>
+      <keyword>powderblue</keyword>
+      <keyword>rebeccapurple</keyword>
+      <keyword>rosybrown</keyword>
+      <keyword>royalblue</keyword>
+      <keyword>saddlebrown</keyword>
+      <keyword>salmon</keyword>
+      <keyword>sandybrown</keyword>
+      <keyword>seagreen</keyword>
+      <keyword>seashell</keyword>
+      <keyword>sienna</keyword>
+      <keyword>skyblue</keyword>
+      <keyword>slateblue</keyword>
+      <keyword>slategray</keyword>
+      <keyword>slategrey</keyword>
+      <keyword>snow</keyword>
+      <keyword>springgreen</keyword>
+      <keyword>steelblue</keyword>
+      <keyword>tan</keyword>
+      <keyword>thistle</keyword>
+      <keyword>tomato</keyword>
+      <keyword>turquoise</keyword>
+      <keyword>violet</keyword>
+      <keyword>wheat</keyword>
+      <keyword>whitesmoke</keyword>
+      <keyword>yellowgreen</keyword>
     </context>
 
     <context id="named-color" style-ref="color">
-      <prefix>\s</prefix>
-      <suffix>($|(?=[;\s]))</suffix>
       <keyword>aqua</keyword>
       <keyword>black</keyword>
       <keyword>blue</keyword>
@@ -161,83 +412,238 @@
       <keyword>yellow</keyword>
     </context>
 
+    <define-regex id="number-magnitude-regex" extended="true">
+      (?: (?> \d* \. \d+ | \d+ ) (?: e [+-]? \d+ )? )
+    </define-regex>
+
+    <define-regex id="number-regex" extended="true">
+      (?: [+-]? \%{number-magnitude-regex} )
+    </define-regex>
+
+    <define-regex id="positive-number-regex" extended="true">
+      (?: \+? \%{number-magnitude-regex} )
+    </define-regex>
+
+    <define-regex id="integer-magnitude-regex" extended="true">
+      (?> \d+ )
+    </define-regex>
+
+    <define-regex id="integer-regex" extended="true">
+      (?: [+-]? \%{integer-magnitude-regex} )
+    </define-regex>
+
+    <define-regex id="positive-integer-regex" extended="true">
+      (?: \+? \%{integer-magnitude-regex} )
+    </define-regex>
+
+    <define-regex id="non-number-char-regex" extended="true">
+      (?:
+        \%{single-identifier-char-regex} |
+        \.
+      )
+    </define-regex>
+
     <context id="dimension" style-ref="dimension">
-      
<match>[\+-]?([0-9]+|[0-9]*\.[0-9]+)(%|e(m|x)|(v(h|w|min|max))|ch|fr|rem|p(x|t|c)|in|ft|(m|c)m|k?Hz|deg|g?rad|m?s)</match>
+      <prefix>(?&lt;!\%{non-number-char-regex})\%{number-regex}</prefix>
+      <keyword>ch</keyword>
+      <keyword>cm</keyword>
+      <keyword>deg</keyword>
+      <keyword>em</keyword>
+      <keyword>ex</keyword>
+      <keyword>fr</keyword>
+      <keyword>ft</keyword>
+      <keyword>grad</keyword>
+      <keyword>hz</keyword>
+      <keyword>in</keyword>
+      <keyword>khz</keyword>
+      <keyword>mm</keyword>
+      <keyword>ms</keyword>
+      <keyword>pc</keyword>
+      <keyword>pt</keyword>
+      <keyword>px</keyword>
+      <keyword>rad</keyword>
+      <keyword>rem</keyword>
+      <keyword>s</keyword>
+      <keyword>turn</keyword>
+      <keyword>vh</keyword>
+      <keyword>vmax</keyword>
+      <keyword>vmin</keyword>
+      <keyword>vw</keyword>
+    </context>
+
+    <context id="percentage" style-ref="dimension">
+      <match extended="true">
+        (?&lt;! \%{non-number-char-regex} )
+        \%{number-regex}%
+      </match>
     </context>
 
     <context id="resolution" style-ref="dimension">
-      <match>[\+-]?([0-9]+|[0-9]*\.[0-9]+)(dpi|dpcm|dppx)</match>
+      <prefix>(?&lt;!\%{non-number-char-regex})\%{positive-number-regex}</prefix>
+      <keyword>dpcm</keyword>
+      <keyword>dpi</keyword>
+      <keyword>dppx</keyword>
     </context>
 
-    <context id="number" style-ref="decimal">
-      <match>\b(0|[\+-]?[1-9][0-9]*)</match>
+    <context id="ratio" style-ref="expression">
+      <match extended="true">
+        (?&lt;! \%{non-number-char-regex} )
+        \%{positive-integer-regex} \s* / \s* \%{positive-integer-regex}
+        (?! \%{non-number-char-regex} )
+      </match>
     </context>
 
-    <define-regex id="float" extended="true">
-      ( (\d+)?\.\d+ | \d+\. ) |
-      ( (\d+|(\d+)?\.\d+|\d+\.)[eE][+-]?\d+ )
-    </define-regex>
+    <context id="number" style-ref="number">
+      <match extended="true">
+        (?&lt;! \%{non-number-char-regex} )
+        \%{number-regex}
+        (?! \%{non-number-char-regex} )
+      </match>
+    </context>
 
-    <context id="float-number" style-ref="dimension">
-      <match>(?&lt;![\w\.])\%{float}(?![\w\.])</match>
+    <context id="positive-integer" style-ref="integer">
+      <match extended="true">
+        (?&lt;! \%{non-number-char-regex} )
+        \%{positive-integer-regex}
+        (?! \%{non-number-char-regex} )
+      </match>
     </context>
 
-    <context id="unicode-range" style-ref="others-2">
-      <match>[uU]\+[a-fA-F0-9]{1,6}(-[a-fA-F0-9]{1,6})?</match>
+    <context id="unicode-range" style-ref="unicode-range">
+      <match extended="true">
+        \%[ u \+ (?> [a-f0-9?]{1,6} ) (?> - [a-f0-9]{1,6} )?
+        (?! \%{single-identifier-char-regex} )
+      </match>
     </context>
 
-    <context id="importance-modifier" style-ref="keyword">
-      <match>\![ \t]*important</match>
+
+    <!-- functions -->
+
+    <context id="css3-function-arguments" style-ref="keyword">
+      <keyword>at</keyword>
+      <keyword>auto-fill</keyword>
+      <keyword>auto-fit</keyword>
+      <keyword>auto</keyword>
+      <keyword>bottom</keyword>
+      <keyword>center</keyword>
+      <keyword>circle</keyword>
+      <keyword>closest-corner</keyword>
+      <keyword>closest-side</keyword>
+      <keyword>ellipse</keyword>
+      <keyword>end</keyword>
+      <keyword>farthest-corner</keyword>
+      <keyword>farthest-side</keyword>
+      <keyword>left</keyword>
+      <keyword>max-content</keyword>
+      <keyword>min-content</keyword>
+      <keyword>right</keyword>
+      <keyword>start</keyword>
+      <keyword>top</keyword>
+      <keyword>to</keyword>
     </context>
 
-    <context id="css3-media-features" style-ref="keyword">
-      <keyword>aspect-ratio</keyword>
-      <keyword>color-index</keyword>
-      <keyword>color</keyword>
-      <keyword>device-aspect-ratio</keyword>
-      <keyword>device-height</keyword>
-      <keyword>device-width</keyword>
-      <keyword>grid</keyword>
-      <keyword>height</keyword>
-      <keyword>max-aspect-ratio</keyword>
-      <keyword>max-color-index</keyword>
-      <keyword>max-color</keyword>
-      <keyword>max-device-aspect-ratio</keyword>
-      <keyword>max-device-height</keyword>
-      <keyword>max-device-width</keyword>
-      <keyword>max-height</keyword>
-      <keyword>max-monochrome</keyword>
-      <keyword>max-resolution</keyword>
-      <keyword>max-width</keyword>
-      <keyword>min-aspect-ratio</keyword>
-      <keyword>min-color-index</keyword>
-      <keyword>min-color</keyword>
-      <keyword>min-device-aspect-ratio</keyword>
-      <keyword>min-device-width</keyword>
-      <keyword>min-device-height</keyword>
-      <keyword>min-height</keyword>
-      <keyword>min-monochrome</keyword>
-      <keyword>min-resolution</keyword>
-      <keyword>min-width</keyword>
-      <keyword>monochrome</keyword>
-      <keyword>orientation</keyword>
-      <keyword>overflow-block</keyword>
-      <keyword>overflow-inline</keyword>
-      <keyword>resolution</keyword>
-      <keyword>scan</keyword>
-      <keyword>update-frequency</keyword>
-      <keyword>width</keyword>
+    <context id="url">
+      <start>url\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="function"/>
+        <context sub-pattern="0" where="end" style-ref="function"/>
+        <context ref="comment"/>
+        <context ref="string-value"/>
+      </include>
     </context>
 
-    <context id="css3-media-feature-values" style-ref="property-values">
-      <keyword>interlace</keyword>
-      <keyword>landscape</keyword>
-      <keyword>portrait</keyword>
-      <keyword>progressive</keyword>
+    <context id="function-content">
+      <include>
+        <context ref="css3-function-arguments"/>
+        <context ref="any-value"/>
+      </include>
+    </context>
+
+    <context id="vendor-specific-function">
+      <start>\%{vendor-specific-identifier-regex}\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="vendor-specific"/>
+        <context sub-pattern="0" where="end" style-ref="vendor-specific"/>
+        <context ref="comment"/>
+        <context ref="function-content"/>
+      </include>
+    </context>
+
+    <context id="function">
+      <start>\%{identifier-regex}\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="function"/>
+        <context sub-pattern="0" where="end" style-ref="function"/>
+        <context ref="comment"/>
+        <context ref="function-content"/>
+      </include>
+    </context>
+
+    <context id="function-call">
+      <include>
+        <context ref="vendor-specific-function"/>
+        <context ref="url"/>
+        <context ref="function"/>
+      </include>
+    </context>
+
+
+    <!-- data values (interface between types and users) -->
+
+    <context id="name-value">
+      <include>
+        <context ref="name"/>
+      </include>
+    </context>
+
+    <context id="string-value">
+      <include>
+        <context ref="string"/>
+      </include>
+    </context>
+
+    <context id="color-value">
+      <include>
+        <context ref="hexadecimal-color"/>
+        <context ref="css3-named-color"/>
+        <context ref="named-color"/>
+      </include>
+    </context>
+
+    <!-- resolution and ratio are used in media queries only -->
+    <context id="number-value">
+      <include>
+        <context ref="dimension"/>
+        <context ref="percentage"/>
+        <context ref="resolution"/>
+        <context ref="ratio"/>
+        <context ref="number"/>
+      </include>
+    </context>
+
+    <context id="unicode-range-value">
+      <include>
+        <context ref="unicode-range"/>
+      </include>
+    </context>
+
+    <!-- unicode-range is used for the unicode-range (@font-face) property only -->
+    <context id="data-value">
+      <include>
+        <context ref="string-value"/>
+        <context ref="color-value"/>
+        <context ref="number-value"/>
+        <context ref="unicode-range"/>
+      </include>
     </context>
 
-    <context id="svg-property-names" style-ref="keyword">
-      <suffix>(?=\s*:)</suffix>
+
+    <!-- style properties -->
+
+    <context id="svg-property-names" style-ref="property-name">
       <keyword>clip-path</keyword>
       <keyword>clip-rule</keyword>
       <keyword>color-interpolatation-filters</keyword>
@@ -267,8 +673,7 @@
       <keyword>text-rendering</keyword>
     </context>
 
-    <context id="css3-property-names" style-ref="keyword">
-      <suffix>(?=\s*:)</suffix>
+    <context id="css3-property-names" style-ref="property-name">
       <keyword>align-content</keyword>
       <keyword>align-items</keyword>
       <keyword>align-self</keyword>
@@ -287,6 +692,7 @@
       <keyword>background-clip</keyword>
       <keyword>background-origin</keyword>
       <keyword>background-size</keyword>
+      <keyword>bleed</keyword>
       <keyword>border-image-outset</keyword>
       <keyword>border-image-repeat</keyword>
       <keyword>border-image-slice</keyword>
@@ -351,11 +757,13 @@
       <keyword>image-rendering</keyword>
       <keyword>image-resolution</keyword>
       <keyword>ime-mode</keyword>
+      <keyword>isolation</keyword>
       <keyword>justify-content</keyword>
       <keyword>justify-self</keyword>
       <keyword>line-break</keyword>
       <keyword>mask-type</keyword>
       <keyword>mask</keyword>
+      <keyword>mix-blend-mode</keyword>
       <keyword>nav-down</keyword>
       <keyword>nav-index</keyword>
       <keyword>nav-left</keyword>
@@ -373,6 +781,7 @@
       <keyword>perspective</keyword>
       <keyword>pointer-events</keyword>
       <keyword>resize</keyword>
+      <keyword>src</keyword>
       <keyword>tab-size</keyword>
       <keyword>text-align-last</keyword>
       <keyword>text-combine-upright</keyword>
@@ -391,13 +800,14 @@
       <keyword>transition-property</keyword>
       <keyword>transition-timing-function</keyword>
       <keyword>transition</keyword>
+      <keyword>unicode-range</keyword>
+      <keyword>will-change</keyword>
       <keyword>word-break</keyword>
       <keyword>word-wrap</keyword>
       <keyword>writing-mode</keyword>
     </context>
 
-    <context id="property-names" style-ref="keyword">
-      <suffix>(?=\s*:)</suffix>
+    <context id="property-names" style-ref="property-name">
       <keyword>azimuth</keyword>
       <keyword>background-attachment</keyword>
       <keyword>background-color</keyword>
@@ -527,57 +937,176 @@
       <keyword>z-index</keyword>
     </context>
 
-    <context id="svg-property-values" style-ref="property-values">
-      <prefix>\s</prefix>
-      <suffix>($|(?=[;\s]))</suffix>
-      <keyword>alphabetic</keyword>
-      <keyword>bevel</keyword>
-      <keyword>butt</keyword>
-      <keyword>central</keyword>
-      <keyword>crisp(E|e)dges</keyword>
-      <keyword>evenodd</keyword>
-      <keyword>geometric(P|p)recision</keyword>
-      <keyword>hanging</keyword>
-      <keyword>ideographic</keyword>
-      <keyword>lr-tb</keyword>
-      <keyword>lr</keyword>
-      <keyword>mathematical</keyword>
-      <keyword>miter</keyword>
-      <keyword>no-change</keyword>
-      <keyword>nonzero</keyword>
-      <keyword>optimize(L|l)egibility</keyword>
-      <keyword>optimize(S|s)peed</keyword>
-      <keyword>reset-size</keyword>
-      <keyword>rl-tb</keyword>
-      <keyword>rl</keyword>
-      <keyword>tb-rl</keyword>
-      <keyword>tb</keyword>
-      <keyword>text-after-edge</keyword>
-      <keyword>text-before-edge</keyword>
-      <keyword>use-script</keyword>
-    </context>
-
-    <context id="css3-property-values" style-ref="property-values">
-      <prefix>\s</prefix>
-      <suffix>($|(?=[;\s]))</suffix>
-      <keyword>active</keyword>
-      <keyword>add</keyword>
-      <keyword>allow-end</keyword>
-      <keyword>all-petite-caps</keyword>
-      <keyword>all-small-caps</keyword>
-      <keyword>all-scroll</keyword> <!-- css2, but needed for regex -->
-      <keyword>all</keyword>
-      <keyword>alpha</keyword>
-      <keyword>alternate-reverse</keyword>
-      <keyword>alternate</keyword>
-      <keyword>avoid-page</keyword>
-      <keyword>auto-flow</keyword>
-      <keyword>backwards</keyword>
-      <keyword>balance</keyword>
-      <keyword>border-box</keyword>
-      <keyword>break-all</keyword>
-      <keyword>break-word</keyword>
+    <context id="animatable-properties" style-ref="keyword">
+      <keyword>background-color</keyword>
+      <keyword>background-position</keyword>
+      <keyword>background-size</keyword>
+      <keyword>background</keyword>
+      <keyword>border-bottom-color</keyword>
+      <keyword>border-bottom-left-radius</keyword>
+      <keyword>border-bottom-right-radius</keyword>
+      <keyword>border-bottom-width</keyword>
+      <keyword>border-bottom</keyword>
+      <keyword>border-color</keyword>
+      <keyword>border-left-color</keyword>
+      <keyword>border-left-width</keyword>
+      <keyword>border-left</keyword>
+      <keyword>border-radius</keyword>
+      <keyword>border-right-color</keyword>
+      <keyword>border-right-width</keyword>
+      <keyword>border-right</keyword>
+      <keyword>border-top-color</keyword>
+      <keyword>border-top-left-radius</keyword>
+      <keyword>border-top-right-radius</keyword>
+      <keyword>border-top-width</keyword>
+      <keyword>border-top</keyword>
+      <keyword>border-width</keyword>
+      <keyword>border</keyword>
+      <keyword>bottom</keyword>
+      <keyword>box-shadow</keyword>
+      <keyword>clip-path</keyword>
+      <keyword>clip</keyword>
+      <keyword>color</keyword>
+      <keyword>column-count</keyword>
+      <keyword>column-gap</keyword>
+      <keyword>column-rule-color</keyword>
+      <keyword>column-rule-width</keyword>
+      <keyword>column-rule</keyword>
+      <keyword>column-width</keyword>
+      <keyword>columns</keyword>
+      <keyword>filter</keyword>
+      <keyword>flex-basis</keyword>
+      <keyword>flex-grow</keyword>
+      <keyword>flex-shrink</keyword>
+      <keyword>flex</keyword>
+      <keyword>font-size-adjust</keyword>
+      <keyword>font-size</keyword>
+      <keyword>font-stretch</keyword>
+      <keyword>font-weight</keyword>
+      <keyword>font</keyword>
+      <keyword>grid-column-gap</keyword>
+      <keyword>grid-gap</keyword>
+      <keyword>grid-row-gap</keyword>
+      <keyword>height</keyword>
+      <keyword>left</keyword>
+      <keyword>letter-spacing</keyword>
+      <keyword>line-height</keyword>
+      <keyword>margin-bottom</keyword>
+      <keyword>margin-left</keyword>
+      <keyword>margin-right</keyword>
+      <keyword>margin-top</keyword>
+      <keyword>margin</keyword>
+      <keyword>mask</keyword>
+      <keyword>max-height</keyword>
+      <keyword>max-width</keyword>
+      <keyword>min-height</keyword>
+      <keyword>min-width</keyword>
+      <keyword>object-position</keyword>
+      <keyword>opacity</keyword>
+      <keyword>order</keyword>
+      <keyword>outline-color</keyword>
+      <keyword>outline-offset</keyword>
+      <keyword>outline-width</keyword>
+      <keyword>outline</keyword>
+      <keyword>padding-bottom</keyword>
+      <keyword>padding-left</keyword>
+      <keyword>padding-right</keyword>
+      <keyword>padding-top</keyword>
+      <keyword>padding</keyword>
+      <keyword>perspective-origin</keyword>
+      <keyword>perspective</keyword>
+      <keyword>right</keyword>
+      <keyword>tab-size</keyword>
+      <keyword>text-decoration-color</keyword>
+      <keyword>text-decoration</keyword>
+      <keyword>text-indent</keyword>
+      <keyword>text-shadow</keyword>
+      <keyword>top</keyword>
+      <keyword>transform-origin</keyword>
+      <keyword>transform</keyword>
+      <keyword>vertical-align</keyword>
+      <keyword>visibility</keyword>
+      <keyword>width</keyword>
+      <keyword>word-spacing</keyword>
+      <keyword>z-index</keyword>
+    </context>
+
+    <context id="svg-property-values" style-ref="keyword">
+      <keyword>alphabetic</keyword>
+      <keyword>bevel</keyword>
+      <keyword>butt</keyword>
+      <keyword>central</keyword>
+      <keyword>crispedges</keyword>
+      <keyword>evenodd</keyword>
+      <keyword>geometricprecision</keyword>
+      <keyword>hanging</keyword>
+      <keyword>ideographic</keyword>
+      <keyword>lr-tb</keyword>
+      <keyword>lr</keyword>
+      <keyword>mathematical</keyword>
+      <keyword>miter</keyword>
+      <keyword>no-change</keyword>
+      <keyword>nonzero</keyword>
+      <keyword>optimizelegibility</keyword>
+      <keyword>optimizespeed</keyword>
+      <keyword>painted</keyword>
+      <keyword>reset-size</keyword>
+      <keyword>rl-tb</keyword>
+      <keyword>rl</keyword>
+      <keyword>stroke</keyword>
+      <keyword>tb-rl</keyword>
+      <keyword>tb</keyword>
+      <keyword>text-after-edge</keyword>
+      <keyword>text-before-edge</keyword>
+      <keyword>use-script</keyword>
+      <keyword>visiblefill</keyword>
+      <keyword>visiblepainted</keyword>
+      <keyword>visiblestroke</keyword>
+    </context>
+
+    <context id="east-asian-variant-values" style-ref="keyword">
+      <keyword>jis04</keyword>
+      <keyword>jis78</keyword>
+      <keyword>jis83</keyword>
+      <keyword>jis90</keyword>
+      <keyword>simplified</keyword>
+      <keyword>traditional</keyword>
+    </context>
+
+    <context id="page-sizes" style-ref="keyword">
+      <keyword>A3</keyword>
+      <keyword>A4</keyword>
+      <keyword>A5</keyword>
+      <keyword>B4</keyword>
+      <keyword>B5</keyword>
+      <keyword>JIS-B4</keyword>
+      <keyword>JIS-B5</keyword>
+      <keyword>ledger</keyword>
+      <keyword>legal</keyword>
+      <keyword>letter</keyword>
+    </context>
+
+    <context id="css3-property-values" style-ref="keyword">
+      <keyword>active</keyword>
+      <keyword>add</keyword>
+      <keyword>allow-end</keyword>
+      <keyword>all-petite-caps</keyword>
+      <keyword>all-small-caps</keyword>
+      <keyword>all-scroll</keyword> <!-- css2, but needed for regex -->
+      <keyword>all</keyword>
+      <keyword>alpha</keyword>
+      <keyword>alternate-reverse</keyword>
+      <keyword>alternate</keyword>
+      <keyword>avoid-page</keyword>
+      <keyword>auto-flow</keyword>
+      <keyword>backwards</keyword>
+      <keyword>balance</keyword>
+      <keyword>border-box</keyword>
+      <keyword>break-all</keyword>
+      <keyword>break-word</keyword>
       <keyword>clip</keyword>
+      <keyword>clone</keyword>
+      <keyword>color-burn</keyword>
       <keyword>color-dodge</keyword>
       <keyword>color</keyword>
       <keyword>column-reverse</keyword>
@@ -585,12 +1114,15 @@
       <keyword>common-ligatures</keyword>
       <keyword>contain</keyword>
       <keyword>content-box</keyword>
+      <keyword>contents</keyword>
       <keyword>contextual</keyword>
       <keyword>cover</keyword>
       <keyword>crisp-edges</keyword>
+      <keyword>currentcolor</keyword>
       <keyword>darken</keyword>
       <keyword>dense</keyword>
       <keyword>diagonal-fractions</keyword>
+      <keyword>difference</keyword>
       <keyword>disabled</keyword>
       <keyword>discretionary-ligatures</keyword>
       <keyword>distribute</keyword>
@@ -601,6 +1133,7 @@
       <keyword>ellipsis</keyword>
       <keyword>end</keyword>
       <keyword>exclude</keyword>
+      <keyword>exclusion</keyword>
       <keyword>fill-box</keyword>
       <keyword>fill</keyword>
       <keyword>first</keyword>
@@ -614,10 +1147,12 @@
       <keyword>from-image</keyword>
       <keyword>full-width</keyword>
       <keyword>grid</keyword>
+      <keyword>hard-light</keyword>
       <keyword>historical-forms</keyword>
       <keyword>historical-ligatures</keyword>
       <keyword>horizontal-tb</keyword>
       <keyword>horizontal</keyword>
+      <keyword>hue</keyword>
       <keyword>inactive</keyword>
       <keyword>infinite</keyword>
       <keyword>initial</keyword>
@@ -627,6 +1162,7 @@
       <keyword>inter-ideograph</keyword>
       <keyword>inter-word</keyword>
       <keyword>intersect</keyword>
+      <keyword>isolate</keyword>
       <keyword>kashida</keyword>
       <keyword>keep-all</keyword>
       <keyword>last</keyword>
@@ -667,17 +1203,21 @@
       <keyword>saturation</keyword>
       <keyword>scale-down</keyword>
       <keyword>screen</keyword>
+      <keyword>scroll-position</keyword>
       <keyword>sideways-left</keyword>
       <keyword>sideways-right</keyword>
       <keyword>sideways</keyword>
-      <keyword>simplified</keyword>
       <keyword>slashed-zero</keyword>
+      <keyword>slice</keyword>
+      <keyword>soft-light</keyword>
       <keyword>space-around</keyword>
       <keyword>space-between</keyword>
       <keyword>space-evenly</keyword>
       <keyword>space</keyword>
       <keyword>stacked-fractions</keyword>
       <keyword>start</keyword>
+      <keyword>step-end</keyword>
+      <keyword>step-start</keyword>
       <keyword>stretch</keyword>
       <keyword>strict</keyword>
       <keyword>stroke-box</keyword>
@@ -686,7 +1226,6 @@
       <keyword>subtract</keyword>
       <keyword>tabular-nums</keyword>
       <keyword>titling-caps</keyword>
-      <keyword>traditional</keyword>
       <keyword>trim</keyword>
       <keyword>under</keyword>
       <keyword>unicase</keyword>
@@ -703,9 +1242,7 @@
       <keyword>wrap</keyword>
     </context>
 
-    <context id="property-values" style-ref="property-values">
-      <prefix>\s</prefix>
-      <suffix>($|(?=[;\s]))</suffix>
+    <context id="property-values" style-ref="keyword">
       <keyword>above</keyword>
       <keyword>absolute</keyword>
       <keyword>alias</keyword>
@@ -831,6 +1368,7 @@
       <keyword>nowrap</keyword>
       <keyword>ns-resize</keyword>
       <keyword>nw-resize</keyword>
+      <keyword>nwse-resize</keyword>
       <keyword>n-resize</keyword>
       <keyword>oblique</keyword>
       <keyword>once</keyword>
@@ -839,7 +1377,7 @@
       <keyword>outside</keyword>
       <keyword>overline</keyword>
       <keyword>pointer</keyword>
-      <keyword>portait</keyword>
+      <keyword>portrait</keyword>
       <keyword>pre-line</keyword>
       <keyword>pre-wrap</keyword>
       <keyword>pre</keyword>
@@ -924,114 +1462,948 @@
       <keyword>zoom-out</keyword>
     </context>
 
-    <context id="style-block">
-      <start>\{</start>
-      <end>\}</end>
+    <context id="property-name">
       <include>
-        <context ref="def:c-like-comment-multiline"/>
-        <context ref="def:c-like-close-comment-outside-comment"/>
-        <context ref="css3-at-rules"/>
-        <context ref="at-rules"/>
-        <context ref="style-block"/>
-        <context ref="hexadecimal-color"/>
-        <context ref="named-color"/>
-        <context ref="function"/>
-        <context ref="dimension"/>
-        <context ref="float-number"/>
-        <context ref="number"/>
-        <context ref="unicode-range"/>
-        <context ref="importance-modifier"/>
+        <context ref="vendor-specific-name"/>
         <context ref="svg-property-names"/>
         <context ref="css3-property-names"/>
         <context ref="property-names"/>
+      </include>
+    </context>
+
+    <context id="property-value-keyword">
+      <include>
+        <context ref="vendor-specific-name"/>
+        <context ref="animatable-properties"/>
         <context ref="svg-property-values"/>
+        <context ref="east-asian-variant-values"/>
+        <context ref="page-sizes"/>
         <context ref="css3-property-values"/>
         <context ref="property-values"/>
       </include>
     </context>
 
-    <context id="punctuators" style-ref="others-3">
-      <match>[{}();,]</match>
+
+    <!-- any assignable value -->
+
+    <context id="any-value">
+      <include>
+        <context ref="function-call"/>
+        <context ref="property-value-keyword"/>
+        <context ref="data-value"/>
+        <context ref="slash"/>
+        <context ref="comma"/> <!-- for lists -->
+      </include>
+    </context>
+
+
+    <!-- modifiers -->
+
+    <context id="modifiers" end-parent="true" style-ref="modifier">
+      <keyword>important</keyword>
     </context>
 
-    <context id="attribute-value-delimiters" style-ref="others-2">
-      <match>(\[|\])</match>
+    <context id="modifier-content">
+      <include>
+        <context ref="modifiers"/>
+      </include>
     </context>
 
-    <context id="operators" style-ref="function">
-      <match>[@%~|!=]</match>
+    <context id="modifier">
+      <start>!</start>
+      <end>\%{declaration-value-end}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="modifier"/>
+        <context ref="comment"/>
+        <context ref="modifier-content"/>
+      </include>
     </context>
 
-    <context id="selector-grammar" style-ref="others-3">
-      <match>[*&gt;+]</match>
+
+    <!-- style block -->
+
+    <context id="declaration-property">
+      <include>
+        <context ref="property-name"/>
+      </include>
     </context>
 
-    <context id="function">
-      <start>[a-zA-Z][a-zA-Z0-9-]+\(</start>
-      <end>\)</end>
+    <context id="declaration-value-content">
       <include>
-        <context sub-pattern="0" where="start" style-ref="function"/>
-        <context sub-pattern="0" where="end" style-ref="function"/>
-        <context ref="def:escape"/>
-        <context ref="def:line-continue"/>
-        <context ref="hexadecimal-color"/>
-        <context ref="resolution"/>
-        <context ref="dimension"/>
-        <context ref="float-number"/>
-        <context ref="number"/>
-        <context ref="function"/>
+        <context ref="any-value"/>
       </include>
     </context>
 
-    <context id="css" class="no-spell-check">
+    <context id="declaration-value">
+      <start>:</start>
+      <end>\%{declaration-value-end}</end>
       <include>
-        <context ref="def:string"/>
-        <context ref="def:single-quoted-string"/>
-        <context ref="def:c-like-comment-multiline"/>
-        <context ref="def:c-like-close-comment-outside-comment"/>
-        <context ref="unicode-character-reference"/>
-        <context ref="selector-pseudo-elements"/>
-        <context ref="selector-pseudo-classes"/>
-        <context ref="css3-at-rules"/>
-        <context ref="at-rules"/>
+        <context sub-pattern="0" where="start" style-ref="delimiter"/>
+        <context ref="comment"/>
+        <context ref="declaration-value-content"/>
+      </include>
+    </context>
+
+    <context id="declaration">
+      <include>
+        <context ref="declaration-property"/>
+        <context ref="declaration-value"/>
+        <context ref="modifier"/>
+        <context ref="semicolon"/>
+      </include>
+    </context>
+
+    <context id="style-block-content">
+      <include>
+        <context ref="declaration"/>
+      </include>
+    </context>
+
+    <context id="style-block">
+      <start>\{</start>
+      <end>\}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="block-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="block-delimiter"/>
+        <context ref="comment"/>
+        <context ref="style-block-content"/>
+      </include>
+    </context>
+
+
+    <!-- media queries -->
+
+    <context id="media-query-operators" style-ref="media-query-operator">
+      <keyword>and</keyword>
+      <keyword>not</keyword>
+      <keyword>only</keyword>
+    </context>
+
+    <context id="media-types" style-ref="media-type">
+      <keyword>all</keyword>
+      <keyword>print</keyword>
+      <keyword>screen</keyword>
+      <keyword>speech</keyword>
+    </context>
+
+    <context id="css3-media-features" style-ref="media-feature">
+      <keyword>any-hover</keyword>
+      <keyword>any-pointer</keyword>
+      <keyword>aspect-ratio</keyword>
+      <keyword>color-gamut</keyword>
+      <keyword>color-index</keyword>
+      <keyword>color</keyword>
+      <keyword>display-mode</keyword>
+      <keyword>grid</keyword>
+      <keyword>height</keyword>
+      <keyword>hover</keyword>
+      <keyword>max-aspect-ratio</keyword>
+      <keyword>max-color-index</keyword>
+      <keyword>max-color</keyword>
+      <keyword>max-height</keyword>
+      <keyword>max-monochrome</keyword>
+      <keyword>max-resolution</keyword>
+      <keyword>max-width</keyword>
+      <keyword>min-aspect-ratio</keyword>
+      <keyword>min-color-index</keyword>
+      <keyword>min-color</keyword>
+      <keyword>min-height</keyword>
+      <keyword>min-monochrome</keyword>
+      <keyword>min-resolution</keyword>
+      <keyword>min-width</keyword>
+      <keyword>monochrome</keyword>
+      <keyword>orientation</keyword>
+      <keyword>overflow-block</keyword>
+      <keyword>overflow-inline</keyword>
+      <keyword>pointer</keyword>
+      <keyword>resolution</keyword>
+      <keyword>scan</keyword>
+      <keyword>update</keyword>
+      <keyword>width</keyword>
+    </context>
+
+    <context id="css3-media-feature-values" style-ref="media-feature-value">
+      <keyword>browser</keyword>
+      <keyword>coarse</keyword>
+      <keyword>fast</keyword>
+      <keyword>fine</keyword>
+      <keyword>fullscreen</keyword>
+      <keyword>hover</keyword>
+      <keyword>interlace</keyword>
+      <keyword>landscape</keyword>
+      <keyword>minimal-ui</keyword>
+      <keyword>none</keyword>
+      <keyword>optional-paged</keyword>
+      <keyword>p3</keyword>
+      <keyword>paged</keyword>
+      <keyword>portrait</keyword>
+      <keyword>progressive</keyword>
+      <keyword>rec2020</keyword>
+      <keyword>scroll</keyword>
+      <keyword>slow</keyword>
+      <keyword>srgb</keyword>
+      <keyword>standalone</keyword>
+    </context>
+
+    <context id="media-type-value">
+      <include>
+        <context ref="media-types"/>
+      </include>
+    </context>
+
+    <context id="media-feature-test-name">
+      <include>
+        <context ref="css3-media-features"/>
+      </include>
+    </context>
+
+    <context id="media-feature-test-value-content">
+      <include>
+        <context ref="css3-media-feature-values"/>
+        <context ref="data-value"/>
+      </include>
+    </context>
+
+    <context id="media-feature-test-value">
+      <start>:</start>
+      <end>\%{test-value-end}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="delimiter"/>
+        <context ref="comment"/>
+        <context ref="media-feature-test-value-content"/>
+      </include>
+    </context>
+
+    <context id="media-feature-test-content">
+      <include>
+        <context ref="media-queries"/>
+        <context ref="media-feature-test-name"/>
+        <context ref="media-feature-test-value"/>
+      </include>
+    </context>
+
+    <context id="media-feature-test">
+      <start>\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="test-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="test-delimiter"/>
+        <context ref="comment"/>
+        <context ref="media-feature-test-content"/>
+      </include>
+    </context>
+
+    <context id="media-queries">
+      <include>
+        <context ref="media-query-operators"/>
+        <context ref="media-type-value"/>
+        <context ref="media-feature-test"/>
+        <context ref="comma"/>
+      </include>
+    </context>
+
+
+    <!-- at-rules -->
+
+    <context id="at-rule-style-block-content">
+      <include>
+        <context ref="declaration"/>
+      </include>
+    </context>
+
+    <context id="at-rule-style-block" end-parent="true">
+      <start>\{</start>
+      <end>\}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="block-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="block-delimiter"/>
+        <context ref="comment"/>
+        <context ref="at-rule-style-block-content"/>
+      </include>
+    </context>
+
+    <context id="at-rule-css-block-content">
+      <include>
+        <context ref="at-rule"/>
+        <context ref="selector"/>
+        <context ref="style-block"/>
+      </include>
+    </context>
+
+    <context id="at-rule-css-block" end-parent="true">
+      <start>\{</start>
+      <end>\}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="block-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="block-delimiter"/>
+        <context ref="comment"/>
+        <context ref="at-rule-css-block-content"/>
+      </include>
+    </context>
+
+    <!--
+    if this was a simple context (<match>), then in a case like this:
+    @supports {
+        @import url();
+        @media screen {}
+    }
+    the @media rule would not be highlighted correctly
+    (seems like a bug?)
+    -->
+    <context id="at-rule-delimiter" end-parent="true" style-ref="delimiter">
+      <start>(?=;)</start>
+      <end>;</end>
+    </context>
+
+    <context id="vendor-specific-at-rule">
+      <start>@\%{vendor-specific-identifier-regex}</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="vendor-specific"/>
+        <context ref="at-rule-css-block"/>
+        <context ref="at-rule-delimiter"/>
+      </include>
+    </context>
+
+    <!--
+    @charset "encoding";
+    -->
+
+    <context id="at-charset" first-line-only="true">
+      <start case-sensitive="true">^@charset(?= "[^"]*";)</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="at-rule"/>
+        <context ref="def:string"/>
+        <context ref="at-rule-delimiter"/>
+      </include>
+    </context>
+
+    <context id="at-charset-error" style-ref="error">
+      <start>@charset\%]</start>
+      <include>
+        <context ref="at-rule-delimiter"/>
+      </include>
+    </context>
+
+    <!--
+    @font-face <style-block>
+    -->
+
+    <context id="at-font-face">
+      <start>@font-face\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="at-rule"/>
+        <context ref="comment"/>
+        <context ref="at-rule-style-block"/>
+      </include>
+    </context>
+
+    <!--
+    @font-feature-values <font name|"font name"> {
+        @<font-feature-type> {
+            <custom-name>: <positive-integer>+;
+        }
+    }
+    -->
+
+    <context id="font-feature-types" style-ref="at-rule-inner-selector">
+      <prefix>@</prefix>
+      <keyword>annotation</keyword>
+      <keyword>character-variant</keyword>
+      <keyword>ornaments</keyword>
+      <keyword>styleset</keyword>
+      <keyword>stylistic</keyword>
+      <keyword>swash</keyword>
+    </context>
+
+    <context id="font-feature-type-value">
+      <include>
+        <context ref="font-feature-types"/>
+      </include>
+    </context>
+
+    <context id="font-feature-value-declaration-name">
+      <include>
+        <context ref="name-value"/>
+      </include>
+    </context>
+
+    <context id="font-feature-value-declaration-value-content">
+      <include>
+        <context ref="positive-integer"/>
+      </include>
+    </context>
+
+    <context id="font-feature-value-declaration-value">
+      <start>:</start>
+      <end>\%{declaration-value-end}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="delimiter"/>
+        <context ref="comment"/>
+        <context ref="font-feature-value-declaration-value-content"/>
+      </include>
+    </context>
+
+    <context id="at-font-feature-values-feature-value-block">
+      <start>\{</start>
+      <end>\}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="block-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="block-delimiter"/>
+        <context ref="comment"/>
+        <context ref="font-feature-value-declaration-name"/>
+        <context ref="font-feature-value-declaration-value"/>
+        <context ref="semicolon"/>
+      </include>
+    </context>
+
+    <context id="at-font-feature-values-block" end-parent="true">
+      <start>\{</start>
+      <end>\}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="block-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="block-delimiter"/>
+        <context ref="comment"/>
+        <context ref="font-feature-type-value"/>
+        <context ref="at-font-feature-values-feature-value-block"/>
+      </include>
+    </context>
+
+    <context id="at-font-feature-values">
+      <start>@font-feature-values\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="at-rule"/>
+        <context ref="comment"/>
+        <context ref="string-value"/>
+        <context ref="name-value"/>
+        <context ref="at-font-feature-values-block"/>
+      </include>
+    </context>
+
+    <!--
+    @import <url(...)|"url"> <media-queries>?;
+    -->
+
+    <context id="at-import">
+      <start>@import\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="at-rule"/>
+        <context ref="comment"/>
+        <context ref="url"/>
+        <context ref="media-queries"/>
+        <context ref="string-value"/>
+        <context ref="at-rule-delimiter"/>
+      </include>
+    </context>
+
+    <!--
+    @keyframes <custom name|"custom name"> {
+        <from|to|%> <style-block>
+    }
+    -->
+
+    <context id="keyframe-selector" style-ref="at-rule-inner-selector">
+      <keyword>from</keyword>
+      <keyword>to</keyword>
+    </context>
+
+    <context id="keyframe-selector-value">
+      <include>
+        <context ref="percentage" style-ref="at-rule-inner-selector"/>
+        <context ref="keyframe-selector"/>
+      </include>
+    </context>
+
+    <context id="at-keyframes-block" end-parent="true">
+      <start>\{</start>
+      <end>\}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="block-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="block-delimiter"/>
+        <context ref="comment"/>
+        <context ref="keyframe-selector-value"/>
+        <context ref="style-block"/>
+      </include>
+    </context>
+
+    <context id="vendor-specific-at-keyframes">
+      <start>@\%{vendor-specific-prefix-regex}keyframes\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="vendor-specific"/>
+        <context ref="comment"/>
+        <context ref="string-value"/>
+        <context ref="name-value"/>
+        <context ref="at-keyframes-block"/>
+      </include>
+    </context>
+
+    <context id="at-keyframes">
+      <start>@keyframes\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="at-rule"/>
+        <context ref="comment"/>
+        <context ref="string-value"/>
+        <context ref="name-value"/>
+        <context ref="at-keyframes-block"/>
+      </include>
+    </context>
+
+    <!--
+    @media <media-queries> <css-block>
+    -->
+
+    <context id="at-media">
+      <start>@media\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="at-rule"/>
+        <context ref="comment"/>
+        <context ref="media-queries"/>
+        <context ref="at-rule-css-block"/>
+      </include>
+    </context>
+
+    <!--
+    @namespace <namespace>? <url(...)|"url">;
+    -->
+
+    <context id="namespace-value">
+      <include>
+        <context ref="name" style-ref="namespace"/>
+      </include>
+    </context>
+
+    <context id="at-namespace">
+      <start>@namespace\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="at-rule"/>
+        <context ref="comment"/>
+        <context ref="url"/>
+        <context ref="string-value"/>
+        <context ref="namespace-value"/>
+        <context ref="at-rule-delimiter"/>
+      </include>
+    </context>
+
+    <!--
+    @page <custom name>?<pseudo-page>* (, <custom name>?<pseudo-page>*)* {
+        <declaration>*
+        (@<page-margin-box-type> <style-block>)*
+    }
+    -->
+
+    <context id="pseudo-pages" style-ref="pseudo-class">
+      <prefix>:</prefix>
+      <keyword>blank</keyword>
+      <keyword>first</keyword>
+      <keyword>left</keyword>
+      <keyword>right</keyword>
+    </context>
+
+    <context id="page-margin-box-types" style-ref="at-rule-inner-selector">
+      <prefix>@</prefix>
+      <keyword>bottom-center</keyword>
+      <keyword>bottom-left-corner</keyword>
+      <keyword>bottom-left</keyword>
+      <keyword>bottom-right-corner</keyword>
+      <keyword>bottom-right</keyword>
+      <keyword>left-bottom</keyword>
+      <keyword>left-middle</keyword>
+      <keyword>left-top</keyword>
+      <keyword>right-bottom</keyword>
+      <keyword>right-middle</keyword>
+      <keyword>right-top</keyword>
+      <keyword>top-center</keyword>
+      <keyword>top-left-corner</keyword>
+      <keyword>top-left</keyword>
+      <keyword>top-right-corner</keyword>
+      <keyword>top-right</keyword>
+    </context>
+
+    <context id="at-page-block" end-parent="true">
+      <start>\{</start>
+      <end>\}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="block-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="block-delimiter"/>
+        <context ref="comment"/>
+        <context ref="declaration"/>
+        <context ref="page-margin-box-types"/>
+        <context ref="style-block"/>
+      </include>
+    </context>
+
+    <context id="at-page">
+      <start>@page\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="at-rule"/>
+        <context ref="comment"/>
+        <context ref="pseudo-pages"/>
+        <context ref="name-value"/>
+        <context ref="comma"/>
+        <context ref="at-page-block"/>
+      </include>
+    </context>
+
+    <!--
+    @supports <test> <css-block>
+    -->
+
+    <context id="at-supports-operators" style-ref="at-rule-operator">
+      <keyword>and</keyword>
+      <keyword>not</keyword>
+      <keyword>or</keyword>
+    </context>
+
+    <define-regex id="at-supports-declaration-value-end" extended="true">
+      (?:
+        \%{test-value-end} |
+        (?= ! )
+      )
+    </define-regex>
+
+    <context id="at-supports-declaration-value">
+      <start>:</start>
+      <end>\%{at-supports-declaration-value-end}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="delimiter"/>
+        <context ref="comment"/>
+        <context ref="declaration-value-content"/>
+      </include>
+    </context>
+
+    <context id="at-supports-modifier">
+      <start>!</start>
+      <end>\%{at-supports-declaration-value-end}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="modifier"/>
+        <context ref="comment"/>
+        <context ref="modifier-content"/>
+      </include>
+    </context>
+
+    <context id="at-supports-test">
+      <start>\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="test-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="test-delimiter"/>
+        <context ref="comment"/>
+        <context ref="at-supports-test"/>
+        <context ref="at-supports-operators"/>
+        <context ref="declaration-property"/>
+        <context ref="at-supports-declaration-value"/>
+        <context ref="at-supports-modifier"/> <!-- allowed here but has no effect -->
+      </include>
+    </context>
+
+    <context id="at-supports">
+      <start>@supports\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="at-rule"/>
+        <context ref="comment"/>
+        <context ref="at-supports-test"/>
+        <context ref="at-supports-operators"/>
+        <context ref="at-rule-css-block"/>
+      </include>
+    </context>
+
+    <!-- all at-rules -->
+
+    <context id="at-rule">
+      <include>
+        <context ref="vendor-specific-at-keyframes"/>
+        <context ref="vendor-specific-at-rule"/>
+        <context ref="at-charset"/>
+        <context ref="at-charset-error"/>
+        <context ref="at-font-face"/>
+        <context ref="at-font-feature-values"/>
+        <context ref="at-import"/>
+        <context ref="at-keyframes"/>
+        <context ref="at-media"/>
+        <context ref="at-namespace"/>
+        <context ref="at-page"/>
+        <context ref="at-supports"/>
+      </include>
+    </context>
+
+
+    <!-- selectors -->
+
+    <!-- namespace qualifier -->
+
+    <context id="namespace-qualifier">
+      <match>(\%{identifier-regex}|\*)?(\|)</match>
+      <include>
+        <context sub-pattern="1" style-ref="namespace"/>
+        <context sub-pattern="2" style-ref="namespace-qualifier"/>
+      </include>
+    </context>
+
+    <!-- simple selectors -->
+
+    <context id="id-selector" style-ref="id-selector">
+      <match>#\%{identifier-regex}</match>
+    </context>
+
+    <context id="class-selector" style-ref="class-selector">
+      <match>\.\%{identifier-regex}</match>
+    </context>
+
+    <context id="type-selector" style-ref="type-selector">
+      <match>\%{identifier-regex}</match>
+    </context>
+
+    <context id="universal-selector" style-ref="universal-selector">
+      <match>\*</match>
+    </context>
+
+    <context id="attribute-selector-attribute-name">
+      <match>(?&lt;=\[)\s*(\%{identifier-regex})</match>
+      <include>
+        <context sub-pattern="1" style-ref="attribute-selector-name"/>
+      </include>
+    </context>
+
+    <context id="attribute-selector-operator" style-ref="attribute-selector-operator">
+      <match>[~|^$*]?=</match>
+    </context>
+
+    <context id="attribute-selector-content">
+      <include>
+        <context ref="string-value"/>
+        <context ref="attribute-selector-attribute-name"/>
+        <context ref="attribute-selector-operator"/>
+      </include>
+    </context>
+
+    <context id="attribute-selector">
+      <start>\[</start>
+      <end>\]</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="attribute-selector"/>
+        <context sub-pattern="0" where="end" style-ref="attribute-selector"/>
+        <context ref="comment"/>
+        <context ref="attribute-selector-content"/>
+      </include>
+    </context>
+
+    <context id="simple-selector">
+      <include>
+        <context ref="id-selector"/>
+        <context ref="class-selector"/>
+        <context ref="type-selector"/>
+        <context ref="universal-selector"/>
+        <context ref="attribute-selector"/>
+      </include>
+    </context>
+
+    <!-- combinators -->
+
+    <!-- technically, this should include the space character (descendant combinator) -->
+    <context id="combinator" style-ref="combinator">
+      <match>[&gt;+~]</match>
+    </context>
+
+    <!-- pseudo-elements -->
+
+    <context id="vendor-specific-pseudo-element" style-ref="vendor-specific">
+      <match>::\%{vendor-specific-identifier-regex}</match>
+    </context>
+
+    <context id="single-colon-pseudo-elements" style-ref="pseudo-element">
+      <prefix>::?</prefix>
+      <keyword>after</keyword>
+      <keyword>before</keyword>
+      <keyword>first-letter</keyword>
+      <keyword>first-line</keyword>
+    </context>
+
+    <context id="pseudo-elements" style-ref="pseudo-element">
+      <prefix>::</prefix>
+      <keyword>placeholder</keyword>
+      <keyword>selection</keyword>
+    </context>
+
+    <context id="pseudo-element">
+      <include>
+        <context ref="vendor-specific-pseudo-element"/>
+        <context ref="single-colon-pseudo-elements"/>
+        <context ref="pseudo-elements"/>
+      </include>
+    </context>
+
+    <!-- pseudo-classes -->
+
+    <context id="vendor-specific-pseudo-class" style-ref="vendor-specific">
+      <match>:\%{vendor-specific-identifier-regex}</match>
+    </context>
+
+    <context id="pseudo-classes" style-ref="pseudo-class">
+      <prefix>:</prefix>
+      <keyword>active</keyword>
+      <keyword>checked</keyword>
+      <keyword>default</keyword>
+      <keyword>disabled</keyword>
+      <keyword>empty</keyword>
+      <keyword>enabled</keyword>
+      <keyword>first-child</keyword>
+      <keyword>first-of-type</keyword>
+      <keyword>focus</keyword>
+      <keyword>hover</keyword>
+      <keyword>in-range</keyword>
+      <keyword>indeterminate</keyword>
+      <keyword>invalid</keyword>
+      <keyword>lang</keyword>
+      <keyword>last-child</keyword>
+      <keyword>last-of-type</keyword>
+      <keyword>link</keyword>
+      <keyword>not</keyword>
+      <keyword>nth-child</keyword>
+      <keyword>nth-last-child</keyword>
+      <keyword>nth-last-of-type</keyword>
+      <keyword>nth-of-type</keyword>
+      <keyword>only-child</keyword>
+      <keyword>only-of-type</keyword>
+      <keyword>optional</keyword>
+      <keyword>out-of-range</keyword>
+      <keyword>read-only</keyword>
+      <keyword>read-write</keyword>
+      <keyword>required</keyword>
+      <keyword>root</keyword>
+      <keyword>target</keyword>
+      <keyword>valid</keyword>
+      <keyword>visited</keyword>
+    </context>
+
+    <context id="pseudo-class">
+      <include>
+        <context ref="vendor-specific-pseudo-class"/>
+        <context ref="pseudo-classes"/>
+      </include>
+    </context>
+
+    <!-- pseudo-class arguments -->
+
+    <context id="lang-pseudo-class-argument-content">
+      <include>
+        <context ref="name-value"/>
+      </include>
+    </context>
+
+    <context id="lang-pseudo-class-argument">
+      <start>(?&lt;=:lang)\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="pseudo-class"/>
+        <context sub-pattern="0" where="end" style-ref="pseudo-class"/>
+        <context ref="comment"/>
+        <context ref="lang-pseudo-class-argument-content"/>
+      </include>
+    </context>
+
+    <context id="not-pseudo-class-nested-not-error" style-ref="error">
+      <start>:not\(</start>
+      <end>\)</end>
+      <include>
+        <context ref="pseudo-class-argument"/>
+      </include>
+    </context>
+
+    <context id="not-pseudo-class-nested-pseudo-element-error">
+      <include>
+        <context ref="vendor-specific-pseudo-element" style-ref="error"/>
+        <context ref="single-colon-pseudo-elements" style-ref="error"/>
+        <context ref="pseudo-elements" style-ref="error"/>
+      </include>
+    </context>
+
+    <context id="not-pseudo-class-argument">
+      <start>(?&lt;=:not)\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="pseudo-class"/>
+        <context sub-pattern="0" where="end" style-ref="pseudo-class"/>
+        <context ref="comment"/>
+        <context ref="not-pseudo-class-nested-not-error"/>
+        <context ref="not-pseudo-class-nested-pseudo-element-error"/>
+        <context ref="simple-selector"/>
+        <context ref="combinator"/>
+        <context ref="pseudo-class"/>
+        <context ref="pseudo-class-argument"/>
+        <context ref="comma"/>
+      </include>
+    </context>
+
+    <context id="nth-pseudo-class-argument-keywords" once-only="true" style-ref="keyword">
+      <keyword>even</keyword>
+      <keyword>odd</keyword>
+    </context>
+
+    <context id="nth-pseudo-class-argument-expression" once-only="true" style-ref="expression">
+      <match extended="true">
+        (
+          \%{integer-regex}? n ( \s* [+-] \s* \%{integer-magnitude-regex} )? |
+          \%{integer-regex}
+        )
+      </match>
+    </context>
+
+    <context id="nth-pseudo-class-argument-content">
+      <include>
+        <context ref="nth-pseudo-class-argument-keywords"/>
+        <context ref="nth-pseudo-class-argument-expression"/>
+      </include>
+    </context>
+
+    <context id="nth-pseudo-class-argument">
+      <start extended="true">
+        (?&lt;=
+          :nth-child |
+          :nth-last-child |
+          :nth-of-type |
+          :nth-last-of-type
+        )
+        \(
+      </start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="pseudo-class"/>
+        <context sub-pattern="0" where="end" style-ref="pseudo-class"/>
+        <context ref="comment"/>
+        <context ref="nth-pseudo-class-argument-content"/>
+      </include>
+    </context>
+
+    <context id="pseudo-class-argument">
+      <include>
+        <context ref="lang-pseudo-class-argument"/>
+        <context ref="not-pseudo-class-argument"/>
+        <context ref="nth-pseudo-class-argument"/>
+      </include>
+    </context>
+
+    <!-- all selectors -->
+
+    <context id="selector">
+      <include>
+        <context ref="namespace-qualifier"/>
+        <context ref="simple-selector"/>
+        <context ref="combinator"/>
+        <context ref="pseudo-element"/>
+        <context ref="pseudo-class"/>
+        <context ref="pseudo-class-argument"/>
+        <context ref="comma"/>
+      </include>
+    </context>
+
+
+    <!-- main context -->
+
+    <context id="css" class="no-spell-check">
+      <include>
+        <context ref="comment"/>
+        <context ref="at-rule"/>
+        <context ref="selector"/>
         <context ref="style-block"/>
-        <context ref="punctuators"/>
-        <context ref="attribute-value-delimiters"/>
-        <context ref="operators"/>
-        <context ref="selector-grammar"/>
-        <context ref="selector-id"/>
-        <context ref="selector-class"/>
-        <context ref="selector-tagname"/>
-        <context id="at-media-call">
-          <start>(?&lt;=(@media))</start>
-          <end>\{</end>
-          <include>
-            <context id="media-keywords" style-ref="at-rules">
-              <keyword>and</keyword>
-              <keyword>not</keyword>
-              <keyword>only</keyword>
-            </context>
-            <context id="media-types" style-ref="keyword">
-              <keyword>all</keyword>
-              <keyword>print</keyword>
-              <keyword>screen</keyword>
-              <keyword>speech</keyword>
-            </context>
-            <context id="at-media-arguments">
-              <start>\(</start>
-              <end>\)</end>
-              <include>
-                <context ref="css3-media-features"/>
-                <context ref="css3-media-feature-values"/>
-                <context ref="hexadecimal-color"/>
-                <context ref="resolution"/>
-                <context ref="dimension"/>
-                <context ref="float-number"/>
-                <context ref="number"/>
-              </include>
-            </context>
-          </include>
-        </context>
       </include>
     </context>
 
diff --git a/data/language-specs/julia.lang b/data/language-specs/julia.lang
index 5c88b6fe..1a2098e2 100644
--- a/data/language-specs/julia.lang
+++ b/data/language-specs/julia.lang
@@ -29,8 +29,7 @@
 
   <!--
   A list of styles can be defined here, and optionally mapped to the default styles.
-  The full list of available styles can be found in the `def.lang` file:
-  https://git.gnome.org/browse/gtksourceview/tree/data/language-specs/def.lang
+  The full list of available styles can be found in the `def.lang` file.
   -->
   <styles>
     <style id="string"           name="String"            map-to="def:string" />
diff --git a/data/language-specs/less.lang b/data/language-specs/less.lang
new file mode 100644
index 00000000..f8a4cd2b
--- /dev/null
+++ b/data/language-specs/less.lang
@@ -0,0 +1,793 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ This file is part of GtkSourceView
+
+ Author: Jeffery To <jeffery to gmail com>
+ Copyright (C) 2018 Jeffery To <jeffery to gmail com>
+
+ GtkSourceView is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ GtkSourceView is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this library; if not, see <http://www.gnu.org/licenses/>.
+
+-->
+<language id="less" name="Less" version="2.0" _section="Other">
+  <metadata>
+    <property name="mimetypes">text/less;text/x-less</property>
+    <property name="globs">*.less</property>
+    <property name="line-comment-start">//</property>
+    <property name="block-comment-start">/*</property>
+    <property name="block-comment-end">*/</property>
+  </metadata>
+
+  <styles>
+
+    <!-- variables -->
+    <style id="variable"                    name="Variable"                    map-to="def:identifier"/>
+    <style id="built-in-variable"           name="Built-in Variable"           map-to="def:builtin"/>
+
+    <!-- operators -->
+    <style id="operator-symbol"             name="Operator Symbol"             map-to="css:symbol"/>
+
+    <!-- Less data types -->
+    <style id="boolean"                     name="Boolean Value"               map-to="def:boolean"/>
+    <style id="group-delimiter"             name="Group Delimiter"             map-to="css:delimiter"/>
+
+    <!-- mixins -->
+    <style id="mixin-parameters-delimiter"  name="Mixin Parameters Delimiter"  map-to="css:delimiter"/>
+
+    <!-- guards -->
+    <style id="guard-operator"              name="Guard Operator"              
map-to="css:at-rule-operator"/>
+
+    <!-- Less selectors -->
+    <style id="selector-fragment"           name="Selector Fragment"/>
+
+  </styles>
+
+  <default-regex-options case-sensitive="false"/>
+
+  <keyword-char-class>[a-z0-9_-]</keyword-char-class>
+
+  <definitions>
+
+    <!-- global -->
+
+    <define-regex id="statement-end" extended="true">
+      (?: ; | (?= \} ) )
+    </define-regex>
+
+    <context id="less-comment">
+      <include>
+        <context ref="def:c-like-comment"/>
+        <context ref="css:comment" original="true"/>
+      </include>
+    </context>
+
+    <replace id="css:comment" ref="less-comment"/>
+
+
+    <!-- variables -->
+
+    <define-regex id="variable-regex" extended="true">
+      (?: @ \%{css:identifier-regex} )
+    </define-regex>
+
+    <context id="variable" style-ref="variable">
+      <match>\%{variable-regex}</match>
+    </context>
+
+    <context id="variable-interpolation" style-ref="variable">
+      <start>@\{</start>
+      <end>\}</end>
+      <include>
+        <!-- nested interpolations are not documented but appear to work
+             (functions as variable reference / indirection) -->
+        <context ref="variable-interpolation-value"/>
+      </include>
+    </context>
+
+    <context id="variable-reference" style-ref="variable">
+      <match>@@\%{css:identifier-regex}</match>
+    </context>
+
+    <context id="property-variable" style-ref="variable">
+      <match>\$\%{css:identifier-regex}</match>
+    </context>
+
+    <context id="arguments-variable" style-ref="built-in-variable">
+      <match>@arguments\%]</match>
+    </context>
+
+    <context id="arguments-variable-interpolation" style-ref="built-in-variable">
+      <match>@\{arguments\}</match>
+    </context>
+
+    <context id="variable-value">
+      <include>
+        <context ref="arguments-variable"/>
+        <context ref="variable"/>
+        <context ref="variable-reference"/>
+        <context ref="property-variable"/>
+      </include>
+    </context>
+
+    <context id="variable-interpolation-value">
+      <include>
+        <context ref="arguments-variable-interpolation"/>
+        <context ref="variable-interpolation"/>
+      </include>
+    </context>
+
+
+    <!-- operators -->
+
+    <!-- it appears the slash is treated as division everywhere except
+         in a font property declaration and in an aspect ratio media query test,
+         not sure how to detect these cases
+         also not sure what are Less' rules regarding hyphen vs subtraction -->
+    <context id="arithmetic-operator" style-ref="operator-symbol">
+      <match extended="true">
+        (
+          [+*/] |
+          (?&lt;! \%{css:single-identifier-char-regex} )
+          -
+          (?! \%{css:single-identifier-char-regex} )
+        )
+      </match>
+    </context>
+
+
+    <!-- Less data types -->
+
+    <context id="boolean" style-ref="boolean">
+      <keyword>true</keyword>
+    </context>
+
+    <context id="double-quoted-escape-string" style-ref="css:string" end-at-line-end="true" class="string" 
class-disabled="no-spell-check">
+      <start>~"</start>
+      <end>"</end>
+      <include>
+        <context ref="css:string-content"/>
+      </include>
+    </context>
+
+    <context id="single-quoted-escape-string" style-ref="css:string" end-at-line-end="true" class="string" 
class-disabled="no-spell-check">
+      <start>~'</start>
+      <end>'</end>
+      <include>
+        <context ref="css:string-content"/>
+      </include>
+    </context>
+
+    <context id="escape-string">
+      <include>
+        <context ref="double-quoted-escape-string"/>
+        <context ref="single-quoted-escape-string"/>
+      </include>
+    </context>
+
+    <context id="detached-ruleset">
+      <start>\{</start>
+      <end>\}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:block-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="css:block-delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="css:style-block-content"/>
+      </include>
+    </context>
+
+    <context id="detached-ruleset-call-close-paren" style-ref="variable">
+      <match>\)</match>
+    </context>
+
+    <context id="detached-ruleset-call">
+      <start>\%{variable-regex}\(</start>
+      <end>\%{statement-end}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="variable"/>
+        <context sub-pattern="0" where="end" style-ref="css:delimiter"/>
+        <!-- no comments allowed -->
+        <context ref="detached-ruleset-call-close-paren"/>
+      </include>
+    </context>
+
+    <context id="data-group">
+      <start>\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="group-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="group-delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="css:data-value"/>
+      </include>
+    </context>
+
+    <context id="any-group">
+      <start>\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="group-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="group-delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="css:any-value"/>
+      </include>
+    </context>
+
+
+    <!-- data types -->
+
+    <context id="less-string-content">
+      <include>
+        <context ref="variable-interpolation-value"/>
+        <context ref="css:string-content" original="true"/>
+      </include>
+    </context>
+
+    <replace id="css:string-content" ref="less-string-content"/>
+
+
+    <!-- Less functions -->
+
+    <!-- since % isn't a valid identifier -->
+    <context id="format">
+      <start>%\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:function"/>
+        <context sub-pattern="0" where="end" style-ref="css:function"/>
+        <context ref="css:comment"/>
+        <context ref="css:function-content"/>
+      </include>
+    </context>
+
+
+    <!-- functions -->
+
+    <context id="less-url">
+      <start>url\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:function"/>
+        <context sub-pattern="0" where="end" style-ref="css:function"/>
+        <!-- only accept multi-line comments because // is part of urls -->
+        <context ref="css:comment" original="true"/>
+        <context ref="css:string-value"/>
+      </include>
+    </context>
+
+    <context id="less-function-content">
+      <include>
+        <context ref="css:function-content" original="true"/>
+        <context ref="css:semicolon"/> <!-- allowed as argument separator -->
+      </include>
+    </context>
+
+    <context id="less-function-call">
+      <include>
+        <context ref="format"/>
+        <context ref="css:function-call" original="true"/>
+      </include>
+    </context>
+
+    <replace id="css:url" ref="less-url"/>
+    <replace id="css:function-content" ref="less-function-content"/>
+    <replace id="css:function-call" ref="less-function-call"/>
+
+
+    <!-- data values -->
+
+    <context id="less-name-value">
+      <include>
+        <context ref="css:function-call"/>
+        <context ref="variable-value"/>
+        <context ref="escape-string"/> <!-- outputs unquoted strings -->
+        <context ref="css:name-value" original="true"/>
+      </include>
+    </context>
+
+    <context id="less-string-value">
+      <include>
+        <context ref="css:function-call"/>
+        <context ref="variable-value"/>
+        <context ref="css:string-value" original="true"/>
+      </include>
+    </context>
+
+    <context id="less-data-value">
+      <include>
+        <context ref="css:function-call"/>
+        <context ref="data-group"/>
+        <context ref="variable-value"/>
+        <context ref="escape-string"/>
+        <context ref="css:string-value" original="true"/>
+        <context ref="css:color-value"/>
+        <context ref="css:number-value"/>
+        <context ref="css:unicode-range"/>
+        <context ref="arithmetic-operator"/>
+      </include>
+    </context>
+
+    <replace id="css:name-value" ref="less-name-value"/>
+    <replace id="css:string-value" ref="less-string-value"/>
+    <replace id="css:data-value" ref="less-data-value"/>
+
+
+    <!-- any assignable value -->
+
+    <context id="less-any-value">
+      <include>
+        <context ref="css:function-call"/>
+        <context ref="any-group"/>
+        <context ref="variable-value"/>
+        <context ref="escape-string"/>
+        <context ref="boolean"/>
+        <context ref="detached-ruleset"/>
+        <context ref="css:property-value-keyword"/>
+        <context ref="css:string-value" original="true"/>
+        <context ref="css:color-value"/>
+        <context ref="css:number-value"/>
+        <context ref="css:unicode-range"/>
+        <context ref="arithmetic-operator"/>
+        <context ref="css:slash"/>
+        <context ref="css:comma"/>
+      </include>
+    </context>
+
+    <replace id="css:any-value" ref="less-any-value"/>
+
+
+    <!-- style properties -->
+
+    <context id="less-property-name">
+      <include>
+        <context ref="variable-interpolation-value"/>
+        <context ref="css:property-name" original="true"/>
+      </include>
+    </context>
+
+    <replace id="css:property-name" ref="less-property-name"/>
+
+
+    <!-- style block -->
+
+    <context id="less-declaration-property">
+      <include>
+        <context ref="variable"/> <!-- variable assignment -->
+        <context ref="css:declaration-property" original="true"/>
+      </include>
+    </context>
+
+    <context id="less-declaration-value">
+      <start extended="true">
+        (?(DEFINE)
+          (?&lt;interpolation&gt;  # recursive subpattern to find matching brackets
+            @\{
+              (?:
+                (?>
+                  (?:
+                    [^@{}]+ |
+                    (?! @\{ | \} ) .
+                  )+
+                ) |
+                (?&amp;interpolation)
+              )*
+            \}
+          )
+        )
+        (
+          \+_?: |  # property merge
+          :
+          (?:
+            (?!                                       # not the start of a
+              \%{css:single-identifier-char-regex} |  #   pseudo-class
+              [:\\] |                                 #   pseudo-element, escape
+              @\{                                     #   variable interpolation
+            ) |                                       # or
+            (?=                                       # ends like a normal declaration
+              (?&gt;
+                (?:
+                  [^;}{@]+ |
+                  (?&amp;interpolation)+ |
+                  \@+
+                )*
+              )
+              \%{css:declaration-value-end}           #   with a semicolon or at the end of a block
+            )
+          )
+        )
+      </start>
+      <end>\%{css:declaration-value-end}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="css:declaration-value-content"/>
+      </include>
+    </context>
+
+    <context id="less-style-block-content">
+      <include>
+        <context ref="css:at-rule"/> <!-- because Less variables look like at-rules -->
+        <context ref="detached-ruleset-call"/>
+        <context ref="standalone-plugin-function-call"/>
+        <context ref="inside-ruleset-extend"/>
+        <context ref="css:style-block-content" original="true"/>
+        <context ref="css:selector"/>
+        <context ref="css:style-block"/>
+      </include>
+    </context>
+
+    <replace id="css:declaration-property" ref="less-declaration-property"/>
+    <replace id="css:declaration-value" ref="less-declaration-value"/>
+    <replace id="css:style-block-content" ref="less-style-block-content"/>
+
+
+    <!-- media queries -->
+
+    <!-- include variable-value at this level because a variable can
+         contain the whole media feature test,
+         e.g. ~'(orientation: landscape)'
+         allowing variable-value here means variables are also allowed
+         for media type and media feature test name/value -->
+    <context id="less-media-queries">
+      <include>
+        <context ref="variable-value"/>
+        <context ref="css:media-queries" original="true"/>
+      </include>
+    </context>
+
+    <replace id="css:media-queries" ref="less-media-queries"/>
+
+
+    <!-- Less at-rules -->
+
+    <!--
+    @plugin <options>? <url(...)|"url">;
+    -->
+
+    <context id="at-plugin-options">
+      <start>(?&lt;=@plugin)\s*(\()</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="1" where="start" style-ref="group-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="group-delimiter"/>
+        <context ref="css:comment"/>
+        <!-- options are passed to the plugin directly, not parsed by Less -->
+      </include>
+    </context>
+
+    <context id="at-plugin">
+      <start>@plugin\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:at-rule"/>
+        <context ref="css:comment"/>
+        <context ref="at-plugin-options"/>
+        <context ref="css:url"/>
+        <!-- appears to follow the same rules as @import regarding variables -->
+        <context ref="escape-string"/>
+        <context ref="css:string-value" original="true"/>
+        <context ref="css:at-rule-delimiter"/>
+      </include>
+    </context>
+
+    <context id="standalone-plugin-function-call">
+      <start>(?=\%{css:identifier-regex}\()</start>
+      <end>\%{statement-end}</end>
+      <include>
+        <context sub-pattern="0" where="end" style-ref="css:delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="css:function-call"/>
+      </include>
+    </context>
+
+
+    <!-- at-rules -->
+
+    <context id="less-font-feature-type-value">
+      <include>
+        <context ref="variable-interpolation-value"/>
+        <context ref="css:font-feature-type-value" original="true"/>
+      </include>
+    </context>
+
+    <context id="less-font-feature-value-declaration-name">
+      <include>
+        <context ref="variable-interpolation-value"/>
+        <context ref="css:font-feature-value-declaration-name" original="true"/>
+      </include>
+    </context>
+
+    <context id="less-font-feature-value-declaration-value-content">
+      <include>
+        <context ref="variable-value"/>
+        <context ref="css:font-feature-value-declaration-value-content" original="true"/>
+      </include>
+    </context>
+
+    <!--
+    @import <option (, option)*>? <url(...)|"url"> <media-queries>?;
+    -->
+
+    <context id="less-at-import-options-keyword" style-ref="css:keyword">
+      <keyword>css</keyword>
+      <keyword>inline</keyword>
+      <keyword>less</keyword>
+      <keyword>multiple</keyword>
+      <keyword>once</keyword>
+      <keyword>optional</keyword>
+      <keyword>reference</keyword>
+    </context>
+
+    <context id="less-at-import-options">
+      <start>(?&lt;=@import)\s*(\()</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="1" where="start" style-ref="group-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="group-delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="less-at-import-options-keyword"/>
+        <context ref="css:comma"/>
+      </include>
+    </context>
+
+    <context id="less-at-import">
+      <start>@import\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:at-rule"/>
+        <context ref="css:comment"/>
+        <context ref="less-at-import-options"/>
+        <context ref="css:url"/>
+        <context ref="css:media-queries"/>
+        <!--
+        it appears only variable interpolation (in strings) is allowed
+        https://github.com/SomMeri/less4j/wiki/Less-Language-Import#syntax
+        but variables are allowed in media queries :-P
+        -->
+        <context ref="css:string-value" original="true"/>
+        <context ref="css:at-rule-delimiter"/>
+      </include>
+    </context>
+
+    <context id="less-keyframe-selector-value">
+      <include>
+        <context ref="variable-interpolation-value"/>
+        <context ref="css:keyframe-selector-value" original="true"/>
+      </include>
+    </context>
+
+    <context id="less-at-rule">
+      <include>
+        <context ref="at-plugin"/>
+        <context ref="css:at-rule" original="true"/>
+      </include>
+    </context>
+
+    <replace id="css:at-rule-style-block-content" ref="less-style-block-content"/>
+    <replace id="css:at-rule-css-block-content" ref="less-style-block-content"/>
+    <replace id="css:font-feature-type-value" ref="less-font-feature-type-value"/>
+    <replace id="css:font-feature-value-declaration-name" ref="less-font-feature-value-declaration-name"/>
+    <replace id="css:font-feature-value-declaration-value-content" 
ref="less-font-feature-value-declaration-value-content"/>
+    <replace id="css:at-import" ref="less-at-import"/>
+    <replace id="css:keyframe-selector-value" ref="less-keyframe-selector-value"/>
+    <replace id="css:at-rule" ref="less-at-rule"/>
+
+
+    <!-- mixins -->
+
+    <context id="variable-arguments" style-ref="operator-symbol">
+      <match>\.\.\.</match>
+    </context>
+
+    <context id="mixin-parameters">
+      <start>\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="mixin-parameters-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="mixin-parameters-delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="css:any-value"/>
+        <context ref="variable-arguments"/>
+        <context ref="css:colon"/> <!-- named parameters / default values -->
+        <context ref="css:semicolon"/>
+      </include>
+    </context>
+
+
+    <!-- guards -->
+
+    <context id="guard-logical-operator" style-ref="guard-operator">
+      <keyword>and</keyword>
+      <keyword>not</keyword>
+      <keyword>or</keyword>
+    </context>
+
+    <context id="guard-comparison-operator" style-ref="operator-symbol">
+      <match>(&gt;=?|=&lt;?|&lt;)</match>
+    </context>
+
+    <context id="guard-test">
+      <start>\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:test-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="css:test-delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="css:any-value"/>
+        <context ref="guard-comparison-operator"/>
+      </include>
+    </context>
+
+    <context id="guard">
+      <start>\%[when\%]</start>
+      <end>(?=\{)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="guard-operator"/>
+        <context ref="css:comment"/>
+        <context ref="guard-test"/>
+        <context ref="guard-logical-operator"/>
+        <context ref="css:comma"/>
+      </include>
+    </context>
+
+
+    <!-- Less selectors -->
+
+    <context id="parent-combinator">
+      <match>(&amp;)(\%{css:identifier-chars-regex}?)</match>
+      <include>
+        <context sub-pattern="1" style-ref="css:combinator"/>
+        <context sub-pattern="2" style-ref="selector-fragment"/>
+      </include>
+    </context>
+
+    <context id="variable-interpolation-fragment" style-ref="selector-fragment">
+      <match>(?&lt;=\})\%{css:identifier-chars-regex}</match>
+    </context>
+
+    <context id="less-pseudo-classes" style-ref="css:pseudo-class">
+      <prefix>:</prefix>
+      <keyword>extend</keyword>
+    </context>
+
+    <context id="extend-pseudo-class-argument-keyword" style-ref="css:keyword">
+      <keyword>all</keyword>
+    </context>
+
+    <context id="extend-pseudo-class-argument">
+      <start>(?&lt;=:extend)\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:pseudo-class"/>
+        <context sub-pattern="0" where="end" style-ref="css:pseudo-class"/>
+        <context ref="css:comment"/>
+        <context ref="extend-pseudo-class-argument-keyword"/>
+        <context ref="css:selector"/>
+      </include>
+    </context>
+
+    <context id="inside-ruleset-extend">
+      <start>(?=&amp;:extend\()</start>
+      <end>\%{statement-end}</end>
+      <include>
+        <context sub-pattern="0" where="end" style-ref="css:delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="css:selector"/>
+      </include>
+    </context>
+
+
+    <!-- selectors -->
+
+    <context id="less-attribute-selector-content">
+      <include>
+        <context ref="variable-interpolation-value"/>
+        <context ref="css:attribute-selector-content" original="true"/>
+      </include>
+    </context>
+
+    <context id="less-simple-selector">
+      <include>
+        <context ref="variable-interpolation-value"/> <!-- include in simple selector to be included in 
:not() -->
+        <context ref="variable-interpolation-fragment"/>
+        <context ref="css:simple-selector" original="true"/>
+      </include>
+    </context>
+
+    <context id="less-combinator">
+      <include>
+        <context ref="parent-combinator"/>
+        <context ref="css:combinator" original="true"/>
+      </include>
+    </context>
+
+    <context id="less-pseudo-class">
+      <include>
+        <context ref="less-pseudo-classes"/>
+        <context ref="css:pseudo-class" original="true"/>
+      </include>
+    </context>
+
+    <context id="less-lang-pseudo-class-argument-content">
+      <include>
+        <context ref="variable-interpolation-value"/>
+        <context ref="css:lang-pseudo-class-argument-content" original="true"/>
+      </include>
+    </context>
+
+    <context id="less-nth-pseudo-class-argument-content">
+      <include>
+        <context ref="variable-interpolation-value"/>
+        <context ref="css:nth-pseudo-class-argument-content" original="true"/>
+      </include>
+    </context>
+
+    <context id="less-pseudo-class-argument">
+      <include>
+        <context ref="extend-pseudo-class-argument"/>
+        <context ref="css:pseudo-class-argument" original="true"/>
+      </include>
+    </context>
+
+    <context id="less-selector">
+      <include>
+        <context ref="guard"/>
+        <context ref="css:modifier"/>
+        <context ref="css:selector" original="true"/>
+        <context ref="mixin-parameters"/> <!-- can interfere with pseudo-class arguments -->
+        <context ref="css:semicolon"/> <!-- after mixin calls -->
+      </include>
+    </context>
+
+    <replace id="css:attribute-selector-content" ref="less-attribute-selector-content"/>
+    <replace id="css:simple-selector" ref="less-simple-selector"/>
+    <replace id="css:combinator" ref="less-combinator"/>
+    <replace id="css:pseudo-class" ref="less-pseudo-class"/>
+    <replace id="css:lang-pseudo-class-argument-content" ref="less-lang-pseudo-class-argument-content"/>
+    <replace id="css:nth-pseudo-class-argument-content" ref="less-nth-pseudo-class-argument-content"/>
+    <replace id="css:pseudo-class-argument" ref="less-pseudo-class-argument"/>
+    <replace id="css:selector" ref="less-selector"/>
+
+
+    <!-- top level declarations -->
+
+    <context id="top-level-declaration-property">
+      <include>
+        <context ref="variable"/>
+      </include>
+    </context>
+
+    <context id="top-level-declaration">
+      <include>
+        <context ref="top-level-declaration-property"/>
+        <context ref="css:declaration-value"/>
+        <context ref="css:modifier"/>
+        <context ref="css:semicolon"/>
+      </include>
+    </context>
+
+
+    <!-- main context -->
+
+    <context id="less" class="no-spell-check">
+      <include>
+        <context ref="css:comment"/>
+        <context ref="css:at-rule"/> <!-- because Less variables look like at-rules -->
+        <context ref="detached-ruleset-call"/>
+        <context ref="standalone-plugin-function-call"/>
+        <context ref="top-level-declaration"/>
+        <context ref="css:selector"/>
+        <context ref="css:style-block"/>
+      </include>
+    </context>
+
+  </definitions>
+</language>
diff --git a/data/language-specs/rust.lang b/data/language-specs/rust.lang
index 570c1aa4..fbe6e703 100644
--- a/data/language-specs/rust.lang
+++ b/data/language-specs/rust.lang
@@ -128,10 +128,12 @@ except according to those terms.
       <keyword>i16</keyword>
       <keyword>i32</keyword>
       <keyword>i64</keyword>
+      <keyword>i128</keyword>
       <keyword>u8</keyword>
       <keyword>u16</keyword>
       <keyword>u32</keyword>
       <keyword>u64</keyword>
+      <keyword>u128</keyword>
       <keyword>f32</keyword>
       <keyword>f64</keyword>
       <keyword>char</keyword>
@@ -149,7 +151,7 @@ except according to those terms.
     </context>
 
     <define-regex id="int-suffix" extended="true">
-      (i8|i16|i32|i64|isize|u8|u16|u32|u64|usize)
+      (i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)
     </define-regex>
 
     <define-regex id="exponent" extended="true">
@@ -230,7 +232,7 @@ except according to those terms.
     </define-regex>
 
     <define-regex id="unicode-escape" extended="true">
-      u{\%{hex-digit}{1,6}}
+      u{(\%{hex-digit}_*){1,6}}
     </define-regex>
 
     <context id="string-escape" style-ref="def:special-char">
diff --git a/data/language-specs/scss.lang b/data/language-specs/scss.lang
new file mode 100644
index 00000000..4320c486
--- /dev/null
+++ b/data/language-specs/scss.lang
@@ -0,0 +1,878 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ This file is part of GtkSourceView
+
+ Author: Jeffery To <jeffery to gmail com>
+ Copyright (C) 2018 Jeffery To <jeffery to gmail com>
+
+ GtkSourceView is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ GtkSourceView is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this library; if not, see <http://www.gnu.org/licenses/>.
+
+-->
+<language id="scss" name="SCSS" version="2.0" _section="Other">
+  <metadata>
+    <property name="mimetypes">text/x-scss</property>
+    <property name="globs">*.scss</property>
+    <property name="line-comment-start">//</property>
+    <property name="block-comment-start">/*</property>
+    <property name="block-comment-end">*/</property>
+  </metadata>
+
+  <styles>
+
+    <!-- interpolations -->
+    <style id="interpolation"               name="Interpolation"               map-to="def:preprocessor"/>
+
+    <!-- variables -->
+    <style id="variable"                    name="Variable"                    map-to="def:identifier"/>
+
+    <!-- operators -->
+    <style id="operator-symbol"             name="Operator Symbol"             map-to="css:symbol"/>
+    <style id="logical-operator"            name="Logical Operator"            map-to="def:preprocessor"/>
+
+    <!-- Sass data types -->
+    <style id="boolean"                     name="Boolean Value"               map-to="def:boolean"/>
+    <style id="null"                        name="Null Value"                  
map-to="def:special-constant"/>
+    <style id="list-delimiter"              name="List Delimiter"              map-to="css:delimiter"/>
+    <style id="group-delimiter"             name="Group Delimiter"             map-to="css:delimiter"/>
+
+    <!-- Sass selectors -->
+    <style id="placeholder-selector"        name="Placeholder Selector"        map-to="def:identifier"/>
+    <style id="selector-fragment"           name="Selector Fragment"/>
+
+    <!-- Sass at-rules -->
+    <style id="mixin-name"                  name="Mixin Name"                  map-to="def:keyword"/>
+
+  </styles>
+
+  <default-regex-options case-sensitive="false"/>
+
+  <keyword-char-class>[a-z0-9_-]</keyword-char-class>
+
+  <definitions>
+
+    <!-- global -->
+
+    <context id="sass-c-like-comment-multiline" style-ref="def:comment" class-disabled="no-spell-check" 
class="comment">
+      <start>/\*</start>
+      <end>\*/</end>
+      <include>
+        <context ref="interpolation"/>
+        <context ref="def:in-comment"/>
+      </include>
+    </context>
+
+    <context id="scss-comment">
+      <include>
+        <context ref="def:c-like-comment"/>
+        <context ref="sass-c-like-comment-multiline"/>
+        <context ref="def:c-like-close-comment-outside-comment"/>
+      </include>
+    </context>
+
+    <replace id="css:comment" ref="scss-comment"/>
+
+
+    <!-- interpolations -->
+
+    <context id="interpolation">
+      <start>#\{</start>
+      <end>\}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="interpolation"/>
+        <context sub-pattern="0" where="end" style-ref="interpolation"/>
+        <context ref="css:comment"/>
+        <context ref="css:any-value"/>
+      </include>
+    </context>
+
+
+    <!-- variables -->
+
+    <context id="variable" style-ref="variable">
+      <match>\$\%{css:identifier-regex}</match>
+    </context>
+
+
+    <!-- operators -->
+
+    <!-- leave out the division operator (/)
+         as we cannot reliably distinguish between a literal slash and
+         a division operation -->
+    <context id="arithmetic-operator" style-ref="operator-symbol">
+      <match extended="true">
+        (
+          [+*%] |
+          (?&lt;! \%{css:single-identifier-char-regex} )
+          -
+          (?! \%{css:single-identifier-char-regex} )
+        )
+      </match>
+    </context>
+
+    <context id="string-operator" style-ref="operator-symbol">
+      <match>\+</match>
+    </context>
+
+    <context id="comparison-operator" style-ref="operator-symbol">
+      <match>(&lt;=?|&gt;=?|[=!]=)</match>
+    </context>
+
+    <context id="logical-operator" style-ref="logical-operator">
+      <keyword>and</keyword>
+      <keyword>not</keyword>
+      <keyword>or</keyword>
+    </context>
+
+
+    <!-- Sass data types -->
+
+    <context id="boolean" style-ref="boolean">
+      <keyword>false</keyword>
+      <keyword>true</keyword>
+    </context>
+
+    <context id="null" style-ref="null">
+      <keyword>null</keyword>
+    </context>
+
+    <context id="parent-selector-list" style-ref="css:combinator">
+      <match>&amp;</match>
+    </context>
+
+    <context id="bracketed-list">
+      <start>\[</start>
+      <end>\]</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="list-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="list-delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="css:any-value"/>
+      </include>
+    </context>
+
+    <!-- not sure why one would use a string group but it appears to be syntactically valid -->
+    <context id="string-group">
+      <start>\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="group-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="group-delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="css:string-value"/>
+      </include>
+    </context>
+
+    <context id="data-group">
+      <start>\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="group-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="group-delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="css:data-value"/>
+      </include>
+    </context>
+
+    <!--
+    this could be a list, a map, or an order of operations grouping
+    not sure how to differentiate between these
+    -->
+    <context id="any-group">
+      <start>\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="group-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="group-delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="css:any-value"/>
+        <context ref="css:colon"/> <!-- for maps -->
+      </include>
+    </context>
+
+
+    <!-- data types -->
+
+    <context id="scss-string-content">
+      <include>
+        <context ref="interpolation"/>
+        <context ref="css:string-content" original="true"/>
+      </include>
+    </context>
+
+    <replace id="css:string-content" ref="scss-string-content"/>
+
+
+    <!-- functions -->
+
+    <context id="variable-arguments" style-ref="operator-symbol">
+      <match>\.\.\.</match>
+    </context>
+
+    <context id="scss-url">
+      <start>url\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:function"/>
+        <context sub-pattern="0" where="end" style-ref="css:function"/>
+        <!-- only accept multi-line comments because // is part of urls -->
+        <context ref="sass-c-like-comment-multiline"/>
+        <context ref="def:c-like-close-comment-outside-comment"/>
+        <context ref="css:string-value"/>
+      </include>
+    </context>
+
+    <context id="scss-function-content">
+      <include>
+        <context ref="css:function-content" original="true"/>
+        <context ref="variable-arguments"/>
+        <context ref="css:colon"/> <!-- for named arguments -->
+      </include>
+    </context>
+
+    <replace id="css:url" ref="scss-url"/>
+    <replace id="css:function-content" ref="scss-function-content"/>
+
+
+    <!-- data values -->
+
+    <context id="scss-name-value">
+      <include>
+        <context ref="css:function-call"/>
+        <context ref="interpolation"/> <!-- outputs unquoted strings -->
+        <context ref="variable"/>
+        <context ref="css:name-value" original="true"/>
+      </include>
+    </context>
+
+    <context id="scss-string-value">
+      <include>
+        <context ref="css:function-call"/>
+        <context ref="string-group"/>
+        <context ref="variable"/>
+        <context ref="css:string-value" original="true"/>
+        <context ref="string-operator"/>
+      </include>
+    </context>
+
+    <context id="scss-data-value">
+      <include>
+        <context ref="css:function-call"/>
+        <context ref="data-group"/>
+        <context ref="interpolation"/>
+        <context ref="variable"/>
+        <context ref="css:string-value" original="true"/>
+        <context ref="css:color-value"/>
+        <context ref="css:number-value"/>
+        <context ref="css:unicode-range"/>
+        <context ref="arithmetic-operator"/>
+      </include>
+    </context>
+
+    <replace id="css:name-value" ref="scss-name-value"/>
+    <replace id="css:string-value" ref="scss-string-value"/>
+    <replace id="css:data-value" ref="scss-data-value"/>
+
+
+    <!-- any assignable value -->
+
+    <context id="scss-any-value">
+      <include>
+        <context ref="css:function-call"/>
+        <context ref="any-group"/>
+        <context ref="parent-selector-list"/>
+        <context ref="bracketed-list"/>
+        <context ref="interpolation"/>
+        <context ref="variable"/>
+        <context ref="boolean"/>
+        <context ref="null"/>
+        <context ref="css:property-value-keyword"/>
+        <context ref="css:string-value" original="true"/>
+        <context ref="css:color-value"/>
+        <context ref="css:number-value"/>
+        <context ref="css:unicode-range"/>
+        <context ref="logical-operator"/>
+        <context ref="comparison-operator"/>
+        <context ref="arithmetic-operator"/>
+        <context ref="css:slash"/>
+        <context ref="css:comma"/>
+      </include>
+    </context>
+
+    <replace id="css:any-value" ref="scss-any-value"/>
+
+
+    <!-- Sass modifiers -->
+
+    <context id="variable-assignment-modifiers" style-ref="css:modifier">
+      <keyword>default</keyword>
+      <keyword>global</keyword>
+    </context>
+
+    <context id="at-extend-modifiers" style-ref="css:modifier">
+      <keyword>optional</keyword>
+    </context>
+
+
+    <!-- modifiers -->
+
+    <context id="scss-modifier-content">
+      <include>
+        <context ref="variable-assignment-modifiers"/>
+        <context ref="at-extend-modifiers"/>
+        <context ref="css:modifier-content" original="true"/>
+      </include>
+    </context>
+
+    <replace id="css:modifier-content" ref="scss-modifier-content"/>
+
+
+    <!-- style properties -->
+
+    <context id="scss-property-name">
+      <include>
+        <context ref="interpolation"/>
+        <context ref="css:property-name" original="true"/>
+      </include>
+    </context>
+
+    <replace id="css:property-name" ref="scss-property-name"/>
+
+
+    <!-- style block -->
+
+    <context id="nested-properties" end-parent="true">
+      <start>\{</start>
+      <end>\}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:block-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="css:block-delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="css:declaration"/>
+      </include>
+    </context>
+
+    <context id="scss-declaration-property">
+      <include>
+        <context ref="variable"/> <!-- variable assignment -->
+        <context ref="css:declaration-property" original="true"/>
+      </include>
+    </context>
+
+    <context id="scss-declaration-value-content">
+      <include>
+        <context ref="nested-properties"/>
+        <context ref="css:declaration-value-content" original="true"/>
+      </include>
+    </context>
+
+    <context id="scss-declaration-value">
+      <start extended="true">
+        (?(DEFINE)
+          (?&lt;interpolation&gt;  # recursive subpattern to find matching brackets
+            \#\{
+              (?:
+                (?>
+                  (?:
+                    [^#{}]+ |
+                    (?! \#\{ | \} ) .
+                  )+
+                ) |
+                (?&amp;interpolation)
+              )*
+            \}
+          )
+        )
+        :
+        (?:
+          (?!                                       # not the start of a
+            \%{css:single-identifier-char-regex} |  #   pseudo-class
+            [:\\] |                                 #   pseudo-element, escape
+            \#\{                                    #   interpolation
+          ) |                                       # or
+          (?=                                       # ends like a normal declaration
+            (?&gt;
+              (?:
+                [^;}{#]+ |
+                (?&amp;interpolation)+ |
+                \#+
+              )*
+            )
+            \%{css:declaration-value-end}           #   with a semicolon or at the end of a block
+          )
+        )
+      </start>
+      <end>\%{css:declaration-value-end}</end> <!-- nested-properties has end-parent="true" -->
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="css:declaration-value-content"/>
+      </include>
+    </context>
+
+    <context id="scss-style-block-content">
+      <include>
+        <context ref="css:style-block-content" original="true"/>
+        <context ref="css:at-rule"/>
+        <context ref="css:selector"/>
+        <context ref="css:style-block"/>
+      </include>
+    </context>
+
+    <replace id="css:declaration-property" ref="scss-declaration-property"/>
+    <replace id="css:declaration-value-content" ref="scss-declaration-value-content"/>
+    <replace id="css:declaration-value" ref="scss-declaration-value"/>
+    <replace id="css:style-block-content" ref="scss-style-block-content"/>
+
+
+    <!-- media queries -->
+
+    <context id="scss-media-type-value">
+      <include>
+        <context ref="interpolation"/>
+        <context ref="css:media-type-value" original="true"/>
+      </include>
+    </context>
+
+    <context id="scss-media-feature-test-name">
+      <include>
+        <context ref="interpolation"/>
+        <context ref="variable"/>
+        <context ref="css:media-feature-test-name" original="true"/>
+      </include>
+    </context>
+
+    <context id="scss-media-feature-test-value-content">
+      <include>
+        <context ref="interpolation"/>
+        <context ref="variable"/>
+        <context ref="css:media-feature-test-value-content" original="true"/>
+      </include>
+    </context>
+
+    <replace id="css:media-type-value" ref="scss-media-type-value"/>
+    <replace id="css:media-feature-test-name" ref="scss-media-feature-test-name"/>
+    <replace id="css:media-feature-test-value-content" ref="scss-media-feature-test-value-content"/>
+
+
+    <!-- Sass at-rules -->
+
+    <!--
+    @extend <selector> <optional modifier>?;
+    -->
+
+    <context id="at-extend">
+      <start>@extend\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:at-rule"/>
+        <context ref="css:comment"/>
+        <context ref="css:selector"/>
+        <context ref="css:modifier"/>
+        <context ref="css:at-rule-delimiter"/>
+      </include>
+    </context>
+
+    <!--
+    @at-root (<selector>|<query>)? <css-block>
+    -->
+
+    <context id="at-at-root-query-type" style-ref="css:property-name">
+      <keyword>without</keyword>
+      <keyword>with</keyword>
+    </context>
+
+    <context id="at-at-root-query-directive" style-ref="css:keyword">
+      <keyword>all</keyword>
+      <keyword>media</keyword>
+      <keyword>rule</keyword>
+      <keyword>supports</keyword>
+    </context>
+
+    <context id="at-at-root-query-value">
+      <start>:</start>
+      <end>\%{css:test-value-end}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="interpolation"/>
+        <context ref="variable"/>
+        <context ref="at-at-root-query-directive"/>
+      </include>
+    </context>
+
+    <context id="at-at-root-query">
+      <start>\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:test-delimiter"/>
+        <context sub-pattern="0" where="end" style-ref="css:test-delimiter"/>
+        <context ref="css:comment"/>
+        <context ref="interpolation"/>
+        <context ref="variable"/>
+        <context ref="at-at-root-query-type"/>
+        <context ref="at-at-root-query-value"/>
+      </include>
+    </context>
+
+    <context id="at-at-root">
+      <start>@at-root\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:at-rule"/>
+        <context ref="css:comment"/>
+        <context ref="css:selector"/>
+        <context ref="at-at-root-query"/>
+        <context ref="css:at-rule-css-block"/>
+      </include>
+    </context>
+
+    <!--
+    @debug <any-value>;
+    @warn <any-value>;
+    @error <any-value>;
+    -->
+
+    <context id="at-debug-warn-error">
+      <start>@(debug|warn|error)\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:at-rule"/>
+        <context ref="css:comment"/>
+        <context ref="css:any-value"/>
+        <context ref="css:at-rule-delimiter"/>
+      </include>
+    </context>
+
+    <!--
+    @if <any-value> <css-block>
+    @else if <any-value> <css-block>
+    @else <css-block>
+    -->
+
+    <context id="at-if-else-if">
+      <start>@(if|else\s+if)\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:at-rule"/>
+        <context ref="css:comment"/>
+        <context ref="css:any-value"/>
+        <context ref="css:at-rule-css-block"/>
+      </include>
+    </context>
+
+    <context id="at-else">
+      <start>@else\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:at-rule"/>
+        <context ref="css:comment"/>
+        <context ref="css:at-rule-css-block"/>
+      </include>
+    </context>
+
+    <!--
+    @for <variable> from <any-value> (through|to) <any-value> <css-block>
+    -->
+
+    <context id="at-for-keyword" style-ref="css:at-rule-operator">
+      <keyword>from</keyword>
+      <keyword>through</keyword>
+      <keyword>to</keyword>
+    </context>
+
+    <context id="at-for">
+      <start>@for\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:at-rule"/>
+        <context ref="css:comment"/>
+        <context ref="at-for-keyword"/>
+        <context ref="variable"/>
+        <context ref="css:any-value"/>
+        <context ref="css:at-rule-css-block"/>
+      </include>
+    </context>
+
+    <!--
+    @each <variable> in <list> <css-block>
+    -->
+
+    <context id="at-each-keyword" style-ref="css:at-rule-operator">
+      <keyword>in</keyword>
+    </context>
+
+    <context id="at-each">
+      <start>@each\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:at-rule"/>
+        <context ref="css:comment"/>
+        <context ref="at-each-keyword"/>
+        <context ref="variable"/>
+        <context ref="css:any-value"/>
+        <context ref="css:comma"/>
+        <context ref="css:at-rule-css-block"/>
+      </include>
+    </context>
+
+    <!--
+    @while <expression> <css-block>
+    -->
+
+    <context id="at-while">
+      <start>@while\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:at-rule"/>
+        <context ref="css:comment"/>
+        <context ref="css:any-value"/>
+        <context ref="css:at-rule-css-block"/>
+      </include>
+    </context>
+
+    <!--
+    @mixin <mixin name> <mixin-parameters>? <css-block>
+    -->
+
+    <context id="mixin-parameters">
+      <start>\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="mixin-name"/>
+        <context sub-pattern="0" where="end" style-ref="mixin-name"/>
+        <context ref="css:comment"/>
+        <context ref="css:function-content"/>
+      </include>
+    </context>
+
+    <context id="at-mixin">
+      <start>@mixin\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:at-rule"/>
+        <context ref="css:comment"/>
+        <context ref="css:name" style-ref="mixin-name"/>
+        <context ref="mixin-parameters"/>
+        <context ref="css:at-rule-css-block"/>
+      </include>
+    </context>
+
+    <!--
+    @include <mixin name> <mixin-parameters>? (;|<css-block>)
+    -->
+
+    <context id="at-include">
+      <start>@include\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:at-rule"/>
+        <context ref="css:comment"/>
+        <context ref="css:name" style-ref="mixin-name"/>
+        <context ref="mixin-parameters"/>
+        <context ref="css:at-rule-delimiter"/>
+        <context ref="css:at-rule-css-block"/>
+      </include>
+    </context>
+
+    <!--
+    @content;
+    -->
+
+    <context id="at-content">
+      <start>@content\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:at-rule"/>
+        <context ref="css:comment"/>
+        <context ref="css:at-rule-delimiter"/>
+      </include>
+    </context>
+
+    <!--
+    @function <function name> <function-parameters> <css-block>
+    -->
+
+    <context id="function-parameters">
+      <start>\(</start>
+      <end>\)</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:function"/>
+        <context sub-pattern="0" where="end" style-ref="css:function"/>
+        <context ref="css:comment"/>
+        <context ref="css:function-content"/>
+      </include>
+    </context>
+
+    <context id="at-function">
+      <start>@function\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:at-rule"/>
+        <context ref="css:comment"/>
+        <!-- we define it this way because there can be whitespace
+             between the function name and the parentheses -->
+        <context ref="css:name" style-ref="css:function"/>
+        <context ref="function-parameters"/>
+        <context ref="css:at-rule-css-block"/>
+      </include>
+    </context>
+
+    <!--
+    @return <any-value>;
+    -->
+
+    <context id="at-return">
+      <start>@return\%]</start>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="css:at-rule"/>
+        <context ref="css:comment"/>
+        <context ref="css:any-value"/>
+        <context ref="css:at-rule-delimiter"/>
+      </include>
+    </context>
+
+
+    <!-- at-rules -->
+
+    <context id="scss-font-feature-value-declaration-value-content">
+      <include>
+        <context ref="interpolation"/>
+        <context ref="variable"/>
+        <context ref="css:font-feature-value-declaration-value-content" original="true"/>
+      </include>
+    </context>
+
+    <context id="scss-keyframe-selector-value">
+      <include>
+        <context ref="interpolation"/>
+        <context ref="css:keyframe-selector-value" original="true"/>
+      </include>
+    </context>
+
+    <context id="scss-namespace-value">
+      <include>
+        <context ref="interpolation"/>
+        <context ref="css:namespace-value" original="true"/>
+      </include>
+    </context>
+
+    <context id="scss-at-rule">
+      <include>
+
+        <context ref="at-extend"/>
+        <context ref="at-at-root"/>
+
+        <context ref="at-debug-warn-error"/>
+
+        <context ref="at-if-else-if"/>
+        <context ref="at-else"/>
+
+        <context ref="at-for"/>
+        <context ref="at-each"/>
+        <context ref="at-while"/>
+
+        <context ref="at-mixin"/>
+        <context ref="at-include"/>
+        <context ref="at-content"/>
+
+        <context ref="at-function"/>
+        <context ref="at-return"/>
+
+        <context ref="css:at-rule" original="true"/>
+
+      </include>
+    </context>
+
+    <replace id="css:at-rule-style-block-content" ref="scss-style-block-content"/>
+    <replace id="css:at-rule-css-block-content" ref="scss-style-block-content"/>
+    <replace id="css:font-feature-value-declaration-value-content" 
ref="scss-font-feature-value-declaration-value-content"/>
+    <replace id="css:keyframe-selector-value" ref="scss-keyframe-selector-value"/>
+    <replace id="css:namespace-value" ref="scss-namespace-value"/>
+    <replace id="css:at-rule" ref="scss-at-rule"/>
+
+
+    <!-- Sass selectors -->
+
+    <context id="parent-combinator">
+      <match>(&amp;)(\%{css:identifier-chars-regex}?)</match>
+      <include>
+        <context sub-pattern="1"  style-ref="css:combinator"/>
+        <context sub-pattern="2"  style-ref="selector-fragment"/>
+      </include>
+    </context>
+
+    <context id="placeholder-selector" style-ref="placeholder-selector">
+      <match>%\%{css:identifier-regex}</match>
+    </context>
+
+    <context id="interpolation-fragment" style-ref="selector-fragment">
+      <match>(?&lt;=\})\%{css:identifier-chars-regex}</match>
+    </context>
+
+
+    <!-- selectors -->
+
+    <context id="scss-simple-selector">
+      <include>
+        <context ref="interpolation"/> <!-- include in simple selector to be included in :not() -->
+        <context ref="interpolation-fragment"/>
+        <context ref="css:simple-selector" original="true"/>
+      </include>
+    </context>
+
+    <context id="scss-combinator">
+      <include>
+        <context ref="parent-combinator"/>
+        <context ref="css:combinator" original="true"/>
+      </include>
+    </context>
+
+    <context id="scss-nth-pseudo-class-argument-content">
+      <include>
+        <context ref="interpolation"/>
+        <context ref="css:nth-pseudo-class-argument-content" original="true"/>
+      </include>
+    </context>
+
+    <context id="scss-selector">
+      <include>
+        <context ref="placeholder-selector"/>
+        <context ref="css:selector" original="true"/>
+      </include>
+    </context>
+
+    <replace id="css:simple-selector" ref="scss-simple-selector"/>
+    <replace id="css:combinator" ref="scss-combinator"/>
+    <replace id="css:nth-pseudo-class-argument-content" ref="scss-nth-pseudo-class-argument-content"/>
+    <replace id="css:selector" ref="scss-selector"/>
+
+
+    <!-- top level declarations -->
+
+    <context id="top-level-declaration-property">
+      <include>
+        <context ref="variable"/>
+      </include>
+    </context>
+
+    <context id="top-level-declaration">
+      <include>
+        <context ref="top-level-declaration-property"/>
+        <context ref="css:declaration-value"/>
+        <context ref="css:modifier"/>
+        <context ref="css:semicolon"/>
+      </include>
+    </context>
+
+
+    <!-- main context -->
+
+    <context id="scss" class="no-spell-check">
+      <include>
+        <context ref="top-level-declaration"/>
+        <context ref="css:css"/>
+      </include>
+    </context>
+
+  </definitions>
+</language>
diff --git a/data/language-specs/xml.lang b/data/language-specs/xml.lang
index 8fd7d3ed..6303e19b 100644
--- a/data/language-specs/xml.lang
+++ b/data/language-specs/xml.lang
@@ -24,8 +24,8 @@
 -->
 <language id="xml" name="XML" version="2.0" _section="Markup">
     <metadata>
-        <property name="mimetypes">application/xml;text/xml</property>
-        <property 
name="globs">*.xml;*.xspf;*.siv;*.smil;*.smi;*.sml;*.kino;*.xul;*.xbel;*.abw;*.zabw;*.glade;*.jnlp;*.xhtml;*.svg;*.mml;*.rdf;*.rss;*.wml;*.xmi;*.fo;*.xslfo</property>
+        <property name="mimetypes">application/xml;text/xml;text/sgml</property>
+        <property 
name="globs">*.xml;*.xspf;*.siv;*.smil;*.smi;*.sml;*.kino;*.xul;*.xbel;*.abw;*.zabw;*.glade;*.jnlp;*.xhtml;*.svg;*.mml;*.rdf;*.rss;*.wml;*.xmi;*.fo;*.xslfo;*.sgml</property>
         <property name="block-comment-start">&lt;!--</property>
         <property name="block-comment-end">--&gt;</property>
     </metadata>
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
index 57e45314..e584dfdc 100644
--- a/po/POTFILES.skip
+++ b/po/POTFILES.skip
@@ -68,6 +68,7 @@ data/language-specs/json.lang
 data/language-specs/julia.lang
 data/language-specs/kotlin.lang
 data/language-specs/latex.lang
+data/language-specs/less.lang
 data/language-specs/lex.lang
 data/language-specs/libtool.lang
 data/language-specs/llvm.lang
@@ -113,6 +114,7 @@ data/language-specs/rust.lang
 data/language-specs/scala.lang
 data/language-specs/scheme.lang
 data/language-specs/scilab.lang
+data/language-specs/scss.lang
 data/language-specs/sh.lang
 data/language-specs/sml.lang
 data/language-specs/sparql.lang
diff --git a/tests/syntax-highlighting/file.css b/tests/syntax-highlighting/file.css
index 1776246d..04c96786 100644
--- a/tests/syntax-highlighting/file.css
+++ b/tests/syntax-highlighting/file.css
@@ -1,35 +1,366 @@
-#testid[type=text] {
-    font: 12px italic "Overpass";
+@charset "UTF-8";
+/* @charset must:
+   * be on the first line of the file
+   * appear at the start of the line
+   * be lowercase
+   * followed by one space
+   * have a double quoted encoding name (encoding is case insensitive)
+   * be terminated by semicolon
+*/
+
+
+/*
+ * general
+ */
+
+/* whitespace */
+#main
+{
+    color:aqua;
+    float: left!important;
+    margin  :  0  ;
+    width
+        :
+        100%
+        !
+        important
+        ;
 }
 
-p + div {
-    color: aqua;
+/* case insensitivity */
+Body {
+    FONT: 12Px/16pX iTaLiC sans-SERIF;
+}
+
+
+/*
+ * selectors
+ */
+
+/* simple selectors */
+#testID,       /* id */
+.someclass,    /* class */
+div,           /* type */
+*,             /* universal */
+[lang|="zh"] { /* attribute */
+    color: black;
 }
 
-.someclass,
-.otherclass {
-    font-size: 20px;
+/* combinators */
+header + main, /* adjacent sibling */
+li ~ li,       /* general sibling */
+ul > li,       /* child */
+ul ul {        /* descendant */
+    color: blue;
 }
 
-ul::before {}
+/* pseudo-elements */
+:after,
+::after,
+::placeholder,
+::selection {
+    color: green;
+}
 
-link:hover {}
+/* pseudo-classes */
+:hover,
+:required,
+:lang(fr),
+:not(div#sidebar.fancy),
+:nth-child(n+1),
+:nth-last-child(-2n - 30),
+:nth-of-type(5),
+:nth-last-of-type(even) {
+    color: yellow;
+}
 
-@import url("fineprint.css");
+/* pseudo-classes with invalid arguments */
+:not(div:before),         /* pseudo-element */
+:not(input::placeholder), /* pseudo-element */
+:not(p:not(:lang(en))),   /* nested :not */
+:nth-child(1.2n),         /* non-integer */
+:nth-child(.5),           /* non-integer */
+:nth-child(n+-1) {        /* number sign */
+    color: red;
+}
 
-@media all {
-    * ~ ul {
-        padding: 10px;
+/* namespace qualified */
+a,           /* type in default namespace */
+svg|a,       /* type in specified namespace */
+|a,          /* type in no namespace */
+*|a,         /* type in all namespaces (including no namespace) */
+svg|*,       /* universal */
+svg|[fill] { /* attribute */
+    color: white;
+}
+
+
+/*
+ * basic data types
+ */
+
+#main {
+    /* angle */
+    transform: rotate(+33.333e+3deg);
+
+    /* color */
+    color: #f00;
+    color: #f00f; /* #rgba */
+    color: #ff0000;
+    color: #ff0000ff; /* #rrggbbaa */
+    color: red;
+    color: lightgoldenrodyellow;
+    color: rebeccapurple;
+    color: currentColor;
+
+    /* freqency (not currently used for any property) */
+    content: 44.1kHz;
+
+    /* integer */
+    z-index: +255;
+    z-index: -1;
+
+    /* length */
+    width: 10px;
+    width: 10.5rem;
+    width: -10e-2vw;
+
+    /* number */
+    opacity: .5;
+    opacity: 0.3333;
+    opacity: 1;
+    opacity: 2e-34;
+
+    /* percentage */
+    width: 100%;
+
+    /* string */
+    content: "double quoted";
+    content: 'single quoted';
+
+    /* time */
+    transition-duration: .4s;
+    transition-duration: 400ms;
+
+    /* unicode range */
+    unicode-range: U+0025-00FF;
+    unicode-range: U+4??; /* wildcard range */
+}
+
+/* ratio */
+@media (min-aspect-ratio: 16/9) {}
+
+/* resolution */
+@media (min-resolution: +2.54dpcm) {}
+
+
+/*
+ * identifiers
+ */
+
+/* leading hyphens */
+#-here.-there,
+#-- .--everywhere { /* two hyphens: https://stackoverflow.com/a/30822662 */
+    color: blue;
+}
+
+/* non-ASCII */
+#español,
+#你好,
+.❤♫ {
+    color: green;
+}
+
+/* invalid identifiers */
+#1id,      /* starts with digit */
+.-2class { /* starts with hyphen digit */
+    color: maroon;
+}
+
+
+/*
+ * escaping
+ */
+
+/* selectors */
+#\..\+\ space\@\>,                            /* special character escape */
+#\E9 dition .\0000E9dition .motion_\e9motion, /* Unicode character escape */
+.\e33 div,                                    /* trailing space terminates Unicode character escape */
+.\e33  div,                                   /* extra space to denote separate tokens */
+.\31 23 {                                     /* escape leading digit of identifier */
+
+    /* property value */
+    content: "\E9 dition \
+              \"\0000E9dition\" \
+              \e9motion";
+
+    /* function name */
+    background: \u\72\l(image.png);
+}
+
+
+/*
+ * functions
+ */
+
+#main {
+    /* url */
+    background: url("image.svg");
+
+    /* function argument keywords */
+    background-image: linear-gradient(to left top, #fff, blue);
+    grid-template-columns: repeat(2, minmax(max-content, 300px) 1fr) 100px;
+}
+
+
+/*
+ * style properties
+ */
+
+#main {
+    /* svg */
+    fill: url(#pattern);
+    text-rendering: optimizeLegibility;
+
+    /* css3 */
+    font-variant-east-asian: jis04;
+    size: letter;
+    transition-timing-function: ease-in;
+
+    /* animatable */
+    transition-property: height, font-size, visibility;
+}
+
+/*
+ * modifiers
+ */
+body {
+    background: pink !important;
+}
+
+
+/*
+ * media queries
+ */
+
+@media screen, (orientation: portrait) {}
+@media not (print and (min-monochrome: 16) and (color)) {}
+@media only screen {} @media not print {}
+
+
+/*
+ * at-rules
+ */
+
+/* @font-face */
+@font-face {
+    font-family: MyHelvetica;
+    src: local("Helvetica Neue"),
+         local("HelveticaNeue"),
+         url(MgOpenModerna.ttf);
+}
+
+/* @font-feature-values */
+@font-feature-values Font One {
+    @styleset {
+        nice-style: 12;
     }
-    @media screen and (orientation: portrait) {
-        .heading > .news {
-            background-image: url(image.png);
-        }
+}
+.nice-look {
+    font-variant-alternates: styleset(nice-style);
+}
+
+/* @import */
+@import URL("fineprint.css");
+@import 'custom.css';
+@import url('landscape.css') screen and (orientation: landscape), print;
+
+/* @keyframes */
+@keyframes myanim {
+    from { opacity: 0.0; }
+    50%  { opacity: 0.5; }
+    to   { opacity: 1.0; }
+}
+
+/* @media */
+@media all {
+    body {
+        background: gray;
     }
-    @media print and (min-monochrome: 16) {
+    @media screen, (orientation: portrait) {
         body {
-            color: #000;
+            background: grey;
         }
     }
 }
 
+/* @namespace */
+@namespace "http://www.w3.org/1999/xhtml";;
+@namespace svg url(http://www.w3.org/2000/svg);
+
+/* @page */
+@page {
+    bleed: 1cm;
+}
+@page toc, :blank {
+    margin: 2cm;
+    marks: crop cross;
+}
+@page index:left {
+    size: A4;
+
+    @top-right {
+        content: "Page " counter(page);
+    }
+}
+
+/* @supports */
+@supports (animation-name: test) {
+    @keyframes 'my-complicated-animation' {
+        0%   { width: 0; }
+        100% { width: 100%; }
+    }
+}
+
+
+/*
+ * vendor-specific extensions
+ */
+
+/* pseudo-elements */
+input[type="number"]::-webkit-outer-spin-button,
+input[type="number"]::-webkit-inner-spin-button {
+    -webkit-appearance: none;
+}
+input[type="number"] {
+    -moz-appearance: textfield;
+}
+
+/* pseudo-classes */
+#page:-moz-full-screen,
+#page:-ms-fullscreen,
+#page:-webkit-full-screen {
+    background: silver;
+}
+
+/* functions */
+.footer {
+    background-image: -webkit-linear-gradient(to left top, #fff, blue);
+}
+
+/* style properties */
+#sidebar {
+    -ms-overflow-style: -ms-autohiding-scrollbar;
+}
+@supports not ((text-align-last: justify) or (-moz-text-align-last: justify)) {
+    body {
+        text-align: justify;
+    }
+}
+
+/* at-rules */
+@-webkit-keyframes myanim {
+    from { opacity: 0.0; }
+    50%  { opacity: 0.5; }
+    to   { opacity: 1.0; }
+}
diff --git a/tests/syntax-highlighting/file.less b/tests/syntax-highlighting/file.less
new file mode 100644
index 00000000..ef8308eb
--- /dev/null
+++ b/tests/syntax-highlighting/file.less
@@ -0,0 +1,779 @@
+/*
+ * nesting
+ */
+
+#header {
+    width: 300px;
+
+    .navigation {
+        font-size: 12px;
+    }
+
+    @media (min-width: 768px) {
+        width: 600px;
+
+        @media (min-resolution: 192dpi) {
+            background-image: url(/img/retina2x.png);
+        }
+    }
+}
+
+
+/*
+ * parent selector
+ */
+
+.component {
+    &:hover {
+        text-decoration: underline;
+    }
+
+    // compound selector
+    &__element,
+    &--modifier {
+        border: 1px;
+    }
+
+    // multiple &
+    & + & {
+        color: red;
+    }
+
+    // changing selector order
+    body.firefox & {
+        font-weight: normal;
+    }
+}
+
+
+/*
+ * variables, data types
+ */
+
+// assignment
+@number:                      5em;
+@double-quoted-string:        "foo";
+@single-quoted-string:        'bar';
+@double-quoted-escape-string: ~"foo";
+@single-quoted-escape-string: ~'bar';
+@not-quoted-string:           baz;
+@spaces-list:                 1px 2px 3px 4px;
+@commas-list:                 arial, some-other-arial, sans-serif;
+@color:                       #fe57a1;
+
+@detached-ruleset: {
+    color: red;
+
+    div {
+        color: blue;
+    }
+};
+
+#main {
+    // property value
+    width: @width;
+
+    // variable reference
+    color: @@color-variable-name;
+
+    // property variable
+    background-color: $color;
+
+    // use detached ruleset
+    @detached-ruleset(); // parentheses required
+}
+
+// media type, feature test
+@import "foo" @type and @feature-test, (@feature-test-content);
+@media @type and @feature-test, (@feature-test-content) {
+    width: 700px;
+}
+
+// font feature value
+@font-feature-values Font One {
+    @styleset {
+        nice-style: @value;
+    }
+}
+
+// @keyframes name
+@keyframes @myanim {
+    from { width: 0; }
+    to   { width: 100%; }
+}
+
+
+/*
+ * cases where Less doesn't currently accept variables (as of Less 3.0.0)
+ * but may be still be incidentally highlighted
+ */
+
+// font feature values font name
+@font-feature-values @fontname {
+    @styleset {
+        nice-style: 12;
+    }
+}
+
+// @namespace name
+@namespace @name url('http://www.w3.org/2000/svg');
+
+// @page custom name, pseudo-page
+@page @name {
+    margin: 0;
+
+    @left-top {
+       content: '';
+       }
+}
+
+
+/*
+ * variable interpolation
+ */
+
+// selector
+@{hash-id},
+#@{id},
+#i@{d},
+@{whole-class},
+.part-@{class}-fragment,
+@{div},
+d@{i}v,
+[@{attr}=@{value}],
+[@{attr-selector-content}],
+@{attr-selector},
+@{selection},
+::se@{lect}ion,
+@{hover},
+:ho@{v}er,
+@{lang-fr},
+:la@{ng}(fr),
+:lang(@{fr}),
+:nth-child(@{expr}),
+:not(@{div}) {
+
+    // property name
+    @{font}: serif;
+    background-@{image}: none;
+    border-@{bottom}-width: 0;
+
+    // inside strings
+    content: "@{var}";
+    content: '@{var}';
+
+    // nested interpolations
+    content: "@{@{nested}-variable}";
+}
+
+// font feature type, custom name
+@font-feature-values Font One {
+    @{type} {
+        @{name}: 12;
+    }
+}
+
+// inside @import url()
+@import url("http://fonts.googleapis.com/css?family=@{family}";);
+// inside @import string
+@import "http://fonts.googleapis.com/css?family=@{family}";;
+
+// @keyframes selectors
+@keyframes myanim {
+    @{from} { width: 0; }
+    @{to}   { width: 100%; }
+}
+
+// @page margin box type
+@page toc, :first {
+    margin: 0;
+
+    @{margin-box-type} {
+       content: '';
+       }
+}
+
+
+/*
+ * operations
+ */
+
+body {
+    width: (1px + (2em - 3rem)) * (4 / 5vh);
+
+    // unary negation
+    z-index: -@z-index;
+    margin-bottom: -(@base * 2);
+}
+
+
+/*
+ * functions
+ */
+
+body {
+    // Less string format function
+    content: %("1 plus 2 is %d", 1 + 2);
+
+    // single line comments not parsed inside url()
+    background: url(http://example.com/styles.css);
+
+    // semicolons separators
+    color: hsl(90; 100%; 50%);
+}
+
+
+/*
+ * extend
+ */
+
+// attached to selector
+#main:extend(.card-style),
+.sidebar :extend(div pre) {
+    color: blue;
+}
+
+#main {
+    // inside ruleset
+    &:extend(#board:nth-child(2n+3));
+
+    // all keyword
+    &:extend(div ~ .inline[name="foo"] all);
+}
+
+
+/*
+ * property merge
+ */
+
+code {
+    // with comma
+    box-shadow+: 0 0 20px black;
+
+    // with space
+    transform+_: scale(2);
+}
+
+
+/*
+ * mixins
+ */
+
+// mixin definition
+.black() {
+    color: black;
+}
+
+// with parameters
+.box(@margin, @padding) { // comma separated
+    margin: @margin;
+    padding: @padding;
+}
+.box(@margin; @padding) { // semicolon separated
+    margin: @margin;
+    padding: @padding;
+}
+.box(@margin: 10px; @padding: 10px) { // default parameters
+    margin: @margin;
+    padding: @padding;
+}
+
+// @arguments
+.box-shadow(@x: 0; @y: 0; @blur: 1px; @color: #000) {
+    box-shadow: @arguments;
+}
+
+// variable arguments
+.mixin(...) {} // 0 or more arguments
+.mixin(@a; ...) {} // at least 1 argument
+.mixin(@a; @rest...) {} // remaining arguments bound to variable
+
+// with pattern
+.mixin(dark; 5px) {}
+.mixin(light; #000) {}
+
+// mixin call
+#main {
+    // existing styles
+    #header;
+    .card-style;
+
+    // existing styles with parentheses (optional),
+    // or mixins with parentheses and no required parameters
+    #header();
+    .card-style();
+
+    // namespaced styles
+    #outer > .inner;
+    #outer .inner;
+    #outer.inner;
+
+    // important modifier
+    #header !important;
+    .card-style() !important;
+    #outer > .inner !important;
+
+    // with parameters
+    .box(20px, 10px); // comma separated
+    .box(20px; 10px); // semicolon separated
+    .box(@padding: 10px; @margin: 20px); // named parameters
+    .box(@list...); // expands values in @list as arguments
+    .mixin({ // detached ruleset
+        color: red;
+        div {
+            color: blue;
+        }
+    });
+
+    // with pattern
+    .mixin(dark; 5px);
+    .mixin(light; #000);
+}
+
+
+/*
+ * guards
+ */
+
+// regular styles
+button when (@my-option = true) {
+    color: white;
+}
+& when (@my-option = true) {
+    button {
+        color: white;
+    }
+    a {
+        color: blue;
+    }
+}
+
+// namespace
+#namespace when (@mode = huge) {
+    .mixin() {}
+}
+#namespace {
+    .mixin() when (@mode = huge) {}
+}
+
+// mixin
+.mixin (@a) when (lightness(@a) >= 50%) {
+    background-color: black;
+}
+.mixin (@a) when (lightness(@a) < 50%) {
+    background-color: white;
+}
+
+// comparison operators, logical operators
+.mixin (@a) when (@a >= 0) and (@a =< 0) {}
+.mixin (@a) when (@a < 0) or (@a > 0) {}
+.mixin (@a) when (@a < 0), (@a > 0) {}
+.mixin (@a) when not (@a = 0) {}
+
+// true keyword
+.mixin (@a) when (@a) {}
+.mixin (@a) when (@a = true) {}
+
+
+/*
+ * at-rules
+ */
+
+// @import
+@import "@{themes}/tidal-wave.less";
+@import (optional, reference) "foo.less" screen and (orientation: landscape), print; // import options
+
+// @plugin
+@plugin 'my-plugin';
+@plugin (options) 'my-plugin'; // plugin options
+
+// @plugin function call
+my-plugin();
+div {
+    my-plugin(red; 10px);
+}
+
+
+/*
+ * test cases
+ */
+
+.declarations-or-selectors {
+    // declarations
+    display:block;
+    font-family:arial;
+    @{property}:block;
+
+    // selectors
+    input:focus {
+        opacity: 0.5;
+    }
+    div:nth-child(2n+1) {
+       background-color: gray;
+    }
+    @{selector}:focus {
+        color: blue;
+    }
+    a:@{state} {
+        color: blue;
+    }
+}
+
+
+// from file.css
+
+/*
+ * general
+ */
+
+/* whitespace */
+#main
+{
+    color:aqua;
+    float: left!important;
+    margin  :  0  ;
+    width
+        :
+        100%
+        !
+        important
+        ;
+}
+
+/* case insensitivity */
+Body {
+    FONT: 12Px/16pX iTaLiC sans-SERIF;
+}
+
+
+/*
+ * selectors
+ */
+
+/* simple selectors */
+#testID,       /* id */
+.someclass,    /* class */
+div,           /* type */
+*,             /* universal */
+[lang|="zh"] { /* attribute */
+    color: black;
+}
+
+/* combinators */
+header + main, /* adjacent sibling */
+li ~ li,       /* general sibling */
+ul > li,       /* child */
+ul ul {        /* descendant */
+    color: blue;
+}
+
+/* pseudo-elements */
+:after,
+::after,
+::placeholder,
+::selection {
+    color: green;
+}
+
+/* pseudo-classes */
+:hover,
+:required,
+:lang(fr),
+:not(div#sidebar.fancy),
+:nth-child(n+1),
+:nth-last-child(-2n - 30),
+:nth-of-type(5),
+:nth-last-of-type(even) {
+    color: yellow;
+}
+
+/* pseudo-classes with invalid arguments */
+:not(div:before),         /* pseudo-element */
+:not(input::placeholder), /* pseudo-element */
+:not(p:not(:lang(en))),   /* nested :not */
+:nth-child(1.2n),         /* non-integer */
+:nth-child(.5),           /* non-integer */
+:nth-child(n+-1) {        /* number sign */
+    color: red;
+}
+
+/* namespace qualified */
+a,           /* type in default namespace */
+svg|a,       /* type in specified namespace */
+|a,          /* type in no namespace */
+*|a,         /* type in all namespaces (including no namespace) */
+svg|*,       /* universal */
+svg|[fill] { /* attribute */
+    color: white;
+}
+
+
+/*
+ * basic data types
+ */
+
+#main {
+    /* angle */
+    transform: rotate(+33.333e+3deg);
+
+    /* color */
+    color: #f00;
+    color: #f00f; /* #rgba */
+    color: #ff0000;
+    color: #ff0000ff; /* #rrggbbaa */
+    color: red;
+    color: lightgoldenrodyellow;
+    color: rebeccapurple;
+    color: currentColor;
+
+    /* freqency (not currently used for any property) */
+    content: 44.1kHz;
+
+    /* integer */
+    z-index: +255;
+    z-index: -1;
+
+    /* length */
+    width: 10px;
+    width: 10.5rem;
+    width: -10e-2vw;
+
+    /* number */
+    opacity: .5;
+    opacity: 0.3333;
+    opacity: 1;
+    opacity: 2e-34;
+
+    /* percentage */
+    width: 100%;
+
+    /* string */
+    content: "double quoted";
+    content: 'single quoted';
+
+    /* time */
+    transition-duration: .4s;
+    transition-duration: 400ms;
+
+    /* unicode range */
+    unicode-range: U+0025-00FF;
+    unicode-range: U+4??; /* wildcard range */
+}
+
+/* ratio */
+@media (min-aspect-ratio: 16/9) {}
+
+/* resolution */
+@media (min-resolution: +2.54dpcm) {}
+
+
+/*
+ * identifiers
+ */
+
+/* leading hyphens */
+#-here.-there,
+#-- .--everywhere { /* two hyphens: https://stackoverflow.com/a/30822662 */
+    color: blue;
+}
+
+/* non-ASCII */
+#español,
+#你好,
+.❤♫ {
+    color: green;
+}
+
+/* invalid identifiers */
+#1id,      /* starts with digit */
+.-2class { /* starts with hyphen digit */
+    color: maroon;
+}
+
+
+/*
+ * escaping
+ */
+
+/* selectors */
+#\..\+\ space\@\>,                            /* special character escape */
+#\E9 dition .\0000E9dition .motion_\e9motion, /* Unicode character escape */
+.\e33 div,                                    /* trailing space terminates Unicode character escape */
+.\e33  div,                                   /* extra space to denote separate tokens */
+.\31 23 {                                     /* escape leading digit of identifier */
+
+    /* property value */
+    content: "\E9 dition \
+              \"\0000E9dition\" \
+              \e9motion";
+
+    /* function name */
+    background: \u\72\l(image.png);
+}
+
+
+/*
+ * functions
+ */
+
+#main {
+    /* url */
+    background: url("image.svg");
+
+    /* function argument keywords */
+    background-image: linear-gradient(to left top, #fff, blue);
+    grid-template-columns: repeat(2, minmax(max-content, 300px) 1fr) 100px;
+}
+
+
+/*
+ * style properties
+ */
+
+#main {
+    /* svg */
+    fill: url(#pattern);
+    text-rendering: optimizeLegibility;
+
+    /* css3 */
+    font-variant-east-asian: jis04;
+    size: letter;
+    transition-timing-function: ease-in;
+
+    /* animatable */
+    transition-property: height, font-size, visibility;
+}
+
+/*
+ * modifiers
+ */
+body {
+    background: pink !important;
+}
+
+
+/*
+ * media queries
+ */
+
+@media screen, (orientation: portrait) {}
+@media not (print and (min-monochrome: 16) and (color)) {}
+@media only screen {} @media not print {}
+
+
+/*
+ * at-rules
+ */
+
+/* @font-face */
+@font-face {
+    font-family: MyHelvetica;
+    src: local("Helvetica Neue"),
+         local("HelveticaNeue"),
+         url(MgOpenModerna.ttf);
+}
+
+/* @font-feature-values */
+@font-feature-values Font One {
+    @styleset {
+        nice-style: 12;
+    }
+}
+.nice-look {
+    font-variant-alternates: styleset(nice-style);
+}
+
+/* @import */
+@import URL("fineprint.css");
+@import 'custom.css';
+@import url('landscape.css') screen and (orientation: landscape), print;
+
+/* @keyframes */
+@keyframes myanim {
+    from { opacity: 0.0; }
+    50%  { opacity: 0.5; }
+    to   { opacity: 1.0; }
+}
+
+/* @media */
+@media all {
+    body {
+        background: gray;
+    }
+    @media screen, (orientation: portrait) {
+        body {
+            background: grey;
+        }
+    }
+}
+
+/* @namespace */
+@namespace "http://www.w3.org/1999/xhtml";;
+@namespace svg url(http://www.w3.org/2000/svg);
+
+/* @page */
+@page {
+    bleed: 1cm;
+}
+@page toc, :blank {
+    margin: 2cm;
+    marks: crop cross;
+}
+@page index:left {
+    size: A4;
+
+    @top-right {
+        content: "Page " counter(page);
+    }
+}
+
+/* @supports */
+@supports (animation-name: test) {
+    @keyframes 'my-complicated-animation' {
+        0%   { width: 0; }
+        100% { width: 100%; }
+    }
+}
+
+
+/*
+ * vendor-specific extensions
+ */
+
+/* pseudo-elements */
+input[type="number"]::-webkit-outer-spin-button,
+input[type="number"]::-webkit-inner-spin-button {
+    -webkit-appearance: none;
+}
+input[type="number"] {
+    -moz-appearance: textfield;
+}
+
+/* pseudo-classes */
+#page:-moz-full-screen,
+#page:-ms-fullscreen,
+#page:-webkit-full-screen {
+    background: silver;
+}
+
+/* functions */
+.footer {
+    background-image: -webkit-linear-gradient(to left top, #fff, blue);
+}
+
+/* style properties */
+#sidebar {
+    -ms-overflow-style: -ms-autohiding-scrollbar;
+}
+@supports not ((text-align-last: justify) or (-moz-text-align-last: justify)) {
+    body {
+        text-align: justify;
+    }
+}
+
+/* at-rules */
+@-webkit-keyframes myanim {
+    from { opacity: 0.0; }
+    50%  { opacity: 0.5; }
+    to   { opacity: 1.0; }
+}
diff --git a/tests/syntax-highlighting/file.scss b/tests/syntax-highlighting/file.scss
new file mode 100644
index 00000000..bc3dd5ef
--- /dev/null
+++ b/tests/syntax-highlighting/file.scss
@@ -0,0 +1,805 @@
+/*
+ * css extensions
+ */
+
+div {
+    color: #00ff00;
+
+    // nested rules
+    #inner.element {
+        color: #000000;
+    }
+
+    // parent selector
+    &:hover {
+        text-decoration: underline;
+    }
+    body.firefox & {
+        font-weight: normal;
+    }
+    &__element, // compound selector
+    &--modifier {
+        border: 1px;
+    }
+
+    // nested properties
+    font: {
+        family: fantasy;
+        size: 30em;
+        weight: bold;
+    }
+    font: 20px/24px fantasy {
+        weight: bold;
+    }
+}
+
+
+/*
+ * variables, data types
+ */
+
+// assignment
+$number:                5em;
+$double-quoted-string:  "foo";
+$single-quoted-string:  'bar';
+$not-quoted-string:     baz;
+$true:                  true;
+$false:                 false;
+$null:                  null;
+$parens-spaces-list:    (left top);
+$parens-commas-list:    (1px, 2px, 3px, 4px);
+$no-parens-spaces-list: 1px 2px 3px 4px;
+$no-parens-commas-list: arial, some-other-arial, sans-serif;
+$trailing-comma:        (1 2 3,); // a comma-separated list containing a space-separated list
+$bracketed-list:        [5rem 6rem 7rem]; // comma or space separated
+$map:                   (medium: 640, 'large': 960, "x-large": 1280, (xx-large,): 1600); // must have 
parentheses, be comma separated
+$color:                 #fe57a1;
+$function-reference:    get-function($function-name);
+
+// assign if not already assigned to
+$var: 1 !default;
+
+#main {
+    // global variable defined in block
+    $width: 5em !global;
+
+    // list of parent selectors
+    $selectors: &;
+
+    // property value
+    width: $width;
+}
+
+// media feature test
+@import "foo" ($orientation: $landscape);
+@media ($orientation-landscape) {
+    width: 700px;
+}
+
+// font feature value
+@font-feature-values Font One {
+    @styleset {
+        nice-style: $value;
+    }
+}
+
+// @supports test
+@supports ($animation-name: $test) {
+    body {
+        animation-name: test;
+    }
+}
+@supports ($animation-name-test) {
+    body {
+        animation-name: test;
+    }
+}
+
+// @at-root query
+@at-root ($type: $value) {
+    .top-level {
+        background: pink;
+    }
+}
+@at-root ($query) {
+    .top-level {
+        background: pink;
+    }
+}
+
+
+/*
+ * operations
+ */
+
+body {
+    // arithmetic operators
+    width: (1px + (2em - 3rem)) * (4 / 5vh) % 6cm;
+
+    // plain css
+    font: 10px/8px;
+    font: (italic bold 10px/8px);
+    font: #{$font-size}/#{$line-height};
+
+    // division
+    width: $width/2;
+    width: round(1.5)/2;
+    width: (500px/2);
+    width: 5px + 8px/2px;
+
+    // minus sign
+    animation-name: a-1; // identifier
+    margin: (5px - 3px) 5px-3px 3-2 (1 -$var); // subtraction
+    margin: 1 -3em; // negative number
+    margin: -$var -(1); // unary negation
+
+    // string concatenation
+    content: "Foo " + Bar; // "Foo Bar"
+    font-family: sans- + "serif"; // sans-serif
+}
+
+// string concatenation in string-only context
+@keyframes ('foo' + bar) {}
+@keyframes (foo + "bar") {}
+
+// comparison operators, logical operators
+$a: (1 < 2 and 1 > 2) or (1 <= 2) and 1 >= 2;
+$b: not (1 == 2) and 1 != 2;
+
+
+/*
+ * interpolation
+ */
+
+// selector
+#{'#id'},
+#i#{'d'},
+#{'.whole-class'},
+.part-#{'class'}-fragment,
+#{'div'},
+d#{'i'}v,
+[#{'attr'}=#{'value'}],
+[#{'attr="value"'}],
+#{'[attr="value"]'},
+#{'::selection'},
+::se#{'lect'}ion,
+#{':hover'},
+:ho#{'v'}er,
+#{':lang(fr)'},
+:la#{'ng(f'}r),
+:lang(#{'fr'}),
+:nth-child(#{'2n+1'}),
+:not(#{'div'}),
+#{'%placeholder'},
+%pla#{'ceho'}lder {
+
+    // property name
+    #{'font'}: serif;
+    background-#{'image'}: none;
+    border-#{'bottom'}-width: 0;
+
+    // property value
+    font-size: #{$font-size};
+    font-family: #{'arial, sans'}-serif;
+    width: #{5 * (3 - 1)}px;
+
+    // function name
+    background: #{'url'}('image.png');
+    background: u#{'r'}l('image.png');
+
+    // !important (exclamation mark needs to be inside)
+    width: 0 #{'!important'};
+    width: 0 #{'!import'}ant;
+
+    // inside strings
+    content: "#{$var}";
+    content: '#{$var}';
+
+    // inside comments
+    /* multi-line: #{$yes} */
+    // single line: #{$no}
+}
+
+// media type, feature test
+@import "foo" #{'screen'} and (#{'orientation'}: #{'landscape'});
+@media #{'screen'} and (#{'orientation: landscape'}) {
+    width: 700px;
+}
+
+// font name, font feature custom name, font feature value
+@font-feature-values #{'Font One'} {
+    @styleset { // interpolation not accepted here?
+        #{'nice-style'}: #{12};
+    }
+}
+
+// inside @import url()
+@import url("http://fonts.googleapis.com/css?family=#{$family}";);
+
+// @keyframes name, selector
+@keyframes #{'myanim'} {
+    #{'from'} { width: 0; }
+    #{'to'}   { width: 100%; }
+}
+
+// @namespace name
+@namespace #{'svg'} url('http://www.w3.org/2000/svg');
+
+// @page custom name, pseudo-page
+@page #{'toc'}, #{':first'} {
+    margin: 0;
+
+    @left-top { // interpolation not accepted here?
+        content: '';
+    }
+}
+
+// @supports test
+@supports (#{'animation-name'}: #{'test'}) {
+    body {
+        animation-name: test;
+    }
+}
+@supports (#{'animation-name: test'}) {
+    body {
+        animation-name: test;
+    }
+}
+
+// @at-root query
+@at-root (#{'without'}: #{'media'}) {
+    .top-level {
+        background: pink;
+    }
+}
+@at-root (#{'without: media'}) {
+    .top-level {
+        background: pink;
+    }
+}
+
+
+/*
+ * functions
+ */
+
+body {
+    // single line comments not parsed inside url()
+    background: url(http://example.com/styles.css);
+
+    // keyword arguments
+    color: hsl($hue: 0, $saturation: 100%, $lightness: 50%);
+}
+
+
+/*
+ * at-rules
+ */
+
+// @import
+@import "rounded-corners", "text-shadow"; // multiple files
+#main { // nested @import
+    @import "example"; // but not inside mixins or control directives
+}
+
+// nested @media
+@media screen {
+    .sidebar {
+        @media (orientation: landscape) {
+            width: 500px;
+        }
+    }
+}
+
+// @extend
+#main {
+    @extend #hello;
+
+    // no error if not found
+    @extend .from[the="other-side"] !optional;
+
+    // placeholder selector
+    @extend div%placeholder;
+}
+
+// @at-root
+#main {
+    @at-root .child {
+        color: red;
+    }
+}
+@media screen {
+    @supports (font-variant-alternates: styleset(nice-style)) {
+        @at-root (without: media supports) { // with query
+            .absolutely-top-level {
+                background: pink;
+            }
+        }
+    }
+}
+
+// @if/@else if/@else, @debug/@warn/@error
+@if $num-errors == 0 {
+    @debug "$num-errors is 0";
+} @else if $num-errors > 0 {
+    @warn "oops there are #{$num-errors} errors";
+} @else {
+    @error "negative errors?!?";
+}
+
+// @for
+@for $i from 1 through 3 {
+    .item-#{$i} {
+        width: 2em * $i;
+    }
+}
+
+// @each
+@each $animal in puma, sea-slug, egret, salamander {
+    .#{$animal}-icon {
+        background-image: url('/images/#{$animal}.png');
+    }
+}
+@each $header, $size in (h1: 2em, h2: 1.5em, h3: 1.2em) {
+    #{$header} {
+        font-size: $size;
+    }
+}
+
+// @while
+$i: 6;
+@while $i > 0 {
+    .item-#{$i} {
+        width: 2em * $i;
+    }
+    $i: $i - 2;
+}
+
+// @mixin
+@mixin large-text {
+    font-size: 128px;
+}
+@mixin sexy-border($color, $width: 1in) { // with arguments, default value
+    border: {
+        color: $color;
+        width: $width;
+    }
+}
+@mixin box-shadow($shadows...) { // variable arguments
+    box-shadow: $shadows;
+}
+@mixin apply-to-ie6-only { // accepts content block
+    * html {
+        @content;
+    }
+}
+
+// @include
+.page-title {
+    @include large-text;
+}
+p {
+    @include sexy-border(blue); // with arguments
+}
+div {
+    @include sexy-border($color: blue, $width: 10cm); // keyword arguments
+}
+.primary {
+    @include box-shadow($shadows...); // expand list into arguments
+}
+@include apply-to-ie6-only { // passing content block
+    display: block;
+
+    #main {
+        background: black;
+    }
+}
+
+// @function
+@function grid-width($n) {
+    @return $n * $grid-width + ($n - 1) * $gutter-width;
+}
+#sidebar {
+    width: grid-width(5);
+}
+
+
+/*
+ * test cases
+ */
+
+.declarations-or-selectors {
+    // declarations
+    display:block;
+    font-family:arial;
+    font: {
+        family: fantasy;
+        weight: bold;
+    }
+    font: fantasy {
+        size: 20px;
+        style: italic;
+    }
+    #{$property}:block;
+    #{$property}: {
+        color: red;
+    }
+    color:#000;
+    width:#{$width};
+
+    // selectors
+    input:focus {
+        opacity: 0.5;
+    }
+    div:nth-child(2n+1) {
+       background-color: gray;
+    }
+    div:-moz-full-screen {
+        display: block;
+    }
+    a:#{$state} {
+        color: blue;
+    }
+    #{$selector}:focus {
+        color: blue;
+    }
+}
+
+
+// from file.css
+
+/*
+ * general
+ */
+
+/* whitespace */
+#main
+{
+    color:aqua;
+    float: left!important;
+    margin  :  0  ;
+    width
+        :
+        100%
+        !
+        important
+        ;
+}
+
+/* case insensitivity */
+Body {
+    FONT: 12Px/16pX iTaLiC sans-SERIF;
+}
+
+
+/*
+ * selectors
+ */
+
+/* simple selectors */
+#testID,       /* id */
+.someclass,    /* class */
+div,           /* type */
+*,             /* universal */
+[lang|="zh"] { /* attribute */
+    color: black;
+}
+
+/* combinators */
+header + main, /* adjacent sibling */
+li ~ li,       /* general sibling */
+ul > li,       /* child */
+ul ul {        /* descendant */
+    color: blue;
+}
+
+/* pseudo-elements */
+:after,
+::after,
+::placeholder,
+::selection {
+    color: green;
+}
+
+/* pseudo-classes */
+:hover,
+:required,
+:lang(fr),
+:not(div#sidebar.fancy),
+:nth-child(n+1),
+:nth-last-child(-2n - 30),
+:nth-of-type(5),
+:nth-last-of-type(even) {
+    color: yellow;
+}
+
+/* pseudo-classes with invalid arguments */
+:not(div:before),         /* pseudo-element */
+:not(input::placeholder), /* pseudo-element */
+:not(p:not(:lang(en))),   /* nested :not */
+:nth-child(1.2n),         /* non-integer */
+:nth-child(.5),           /* non-integer */
+:nth-child(n+-1) {        /* number sign */
+    color: red;
+}
+
+/* namespace qualified */
+a,           /* type in default namespace */
+svg|a,       /* type in specified namespace */
+|a,          /* type in no namespace */
+*|a,         /* type in all namespaces (including no namespace) */
+svg|*,       /* universal */
+svg|[fill] { /* attribute */
+    color: white;
+}
+
+
+/*
+ * basic data types
+ */
+
+#main {
+    /* angle */
+    transform: rotate(+33.333e+3deg);
+
+    /* color */
+    color: #f00;
+    color: #f00f; /* #rgba */
+    color: #ff0000;
+    color: #ff0000ff; /* #rrggbbaa */
+    color: red;
+    color: lightgoldenrodyellow;
+    color: rebeccapurple;
+    color: currentColor;
+
+    /* freqency (not currently used for any property) */
+    content: 44.1kHz;
+
+    /* integer */
+    z-index: +255;
+    z-index: -1;
+
+    /* length */
+    width: 10px;
+    width: 10.5rem;
+    width: -10e-2vw;
+
+    /* number */
+    opacity: .5;
+    opacity: 0.3333;
+    opacity: 1;
+    opacity: 2e-34;
+
+    /* percentage */
+    width: 100%;
+
+    /* string */
+    content: "double quoted";
+    content: 'single quoted';
+
+    /* time */
+    transition-duration: .4s;
+    transition-duration: 400ms;
+
+    /* unicode range */
+    unicode-range: U+0025-00FF;
+    unicode-range: U+4??; /* wildcard range */
+}
+
+/* ratio */
+@media (min-aspect-ratio: 16/9) {}
+
+/* resolution */
+@media (min-resolution: +2.54dpcm) {}
+
+
+/*
+ * identifiers
+ */
+
+/* leading hyphens */
+#-here.-there,
+#-- .--everywhere { /* two hyphens: https://stackoverflow.com/a/30822662 */
+    color: blue;
+}
+
+/* non-ASCII */
+#español,
+#你好,
+.❤♫ {
+    color: green;
+}
+
+/* invalid identifiers */
+#1id,      /* starts with digit */
+.-2class { /* starts with hyphen digit */
+    color: maroon;
+}
+
+
+/*
+ * escaping
+ */
+
+/* selectors */
+#\..\+\ space\@\>,                            /* special character escape */
+#\E9 dition .\0000E9dition .motion_\e9motion, /* Unicode character escape */
+.\e33 div,                                    /* trailing space terminates Unicode character escape */
+.\e33  div,                                   /* extra space to denote separate tokens */
+.\31 23 {                                     /* escape leading digit of identifier */
+
+    /* property value */
+    content: "\E9 dition \
+              \"\0000E9dition\" \
+              \e9motion";
+
+    /* function name */
+    background: \u\72\l(image.png);
+}
+
+
+/*
+ * functions
+ */
+
+#main {
+    /* url */
+    background: url("image.svg");
+
+    /* function argument keywords */
+    background-image: linear-gradient(to left top, #fff, blue);
+    grid-template-columns: repeat(2, minmax(max-content, 300px) 1fr) 100px;
+}
+
+
+/*
+ * style properties
+ */
+
+#main {
+    /* svg */
+    fill: url(#pattern);
+    text-rendering: optimizeLegibility;
+
+    /* css3 */
+    font-variant-east-asian: jis04;
+    size: letter;
+    transition-timing-function: ease-in;
+
+    /* animatable */
+    transition-property: height, font-size, visibility;
+}
+
+/*
+ * modifiers
+ */
+body {
+    background: pink !important;
+}
+
+
+/*
+ * media queries
+ */
+
+@media screen, (orientation: portrait) {}
+@media not (print and (min-monochrome: 16) and (color)) {}
+@media only screen {} @media not print {}
+
+
+/*
+ * at-rules
+ */
+
+/* @font-face */
+@font-face {
+    font-family: MyHelvetica;
+    src: local("Helvetica Neue"),
+         local("HelveticaNeue"),
+         url(MgOpenModerna.ttf);
+}
+
+/* @font-feature-values */
+@font-feature-values Font One {
+    @styleset {
+        nice-style: 12;
+    }
+}
+.nice-look {
+    font-variant-alternates: styleset(nice-style);
+}
+
+/* @import */
+@import URL("fineprint.css");
+@import 'custom.css';
+@import url('landscape.css') screen and (orientation: landscape), print;
+
+/* @keyframes */
+@keyframes myanim {
+    from { opacity: 0.0; }
+    50%  { opacity: 0.5; }
+    to   { opacity: 1.0; }
+}
+
+/* @media */
+@media all {
+    body {
+        background: gray;
+    }
+    @media screen, (orientation: portrait) {
+        body {
+            background: grey;
+        }
+    }
+}
+
+/* @namespace */
+@namespace "http://www.w3.org/1999/xhtml";;
+@namespace svg url(http://www.w3.org/2000/svg);
+
+/* @page */
+@page {
+    bleed: 1cm;
+}
+@page toc, :blank {
+    margin: 2cm;
+    marks: crop cross;
+}
+@page index:left {
+    size: A4;
+
+    @top-right {
+        content: "Page " counter(page);
+    }
+}
+
+/* @supports */
+@supports (animation-name: test) {
+    @keyframes 'my-complicated-animation' {
+        0%   { width: 0; }
+        100% { width: 100%; }
+    }
+}
+
+
+/*
+ * vendor-specific extensions
+ */
+
+/* pseudo-elements */
+input[type="number"]::-webkit-outer-spin-button,
+input[type="number"]::-webkit-inner-spin-button {
+    -webkit-appearance: none;
+}
+input[type="number"] {
+    -moz-appearance: textfield;
+}
+
+/* pseudo-classes */
+#page:-moz-full-screen,
+#page:-ms-fullscreen,
+#page:-webkit-full-screen {
+    background: silver;
+}
+
+/* functions */
+.footer {
+    background-image: -webkit-linear-gradient(to left top, #fff, blue);
+}
+
+/* style properties */
+#sidebar {
+    -ms-overflow-style: -ms-autohiding-scrollbar;
+}
+@supports not ((text-align-last: justify) or (-moz-text-align-last: justify)) {
+    body {
+        text-align: justify;
+    }
+}
+
+/* at-rules */
+@-webkit-keyframes myanim {
+    from { opacity: 0.0; }
+    50%  { opacity: 0.5; }
+    to   { opacity: 1.0; }
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]