Commits

Natalie Weizenbaum committed 54478fb

Add a Sass lexer.

Comments (0)

Files changed (2)

pygments/lexers/_mapping.py

     'RubyConsoleLexer': ('pygments.lexers.agile', 'Ruby irb session', ('rbcon', 'irb'), (), ('text/x-ruby-shellsession',)),
     'RubyLexer': ('pygments.lexers.agile', 'Ruby', ('rb', 'ruby'), ('*.rb', '*.rbw', 'Rakefile', '*.rake', '*.gemspec', '*.rbx'), ('text/x-ruby', 'application/x-ruby')),
     'SLexer': ('pygments.lexers.math', 'S', ('splus', 's', 'r'), ('*.S', '*.R'), ('text/S-plus', 'text/S', 'text/R')),
+    'SassLexer': ('pygments.lexers.web', 'Sass', ('sass', 'SASS'), ('*.sass',), ('text/x-sass',)),
     'ScalaLexer': ('pygments.lexers.compiled', 'Scala', ('scala',), ('*.scala',), ('text/x-scala',)),
     'SchemeLexer': ('pygments.lexers.functional', 'Scheme', ('scheme', 'scm'), ('*.scm',), ('text/x-scheme', 'application/x-scheme')),
     'SmalltalkLexer': ('pygments.lexers.other', 'Smalltalk', ('smalltalk', 'squeak'), ('*.st',), ('text/x-smalltalk',)),

pygments/lexers/web.py

 
 __all__ = ['HtmlLexer', 'XmlLexer', 'JavascriptLexer', 'CssLexer',
            'PhpLexer', 'ActionScriptLexer', 'XsltLexer', 'ActionScript3Lexer',
-           'MxmlLexer', 'HaxeLexer', 'HamlLexer', 'ObjectiveJLexer']
+           'MxmlLexer', 'HaxeLexer', 'HamlLexer', 'SassLexer', 'ObjectiveJLexer']
 
 
 class JavascriptLexer(RegexLexer):
             (r'"(\\\\|\\"|[^"\n])*"', String, '#pop'),
         ],
     }
+
+
+class SassLexer(RegexLexer):
+    """
+    For Sass stylesheets.
+    """
+
+    name = 'Sass'
+    aliases = ['sass', 'SASS']
+    filenames = ['*.sass']
+    mimetypes = ['text/x-sass']
+
+    flags = re.IGNORECASE
+    tokens = {
+        'root': [
+            (r'[ \t]*\n', Text),
+            (r'[ \t]*', Text, 'content'),
+        ],
+
+        'content': [
+            (r'//[^\n]*', Comment.Single, 'root'),
+            (r'/\*[^\n]*', Comment.Multiline, 'root'),
+            (r'@import', Keyword, 'import'),
+            (r'@for', Keyword, 'for'),
+            (r'@(debug|if|while)', Keyword, 'script'),
+            (r'@[a-z0-9_-]+', Keyword, 'selector'),
+            (r'=[\w-]+', Name.Function, 'script'),
+            (r'\+[\w-]+', Name.Decorator, 'script'),
+            (r'(![a-z_]\w*)([ \t]*(?:\|\|)?=)',
+             bygroups(Name.Variable, Operator), 'script'),
+            (r':', Name.Attribute, 'old-style-attr'),
+            (r'(?=[^\s:"\[]+\s*[=:]([ \t]|$))', Name.Attribute, 'new-style-attr'),
+            (r'', Text, 'selector'),
+        ],
+
+        'import': [
+            (r'[ \t]+', Text),
+            (r'[^\s]+', String),
+            (r'\n', Text, 'root'),
+        ],
+
+        'for': [
+            (r'(from|to|through)', Operator.Word),
+            include('script'),
+        ],
+
+        'old-style-attr': [
+            (r'[^\s:="\[]+', Name.Attribute),
+            (r'#{', String.Interpol, 'interpolation'),
+            (r'[ \t]*=', Operator, 'script'),
+            (r'', Text, 'value'),
+        ],
+
+        'new-style-attr': [
+            (r'[^\s:="\[]+', Name.Attribute),
+            (r'#{', String.Interpol, 'interpolation'),
+            (r'[ \t]*=', Operator, 'script'),
+            (r':', Name.Attribute, 'value'),
+        ],
+
+        'value': [
+            (r'[ \t]+', Text),
+            (r'url\(', String.Other, 'string-url'),
+            (r'(azimuth|background-attachment|background-color|'
+             r'background-image|background-position|background-repeat|'
+             r'background|border-bottom-color|border-bottom-style|'
+             r'border-bottom-width|border-left-color|border-left-style|'
+             r'border-left-width|border-right|border-right-color|'
+             r'border-right-style|border-right-width|border-top-color|'
+             r'border-top-style|border-top-width|border-bottom|'
+             r'border-collapse|border-left|border-width|border-color|'
+             r'border-spacing|border-style|border-top|border|caption-side|'
+             r'clear|clip|color|content|counter-increment|counter-reset|'
+             r'cue-after|cue-before|cue|cursor|direction|display|'
+             r'elevation|empty-cells|float|font-family|font-size|'
+             r'font-size-adjust|font-stretch|font-style|font-variant|'
+             r'font-weight|font|height|letter-spacing|line-height|'
+             r'list-style-type|list-style-image|list-style-position|'
+             r'list-style|margin-bottom|margin-left|margin-right|'
+             r'margin-top|margin|marker-offset|marks|max-height|max-width|'
+             r'min-height|min-width|opacity|orphans|outline|outline-color|'
+             r'outline-style|outline-width|overflow|padding-bottom|'
+             r'padding-left|padding-right|padding-top|padding|page|'
+             r'page-break-after|page-break-before|page-break-inside|'
+             r'pause-after|pause-before|pause|pitch|pitch-range|'
+             r'play-during|position|quotes|richness|right|size|'
+             r'speak-header|speak-numeral|speak-punctuation|speak|'
+             r'speech-rate|stress|table-layout|text-align|text-decoration|'
+             r'text-indent|text-shadow|text-transform|top|unicode-bidi|'
+             r'vertical-align|visibility|voice-family|volume|white-space|'
+             r'widows|width|word-spacing|z-index|bottom|left|'
+             r'above|absolute|always|armenian|aural|auto|avoid|baseline|'
+             r'behind|below|bidi-override|blink|block|bold|bolder|both|'
+             r'capitalize|center-left|center-right|center|circle|'
+             r'cjk-ideographic|close-quote|collapse|condensed|continuous|'
+             r'crop|crosshair|cross|cursive|dashed|decimal-leading-zero|'
+             r'decimal|default|digits|disc|dotted|double|e-resize|embed|'
+             r'extra-condensed|extra-expanded|expanded|fantasy|far-left|'
+             r'far-right|faster|fast|fixed|georgian|groove|hebrew|help|'
+             r'hidden|hide|higher|high|hiragana-iroha|hiragana|icon|'
+             r'inherit|inline-table|inline|inset|inside|invert|italic|'
+             r'justify|katakana-iroha|katakana|landscape|larger|large|'
+             r'left-side|leftwards|level|lighter|line-through|list-item|'
+             r'loud|lower-alpha|lower-greek|lower-roman|lowercase|ltr|'
+             r'lower|low|medium|message-box|middle|mix|monospace|'
+             r'n-resize|narrower|ne-resize|no-close-quote|no-open-quote|'
+             r'no-repeat|none|normal|nowrap|nw-resize|oblique|once|'
+             r'open-quote|outset|outside|overline|pointer|portrait|px|'
+             r'relative|repeat-x|repeat-y|repeat|rgb|ridge|right-side|'
+             r'rightwards|s-resize|sans-serif|scroll|se-resize|'
+             r'semi-condensed|semi-expanded|separate|serif|show|silent|'
+             r'slow|slower|small-caps|small-caption|smaller|soft|solid|'
+             r'spell-out|square|static|status-bar|super|sw-resize|'
+             r'table-caption|table-cell|table-column|table-column-group|'
+             r'table-footer-group|table-header-group|table-row|'
+             r'table-row-group|text|text-bottom|text-top|thick|thin|'
+             r'transparent|ultra-condensed|ultra-expanded|underline|'
+             r'upper-alpha|upper-latin|upper-roman|uppercase|url|'
+             r'visible|w-resize|wait|wider|x-fast|x-high|x-large|x-loud|'
+             r'x-low|x-small|x-soft|xx-large|xx-small|yes)\b', Name.Constant),
+            (r'(indigo|gold|firebrick|indianred|yellow|darkolivegreen|'
+             r'darkseagreen|mediumvioletred|mediumorchid|chartreuse|'
+             r'mediumslateblue|black|springgreen|crimson|lightsalmon|brown|'
+             r'turquoise|olivedrab|cyan|silver|skyblue|gray|darkturquoise|'
+             r'goldenrod|darkgreen|darkviolet|darkgray|lightpink|teal|'
+             r'darkmagenta|lightgoldenrodyellow|lavender|yellowgreen|thistle|'
+             r'violet|navy|orchid|blue|ghostwhite|honeydew|cornflowerblue|'
+             r'darkblue|darkkhaki|mediumpurple|cornsilk|red|bisque|slategray|'
+             r'darkcyan|khaki|wheat|deepskyblue|darkred|steelblue|aliceblue|'
+             r'gainsboro|mediumturquoise|floralwhite|coral|purple|lightgrey|'
+             r'lightcyan|darksalmon|beige|azure|lightsteelblue|oldlace|'
+             r'greenyellow|royalblue|lightseagreen|mistyrose|sienna|'
+             r'lightcoral|orangered|navajowhite|lime|palegreen|burlywood|'
+             r'seashell|mediumspringgreen|fuchsia|papayawhip|blanchedalmond|'
+             r'peru|aquamarine|white|darkslategray|ivory|dodgerblue|'
+             r'lemonchiffon|chocolate|orange|forestgreen|slateblue|olive|'
+             r'mintcream|antiquewhite|darkorange|cadetblue|moccasin|'
+             r'limegreen|saddlebrown|darkslateblue|lightskyblue|deeppink|'
+             r'plum|aqua|darkgoldenrod|maroon|sandybrown|magenta|tan|'
+             r'rosybrown|pink|lightblue|palevioletred|mediumseagreen|'
+             r'dimgray|powderblue|seagreen|snow|mediumblue|midnightblue|'
+             r'paleturquoise|palegoldenrod|whitesmoke|darkorchid|salmon|'
+             r'lightslategray|lawngreen|lightgreen|tomato|hotpink|'
+             r'lightyellow|lavenderblush|linen|mediumaquamarine|green|'
+             r'blueviolet|peachpuff)\b', Name.Entity),
+            (r'\!important', Name.Exception),
+            (r'/\*', Comment, 'inline-comment'),
+            (r'\#[a-z0-9]{1,6}', Number.Hex),
+            (r'(-?\d+)(\%|[a-z]+)?', bygroups(Number.Integer, Keyword.Type)),
+            (r'(-?\d*\.\d+)(\%|[a-z]+)?', bygroups(Number.Float, Keyword.Type)),
+            (r'#{', String.Interpol, 'interpolation'),
+            (r'[~\^\*!&%<>\|+=@:,./?-]+', Operator),
+            (r'[\[\]();]+', Punctuation),
+            (r'"', String.Double, 'string-double'),
+            (r"'", String.Single, 'string-single'),
+            (r'[a-z][\w-]*', Name),
+            (r'\n', Text, 'root'),
+        ],
+
+        'script': [
+            (r'[ \t]+', Text),
+            (r'![\w_]+', Name.Variable),
+            (r'[+\-*/%=(),!><]', Operator),
+            (r'"', String.Double, 'string-double'),
+            (r"'", String.Single, 'string-single'),
+            (r'\#[a-z0-9]{1,6}', Number.Hex),
+            (r'(-?\d+)(\%|[a-z]+)?', bygroups(Number.Integer, Keyword.Type)),
+            (r'(-?\d*\.\d+)(\%|[a-z]+)?', bygroups(Number.Float, Keyword.Type)),
+            (r'(black|silver|gray|white|maroon|red|purple|fuchsia|green|'
+             r'lime|olive|yellow|navy|blue|teal|aqua)\b', Name.Builtin),
+            (r'(true|false)', Name.Pseudo),
+            (r'(and|or|not)', Operator.Word),
+            (r'(\\.|[^\s\\+*\/%(),=!])+(?=[ \t]*\()', Name.Function),
+            (r'(\\.|[^\s\\+*\/%(),=!])+', Name),
+            (r'\n', Text, 'root'),
+        ],
+
+        'interpolation': [
+            (r'\}', String.Interpol, '#pop'),
+            include('script'),
+        ],
+
+        'selector': [
+            (r'[ \t]+', Text),
+            (r'\:', Name.Decorator, 'pseudo-class'),
+            (r'\.', Name.Class, 'class'),
+            (r'\#', Name.Namespace, 'id'),
+            (r'[a-zA-Z0-9_-]+', Name.Tag),
+            (r'#\{', String.Interpol, 'interpolation'),
+            (r'&', Keyword),
+            (r'[~\^\*!&\[\]\(\)<>\|+=@:;,./?-]', Operator),
+            (r'"', String.Double, 'string-double'),
+            (r"'", String.Single, 'string-single'),
+            (r'\n', Text, 'root'),
+        ],
+
+        'string-double': [
+            (r'(\\.|#(?=[^\n{])|[^\n"#])+', String.Double),
+            (r'#\{', String.Interpol, 'interpolation'),
+            (r'"', String.Double, '#pop'),
+        ],
+
+        'string-single': [
+            (r"(\\.|#(?=[^\n{])|[^\n'#])+", String.Double),
+            (r'#\{', String.Interpol, 'interpolation'),
+            (r"'", String.Double, '#pop'),
+        ],
+
+        'string-url': [
+            (r'(\\#|#(?=[^\n{])|[^\n#)])+', String.Other),
+            (r'#\{', String.Interpol, 'interpolation'),
+            (r'\)', String.Other, '#pop'),
+        ],
+
+        'inline-comment': [
+            (r"(\\#|#(?=[^\n{])|\*(?=[^\n/])|[^\n#*])+", Comment),
+            (r'#\{', String.Interpol, 'interpolation'),
+            (r"\*/", Comment, '#pop'),
+        ],
+
+        'pseudo-class': [
+            (r'[\w-]+', Name.Decorator),
+            (r'#\{', String.Interpol, 'interpolation'),
+            (r'', Text, '#pop'),
+        ],
+
+        'class': [
+            (r'[\w-]+', Name.Class),
+            (r'#\{', String.Interpol, 'interpolation'),
+            (r'', Text, '#pop'),
+        ],
+
+        'id': [
+            (r'[\w-]+', Name.Namespace),
+            (r'#\{', String.Interpol, 'interpolation'),
+            (r'', Text, '#pop'),
+        ],
+    }