Skip to content

Commit

Permalink
Fix parsing of @if(...), where there's no literal space.
Browse files Browse the repository at this point in the history
  • Loading branch information
eevee committed Dec 10, 2014
1 parent 77a5828 commit 20c74b6
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 15 deletions.
10 changes: 6 additions & 4 deletions scss/cssdefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ def determine_encoding(buf):


# ------------------------------------------------------------------------------
# Bits and pieces of grammar, mostly as regexen
# Bits and pieces of the official CSS grammar

# These are the only pseudo-elements allowed to be specified with a single
# colon, for backwards compatibility
Expand All @@ -443,8 +443,7 @@ def determine_encoding(buf):
# or a backslash followed by one to six hex digits and a single optional
# whitespace. Escaped newlines become nothing.
# Ref: http://dev.w3.org/csswg/css-syntax-3/#consume-an-escaped-code-point
unescape_rx = re.compile(
r"\\([0-9a-fA-F]{1,6})[\n\t ]?|\\(.)|\\\n", re.DOTALL)
escape_rx = re.compile(r"(?s)\\([0-9a-fA-F]{1,6})[\n\t ]?|\\(.)|\\\n")


def _unescape_one(match):
Expand All @@ -460,9 +459,12 @@ def unescape(string):
"""Given a raw CSS string (i.e. taken directly from CSS source with no
processing), eliminate all backslash escapes.
"""
return unescape_rx.sub(_unescape_one, string)
return escape_rx.sub(_unescape_one, string)


# ------------------------------------------------------------------------------
# Ad-hoc regexes specific to pyscss

_expr_glob_re = re.compile(r'''
\#\{(.*?)\} # Global Interpolation only
''', re.VERBOSE)
Expand Down
23 changes: 12 additions & 11 deletions scss/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from __future__ import print_function

import logging
import re

from scss.namespace import Namespace

Expand Down Expand Up @@ -239,17 +240,17 @@ def parse(cls, prop, has_contents=False):

# Minor parsing
if prop.startswith('@'):
if prop.lower().startswith('@else if '):
directive = '@else if'
argument = prop[9:]
else:
chunks = prop.split(None, 1)
if len(chunks) == 2:
directive, argument = chunks
else:
directive, argument = prop, None
directive = directive.lower()

# This pattern MUST NOT BE ABLE TO FAIL!
# This is slightly more lax than the CSS syntax technically allows,
# e.g. identifiers aren't supposed to begin with three hyphens.
# But we don't care, and will just spit it back out anyway.
m = re.match(
u'@(else if|[-_a-zA-Z0-9\U00000080-\U0010FFFF]*)\\b',
prop, re.I)
directive = m.group(0).lower()
argument = prop[len(directive):].strip()
if not argument:
argument = None
return BlockAtRuleHeader(directive, argument, num_lines)
elif prop.split(None, 1)[0].endswith(':'):
# Syntax is "<scope>: [prop]" -- if the optional prop exists, it
Expand Down
3 changes: 3 additions & 0 deletions scss/tests/files/bugs/if-with-parentheses.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
a:hover {
text-decoration: underline;
}
7 changes: 7 additions & 0 deletions scss/tests/files/bugs/if-with-parentheses.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
a {
@if(true) {
&:hover {
text-decoration: underline;
}
}
}

0 comments on commit 20c74b6

Please sign in to comment.