From f0fb2b3d923e00a5891b393b222f134229e1e70b Mon Sep 17 00:00:00 2001 From: jtm Date: Sat, 3 Mar 2012 09:58:47 +0000 Subject: [PATCH] checkpoint --- lesscpy/lessc/formatter.py | 2 +- lesscpy/lessc/lexer.py | 2 +- lesscpy/lessc/parser.py | 2 +- lesscpy/lessc/utility.py | 11 +++--- lesscpy/plib/block.py | 8 ++-- lesscpy/plib/identifier.py | 2 +- lesscpy/plib/node.py | 2 +- lesscpy/plib/property.py | 7 ++-- lesscpy/plib/statement.py | 2 +- lesscpy/plib/string.py | 18 ++++++++- lesscpy/test/css/properties-uri.css | 2 + lesscpy/test/css/properties-uri.min.css | 2 +- lesscpy/test/css/properties-vendor.css | 11 ++++++ lesscpy/test/css/properties-vendor.min.css | 3 ++ lesscpy/test/css/properties.css | 46 ++++++++++++++++++++++ lesscpy/test/css/properties.min.css | 12 ++++++ lesscpy/test/css/strings.css | 26 ++++++++++++ lesscpy/test/css/strings.min.css | 5 +++ lesscpy/test/less/css-escapes.less | 0 lesscpy/test/less/properties-uri.less | 2 + lesscpy/test/less/properties-vendor.less | 12 ++++++ lesscpy/test/less/properties.less | 13 ++++++ lesscpy/test/less/properties_vendor.less | 4 -- lesscpy/test/less/strings.less | 35 ++++++++++++++++ 24 files changed, 205 insertions(+), 24 deletions(-) create mode 100644 lesscpy/test/css/properties-vendor.css create mode 100644 lesscpy/test/css/properties-vendor.min.css create mode 100644 lesscpy/test/css/properties.css create mode 100644 lesscpy/test/css/properties.min.css create mode 100644 lesscpy/test/css/strings.css create mode 100644 lesscpy/test/css/strings.min.css delete mode 100644 lesscpy/test/less/css-escapes.less create mode 100644 lesscpy/test/less/properties-vendor.less delete mode 100644 lesscpy/test/less/properties_vendor.less diff --git a/lesscpy/lessc/formatter.py b/lesscpy/lessc/formatter.py index 68eb8b7..75ca954 100644 --- a/lesscpy/lessc/formatter.py +++ b/lesscpy/lessc/formatter.py @@ -31,7 +31,7 @@ class Formatter(object): 'ws': ' ', 'eb': eb }) - self.out = [u.format(self.items) + self.out = [u.fmt(self.items) for u in parse.result if u] return ''.join(self.out).strip() diff --git a/lesscpy/lessc/lexer.py b/lesscpy/lessc/lexer.py index dce0428..aeeb380 100644 --- a/lesscpy/lessc/lexer.py +++ b/lesscpy/lessc/lexer.py @@ -127,7 +127,7 @@ class LessLexer: (r'data:[^\)]+' '|(([a-z]+://)?' '(' - '([\.\w:]+[\\/])+' + '([\.\w:]+[\\/][\\/]?)+' '|([a-z][\w\.\-]+(\.[a-z0-9]+))' '(\#[a-z]+)?)' ')+') diff --git a/lesscpy/lessc/parser.py b/lesscpy/lessc/parser.py index 6a6f4ad..6b5fe73 100644 --- a/lesscpy/lessc/parser.py +++ b/lesscpy/lessc/parser.py @@ -532,7 +532,7 @@ class LessParser(object): def p_interpolated_str(self, p): """ istring : less_string """ - p[0] = String(p) + p[0] = String(p[1], p.lineno(1)) def p_variable_neg(self, p): """ variable : '-' variable diff --git a/lesscpy/lessc/utility.py b/lesscpy/lessc/utility.py index a2e2080..a0f9abe 100644 --- a/lesscpy/lessc/utility.py +++ b/lesscpy/lessc/utility.py @@ -26,10 +26,11 @@ def pairwise(lst): (lst[0], lst[1]), (lst[1], lst[2]), ..., (lst[-1], None) """ if not lst: return - for i in range(len(lst)-1): + l = len(lst) + for i in range(l-1): yield lst[i], lst[i+1] yield lst[-1], None - + def rename(ll, fr, scope): """ Rename all sub-blocks moved under another block. (mixins) @@ -116,7 +117,7 @@ def is_variable(v): return False def is_int(v): - """ + """ Is value integer """ try: int(str(v)) @@ -126,7 +127,7 @@ def is_int(v): return False def is_float(v): - """ + """ Is value float """ if not is_int(v): try: @@ -137,7 +138,7 @@ def is_float(v): return False def split_unit(v): - """ + """ Split a number from its unit """ r = re.search('^(\-?[\d\.]+)(.*)$', str(v)) return r.groups() if r else ('','') diff --git a/lesscpy/plib/block.py b/lesscpy/plib/block.py index b48676c..a3d2e54 100644 --- a/lesscpy/plib/block.py +++ b/lesscpy/plib/block.py @@ -27,20 +27,20 @@ class Block(Node): def raw(self): return self.name.raw() - def format(self, fills): + def fmt(self, fills): """ """ out = [] if self.parsed: f = "%(identifier)s%(ws)s{%(nl)s%(proplist)s}%(eb)s" - name = self.name.format(fills) + name = self.name.fmt(fills) fills.update({ 'identifier': name, - 'proplist': ''.join([p.format(fills) for p in self.parsed]), + 'proplist': ''.join([p.fmt(fills) for p in self.parsed]), }) out.append(f % fills) if self.inner: - out.append(''.join([p.format(fills) for p in self.inner])) + out.append(''.join([p.fmt(fills) for p in self.inner])) return ''.join(out) def copy(self, scope): diff --git a/lesscpy/plib/identifier.py b/lesscpy/plib/identifier.py index 281454a..d9dbfdb 100644 --- a/lesscpy/plib/identifier.py +++ b/lesscpy/plib/identifier.py @@ -64,7 +64,7 @@ class Identifier(Node): return '%'.join('%'.join(p) for p in self.parsed).strip().strip('%') - def format(self, fills): + def fmt(self, fills): """ """ name = ',$$'.join(''.join(p).strip() diff --git a/lesscpy/plib/node.py b/lesscpy/plib/node.py index ccb0eb2..eed9b28 100644 --- a/lesscpy/plib/node.py +++ b/lesscpy/plib/node.py @@ -36,5 +36,5 @@ class Node(object): else t for t in tokens] - def format(self, fills): + def fmt(self, fills): raise ValueError('No defined format') diff --git a/lesscpy/plib/property.py b/lesscpy/plib/property.py index f10e6fe..ddc3f29 100644 --- a/lesscpy/plib/property.py +++ b/lesscpy/plib/property.py @@ -37,7 +37,7 @@ class Property(Node): for u in style] return style - def format(self, fills): + def fmt(self, fills): """ """ f = "%(tab)s%(property)s:%(ws)s%(style)s%(important)s;%(nl)s" @@ -47,8 +47,9 @@ class Property(Node): if p == ',' else p for p in self.parsed] - style = ''.join([p.format(fills) - if hasattr(p, 'format') + + style = ''.join([p.fmt(fills) + if hasattr(p, 'fmt') else str(p) for p in self.parsed]) fills.update({ diff --git a/lesscpy/plib/statement.py b/lesscpy/plib/statement.py index b3825c6..58d0d4f 100644 --- a/lesscpy/plib/statement.py +++ b/lesscpy/plib/statement.py @@ -13,7 +13,7 @@ class Statement(Node): # Media @import self.parsed.insert(3, ' ') - def format(self, fills): + def fmt(self, fills): """ """ return ''.join(self.parsed) + fills['eb'] \ No newline at end of file diff --git a/lesscpy/plib/string.py b/lesscpy/plib/string.py index 58b9609..a47cede 100644 --- a/lesscpy/plib/string.py +++ b/lesscpy/plib/string.py @@ -1,5 +1,21 @@ """ """ +import re from .node import Node +from lesscpy.lessc import utility + class String(Node): - pass \ No newline at end of file + def parse(self, scope): + """ + """ + self.scope = scope + return re.sub(r'@\{([^\}]+)\}', lambda m: self.swap(m.group(1)), self.tokens) + + def swap(self, var): + """ Replace variable + @param string: var + @return: string + """ + var = '@' + var + var = ''.join(utility.flatten(self.scope.swap(var))) + return var.strip("\"'") \ No newline at end of file diff --git a/lesscpy/test/css/properties-uri.css b/lesscpy/test/css/properties-uri.css index 949a468..b21d4c7 100644 --- a/lesscpy/test/css/properties-uri.css +++ b/lesscpy/test/css/properties-uri.css @@ -17,4 +17,6 @@ background-image: url(https://some.server.com:9696/path/img.jpeg); behavior: url(border-radius.htc); background-image: url(fonts.svg#MyGeometricModern); + image: url(http://), "}", url("http://}"); + image: url(http://tooks.com); } diff --git a/lesscpy/test/css/properties-uri.min.css b/lesscpy/test/css/properties-uri.min.css index bd9d5dd..86fa69e 100644 --- a/lesscpy/test/css/properties-uri.min.css +++ b/lesscpy/test/css/properties-uri.min.css @@ -3,4 +3,4 @@ k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);background-image:url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);} #svg-data-uri{background:transparent url('data:image/svg+xml, ');} -.uri_test{background-image:url(images/image.jpg);background-image:url(../some/path);background-image:url(./../some/path);background-image:url(./images/image.jpg);background-image:url(http://some/path/img.jpeg);background-image:url(https://some.server.com:9696/path/img.jpeg);behavior:url(border-radius.htc);background-image:url(fonts.svg#MyGeometricModern);} +.uri_test{background-image:url(images/image.jpg);background-image:url(../some/path);background-image:url(./../some/path);background-image:url(./images/image.jpg);background-image:url(http://some/path/img.jpeg);background-image:url(https://some.server.com:9696/path/img.jpeg);behavior:url(border-radius.htc);background-image:url(fonts.svg#MyGeometricModern);image:url(http://),"}",url("http://}");image:url(http://tooks.com);} diff --git a/lesscpy/test/css/properties-vendor.css b/lesscpy/test/css/properties-vendor.css new file mode 100644 index 0000000..455b0a2 --- /dev/null +++ b/lesscpy/test/css/properties-vendor.css @@ -0,0 +1,11 @@ +div.vendor { + -moz-transform: translate(0,11em)rotate(-90deg); + -webkit-animation: anim2 7s infinite ease-in-out; +} +div.long { + -moz-box-shadow: 0pt 0pt 2px rgba(255,255,255,0.4)inset, 0pt 4px 6px rgba(255,255,255,0.4)inset; +} +div.styles { + display: -moz-inline-stack; + background: -webkit-gradient(linear,left top,left bottom,from(red),to(blue)); +} diff --git a/lesscpy/test/css/properties-vendor.min.css b/lesscpy/test/css/properties-vendor.min.css new file mode 100644 index 0000000..50f7c50 --- /dev/null +++ b/lesscpy/test/css/properties-vendor.min.css @@ -0,0 +1,3 @@ +div.vendor{-moz-transform:translate(0,11em)rotate(-90deg);-webkit-animation:anim2 7s infinite ease-in-out;} +div.long{-moz-box-shadow:0pt 0pt 2px rgba(255,255,255,0.4)inset,0pt 4px 6px rgba(255,255,255,0.4)inset;} +div.styles{display:-moz-inline-stack;background:-webkit-gradient(linear,left top,left bottom,from(red),to(blue));} diff --git a/lesscpy/test/css/properties.css b/lesscpy/test/css/properties.css new file mode 100644 index 0000000..f04ce9c --- /dev/null +++ b/lesscpy/test/css/properties.css @@ -0,0 +1,46 @@ +div.properties { + color: red; +} +div.empty { + margin: ; +} +div.important { + color: red !important; + width: 100% !important; + height: 20px !important; +} +div.annoying_font_property { + font: 12px/16px Arial; + font: 100%/16px Arial; + font: normal small/20px 'Trebuchet MS', Verdana, sans-serif; +} +div.shorthands { + border: 1px solid #000000; + margin: 1px 0; + padding: 0 auto; + padding: 1px 0 2px 0; + margin: 0; + padding: -1px -0 -2px -0; +} +table { + counter-reset: group; +} +tbody { + counter-increment: group; + counter-reset: row; +} +tbody tr { + counter-increment: row; +} +tbody td:first-child:before { + content: counter(group,upper-latin)"."counter(row); +} +.escape\|random\|char { + color: red; +} +.mixin\!tUp { + font-weight: bold; +} +.trailingTest\+ { + color: red; +} diff --git a/lesscpy/test/css/properties.min.css b/lesscpy/test/css/properties.min.css new file mode 100644 index 0000000..18c4acb --- /dev/null +++ b/lesscpy/test/css/properties.min.css @@ -0,0 +1,12 @@ +div.properties{color:red;} +div.empty{margin:;} +div.important{color:red !important;width:100% !important;height:20px !important;} +div.annoying_font_property{font:12px/16px Arial;font:100%/16px Arial;font:normal small/20px 'Trebuchet MS',Verdana,sans-serif;} +div.shorthands{border:1px solid #000000;margin:1px 0;padding:0 auto;padding:1px 0 2px 0;margin:0;padding:-1px -0 -2px -0;} +table{counter-reset:group;} +tbody{counter-increment:group;counter-reset:row;} +tbody tr{counter-increment:row;} +tbody td:first-child:before{content:counter(group,upper-latin)"."counter(row);} +.escape\|random\|char{color:red;} +.mixin\!tUp{font-weight:bold;} +.trailingTest\+{color:red;} diff --git a/lesscpy/test/css/strings.css b/lesscpy/test/css/strings.css new file mode 100644 index 0000000..17908df --- /dev/null +++ b/lesscpy/test/css/strings.css @@ -0,0 +1,26 @@ +#strings { + quotes: "~""~"; + content: "#*%:&^,)!.(~*})"; + empty: ""; + brackets: "{""}"; +} +#comments { + content: "/* hello */ // not-so-secret"; +} +#quotes { + quotes: "'""'"; + quotes: '"''"'; + content: '""#!&""'; + empty: ''; + semi-colon: ';'; +} +#escaped { + filter: DX.Transform.MS.BS.filter(opacity=50); +} +#interpolation { + url: "http://lesscss.org/dev/image.jpg"; + url2: "http://lesscss.org/image-256.jpg"; + url3: "http://lesscss.org#445566"; + url4: "http://lesscss.org/hello"; + url5: "http://lesscss.org/54.4px"; +} diff --git a/lesscpy/test/css/strings.min.css b/lesscpy/test/css/strings.min.css new file mode 100644 index 0000000..c57fffb --- /dev/null +++ b/lesscpy/test/css/strings.min.css @@ -0,0 +1,5 @@ +#strings{quotes:"~""~";content:"#*%:&^,)!.(~*})";empty:"";brackets:"{""}";} +#comments{content:"/* hello */ // not-so-secret";} +#quotes{quotes:"'""'";quotes:'"''"';content:'""#!&""';empty:'';semi-colon:';';} +#escaped{filter:DX.Transform.MS.BS.filter(opacity=50);} +#interpolation{url:"http://lesscss.org/dev/image.jpg";url2:"http://lesscss.org/image-256.jpg";url3:"http://lesscss.org#445566";url4:"http://lesscss.org/hello";url5:"http://lesscss.org/54.4px";} diff --git a/lesscpy/test/less/css-escapes.less b/lesscpy/test/less/css-escapes.less deleted file mode 100644 index e69de29..0000000 diff --git a/lesscpy/test/less/properties-uri.less b/lesscpy/test/less/properties-uri.less index 9291e79..d85da8a 100644 --- a/lesscpy/test/less/properties-uri.less +++ b/lesscpy/test/less/properties-uri.less @@ -20,4 +20,6 @@ background-image: url(https://some.server.com:9696/path/img.jpeg); behavior:url(border-radius.htc); background-image: url(fonts.svg#MyGeometricModern); + image: url(http://), "}", url("http://}"); + image: url(http://tooks.com); } \ No newline at end of file diff --git a/lesscpy/test/less/properties-vendor.less b/lesscpy/test/less/properties-vendor.less new file mode 100644 index 0000000..ba07f35 --- /dev/null +++ b/lesscpy/test/less/properties-vendor.less @@ -0,0 +1,12 @@ +div.vendor { + -moz-transform: translate(0, 11em) rotate(-90deg); + -webkit-animation: anim2 7s infinite ease-in-out; +} +div.long { + -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, + 0pt 4px 6px rgba(255, 255, 255, 0.4) inset; +} +div.styles { + display: -moz-inline-stack; + background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue)); +} \ No newline at end of file diff --git a/lesscpy/test/less/properties.less b/lesscpy/test/less/properties.less index bfe97af..634d63d 100644 --- a/lesscpy/test/less/properties.less +++ b/lesscpy/test/less/properties.less @@ -23,6 +23,7 @@ div.shorthands { padding: 0 auto; padding: 1px 0 2px 0; margin: 0; + padding: -1px -0 -2px -0; } /* @@ -39,4 +40,16 @@ tbody tr { } tbody td:first-child:before { content: counter(group, upper-latin) "." counter(row); +} +/* + Escapes +*/ +.escape\|random\|char { + color: red; +} +.mixin\!tUp { + font-weight: bold; +} +.trailingTest\+ { + color: red; } \ No newline at end of file diff --git a/lesscpy/test/less/properties_vendor.less b/lesscpy/test/less/properties_vendor.less deleted file mode 100644 index da2fd66..0000000 --- a/lesscpy/test/less/properties_vendor.less +++ /dev/null @@ -1,4 +0,0 @@ -div.vendor { - display: -moz-inline-stack; - background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue)); -} \ No newline at end of file diff --git a/lesscpy/test/less/strings.less b/lesscpy/test/less/strings.less index e69de29..8ccc4fd 100644 --- a/lesscpy/test/less/strings.less +++ b/lesscpy/test/less/strings.less @@ -0,0 +1,35 @@ +#strings { + quotes: "~" "~"; + content: "#*%:&^,)!.(~*})"; + empty: ""; + brackets: "{" "}"; +} +#comments { + content: "/* hello */ // not-so-secret"; +} +#quotes { + quotes: "'" "'"; + quotes: '"' '"'; + content: '""#!&""'; + empty: ''; + semi-colon: ';'; +} +#escaped { + filter: ~"DX.Transform.MS.BS.filter(opacity=50)"; +} +#interpolation { + @var: '/dev'; + url: "http://lesscss.org@{var}/image.jpg"; + + @var2: 256; + url2: "http://lesscss.org/image-@{var2}.jpg"; + + @var3: #456; + url3: "http://lesscss.org@{var3}"; + + @var4: hello; + url4: "http://lesscss.org/@{var4}"; + + @var5: 54.4px; + url5: "http://lesscss.org/@{var5}"; +}