From 1831a46fcc776a58016f242429343f6ce464f491 Mon Sep 17 00:00:00 2001 From: Sascha Peilicke Date: Wed, 7 Aug 2013 16:47:02 +0200 Subject: [PATCH 1/8] Fix test path issues. Find fixtures when invoke via "python lesscpy/tests/__main__.py" and generate better names for 'less' and 'issues' tests. --- lesscpy/test/testissues.py | 10 +++++++--- lesscpy/test/testless.py | 12 ++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/lesscpy/test/testissues.py b/lesscpy/test/testissues.py index 4956991..e7d4610 100644 --- a/lesscpy/test/testissues.py +++ b/lesscpy/test/testissues.py @@ -51,12 +51,16 @@ def create_test(args): return do_test_expected LESS = glob.glob(os.path.join('less/issues', '*.less')) +_less_path = os.path.join(os.path.dirname(__file__), 'less', 'issues') +_css_path = os.path.join(os.path.dirname(__file__), 'css', 'issues') + +LESS = glob.glob(os.path.join(_less_path, '*.less')) for less in LESS: lessf = less.split('.')[0].split('/')[-1] - css = 'css/issues/' + lessf + '.css' - mincss = 'css/issues/' + lessf + '.min.css' + css = os.path.join(_css_path, lessf + '.css') + mincss = os.path.join(_css_path, lessf + '.min.css') test_method = create_test((less, css, mincss)) - test_method.__name__ = 'test_%s' % less.replace('./-', '_') + test_method.__name__ = 'test_%s' % "_".join(reversed(os.path.basename(less).split('.'))) setattr(TestCase, test_method.__name__, test_method) if __name__ == "__main__": diff --git a/lesscpy/test/testless.py b/lesscpy/test/testless.py index bed0815..51c7602 100644 --- a/lesscpy/test/testless.py +++ b/lesscpy/test/testless.py @@ -72,13 +72,17 @@ def create_test(args): self.fail("%s not found..." % minf) return do_test_expected -LESS = glob.glob(os.path.join('less/', '*.less')) + +_less_path = os.path.join(os.path.dirname(__file__), 'less') +_css_path = os.path.join(os.path.dirname(__file__), 'css') + +LESS = glob.glob(os.path.join(_less_path, '*.less')) for less in LESS: lessf = less.split('.')[0].split('/')[-1] - css = 'css/' + lessf + '.css' - mincss = 'css/' + lessf + '.min.css' + css = os.path.join(_css_path, lessf + '.css') + mincss = os.path.join(_css_path, lessf + '.min.css') test_method = create_test((less, css, mincss)) - test_method.__name__ = 'test_%s' % less.replace('./-', '_') + test_method.__name__ = 'test_%s' % "_".join(reversed(os.path.basename(less).split('.'))) setattr(TestCase, test_method.__name__, test_method) if __name__ == "__main__": From cea4f297c72db533760b4839772519aee5110605 Mon Sep 17 00:00:00 2001 From: Sascha Peilicke Date: Thu, 8 Aug 2013 09:39:30 +0200 Subject: [PATCH 2/8] Verbose testsuite runs --- .travis.yml | 3 +-- tox.ini | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 84f25ff..f210315 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,5 +6,4 @@ python: # command to install dependencies install: "pip install -r requirements.txt --use-mirrors" # command to run tests -script: python lesscpy/test/__main__.py - +script: python lesscpy/test/__main__.py -v diff --git a/tox.ini b/tox.ini index e1744d8..7b9e3da 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ envlist = py26,py27,py33,pep8 [testenv] deps = -r{toxinidir}/requirements.txt -commands = python lesscpy/test/__main__.py +commands = python lesscpy/test/__main__.py -v [testenv:pep8] deps = pep8 From 9044b43eb58d175490cb128b6161f10e962b8388 Mon Sep 17 00:00:00 2001 From: Sascha Peilicke Date: Thu, 8 Aug 2013 09:16:01 +0200 Subject: [PATCH 3/8] Convert to int when using round(), ceil() or floor() round(1.2px) is expected return '1px', not '1.0px' --- lesscpy/plib/call.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lesscpy/plib/call.py b/lesscpy/plib/call.py index 0fb4137..d2fe8c7 100644 --- a/lesscpy/plib/call.py +++ b/lesscpy/plib/call.py @@ -196,7 +196,7 @@ class Call(Node): str """ n, u = utility.analyze_number(value) - return utility.with_unit(round(float(n)), u) + return utility.with_unit(int(round(float(n))), u) def ceil(self, value, *args): """ Ceil number @@ -206,7 +206,7 @@ class Call(Node): str """ n, u = utility.analyze_number(value) - return utility.with_unit(math.ceil(n), u) + return utility.with_unit(int(math.ceil(n)), u) def floor(self, value, *args): """ Floor number @@ -216,7 +216,7 @@ class Call(Node): str """ n, u = utility.analyze_number(value) - return utility.with_unit(math.floor(n), u) + return utility.with_unit(int(math.floor(n)), u) def percentage(self, value, *args): """ Return percentage value From 59b243a181349f82b2c66bd3c87fd2b3919e167d Mon Sep 17 00:00:00 2001 From: Sascha Peilicke Date: Thu, 8 Aug 2013 09:19:20 +0200 Subject: [PATCH 4/8] lighten(#555, 10%) should return #6f6f6f, not #6e6e6e Matches lessc's output. --- lesscpy/test/css/colors.css | 2 +- lesscpy/test/css/colors.min.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lesscpy/test/css/colors.css b/lesscpy/test/css/colors.css index 0ddc16e..1f0d87d 100644 --- a/lesscpy/test/css/colors.css +++ b/lesscpy/test/css/colors.css @@ -75,7 +75,7 @@ } .lighten { color: #585858; - color: #6e6e6e; + color: #6f6f6f; color: #888888; color: #bbbbbb; color: #eeeeee; diff --git a/lesscpy/test/css/colors.min.css b/lesscpy/test/css/colors.min.css index 60bee80..839529d 100644 --- a/lesscpy/test/css/colors.min.css +++ b/lesscpy/test/css/colors.min.css @@ -12,7 +12,7 @@ .hsl{color:#ffffff;color:#ffffff;color:#000000;color:#000000;} .saturate{color:#565454;color:#5e4c4c;color:#664444;color:#773333;color:#882222;color:#aa0000;color:#000000;color:#000000;color:#ffffff;color:#ffffff;color:#29332f;color:#243830;color:#203c31;color:#174533;color:#0d4f35;color:#005c37;} .desaturate{color:#555555;color:#555555;color:#555555;color:#555555;color:#555555;color:#555555;color:#000000;color:#000000;color:#ffffff;color:#ffffff;color:#29332f;color:#2e2e2e;color:#2e2e2e;color:#2e2e2e;color:#2e2e2e;color:#2e2e2e;} -.lighten{color:#585858;color:#6e6e6e;color:#888888;color:#bbbbbb;color:#eeeeee;color:#ffffff;color:#ffffff;color:#000000;color:#ffffff;color:#ffffff;color:#2b3632;color:#404f49;color:#566c63;color:#88a096;color:#c1cdc8;color:#ffffff;} +.lighten{color:#585858;color:#6f6f6f;color:#888888;color:#bbbbbb;color:#eeeeee;color:#ffffff;color:#ffffff;color:#000000;color:#ffffff;color:#ffffff;color:#2b3632;color:#404f49;color:#566c63;color:#88a096;color:#c1cdc8;color:#ffffff;} .lighten{color:#525252;color:#3b3b3b;color:#222222;color:#000000;color:#000000;color:#000000;color:#000000;color:#000000;color:#000000;color:#ffffff;color:#27302c;color:#121715;color:#000000;color:#000000;color:#000000;color:#000000;} .spin{color:#555555;color:#555555;color:#555555;color:#555555;color:#555555;color:#555555;color:#000000;color:#000000;color:#ffffff;color:#ffffff;color:#29332f;color:#29332d;color:#293332;color:#2a3329;color:#292d33;color:#2c2933;} .grayscale{color:#000000;color:#000000;color:#ffffff;color:#ffffff;color:#2e2e2e;color:#2e2e2e;color:#2e2e2e;color:#2e2e2e;color:#2e2e2e;color:#2e2e2e;} From 2b2a41751e97fa14f6c37ab5aea6598645e2eb4a Mon Sep 17 00:00:00 2001 From: Sascha Peilicke Date: Thu, 8 Aug 2013 10:07:43 +0200 Subject: [PATCH 5/8] Use precise grid margin values This is a bit controversial since it's different from lessc output. Still, it's correct since 87.8+27+1.7 == 116.5 (offset3_margin-left + span1_width + span_margin-left == offset4_margin-left) --- lesscpy/test/css/grid.css | 4 ++-- lesscpy/test/css/grid.min.css | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lesscpy/test/css/grid.css b/lesscpy/test/css/grid.css index 67674c2..ba266f1 100644 --- a/lesscpy/test/css/grid.css +++ b/lesscpy/test/css/grid.css @@ -124,13 +124,13 @@ margin-left: 59.1; } .offset3 { - margin-left: 87.80000000000001; + margin-left: 87.8; } .offset4 { margin-left: 116.5; } .offset5 { - margin-left: 145.20000000000002; + margin-left: 145.2; } .offset6 { margin-left: 173.9; diff --git a/lesscpy/test/css/grid.min.css b/lesscpy/test/css/grid.min.css index 06c58e4..215ccc7 100644 --- a/lesscpy/test/css/grid.min.css +++ b/lesscpy/test/css/grid.min.css @@ -39,9 +39,9 @@ .span12,.container{width:342.7;} .offset1{margin-left:30.4;} .offset2{margin-left:59.1;} -.offset3{margin-left:87.80000000000001;} +.offset3{margin-left:87.8;} .offset4{margin-left:116.5;} -.offset5{margin-left:145.20000000000002;} +.offset5{margin-left:145.2;} .offset6{margin-left:173.9;} .offset7{margin-left:202.6;} .offset8{margin-left:231.3;} From 81c4e765d6ffc171750c6922430209eae31a07f4 Mon Sep 17 00:00:00 2001 From: Sascha Peilicke Date: Wed, 7 Aug 2013 17:47:44 +0200 Subject: [PATCH 6/8] Implement SVG stylesheets. Including SVG-specific elements and attributes and an initial testsuite. --- lesscpy/lib/css.py | 50 ++++++++++++++++++++++++++++++++-- lesscpy/lib/dom.py | 19 +++++++++++++ lesscpy/test/css/svg.css | 53 ++++++++++++++++++++++++++++++++++++ lesscpy/test/css/svg.min.css | 15 ++++++++++ lesscpy/test/less/svg.less | 39 ++++++++++++++++++++++++++ 5 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 lesscpy/test/css/svg.css create mode 100644 lesscpy/test/css/svg.min.css create mode 100644 lesscpy/test/less/svg.less diff --git a/lesscpy/lib/css.py b/lesscpy/lib/css.py index cf95d07..14cb58a 100644 --- a/lesscpy/lib/css.py +++ b/lesscpy/lib/css.py @@ -272,6 +272,52 @@ css3 = [ 'word-break', 'word-wrap' ] +# SVG only includes style not present in either css2 or css3: +svg = [ + # clipping / masking / compositing: + 'clip-path', + 'clip-rule', + 'mask', + # filter effects: + 'enable-background', + 'filter', + 'flood-color', + 'flood-opacity', + 'lightning-color', + # gradient: + 'stop-color', + 'stop-opacity', + # interactivity: + 'pointer-events', + # color / painting: + 'color-interpolation', + 'color-interpolation-filters', + 'color-rendering', + 'fill', + 'fill-opacity', + 'fill-rule', + 'image-rendering', + 'marker', + 'marker-end', + 'marker-mid', + 'marker-start', + 'shape-rendering', + 'stroke', + 'stroke-dasharray', + 'stroke-dashoffset', + 'stroke-linecap', + 'stroke-linejoin', + 'stroke-miterlimit', + 'stroke-opacity', + 'stroke-width', + 'text-rendering', + # text: + 'glyph-orientation-horizontal', + 'glyph-orientation-vertical', + 'kerning', + 'text-anchor', + 'writing-mode', +] vendor_prefix = [ '-ms-', '-moz-', @@ -284,10 +330,8 @@ vendor_prefix = [ 'mso-', ] vendor_ugly = [ - 'filter', 'accelerator', 'behavior', - 'filter', 'zoom', ] -propertys = css2 + css3 + vendor_ugly +propertys = css2 + css3 + svg + vendor_ugly diff --git a/lesscpy/lib/dom.py b/lesscpy/lib/dom.py index 2569d84..8f662af 100644 --- a/lesscpy/lib/dom.py +++ b/lesscpy/lib/dom.py @@ -140,5 +140,24 @@ html5 = [ 'video', 'wbr', ] +svg = [ + 'altGlyph', + 'altGlyphDef', + 'altGlyphItem', + 'circle', + 'desc', + 'ellipse', + 'glyphRef', + 'line', + 'path', + 'polygon', + 'polyline', + 'rect', + 'text', + 'textPath', + 'tref', + 'tspan', +] html = html4 html.extend(html5) +html.extend(svg) diff --git a/lesscpy/test/css/svg.css b/lesscpy/test/css/svg.css new file mode 100644 index 0000000..afabf9d --- /dev/null +++ b/lesscpy/test/css/svg.css @@ -0,0 +1,53 @@ +svg { + color: red; +} +circle { + stroke: #006600; + fill: #00cc00; +} +circle .green { + stroke: #006600; + stroke-width: 9; + fill: #00cc00; +} +rect { + fill: blue; + fill-opacity: 0.1; + stroke: green; + opacity: 0.5; +} +ellipse { + fill: yellow; +} +line { + stroke: red; +} +path { + stroke: blue; +} +polygon { + fill: lime; + fill-rule: nonzero; +} +polygon { + fill: lime; + fill-rule: evenodd; +} +polyline { + fill: none; +} +.node text { + font: 12px sans-serif; +} +tref { + font-weight: bold; +} +text tref { + font-weight: bold; +} +tspan { + font-weight: bold; +} +text tspan { + font-weight: bold; +} diff --git a/lesscpy/test/css/svg.min.css b/lesscpy/test/css/svg.min.css new file mode 100644 index 0000000..6f96b1b --- /dev/null +++ b/lesscpy/test/css/svg.min.css @@ -0,0 +1,15 @@ +svg{color:red;} +circle{stroke:#006600;fill:#00cc00;} +circle .green{stroke:#006600;stroke-width:9;fill:#00cc00;} +rect{fill:blue;fill-opacity:0.1;stroke:green;opacity:0.5;} +ellipse{fill:yellow;} +line{stroke:red;} +path{stroke:blue;} +polygon{fill:lime;fill-rule:nonzero;} +polygon{fill:lime;fill-rule:evenodd;} +polyline{fill:none;} +.node text{font:12px sans-serif;} +tref{font-weight:bold;} +text tref{font-weight:bold;} +tspan{font-weight:bold;} +text tspan{font-weight:bold;} diff --git a/lesscpy/test/less/svg.less b/lesscpy/test/less/svg.less new file mode 100644 index 0000000..fe1443d --- /dev/null +++ b/lesscpy/test/less/svg.less @@ -0,0 +1,39 @@ +svg {color: red;} + +circle { + stroke: #006600; + fill: #00cc00; +} +circle .green { + stroke: #006600; + stroke-width: 9; + fill: #00cc00; +} +rect { + fill: blue; + fill-opacity: 0.1; + stroke: green; + opacity: 0.5; +} +ellipse { fill: yellow; } +line { stroke: red; } +path { stroke: blue; } +polygon { + fill: lime; + fill-rule: nonzero; +} +polygon { + fill: lime; + fill-rule: evenodd; +} +polyline { fill: none; } + +.node text { font: 12px sans-serif; } +tref { font-weight: bold; } +text tref { font-weight: bold; } +tspan { font-weight: bold; } +text tspan { font-weight: bold; } +/* NOTE(saschpe): TODO +textPath { font-weight: bold; } +text textPath { font-weight: bold; } +svg text textPath { font-weight: bold; } */ From a80cb8942a0d95b6b1d9ed5733bd1f706aa31a46 Mon Sep 17 00:00:00 2001 From: Sascha Peilicke Date: Thu, 8 Aug 2013 10:53:46 +0200 Subject: [PATCH 7/8] Allow camel-case DOM elements defined in SVG-1.1 The SVG standard defines several DOM elements in camel-case (namely textPath, altGlyph, altGlyphDef, altGlyphItem and glyphRef). Even though most browser also accept lower-case, the lexer should take this into account. --- lesscpy/lessc/lexer.py | 2 +- lesscpy/test/css/svg.css | 9 +++++++++ lesscpy/test/css/svg.min.css | 3 +++ lesscpy/test/less/svg.less | 3 +-- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lesscpy/lessc/lexer.py b/lesscpy/lessc/lexer.py index e03d86a..d6ad3f1 100644 --- a/lesscpy/lessc/lexer.py +++ b/lesscpy/lessc/lexer.py @@ -129,7 +129,7 @@ class LessLexer: elif v in css.propertys: t.type = 'css_property' t.value = t.value.strip() - elif v.lower() in dom.html: + elif v in dom.html or v.lower() in dom.html: t.type = 'css_dom' elif c == '@': v = v.lower() diff --git a/lesscpy/test/css/svg.css b/lesscpy/test/css/svg.css index afabf9d..398ecea 100644 --- a/lesscpy/test/css/svg.css +++ b/lesscpy/test/css/svg.css @@ -51,3 +51,12 @@ tspan { text tspan { font-weight: bold; } +textPath { + font-weight: bold; +} +text textPath { + font-weight: bold; +} +svg text textPath { + font-weight: bold; +} diff --git a/lesscpy/test/css/svg.min.css b/lesscpy/test/css/svg.min.css index 6f96b1b..c79a416 100644 --- a/lesscpy/test/css/svg.min.css +++ b/lesscpy/test/css/svg.min.css @@ -13,3 +13,6 @@ tref{font-weight:bold;} text tref{font-weight:bold;} tspan{font-weight:bold;} text tspan{font-weight:bold;} +textPath{font-weight:bold;} +text textPath{font-weight:bold;} +svg text textPath{font-weight:bold;} diff --git a/lesscpy/test/less/svg.less b/lesscpy/test/less/svg.less index fe1443d..95fe8f6 100644 --- a/lesscpy/test/less/svg.less +++ b/lesscpy/test/less/svg.less @@ -33,7 +33,6 @@ tref { font-weight: bold; } text tref { font-weight: bold; } tspan { font-weight: bold; } text tspan { font-weight: bold; } -/* NOTE(saschpe): TODO textPath { font-weight: bold; } text textPath { font-weight: bold; } -svg text textPath { font-weight: bold; } */ +svg text textPath { font-weight: bold; } From 92c0321b3a704274a02bfadb769713d6f14496cb Mon Sep 17 00:00:00 2001 From: Sascha Peilicke Date: Thu, 8 Aug 2013 10:57:16 +0200 Subject: [PATCH 8/8] Bump version to 0.9i --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 6bce3ba..dc0e9ae 100755 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ from distutils.core import setup setup( name='lesscpy', - version='0.9h', + version='0.9i', description='Lesscss compiler.', author='Jóhann T Maríusson', author_email='jtm@robot.is',