import attributes from "./attributes"; import * as hooklib from "hooks"; import hooks from "./hooks"; import { version } from "../package.json"; function svg(pattern) { this.openGroups = []; this.freeId = 0; this.body = ""; this.style = ""; this.script = ""; this.header = ""; this.footer = ""; this.defs = ""; this.pattern = pattern; // Needed to expose pattern to hooks this.prefix = ''; this.attributes = new attributes(); this.attributes.add("xmlns", "http://www.w3.org/2000/svg"); this.attributes.add("xmlns:svg", "http://www.w3.org/2000/svg"); this.attributes.add("xmlns:xlink", "http://www.w3.org/1999/xlink"); this.attributes.add( "xmlns:freesewing", "http://freesewing.org/namespaces/freesewing" ); this.attributes.add("freesewing", version); this.hooks = hooks.all; for (let k in hooklib) this[k] = hooklib[k]; for (let k in this.hooks) this.hook(k, this[k]); } /** Method to attach preRenderSvg hooks on */ svg.prototype.preRenderSvg = function() {}; /** Method to attach postRenderSvg hooks on */ svg.prototype.postRenderSvg = function() {}; /** Method to attach insertText hooks on */ svg.prototype.insertText = function() {}; /** Renders a draft object as SVG */ svg.prototype.render = function(pattern) { this.preRenderSvg(); this.svg = this.prefix; this.svg += this.renderComments(this.header); this.svg += this.renderSvgTag(pattern); this.svg += this.renderStyle(); this.svg += this.renderScript(); this.svg += this.renderDefs(); this.svg += this.openGroup("draftContainer"); for (let partId in pattern.parts) { let part = pattern.parts[partId]; if (part.render) { this.svg += this.openGroup(part.id, part.attributes); this.svg += this.renderPart(part); this.svg += this.closeGroup(); } } this.svg += this.closeGroup(); this.svg += this.nl() + ""; this.svg += this.renderComments(this.footer); this.postRenderSvg(); return this.svg; }; /** Returns SVG code for the opening SVG tag */ svg.prototype.renderSvgTag = function(pattern) { let svg = "" + this.nl(); return svg; }; /** Returns SVG code for the style block */ svg.prototype.renderStyle = function() { let svg = '" + this.nl(); return svg; }; /** Returns SVG code for the script block */ svg.prototype.renderScript = function() { let svg = '" + this.nl(); return svg; }; /** Returns SVG code for the defs block */ svg.prototype.renderDefs = function() { let svg = ''; this.indent(); svg += this.nl() + this.defs; this.outdent(); svg += this.nl() + "" + this.nl(); return svg; }; /** Returns SVG code for a comment block */ svg.prototype.renderComments = function(comments) { return ( this.nl() + this.nl() + "" ); }; /** Returns SVG code for a Part object */ svg.prototype.renderPart = function(part) { let svg = ""; for (let key in part.paths) { let path = part.paths[key]; if (path.render) svg += this.renderPath(path); } for (let key in part.points) { if (part.points[key].attributes.get("data-text")) { svg += this.renderPoint(part.points[key]); } } for (let key in part.snippets) { let snippet = part.snippets[key]; svg += this.renderSnippet(snippet); } return svg; }; /** Returns SVG code for a Point object */ svg.prototype.renderPoint = function(point) { let svg = ""; if (point.attributes.get("data-text")) svg += this.renderText(point); return svg; }; /** Returns SVG code for a Path object */ svg.prototype.renderPath = function(path) { if (!path.attributes.get("id")) path.attributes.add("id", this.getUid()); path.attributes.add("d", path.asPathstring()); return `${this.nl()}${this.renderPathText( path )}`; }; svg.prototype.renderPathText = function(path) { let text = path.attributes.get("data-text"); if (!text) return false; let attributes = path.attributes.renderIfPrefixIs("data-text-"); let svg = this.nl() + ""; this.indent(); svg += `${text}`; this.outdent(); svg += this.nl() + ""; return svg; }; svg.prototype.renderText = function(point) { let text = point.attributes.get("data-text"); if (!text) return false; point.attributes.add("data-text-x", point.x); point.attributes.add("data-text-y", point.y); let attributes = point.attributes.renderIfPrefixIs("data-text-"); let svg = `${this.nl()}`; this.indent(); svg += `${text}`; this.outdent(); svg += this.nl() + ""; return svg; }; /** Returns SVG code for a snippet */ svg.prototype.renderSnippet = function(snippet) { let svg = this.nl(); svg += ``; if (snippet.description) { svg += `${snippet.description}`; } svg += ""; return svg; }; /** Returns SVG code to open a group */ svg.prototype.openGroup = function(id) { let svg = this.nl() + this.nl(); svg += ``; svg += this.nl(); svg += ``; this.indent(); this.openGroups.push(id); return svg; }; /** Returns SVG code to close a group */ svg.prototype.closeGroup = function() { this.outdent(); return `${this.nl()}${this.nl()}`; }; /** Returns a linebreak + identation */ svg.prototype.nl = function() { return "\n" + this.tab(); }; /** Returns indentation */ svg.prototype.tab = function() { let space = ""; for (let i = 0; i < this.tabs; i++) { space += " "; } return space; }; /** Increases indentation by 1 */ svg.prototype.indent = function() { this.tabs += 1; }; /** Decreases indentation by 1 */ svg.prototype.outdent = function() { this.tabs -= 1; }; /** Returns an unused ID */ svg.prototype.getUid = function() { this.freeId += 1; return "" + this.freeId; }; export default svg;