├── .nvmrc
├── .jshintrc
├── .gitignore
├── .travis.yml
├── src
├── parse.js
├── transform.js
├── lib.js
├── flatten.js
└── pathify.js
├── LICENSE
├── package.json
├── test
├── lib-samples.spec.js
├── flatten.spec.js
├── samples
│ ├── sample2_result.svg
│ ├── sample2.svg
│ ├── sample1_result.svg
│ ├── sample1.svg
│ ├── sample3.svg
│ └── sample3_result.svg
├── transform.spec.js
├── lib.spec.js
├── pathify.spec.js
└── parse.spec.js
└── README.md
/.nvmrc:
--------------------------------------------------------------------------------
1 | 8
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "esversion": 6
3 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependency directories
2 | node_modules
3 | jspm_packages
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
3 | node_js:
4 | - 8
5 | - 14
6 | - lts/*
7 |
8 | scripts:
9 | - npm test
10 | - npm run lint
11 |
--------------------------------------------------------------------------------
/src/parse.js:
--------------------------------------------------------------------------------
1 | var xmldoc = require('xmldoc');
2 |
3 | module.exports = function (source) {
4 | try {
5 | return new xmldoc.XmlDocument(source);
6 | } catch (exception) {
7 | var dom = new xmldoc.XmlDocument('');
8 | dom.attr.reason = exception.toString();
9 |
10 | return dom;
11 | }
12 | };
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2016 StadLine
2 |
3 | Permission to use, copy, modify, and/or distribute this software for any
4 | purpose with or without fee is hereby granted, provided that the above
5 | copyright notice and this permission notice appear in all copies.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 | OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 | CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "svg-flatten",
3 | "version": "1.0.1",
4 | "description": "Turns SVG shapes (polygon, polyline, rect, g) into SVG paths. It can merge groups and apply transforms.",
5 | "main": "src/lib.js",
6 | "dependencies": {
7 | "svgpath": "^2.1.6",
8 | "xmldoc": "^0.5.0"
9 | },
10 | "devDependencies": {
11 | "chai": "^3.5.0",
12 | "jshint": "^2.9.1",
13 | "mocha": "^2.4.5",
14 | "proxyquire": "^1.7.9",
15 | "sinon": "^1.17.4"
16 | },
17 | "scripts": {
18 | "test": "mocha",
19 | "lint": "jshint **/*.js"
20 | },
21 | "keywords": [
22 | "svg",
23 | "flatten",
24 | "flattener",
25 | "shape",
26 | "circle",
27 | "ellipse",
28 | "line",
29 | "path",
30 | "polygon",
31 | "polyline",
32 | "rect",
33 | "g",
34 | "transform"
35 | ],
36 | "author": "alex-pex",
37 | "license": "ISC",
38 | "repository": "stadline/svg-flatten"
39 | }
40 |
--------------------------------------------------------------------------------
/src/transform.js:
--------------------------------------------------------------------------------
1 | var svgpath = require('svgpath');
2 |
3 | function transformGroup(dom) {
4 | var newChildren = [];
5 |
6 | dom.children.forEach(function (child) {
7 | newChildren.push(transform(child));
8 | });
9 |
10 | dom.children = newChildren;
11 |
12 | if (newChildren.length > 0) {
13 | dom.firstChild = newChildren[0];
14 | dom.lastChild = newChildren[newChildren.length - 1];
15 | }
16 |
17 | return dom;
18 | }
19 |
20 | function transformPath(dom) {
21 | dom.attr.d = svgpath(dom.attr.d).transform(dom.attr.transform)
22 | .round(10)
23 | .toString();
24 |
25 | delete dom.attr.transform;
26 |
27 | return dom;
28 | }
29 |
30 | function transform(dom) {
31 | if (dom.name === 'path' && dom.attr.transform) {
32 | return transformPath(dom);
33 | } else if (dom.name === 'svg' || dom.name === 'g') {
34 | return transformGroup(dom);
35 | } else {
36 | return dom;
37 | }
38 | }
39 |
40 | module.exports = transform;
--------------------------------------------------------------------------------
/src/lib.js:
--------------------------------------------------------------------------------
1 | var parseFn = require('./parse.js');
2 | var pathifyFn = require('./pathify.js');
3 | var transformFn = require('./transform.js');
4 | var flattenFn = require('./flatten.js');
5 |
6 | function Wrapper(source) {
7 | if (typeof source === "string") {
8 | this._value = parseFn(source);
9 | } else {
10 | this._value = source;
11 | }
12 |
13 | this.pathify = function() {
14 | this._value = pathifyFn(this._value);
15 | return this;
16 | };
17 |
18 | this.transform = function() {
19 | this._value = transformFn(this._value);
20 | return this;
21 | };
22 |
23 | this.flatten = function() {
24 | this._value = flattenFn(this._value);
25 | return this;
26 | };
27 |
28 | this.value = function() {
29 | if (typeof source === "string") {
30 | var meta = source.substr(0, source.indexOf("<" + this._value.name));
31 | return meta + this._value.toString();
32 | } else {
33 | return this._value;
34 | }
35 | };
36 | }
37 |
38 | module.exports = function(source) {
39 | return new Wrapper(source);
40 | };
41 |
--------------------------------------------------------------------------------
/src/flatten.js:
--------------------------------------------------------------------------------
1 | var transform = require('./transform.js');
2 | var xmldoc = require('xmldoc');
3 |
4 | function flattenSvg(dom) {
5 | var newChildren = [];
6 |
7 | dom.children.forEach(function (child) {
8 | newChildren.push(flatten(child));
9 | });
10 |
11 | dom.children = newChildren;
12 |
13 | if (newChildren.length > 0) {
14 | dom.firstChild = newChildren[0];
15 | dom.lastChild = newChildren[newChildren.length - 1];
16 | }
17 |
18 | return dom;
19 | }
20 |
21 | function flattenGroup(dom) {
22 | var path = new xmldoc.XmlDocument('');
23 |
24 | path.attr = dom.attr;
25 | path.attr.d = "";
26 |
27 | dom.children.forEach(function (child) {
28 | var flatChild = transform(flatten(child));
29 |
30 | if (flatChild.attr.d) {
31 | var prefix = path.attr.d.length ? " " : "";
32 | path.attr.d += prefix + flatChild.attr.d;
33 | }
34 | });
35 |
36 | return path;
37 | }
38 |
39 | function flatten(dom) {
40 | if (dom.name === 'svg') {
41 | return flattenSvg(dom);
42 | } else if (dom.name === 'g') {
43 | return flattenGroup(dom);
44 | } else {
45 | return dom;
46 | }
47 | }
48 |
49 | module.exports = flatten;
--------------------------------------------------------------------------------
/test/lib-samples.spec.js:
--------------------------------------------------------------------------------
1 | /*jshint mocha: true*/
2 |
3 | var expect = require('chai').expect;
4 | var fs = require('fs');
5 | var svgflatten = require('../src/lib.js');
6 | var xmldoc = require('xmldoc');
7 |
8 | // test
9 | describe('svg-flatten: test samples', function () {
10 | var samples = ["sample1", "sample2", "sample3"];
11 |
12 | samples.forEach(function(basename) {
13 | it('should give accurate results (' + basename + ')', function () {
14 | var sample = fs.readFileSync(__dirname + '/samples/' + basename + '.svg', 'utf8');
15 | var expectedResult = fs.readFileSync(__dirname + '/samples/' + basename + '_result.svg', 'utf8');
16 |
17 | // test with string
18 | var result = svgflatten(sample)
19 | .pathify()
20 | .flatten()
21 | .transform()
22 | .value();
23 |
24 | expect(result).to.be.equal(expectedResult);
25 |
26 | // test with dom
27 | var sampleDom = new xmldoc.XmlDocument(sample);
28 | var expectedResultDom = new xmldoc.XmlDocument(expectedResult);
29 |
30 | var resultDom = svgflatten(sampleDom)
31 | .pathify()
32 | .flatten()
33 | .transform()
34 | .value();
35 |
36 | expect(resultDom.toString()).to.be.equal(expectedResultDom.toString());
37 | });
38 | });
39 | });
40 |
--------------------------------------------------------------------------------
/test/flatten.spec.js:
--------------------------------------------------------------------------------
1 | /*jshint mocha: true*/
2 |
3 | var expect = require('chai').expect;
4 | var xmldoc = require('xmldoc');
5 | var flattenFn = require('../src/flatten.js');
6 |
7 | // test
8 | describe('svg-flatten: flatten function', function() {
9 | it('should flatten path groups', function() {
10 | var source = new xmldoc.XmlDocument('');
11 | var target = new xmldoc.XmlDocument('');
12 |
13 | // test
14 | expect(flattenFn(source).toString()).to.be.equal(target.toString());
15 | });
16 |
17 | it('should flatten nested path groups', function() {
18 | var source = new xmldoc.XmlDocument('');
19 | var target = new xmldoc.XmlDocument('');
20 |
21 | // test
22 | expect(flattenFn(source).toString()).to.be.equal(target.toString());
23 | });
24 |
25 | it('should work with complex groups', function() {
26 | var source = new xmldoc.XmlDocument('');
27 | var target = new xmldoc.XmlDocument('');
28 |
29 | // test
30 | expect(flattenFn(source).toString()).to.be.equal(target.toString());
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | svg-flatten
2 | ==========================================================================================
3 |
4 | Turns SVG shapes (polygon, polyline, rect, g) into SVG paths. It can merge groups and apply transforms.
5 |
6 | How to use?
7 | -----------
8 |
9 | ```js
10 | const svgFlatten = require('svg-flatten')
11 | const fs = require('fs')
12 |
13 | let flattendSvgPath = 'tmp-flattened.svg'
14 |
15 | // read SVG file into string
16 | let svgString = fs.readFileSync('circle-rect.svg', 'utf8')
17 | // convert all objects to paths
18 | let modifiedSvgString = svgFlatten(svgString).pathify().value()
19 | // write SVG string to disk
20 | fs.writeFileSync(flattendSvgPath,modifiedSvgString)
21 | ```
22 |
23 | API
24 | ---
25 |
26 | ### svgFlatten(content: string): SvgFlatten
27 |
28 | Reads SVG content and creates a SvgFlatten instance.
29 |
30 | ### .pathify(): SvgFlatten
31 |
32 | Turns SVG shapes (polygon, polyline, rect, g) into SVG paths. It is **needed** before other transformations.
33 |
34 | ### .flatten(): SvgFlatten
35 |
36 | Converts groups of paths to a fat path, combining all child paths into one.
37 |
38 | **Be careful: it tries to squash the xml structure, information can be lost.**
39 |
40 | Some example of the limitations:
41 | - duplicate attributes cannot be safely squashed, like the id in ``
42 | - style rules based on the structure like `#g1 > circle`
43 | - [`use`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use) directive may not apply
44 |
45 | ### .transform(): SvgFlatten
46 |
47 | Apply [SVG transformations](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform) to paths. It doesn't apply clipPath.
48 |
49 | ### .value(): string
50 |
51 | Returns the final result as SVG content.
52 |
53 | Need more info?
54 | ---------------
55 |
56 | Sadly, I wrote this lib for an old project (2016) and didn't need to tweak it since. It is not actively maintened, but I'll try to watch pull-requests.
57 |
--------------------------------------------------------------------------------
/test/samples/sample2_result.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/test/samples/sample2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/test/samples/sample1_result.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/test/samples/sample1.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
19 |
--------------------------------------------------------------------------------
/test/transform.spec.js:
--------------------------------------------------------------------------------
1 | /*jshint mocha: true*/
2 |
3 | var expect = require('chai').expect;
4 | var xmldoc = require('xmldoc');
5 | var transformFn = require('../src/transform.js');
6 |
7 | // test
8 | describe('svg-flatten: transform function', function() {
9 | it('should apply translate transformation', function() {
10 | var source = new xmldoc.XmlDocument('');
11 | var target = new xmldoc.XmlDocument('');
12 |
13 | // test
14 | expect(transformFn(source).toString()).to.be.equal(target.toString());
15 | });
16 |
17 | it('should apply rotate transformation', function() {
18 | var source = new xmldoc.XmlDocument('');
19 | var target = new xmldoc.XmlDocument('');
20 |
21 | // test
22 | expect(transformFn(source).toString()).to.be.equal(target.toString());
23 | });
24 |
25 | it('should apply chained transformation', function() {
26 | var source = new xmldoc.XmlDocument('');
27 | var target = new xmldoc.XmlDocument('');
28 |
29 | // test
30 | expect(transformFn(source).toString()).to.be.equal(target.toString());
31 | });
32 |
33 | it('should work with complex paths', function() {
34 | var circle = new xmldoc.XmlDocument('');
35 | var ellipse = new xmldoc.XmlDocument('');
36 | var line = new xmldoc.XmlDocument('');
37 | var polygon = new xmldoc.XmlDocument('');
38 | var polyline = new xmldoc.XmlDocument('');
39 | var rect = new xmldoc.XmlDocument('');
40 | var shape = new xmldoc.XmlDocument('');
41 |
42 | // test
43 | expect(transformFn(circle).toString()).to.be.equal('');
44 | expect(transformFn(ellipse).toString()).to.be.equal('');
45 | expect(transformFn(line).toString()).to.be.equal('');
46 | expect(transformFn(polygon).toString()).to.be.equal('');
47 | expect(transformFn(polyline).toString()).to.be.equal('');
48 | expect(transformFn(rect).toString()).to.be.equal('');
49 | expect(transformFn(shape).toString()).to.be.equal('');
50 | });
51 | });
52 |
--------------------------------------------------------------------------------
/test/samples/sample3.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
62 |
--------------------------------------------------------------------------------
/src/pathify.js:
--------------------------------------------------------------------------------
1 | /*jshint singleGroups: false*/
2 |
3 | function _convertEllipse(cx = 0, cy = 0, rx = 0, ry = 0) {
4 | return "M" + (cx - rx) + "," + cy + "a" + rx + "," + ry + " 0 1,0 " + (rx * 2) + ",0a" + rx + "," + ry + " 0 1,0 " + (rx * -2) + ",0";
5 | }
6 |
7 | function _convertPoints(points) {
8 | var path = "";
9 |
10 | for (var i=0; i 0) {
28 | dom.firstChild = newChildren[0];
29 | dom.lastChild = newChildren[newChildren.length - 1];
30 | }
31 |
32 | return dom;
33 | }
34 |
35 | function convertCircle(dom) {
36 | var path = _convertEllipse(dom.attr.cx, dom.attr.cy, dom.attr.r, dom.attr.r);
37 |
38 | delete dom.attr.cx;
39 | delete dom.attr.cy;
40 | delete dom.attr.r;
41 |
42 | dom.name = 'path';
43 | dom.attr.d = path;
44 |
45 | return dom;
46 | }
47 |
48 | function convertEllipse(dom) {
49 | var path = _convertEllipse(dom.attr.cx, dom.attr.cy, dom.attr.rx, dom.attr.ry);
50 |
51 | delete dom.attr.cx;
52 | delete dom.attr.cy;
53 | delete dom.attr.rx;
54 | delete dom.attr.ry;
55 |
56 | dom.name = 'path';
57 | dom.attr.d = path;
58 |
59 | return dom;
60 | }
61 |
62 | function convertLine(dom) {
63 | var path = _convertPoints([dom.attr.x1, dom.attr.y1, dom.attr.x2, dom.attr.y2]);
64 |
65 | delete dom.attr.x1;
66 | delete dom.attr.y1;
67 | delete dom.attr.x2;
68 | delete dom.attr.y2;
69 |
70 | dom.name = 'path';
71 | dom.attr.d = path;
72 |
73 | return dom;
74 | }
75 |
76 | function convertPolygon(dom) {
77 | var points = dom.attr.points.trim().split(/[\s,]+/);
78 | var path = _convertPoints(points) + "z";
79 |
80 | delete dom.attr.points;
81 |
82 | dom.name = 'path';
83 | dom.attr.d = path;
84 |
85 | return dom;
86 | }
87 |
88 | function convertPolyline(dom) {
89 | var points = dom.attr.points.trim().split(/[\s,]+/);
90 | var path = _convertPoints(points);
91 |
92 | delete dom.attr.points;
93 |
94 | dom.name = 'path';
95 | dom.attr.d = path;
96 |
97 | return dom;
98 | }
99 |
100 | function convertRect(dom) {
101 | var x = parseFloat(dom.attr.x || 0);
102 | var y = parseFloat(dom.attr.y || 0);
103 | var width = parseFloat(dom.attr.width);
104 | var height = parseFloat(dom.attr.height);
105 |
106 | var points = [];
107 | points.push(x, y);
108 | points.push(x + width, y);
109 | points.push(x + width, y + height);
110 | points.push(x, y + height);
111 | var path = _convertPoints(points) + "z";
112 |
113 | delete dom.attr.x;
114 | delete dom.attr.y;
115 | delete dom.attr.width;
116 | delete dom.attr.height;
117 |
118 | dom.name = 'path';
119 | dom.attr.d = path;
120 |
121 | return dom;
122 | }
123 |
124 | function pathify(dom) {
125 | if (dom.name === 'svg') {
126 | return convertGroup(dom);
127 | } else if (dom.name === 'circle') {
128 | return convertCircle(dom);
129 | } else if (dom.name === 'ellipse') {
130 | return convertEllipse(dom);
131 | } else if (dom.name === 'line') {
132 | return convertLine(dom);
133 | } else if (dom.name === 'polygon') {
134 | return convertPolygon(dom);
135 | } else if (dom.name === 'polyline') {
136 | return convertPolyline(dom);
137 | } else if (dom.name === 'rect') {
138 | return convertRect(dom);
139 | } else if (dom.name === 'g') {
140 | return convertGroup(dom);
141 | } else {
142 | return dom;
143 | }
144 | }
145 |
146 | module.exports = pathify;
147 |
--------------------------------------------------------------------------------
/test/lib.spec.js:
--------------------------------------------------------------------------------
1 | /*jshint mocha: true*/
2 | /*jshint expr: true*/
3 | /*jshint multistr: true*/
4 |
5 | var expect = require('chai').expect;
6 | var sinon = require('sinon');
7 | var proxyquire = require('proxyquire');
8 |
9 | // sample file
10 | var file = ' \
11 | \
12 | \
13 | ';
16 |
17 | // test
18 | describe('svg-flatten lib', function() {
19 | var parse;
20 | var pathify;
21 | var transform;
22 | var flatten;
23 | var lib;
24 |
25 | beforeEach(function () {
26 | parse = sinon.stub();
27 | pathify = sinon.stub();
28 | transform = sinon.stub();
29 | flatten = sinon.stub();
30 |
31 | parse.withArgs(file).returns(file);
32 |
33 | // inject stubs into library
34 | lib = proxyquire('../src/lib.js', {
35 | './parse.js': parse,
36 | './pathify.js': pathify,
37 | './transform.js': transform,
38 | './flatten.js': flatten
39 | });
40 | });
41 |
42 | it('should wrap the source', function() {
43 | var wrapper = lib(file);
44 |
45 | // test
46 | expect(wrapper).to.be.an('object');
47 | expect(wrapper._value).to.be.equal(file);
48 | });
49 |
50 | it('should apply the parse filter', function() {
51 | // init mocks
52 | var parsedFile = {
53 | parsed: true
54 | };
55 |
56 | parse.withArgs(file).returns(parsedFile);
57 |
58 | // test
59 | expect(lib(file)._value).to.be.equal(parsedFile);
60 | expect(parse.calledOnce).to.be.true;
61 | });
62 |
63 | it('should apply the pathify filter', function() {
64 | var wrapper = lib(file);
65 |
66 | // init mocks
67 | var pathifiedFile = {
68 | pathified: true
69 | };
70 |
71 | pathify.withArgs(file).returns(pathifiedFile);
72 |
73 | // test
74 | expect(wrapper.pathify()._value).to.be.equal(pathifiedFile);
75 | expect(pathify.calledOnce).to.be.true;
76 | });
77 |
78 | it('should apply the transform filter', function() {
79 | var wrapper = lib(file);
80 |
81 | // init mocks
82 | var transformedFile = {
83 | transformed: true
84 | };
85 |
86 | transform.withArgs(file).returns(transformedFile);
87 |
88 | // test
89 | expect(wrapper.transform()._value).to.be.equal(transformedFile);
90 | expect(transform.calledOnce).to.be.true;
91 | });
92 |
93 | it('should apply the flatten filter', function() {
94 | var wrapper = lib(file);
95 |
96 | // init mocks
97 | var flatFile = {
98 | flat: true
99 | };
100 |
101 | flatten.withArgs(file).returns(flatFile);
102 |
103 | // test
104 | expect(wrapper.flatten()._value).to.be.equal(flatFile);
105 | expect(flatten.calledOnce).to.be.true;
106 | });
107 |
108 | it('should chain filters', function() {
109 | var wrapper = lib(file);
110 |
111 | // init mocks
112 | var pathifiedFile = {
113 | pathified: true
114 | };
115 |
116 | var flatFile = {
117 | flat: true
118 | };
119 |
120 | pathify.withArgs(file).returns(pathifiedFile);
121 | flatten.withArgs(pathifiedFile).returns(flatFile);
122 |
123 | // test
124 | expect(wrapper.pathify().flatten()._value).to.be.equal(flatFile);
125 | expect(parse.calledOnce).to.be.true;
126 | expect(pathify.calledOnce).to.be.true;
127 | expect(flatten.calledOnce).to.be.true;
128 | });
129 | });
130 |
--------------------------------------------------------------------------------
/test/pathify.spec.js:
--------------------------------------------------------------------------------
1 | /*jshint mocha: true*/
2 |
3 | var expect = require('chai').expect;
4 | var xmldoc = require('xmldoc');
5 | var pathifyFn = require('../src/pathify.js');
6 |
7 | // test
8 | describe('svg-flatten: pathify function', function() {
9 | it('should convert circle', function() {
10 | var source = new xmldoc.XmlDocument('');
11 | var target = new xmldoc.XmlDocument('');
12 |
13 | // test
14 | expect(pathifyFn(source).toString()).to.be.equal(target.toString());
15 | });
16 |
17 | it('should convert circle without center point', function() {
18 | var source = new xmldoc.XmlDocument('');
19 | var target = new xmldoc.XmlDocument('');
20 |
21 | // test
22 | expect(pathifyFn(source).toString()).to.be.equal(target.toString());
23 | });
24 |
25 | it('should convert circle without radius', function() {
26 | var source = new xmldoc.XmlDocument('');
27 | var target = new xmldoc.XmlDocument('');
28 |
29 | // test
30 | expect(pathifyFn(source).toString()).to.be.equal(target.toString());
31 | });
32 |
33 | it('should convert ellipse', function() {
34 | var source = new xmldoc.XmlDocument('');
35 | var target = new xmldoc.XmlDocument('');
36 |
37 | // test
38 | expect(pathifyFn(source).toString()).to.be.equal(target.toString());
39 | });
40 |
41 | it('should convert line', function() {
42 | var source = new xmldoc.XmlDocument('');
43 | var target = new xmldoc.XmlDocument('');
44 |
45 | // test
46 | expect(pathifyFn(source).toString()).to.be.equal(target.toString());
47 | });
48 |
49 | it('should convert polygons', function() {
50 | var source = new xmldoc.XmlDocument('');
51 | var target = new xmldoc.XmlDocument('');
52 |
53 | // test
54 | expect(pathifyFn(source).toString()).to.be.equal(target.toString());
55 | });
56 |
57 | it('should convert polyline', function() {
58 | var source = new xmldoc.XmlDocument('');
59 | var target = new xmldoc.XmlDocument('');
60 |
61 | // test
62 | expect(pathifyFn(source).toString()).to.be.equal(target.toString());
63 | });
64 |
65 | it('should convert polyline with extra whitespaces', function() {
66 | var source = new xmldoc.XmlDocument('');
67 | var target = new xmldoc.XmlDocument('');
68 |
69 | // test
70 | expect(pathifyFn(source).toString()).to.be.equal(target.toString());
71 | });
72 |
73 | it('should convert rect', function() {
74 | var source = new xmldoc.XmlDocument('');
75 | var target = new xmldoc.XmlDocument('');
76 |
77 | // test
78 | expect(pathifyFn(source).toString()).to.be.equal(target.toString());
79 | });
80 |
81 | it('should preserve groups', function() {
82 | var source = new xmldoc.XmlDocument('');
83 |
84 | // test
85 | expect(pathifyFn(source)).to.be.equal(source);
86 | });
87 | it('should preserve nested groups', function() {
88 | var source = new xmldoc.XmlDocument('');
89 | var target = new xmldoc.XmlDocument('');
90 |
91 | // test
92 | expect(pathifyFn(source).toString()).to.be.equal(target.toString());
93 | });
94 |
95 | it('should should convert group children', function() {
96 | var source = new xmldoc.XmlDocument('');
97 | var target = new xmldoc.XmlDocument('');
98 |
99 | // test
100 | expect(pathifyFn(source).toString()).to.be.equal(target.toString());
101 | });
102 | });
103 |
--------------------------------------------------------------------------------
/test/parse.spec.js:
--------------------------------------------------------------------------------
1 | /*jshint mocha: true*/
2 | /*jshint expr: true*/
3 | /*jshint multistr: true*/
4 |
5 | var expect = require('chai').expect;
6 | var parseFn = require('../src/parse.js');
7 |
8 | // sample files
9 | var file1 = ' \
10 | \
11 | \
12 | ';
15 |
16 | var file2 = ' \
17 | \
18 | \
19 | ';
36 |
37 | // test
38 | describe('svg-flatten: parse function', function() {
39 | it('should successfully parse a simple svg', function() {
40 | var dom = parseFn(file1);
41 |
42 | // test root node
43 | expect(dom.name).to.be.equal('svg');
44 | expect(dom.attr.viewBox).to.be.equal('0 0 1920.7 1133.7');
45 |
46 | // test child nodes
47 | expect(dom.children.length).to.be.equal(1);
48 | expect(dom.children[0].name).to.be.equal('rect');
49 | });
50 |
51 | it('should successfully parse a complex svg', function() {
52 | var dom = parseFn(file2);
53 |
54 | // test root node
55 | expect(dom.name).to.be.equal('svg');
56 | expect(dom.attr.viewBox).to.be.equal('0 0 1920.7 1133.7');
57 |
58 | // test child nodes
59 | expect(dom.children.length).to.be.equal(10);
60 | expect(dom.children[0].name).to.be.equal('style');
61 | expect(dom.children[1].name).to.be.equal('rect');
62 | expect(dom.children[7].attr.transform).to.be.equal('translate(0, 100)');
63 | });
64 |
65 | it('should not fail when the source is invalid', function() {
66 | var dom = parseFn("invalid input");
67 |
68 | // test root node
69 | expect(dom.name).to.be.equal('invalid');
70 | expect(dom.attr.reason).not.to.be.empty;
71 | });
72 | });
73 |
--------------------------------------------------------------------------------
/test/samples/sample3_result.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------