diff --git a/README.md b/README.md index f193bfa..306b294 100644 --- a/README.md +++ b/README.md @@ -62,11 +62,13 @@ let lsParams = { // Output SVG parameters (all of them are optional) let svgParams = { - width: 600, // Desired SVG element width - height: 600, // Desired SVG element height - padding: 5, // Additional space to extend the viewBox - fill: "none", // Value of the “fill” attribute on the “path” element - stroke: "green" // Value of the “stroke” attribute on the “path” element + width: 600, // Desired SVG element width + height: 600, // Desired SVG element height + padding: 5, // Additional space to extend the viewBox + pathAttributes: { // Name to value map for the “path” element attributes + stroke: "green", + "stroke-width": "2px" + } }; // Get ready-to-render L-system’s SVG code as a string diff --git a/dist/lindsvg.esm.js b/dist/lindsvg.esm.js index e37e8f6..1227431 100644 --- a/dist/lindsvg.esm.js +++ b/dist/lindsvg.esm.js @@ -1,5 +1,5 @@ /*! -lindsvg v1.1.0 +lindsvg v1.2.0 https://amphiluke.github.io/l-systems/ (c) 2020 Amphiluke */ @@ -265,17 +265,24 @@ function getSVGData(lsParams) { */ function getSVGCode(lsParams, svgParams) { let {pathData, minX, minY, width, height} = getSVGData(lsParams); - svgParams = { - width, - height, - padding: 0, - fill: "none", - stroke: "#000", - ...svgParams + let svgConfig = { + width: svgParams.width || width, + height: svgParams.height || height, + padding: svgParams.padding || 0, + pathAttributes: { + // for backward compatibility with v1.1.0, also check fill and stroke as direct props of svgParams + fill: svgParams.fill || "none", + stroke: svgParams.stroke || "#000", + ...svgParams.pathAttributes + } }; - let {padding} = svgParams; - return ` - + let {padding} = svgConfig; + let pathAttrStr = Object.entries(svgConfig.pathAttributes).reduce((accumulator, [name, value]) => { + value = value.replace(/"/g, """); + return `${accumulator} ${name}="${value}"`; + }, ""); + return ` + `; } diff --git a/dist/lindsvg.esm.min.js b/dist/lindsvg.esm.min.js index 0c24bfb..9906a7c 100644 --- a/dist/lindsvg.esm.min.js +++ b/dist/lindsvg.esm.min.js @@ -1,6 +1,6 @@ /*! -lindsvg v1.1.0 +lindsvg v1.2.0 https://amphiluke.github.io/l-systems/ (c) 2020 Amphiluke */ -let t={AXIOM:"Axiom may only contain the following characters: A..Z,+,-,[,]",RULE:"Production rules may only contain the following characters: A..Z,+,-,[,]",LETTER:"Allowed alphabet letters are: A..Z",ALPHA:"The “alpha” parameter must be a finite number",THETA:"The “theta” parameter must be a finite number",STEP:"The “step” parameter must be a positive finite number",COUNT:"The number of iterations must be integer and finite",NUMBER:"A valid finite number expected"},e=/^[A-Z]$/;let a=/^[A-Z+\-[\]]*$/;function i(e,i=t.RULE){return a.test(e)||i}function r(a,r,n){let s=Object.create(null);return Object.entries(a).forEach(([a,h])=>{let l=function(a,i=t.LETTER){return e.test(a)||i}(a,r);!0===l&&(l=i(h,n)),!0!==l&&(s[a]=l)}),!Object.keys(s).length||s}function n(e){let a=Object.create(null);return Object.entries(e).forEach(([e,n])=>{let s=!0;switch(e){case"axiom":s=i(n,t.AXIOM);break;case"rules":s=r(n);break;case"alpha":case"theta":s=function(e,a=t.NUMBER){return Number.isFinite(e)||a}(n,t[e.toUpperCase()]);break;case"step":s=function(e,a=t.STEP){return Number.isFinite(e)&&e>0||a}(n);break;case"iterations":s=function(e,a=t.COUNT){return Number.isInteger(e)&&e>0||a}(n)}!0!==s&&(a[e]=s)}),!Object.keys(a).length||a}class s extends Error{constructor(t){let e=JSON.stringify(t,null,2);super(e),Object.defineProperty(this,"lsErrors",{value:JSON.parse(e)})}toJSON(){return JSON.parse(JSON.stringify(this.lsErrors))}}Object.defineProperty(s.prototype,"name",{configurable:!0,enumerable:!1,writable:!0,value:"LSError"});let h={F:"",B:"","+":"+","-":"-","[":"[","]":"]"},l={alpha:0,theta:0,step:10,iterations:3};let o={translate(){this.x+=this.step*Math.cos(this.alpha),this.y+=this.step*Math.sin(this.alpha),this.minX=Math.min(this.minX,this.x),this.maxX=Math.max(this.maxX,this.x),this.minY=Math.min(this.minY,this.y),this.maxY=Math.max(this.maxY,this.y)},rotate(t){this.alpha+=t*this.theta},pushStack(){this.stack.push({x:this.x,y:this.y,alpha:this.alpha})},popStack(){({x:this.x,y:this.y,alpha:this.alpha}=this.stack.pop())},getDrawingRect(){let t=Math.floor(this.minX),e=Math.floor(this.minY),a=Math.ceil(this.maxX),i=Math.ceil(this.maxY);return{minX:t,minY:e,maxX:a,maxY:i,width:a-t,height:i-e}}};function c(t,e){return`${+t.toFixed(4)} ${+e.toFixed(4)}`}function u(t){let e=function(t){let e=n(t);if(!0!==e)throw new s(e);let{axiom:a,iterations:i}={...l,...t},r={...h,...t.rules};for(;i>0;i--)a=[...a].reduce((t,e)=>t+(r[e]||""),"");return a}(t),a=function({x:t,y:e,step:a,alpha:i,theta:r}){let n=Object.create(o);return n.stack=[],n.x=n.minX=n.maxX=t,n.y=n.minY=n.maxY=e,n.step=a,n.alpha=-i,n.theta=r,n}({x:0,y:0,...t});return{pathData:function(t,e){let a;return[...t].reduce((t,i)=>{switch(i){case"F":e.translate(),t+=("L"===a?" ":"L")+c(e.x,e.y),a="L";break;case"B":e.translate(),"M"===a&&(t=t.slice(0,t.lastIndexOf("M"))),t+="M"+c(e.x,e.y),a="M";break;case"+":e.rotate(1);break;case"-":e.rotate(-1);break;case"[":e.pushStack();break;case"]":e.popStack(),t+=`M${c(e.x,e.y)}`,a="M"}return t},"M"+c(e.x,e.y))}(function(t){return t.replace(/[^FB[\]+-]/g,"")}(e),a),...a.getDrawingRect()}}function p(t,e){let{pathData:a,minX:i,minY:r,width:n,height:s}=u(t);e={width:n,height:s,padding:0,fill:"none",stroke:"#000",...e};let{padding:h}=e;return`\n \n`}export{p as getSVGCode,u as getSVGData}; +let t={AXIOM:"Axiom may only contain the following characters: A..Z,+,-,[,]",RULE:"Production rules may only contain the following characters: A..Z,+,-,[,]",LETTER:"Allowed alphabet letters are: A..Z",ALPHA:"The “alpha” parameter must be a finite number",THETA:"The “theta” parameter must be a finite number",STEP:"The “step” parameter must be a positive finite number",COUNT:"The number of iterations must be integer and finite",NUMBER:"A valid finite number expected"},e=/^[A-Z]$/;let a=/^[A-Z+\-[\]]*$/;function i(e,i=t.RULE){return a.test(e)||i}function r(a,r,n){let s=Object.create(null);return Object.entries(a).forEach(([a,h])=>{let l=function(a,i=t.LETTER){return e.test(a)||i}(a,r);!0===l&&(l=i(h,n)),!0!==l&&(s[a]=l)}),!Object.keys(s).length||s}function n(e){let a=Object.create(null);return Object.entries(e).forEach(([e,n])=>{let s=!0;switch(e){case"axiom":s=i(n,t.AXIOM);break;case"rules":s=r(n);break;case"alpha":case"theta":s=function(e,a=t.NUMBER){return Number.isFinite(e)||a}(n,t[e.toUpperCase()]);break;case"step":s=function(e,a=t.STEP){return Number.isFinite(e)&&e>0||a}(n);break;case"iterations":s=function(e,a=t.COUNT){return Number.isInteger(e)&&e>0||a}(n)}!0!==s&&(a[e]=s)}),!Object.keys(a).length||a}class s extends Error{constructor(t){let e=JSON.stringify(t,null,2);super(e),Object.defineProperty(this,"lsErrors",{value:JSON.parse(e)})}toJSON(){return JSON.parse(JSON.stringify(this.lsErrors))}}Object.defineProperty(s.prototype,"name",{configurable:!0,enumerable:!1,writable:!0,value:"LSError"});let h={F:"",B:"","+":"+","-":"-","[":"[","]":"]"},l={alpha:0,theta:0,step:10,iterations:3};let c={translate(){this.x+=this.step*Math.cos(this.alpha),this.y+=this.step*Math.sin(this.alpha),this.minX=Math.min(this.minX,this.x),this.maxX=Math.max(this.maxX,this.x),this.minY=Math.min(this.minY,this.y),this.maxY=Math.max(this.maxY,this.y)},rotate(t){this.alpha+=t*this.theta},pushStack(){this.stack.push({x:this.x,y:this.y,alpha:this.alpha})},popStack(){({x:this.x,y:this.y,alpha:this.alpha}=this.stack.pop())},getDrawingRect(){let t=Math.floor(this.minX),e=Math.floor(this.minY),a=Math.ceil(this.maxX),i=Math.ceil(this.maxY);return{minX:t,minY:e,maxX:a,maxY:i,width:a-t,height:i-e}}};function o(t,e){return`${+t.toFixed(4)} ${+e.toFixed(4)}`}function u(t){let e=function(t){let e=n(t);if(!0!==e)throw new s(e);let{axiom:a,iterations:i}={...l,...t},r={...h,...t.rules};for(;i>0;i--)a=[...a].reduce((t,e)=>t+(r[e]||""),"");return a}(t),a=function({x:t,y:e,step:a,alpha:i,theta:r}){let n=Object.create(c);return n.stack=[],n.x=n.minX=n.maxX=t,n.y=n.minY=n.maxY=e,n.step=a,n.alpha=-i,n.theta=r,n}({x:0,y:0,...t});return{pathData:function(t,e){let a;return[...t].reduce((t,i)=>{switch(i){case"F":e.translate(),t+=("L"===a?" ":"L")+o(e.x,e.y),a="L";break;case"B":e.translate(),"M"===a&&(t=t.slice(0,t.lastIndexOf("M"))),t+="M"+o(e.x,e.y),a="M";break;case"+":e.rotate(1);break;case"-":e.rotate(-1);break;case"[":e.pushStack();break;case"]":e.popStack(),t+=`M${o(e.x,e.y)}`,a="M"}return t},"M"+o(e.x,e.y))}(function(t){return t.replace(/[^FB[\]+-]/g,"")}(e),a),...a.getDrawingRect()}}function p(t,e){let{pathData:a,minX:i,minY:r,width:n,height:s}=u(t),h={width:e.width||n,height:e.height||s,padding:e.padding||0,pathAttributes:{fill:e.fill||"none",stroke:e.stroke||"#000",...e.pathAttributes}},{padding:l}=h,c=Object.entries(h.pathAttributes).reduce((t,[e,a])=>`${t} ${e}="${a=a.replace(/"/g,""")}"`,"");return`\n \n`}export{p as getSVGCode,u as getSVGData}; diff --git a/dist/lindsvg.js b/dist/lindsvg.js index 17b216b..95c4aa8 100644 --- a/dist/lindsvg.js +++ b/dist/lindsvg.js @@ -1,5 +1,5 @@ /*! -lindsvg v1.1.0 +lindsvg v1.2.0 https://amphiluke.github.io/l-systems/ (c) 2020 Amphiluke */ @@ -271,17 +271,24 @@ https://amphiluke.github.io/l-systems/ */ function getSVGCode(lsParams, svgParams) { let {pathData, minX, minY, width, height} = getSVGData(lsParams); - svgParams = { - width, - height, - padding: 0, - fill: "none", - stroke: "#000", - ...svgParams + let svgConfig = { + width: svgParams.width || width, + height: svgParams.height || height, + padding: svgParams.padding || 0, + pathAttributes: { + // for backward compatibility with v1.1.0, also check fill and stroke as direct props of svgParams + fill: svgParams.fill || "none", + stroke: svgParams.stroke || "#000", + ...svgParams.pathAttributes + } }; - let {padding} = svgParams; - return ` - + let {padding} = svgConfig; + let pathAttrStr = Object.entries(svgConfig.pathAttributes).reduce((accumulator, [name, value]) => { + value = value.replace(/"/g, """); + return `${accumulator} ${name}="${value}"`; + }, ""); + return ` + `; } diff --git a/dist/lindsvg.min.js b/dist/lindsvg.min.js index c770b30..9fe8e8c 100644 --- a/dist/lindsvg.min.js +++ b/dist/lindsvg.min.js @@ -1,6 +1,6 @@ /*! -lindsvg v1.1.0 +lindsvg v1.2.0 https://amphiluke.github.io/l-systems/ (c) 2020 Amphiluke */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self).lindsvg={})}(this,(function(t){"use strict";let e={AXIOM:"Axiom may only contain the following characters: A..Z,+,-,[,]",RULE:"Production rules may only contain the following characters: A..Z,+,-,[,]",LETTER:"Allowed alphabet letters are: A..Z",ALPHA:"The “alpha” parameter must be a finite number",THETA:"The “theta” parameter must be a finite number",STEP:"The “step” parameter must be a positive finite number",COUNT:"The number of iterations must be integer and finite",NUMBER:"A valid finite number expected"},a=/^[A-Z]$/;let i=/^[A-Z+\-[\]]*$/;function r(t,a=e.RULE){return i.test(t)||a}function n(t,i,n){let s=Object.create(null);return Object.entries(t).forEach(([t,h])=>{let o=function(t,i=e.LETTER){return a.test(t)||i}(t,i);!0===o&&(o=r(h,n)),!0!==o&&(s[t]=o)}),!Object.keys(s).length||s}function s(t){let a=Object.create(null);return Object.entries(t).forEach(([t,i])=>{let s=!0;switch(t){case"axiom":s=r(i,e.AXIOM);break;case"rules":s=n(i);break;case"alpha":case"theta":s=function(t,a=e.NUMBER){return Number.isFinite(t)||a}(i,e[t.toUpperCase()]);break;case"step":s=function(t,a=e.STEP){return Number.isFinite(t)&&t>0||a}(i);break;case"iterations":s=function(t,a=e.COUNT){return Number.isInteger(t)&&t>0||a}(i)}!0!==s&&(a[t]=s)}),!Object.keys(a).length||a}class h extends Error{constructor(t){let e=JSON.stringify(t,null,2);super(e),Object.defineProperty(this,"lsErrors",{value:JSON.parse(e)})}toJSON(){return JSON.parse(JSON.stringify(this.lsErrors))}}Object.defineProperty(h.prototype,"name",{configurable:!0,enumerable:!1,writable:!0,value:"LSError"});let o={F:"",B:"","+":"+","-":"-","[":"[","]":"]"},l={alpha:0,theta:0,step:10,iterations:3};let c={translate(){this.x+=this.step*Math.cos(this.alpha),this.y+=this.step*Math.sin(this.alpha),this.minX=Math.min(this.minX,this.x),this.maxX=Math.max(this.maxX,this.x),this.minY=Math.min(this.minY,this.y),this.maxY=Math.max(this.maxY,this.y)},rotate(t){this.alpha+=t*this.theta},pushStack(){this.stack.push({x:this.x,y:this.y,alpha:this.alpha})},popStack(){({x:this.x,y:this.y,alpha:this.alpha}=this.stack.pop())},getDrawingRect(){let t=Math.floor(this.minX),e=Math.floor(this.minY),a=Math.ceil(this.maxX),i=Math.ceil(this.maxY);return{minX:t,minY:e,maxX:a,maxY:i,width:a-t,height:i-e}}};function u(t,e){return`${+t.toFixed(4)} ${+e.toFixed(4)}`}function p(t){let e=function(t){let e=s(t);if(!0!==e)throw new h(e);let{axiom:a,iterations:i}={...l,...t},r={...o,...t.rules};for(;i>0;i--)a=[...a].reduce((t,e)=>t+(r[e]||""),"");return a}(t),a=function({x:t,y:e,step:a,alpha:i,theta:r}){let n=Object.create(c);return n.stack=[],n.x=n.minX=n.maxX=t,n.y=n.minY=n.maxY=e,n.step=a,n.alpha=-i,n.theta=r,n}({x:0,y:0,...t});return{pathData:function(t,e){let a;return[...t].reduce((t,i)=>{switch(i){case"F":e.translate(),t+=("L"===a?" ":"L")+u(e.x,e.y),a="L";break;case"B":e.translate(),"M"===a&&(t=t.slice(0,t.lastIndexOf("M"))),t+="M"+u(e.x,e.y),a="M";break;case"+":e.rotate(1);break;case"-":e.rotate(-1);break;case"[":e.pushStack();break;case"]":e.popStack(),t+=`M${u(e.x,e.y)}`,a="M"}return t},"M"+u(e.x,e.y))}(function(t){return t.replace(/[^FB[\]+-]/g,"")}(e),a),...a.getDrawingRect()}}t.getSVGCode=function(t,e){let{pathData:a,minX:i,minY:r,width:n,height:s}=p(t);e={width:n,height:s,padding:0,fill:"none",stroke:"#000",...e};let{padding:h}=e;return`\n \n`},t.getSVGData=p,Object.defineProperty(t,"__esModule",{value:!0})})); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self).lindsvg={})}(this,(function(t){"use strict";let e={AXIOM:"Axiom may only contain the following characters: A..Z,+,-,[,]",RULE:"Production rules may only contain the following characters: A..Z,+,-,[,]",LETTER:"Allowed alphabet letters are: A..Z",ALPHA:"The “alpha” parameter must be a finite number",THETA:"The “theta” parameter must be a finite number",STEP:"The “step” parameter must be a positive finite number",COUNT:"The number of iterations must be integer and finite",NUMBER:"A valid finite number expected"},a=/^[A-Z]$/;let i=/^[A-Z+\-[\]]*$/;function r(t,a=e.RULE){return i.test(t)||a}function n(t,i,n){let s=Object.create(null);return Object.entries(t).forEach(([t,h])=>{let o=function(t,i=e.LETTER){return a.test(t)||i}(t,i);!0===o&&(o=r(h,n)),!0!==o&&(s[t]=o)}),!Object.keys(s).length||s}function s(t){let a=Object.create(null);return Object.entries(t).forEach(([t,i])=>{let s=!0;switch(t){case"axiom":s=r(i,e.AXIOM);break;case"rules":s=n(i);break;case"alpha":case"theta":s=function(t,a=e.NUMBER){return Number.isFinite(t)||a}(i,e[t.toUpperCase()]);break;case"step":s=function(t,a=e.STEP){return Number.isFinite(t)&&t>0||a}(i);break;case"iterations":s=function(t,a=e.COUNT){return Number.isInteger(t)&&t>0||a}(i)}!0!==s&&(a[t]=s)}),!Object.keys(a).length||a}class h extends Error{constructor(t){let e=JSON.stringify(t,null,2);super(e),Object.defineProperty(this,"lsErrors",{value:JSON.parse(e)})}toJSON(){return JSON.parse(JSON.stringify(this.lsErrors))}}Object.defineProperty(h.prototype,"name",{configurable:!0,enumerable:!1,writable:!0,value:"LSError"});let o={F:"",B:"","+":"+","-":"-","[":"[","]":"]"},c={alpha:0,theta:0,step:10,iterations:3};let l={translate(){this.x+=this.step*Math.cos(this.alpha),this.y+=this.step*Math.sin(this.alpha),this.minX=Math.min(this.minX,this.x),this.maxX=Math.max(this.maxX,this.x),this.minY=Math.min(this.minY,this.y),this.maxY=Math.max(this.maxY,this.y)},rotate(t){this.alpha+=t*this.theta},pushStack(){this.stack.push({x:this.x,y:this.y,alpha:this.alpha})},popStack(){({x:this.x,y:this.y,alpha:this.alpha}=this.stack.pop())},getDrawingRect(){let t=Math.floor(this.minX),e=Math.floor(this.minY),a=Math.ceil(this.maxX),i=Math.ceil(this.maxY);return{minX:t,minY:e,maxX:a,maxY:i,width:a-t,height:i-e}}};function u(t,e){return`${+t.toFixed(4)} ${+e.toFixed(4)}`}function p(t){let e=function(t){let e=s(t);if(!0!==e)throw new h(e);let{axiom:a,iterations:i}={...c,...t},r={...o,...t.rules};for(;i>0;i--)a=[...a].reduce((t,e)=>t+(r[e]||""),"");return a}(t),a=function({x:t,y:e,step:a,alpha:i,theta:r}){let n=Object.create(l);return n.stack=[],n.x=n.minX=n.maxX=t,n.y=n.minY=n.maxY=e,n.step=a,n.alpha=-i,n.theta=r,n}({x:0,y:0,...t});return{pathData:function(t,e){let a;return[...t].reduce((t,i)=>{switch(i){case"F":e.translate(),t+=("L"===a?" ":"L")+u(e.x,e.y),a="L";break;case"B":e.translate(),"M"===a&&(t=t.slice(0,t.lastIndexOf("M"))),t+="M"+u(e.x,e.y),a="M";break;case"+":e.rotate(1);break;case"-":e.rotate(-1);break;case"[":e.pushStack();break;case"]":e.popStack(),t+=`M${u(e.x,e.y)}`,a="M"}return t},"M"+u(e.x,e.y))}(function(t){return t.replace(/[^FB[\]+-]/g,"")}(e),a),...a.getDrawingRect()}}t.getSVGCode=function(t,e){let{pathData:a,minX:i,minY:r,width:n,height:s}=p(t),h={width:e.width||n,height:e.height||s,padding:e.padding||0,pathAttributes:{fill:e.fill||"none",stroke:e.stroke||"#000",...e.pathAttributes}},{padding:o}=h,c=Object.entries(h.pathAttributes).reduce((t,[e,a])=>`${t} ${e}="${a=a.replace(/"/g,""")}"`,"");return`\n \n`},t.getSVGData=p,Object.defineProperty(t,"__esModule",{value:!0})})); diff --git a/package-lock.json b/package-lock.json index db29e41..165866c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "lindsvg", - "version": "1.1.0", + "version": "1.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index e9ec982..5f6d5bb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lindsvg", - "version": "1.1.0", + "version": "1.2.0", "description": "Lindenmayer System [Scalable] Vector Graphics", "main": "dist/lindsvg.js", "module": "dist/lindsvg.esm.js", diff --git a/src/lindsvg.mjs b/src/lindsvg.mjs index 619181d..b3e5d79 100644 --- a/src/lindsvg.mjs +++ b/src/lindsvg.mjs @@ -19,8 +19,8 @@ * @typedef {Object} SVGParams * @property {Number} [width] - Desired SVG width * @property {Number} [height] - Desired SVG height - * @property {String} [fill="none"] - Value of the “fill” attribute on the “path” element - * @property {String} [stroke="#000"] - Value of the “stroke” attribute on the “path” element + * @property {Number} [padding=0] - Additional space to extend the viewBox + * @property {Object} [pathAttributes={fill:"none",stroke:"#000"}] - Name to value map for the “path” element attributes */ diff --git a/src/svg.mjs b/src/svg.mjs index fdb539a..c067ab3 100644 --- a/src/svg.mjs +++ b/src/svg.mjs @@ -83,16 +83,23 @@ export function getSVGData(lsParams) { */ export function getSVGCode(lsParams, svgParams) { let {pathData, minX, minY, width, height} = getSVGData(lsParams); - svgParams = { - width, - height, - padding: 0, - fill: "none", - stroke: "#000", - ...svgParams + let svgConfig = { + width: svgParams.width || width, + height: svgParams.height || height, + padding: svgParams.padding || 0, + pathAttributes: { + // for backward compatibility with v1.1.0, also check fill and stroke as direct props of svgParams + fill: svgParams.fill || "none", + stroke: svgParams.stroke || "#000", + ...svgParams.pathAttributes + } }; - let {padding} = svgParams; - return ` - + let {padding} = svgConfig; + let pathAttrStr = Object.entries(svgConfig.pathAttributes).reduce((accumulator, [name, value]) => { + value = value.replace(/"/g, """); + return `${accumulator} ${name}="${value}"`; + }, ""); + return ` + `; } diff --git a/test/params.mjs b/test/params.mjs index a00aaab..389f24f 100644 --- a/test/params.mjs +++ b/test/params.mjs @@ -44,6 +44,9 @@ export let svgParams = { width: 600, height: 600, padding: 10, - // fill: "skyblue", - stroke: "green" + pathAttributes: { + // fill: "skyblue", + stroke: "green", + "stroke-width": "2px" + } };