From b2c5385e06b0b8ccc921509b6421de0b33822aed Mon Sep 17 00:00:00 2001 From: Nikos M Date: Sun, 23 Apr 2023 12:44:15 +0300 Subject: [PATCH] v.1.1.0 * don't track current position * handle implicit lines in moves * include id/class atts * parse defs/style --- README.md | 41 +++++++--- src/svg2json.js | 194 ++++++++++++++++++++++++++++++++++++-------- src/svg2json.min.js | 4 +- test/Peace_sign.svg | 5 +- test/out.txt | Bin 7264 -> 8174 bytes 5 files changed, 192 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 646cfac..ea0183c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Simple utility to parse SVG to JSON -**version: 1.0.1** (8 kB minified) +**version: 1.1.0** (9 kB minified) Example (see tests): @@ -23,9 +23,10 @@ output: + - - + + ``` @@ -38,13 +39,30 @@ output: "width": "250", "height": "250", "nodes": [ + { + "type": "Defs", + "nodes": [ + { + "type": "Style", + "rules": [ + { + "selector": ".circ", + "style": { + "stroke": "red" + } + }, + { + "selector": "#p,.circ", + "style": { + "stroke-width": "2" + } + } + ] + } + ] + }, { "type": "Group", - "style": { - "stroke-width": "21", - "stroke": "#000", - "fill": "none" - }, "transform": [ [ "scale", @@ -57,8 +75,7 @@ output: "nodes": [ { "type": "Circle", - "style": {}, - "transform": null, + "class": "circ", "center": [ 125, 125 @@ -67,8 +84,8 @@ output: }, { "type": "Path", - "style": {}, - "transform": null, + "id": "p", + "class": "pth", "d": [ { "type": "Move", diff --git a/src/svg2json.js b/src/svg2json.js index 8fafbbc..2e9e657 100644 --- a/src/svg2json.js +++ b/src/svg2json.js @@ -2,7 +2,7 @@ * * SVG2JSON Parse SVG string or nodes into a JSON * https://github.com/foo123/svg2json -* @VERSION 1.0.1 +* @VERSION 1.1.0 * **/ !function(root, name, factory) { @@ -18,8 +18,9 @@ else if (!(name in root)) /* Browser/WebWorker/.. */ /* module factory */ function ModuleFactory__svg2json(undef) { "use strict"; -var VERSION = "1.0.1", +var VERSION = "1.1.0", COMMENT = //m, + COMMENT2 = /\/\*.*?\*\//m, TAG = /<(\/)?([a-z0-9_:\-]+)\b\s*([^<>]*)\/?>/im, ATT = /([a-z0-9_:\-]+)\b\s*(?:=\s*"([^"]*)")?/im, COMMAND = /[MLHVCSQTAZ]/gi, @@ -32,10 +33,11 @@ function trim(s) { return s.trim(); } -function strip_comments(s) +function strip_comments(s, comment_re) { var m; - while (m=s.match(COMMENT)) s = s.slice(0, m.index) + s.slice(m.index + m[0].length); + comment_re = comment_re || COMMENT; + while (m=s.match(comment_re)) s = s.slice(0, m.index) + s.slice(m.index + m[0].length); return s; } function parse_number(s) @@ -74,29 +76,75 @@ function parse_transform(atts) } return tr.length ? tr : null; } +function parse_css(css) +{ + var parts = trim(strip_comments(css, COMMENT2)).split('{'), + i, l = parts.length - 1, parts2, + p1, p2, rules = new Array(0 < l ? l : 0); + for (i=0; i/m,r=/<(\/)?([a-z0-9_:\-]+)\b\s*([^<>]*)\/?>/im,i=/([a-z0-9_:\-]+)\b\s*(?:=\s*"([^"]*)")?/im,s=/[MLHVCSQTAZ]/gi,l=/(matrix|scale|rotate|translate|skewX|skewY)\s*\(([^\(\)]*)\)/im,f=/-?(?:(?:\d+\.\d+)|(?:\.\d+)|(?:\d+))/g,a=Object.prototype.hasOwnProperty,d=(Math,{});function g(t){return t.trim()}function y(t){return parseFloat(t||"")||0}function o(e){var s={"stroke-width":1,stroke:1,"stroke-opacity":1,"stroke-linecap":1,"stroke-linejoin":1,fill:1,"fill-opacity":1,"fill-rule":1},n=g(e.style?String(e.style.cssText||e.style):"").split(";").reduce(function(t,e){var e=g(e).split(":"),n=g(e[0]),e=g(e.slice(1).join(":"));return a.call(s,n)&&(t[n]=e),t},{});return Object.keys(s).forEach(function(t){a.call(e,t)&&(n[t]=e[t])}),n}function p(t){for(var e,n=g(t.transform||""),s=[];e=n.match(l);)s.push([g(e[1]).toLowerCase(),(g(e[2]).match(f)||[]).map(y)]),n=n.slice(e.index+e[0].length);return s.length?s:null}function m(t,h){h=h||[0,0];var e=(t=g(String(t))).match(s),u=t.split(s),c=[h[0],h[1]];return e?e.reduce(function(t,e,n){var s,r,i,l,a,o=e===e.toLowerCase(),p=(g(u[n+1]||"").match(f)||[]).map(y);switch(e.toUpperCase()){case"M":2<=p.length&&(c=[o?[p[0],p[1]]:[p[0]-h[0],p[1]-h[1]]],h[0]=(o?h[0]:0)+p[0],h[1]=(o?h[1]:0)+p[1],t.push({type:"Move",points:[h.slice()],pointsrel:c}),c=[h[0],h[1]]);break;case"H":for(;1<=p.length;)s=[h[0],h[1]],r=[(o?s[0]:0)+p.shift(),s[1]],h[0]=r[0],h[1]=r[1],!t.length||"Line"!==t[t.length-1].type&&"Polyline"!==t[t.length-1].type||t[t.length-1].Z?t.push({type:"Line",points:[s,r],pointsrel:[[r[0]-s[0],r[1]-s[1]]],H:!0}):(t[t.length-1].type="Polyline",t[t.length-1].points.push(r),t[t.length-1].pointsrel.push([r[0]-s[0],r[1]-s[1]]),t[t.length-1].H&&delete t[t.length-1].H,t[t.length-1].V&&delete t[t.length-1].V);break;case"V":for(;1<=p.length;)r=[(s=[h[0],h[1]])[0],(o?s[1]:0)+p.shift()],h[0]=r[0],h[1]=r[1],!t.length||"Line"!==t[t.length-1].type&&"Polyline"!==t[t.length-1].type||t[t.length-1].Z?t.push({type:"Line",points:[s,r],pointsrel:[[r[0]-s[0],r[1]-s[1]]],V:!0}):(t[t.length-1].type="Polyline",t[t.length-1].points.push(r),t[t.length-1].pointsrel.push([r[0]-s[0],r[1]-s[1]]),t[t.length-1].H&&delete t[t.length-1].H,t[t.length-1].V&&delete t[t.length-1].V);break;case"L":for(;2<=p.length;)s=[h[0],h[1]],r=[(o?s[0]:0)+p.shift(),(o?s[1]:0)+p.shift()],h[0]=r[0],h[1]=r[1],!t.length||"Line"!==t[t.length-1].type&&"Polyline"!==t[t.length-1].type||t[t.length-1].Z?t.push({type:"Line",points:[s,r],pointsrel:[[r[0]-s[0],r[1]-s[1]]]}):(t[t.length-1].type="Polyline",t[t.length-1].points.push(r),t[t.length-1].pointsrel.push([r[0]-s[0],r[1]-s[1]]),t[t.length-1].H&&delete t[t.length-1].H,t[t.length-1].V&&delete t[t.length-1].V);break;case"A":for(;7<=p.length;)a={start:null,end:null,endrel:null,radiusX:p.shift(),radiusY:p.shift(),angle:p.shift(),largeArc:p.shift(),sweep:p.shift()},s=[h[0],h[1]],r=[(o?s[0]:0)+p.shift(),(o?s[1]:0)+p.shift()],h[0]=r[0],h[1]=r[1],a.start=s,a.end=r,a.endrel=[r[0]-s[0],r[1]-s[1]],t.push({type:"Arc",params:a});break;case"Q":for(;4<=p.length;)s=[h[0],h[1]],r=[(o?s[0]:0)+p.shift(),(o?s[1]:0)+p.shift()],i=[(o?s[0]:0)+p.shift(),(o?s[1]:0)+p.shift()],h[0]=i[0],h[1]=i[1],t.push({type:"Quadratic",points:[s,r,i],pointsrel:[[r[0]-s[0],r[1]-s[1]],[i[0]-s[0],i[1]-s[1]]]});break;case"T":for(;2<=p.length;)a=t.length?t[t.length-1]:d,s=[h[0],h[1]],i=[(o?s[0]:0)+p.shift(),(o?s[1]:0)+p.shift()],r="Quadratic"===a.type?[2*s[0]-a.points[1][0],2*s[1]-a.points[1][1]]:[s[0],s[1]],h[0]=i[0],h[1]=i[1],t.push({type:"Quadratic",points:[s,r,i],pointsrel:[[r[0]-s[0],r[1]-s[1]],[i[0]-s[0],i[1]-s[1]]],T:!0});break;case"C":for(;6<=p.length;)s=[h[0],h[1]],r=[(o?s[0]:0)+p.shift(),(o?s[1]:0)+p.shift()],i=[(o?s[0]:0)+p.shift(),(o?s[1]:0)+p.shift()],l=[(o?s[0]:0)+p.shift(),(o?s[1]:0)+p.shift()],h[0]=l[0],h[1]=l[1],t.push({type:"Cubic",points:[s,r,i,l],pointsrel:[[r[0]-s[0],r[1]-s[1]],[i[0]-s[0],i[1]-s[1]],[l[0]-s[0],l[1]-s[1]]]});break;case"S":for(;4<=p.length;)a=t.length?t[t.length-1]:d,s=[h[0],h[1]],i=[(o?s[0]:0)+p.shift(),(o?s[1]:0)+p.shift()],l=[(o?s[0]:0)+p.shift(),(o?s[1]:0)+p.shift()],r="Cubic"===a.type?[2*s[0]-a.points[2][0],2*s[1]-a.points[2][1]]:[s[0],s[1]],h[0]=l[0],h[1]=l[1],t.push({type:"Cubic",points:[s,r,i,l],pointsrel:[[r[0]-s[0],r[1]-s[1]],[i[0]-s[0],i[1]-s[1]],[l[0]-s[0],l[1]-s[1]]],S:!0});break;case"Z":s=[h[0],h[1]],r=[c[0],c[1]],h[0]=r[0],h[1]=r[1],c=[h[0],h[1]],t.push({type:"Line",points:[s,r],pointsrel:[[r[0]-s[0],r[1]-s[1]]],Z:!0})}return t},[]):[]}function b(t,e){var n,s;if(!e||!e.parsed)return t.tagName&&t.children?((s=function(t){var e,n,s={};if(t.attributes)for(e=0,n=t.attributes.length;e/m,a=/\/\*.*?\*\//m,i=/<(\/)?([a-z0-9_:\-]+)\b\s*([^<>]*)\/?>/im,l=/([a-z0-9_:\-]+)\b\s*(?:=\s*"([^"]*)")?/im,s=/[MLHVCSQTAZ]/gi,o=/(matrix|scale|rotate|translate|skewX|skewY)\s*\(([^\(\)]*)\)/im,d=/-?(?:(?:\d+\.\d+)|(?:\.\d+)|(?:\d+))/g,p=Object.prototype.hasOwnProperty,y=(Math,{});function g(t){return t.trim()}function h(t,e){var s;for(e=e||n;s=t.match(e);)t=t.slice(0,s.index)+t.slice(s.index+s[0].length);return t}function m(t){return parseFloat(t||"")||0}function c(e){var n={"stroke-width":1,stroke:1,"stroke-opacity":1,"stroke-linecap":1,"stroke-linejoin":1,fill:1,"fill-opacity":1,"fill-rule":1},s=g(e.style?String(e.style.cssText||e.style):"").split(";").reduce(function(t,e){var e=g(e).split(":"),s=g(e[0]),e=g(e.slice(1).join(":"));return p.call(n,s)&&(t[s]=e),t},{});return Object.keys(n).forEach(function(t){p.call(e,t)&&(s[t]=e[t])}),s}function u(t){for(var e,s=g(t.transform||""),n=[];e=s.match(o);)n.push([g(e[1]).toLowerCase(),(g(e[2]).match(d)||[]).map(m)]),s=s.slice(e.index+e[0].length);return n.length?n:null}function f(t){for(var e,s,n=g(h(t,a)).split("{"),r=n.length-1,i=new Array(0 + - - + + diff --git a/test/out.txt b/test/out.txt index 0bce0909f111a937d4dde808d71980cce608109d..af45f5f60908ca62f7485a8677f5b4c0f752126e 100644 GIT binary patch delta 574 zcmZ`$%}N4c6uqD6%*2$MmY{{{Od(ilvrxxa& zi?^srm)PWhRjER4%2FCE19%f018fsdjvBZ(z-eQjC7mqV{8w#@pM;vs(GJ*ou*V%Z z_klY;7tc#3U0`q19%&@5^xxu1MTbPf|9lI89HAPV_Y`9T($bG1q6$AA@*=dob`LFT!_(%}|KH rX4YPOuOj+a$P*@f! zBE+i9V8CE7xsgS9asWGzv=T!aLncEG5GpZPF(?4ZJcfKAPGwM<{E1h_QCEBfC6EX!0cvvB?@NVnAaAHXq^gz$ab8QzZ-lmkBYT