diff options
Diffstat (limited to 'node_modules/svgo/lib/parser.js')
| -rw-r--r-- | node_modules/svgo/lib/parser.js | 262 |
1 files changed, 0 insertions, 262 deletions
diff --git a/node_modules/svgo/lib/parser.js b/node_modules/svgo/lib/parser.js deleted file mode 100644 index 4637acf1..00000000 --- a/node_modules/svgo/lib/parser.js +++ /dev/null @@ -1,262 +0,0 @@ -'use strict'; - -/** - * @typedef {import('./types').XastNode} XastNode - * @typedef {import('./types').XastInstruction} XastInstruction - * @typedef {import('./types').XastDoctype} XastDoctype - * @typedef {import('./types').XastComment} XastComment - * @typedef {import('./types').XastRoot} XastRoot - * @typedef {import('./types').XastElement} XastElement - * @typedef {import('./types').XastCdata} XastCdata - * @typedef {import('./types').XastText} XastText - * @typedef {import('./types').XastParent} XastParent - * @typedef {import('./types').XastChild} XastChild - */ - -// @ts-ignore sax will be replaced with something else later -const SAX = require('@trysound/sax'); -const { textElems } = require('../plugins/_collections'); - -class SvgoParserError extends Error { - /** - * @param message {string} - * @param line {number} - * @param column {number} - * @param source {string} - * @param file {void | string} - */ - constructor(message, line, column, source, file) { - super(message); - this.name = 'SvgoParserError'; - this.message = `${file || '<input>'}:${line}:${column}: ${message}`; - this.reason = message; - this.line = line; - this.column = column; - this.source = source; - if (Error.captureStackTrace) { - Error.captureStackTrace(this, SvgoParserError); - } - } - toString() { - const lines = this.source.split(/\r?\n/); - const startLine = Math.max(this.line - 3, 0); - const endLine = Math.min(this.line + 2, lines.length); - const lineNumberWidth = String(endLine).length; - const startColumn = Math.max(this.column - 54, 0); - const endColumn = Math.max(this.column + 20, 80); - const code = lines - .slice(startLine, endLine) - .map((line, index) => { - const lineSlice = line.slice(startColumn, endColumn); - let ellipsisPrefix = ''; - let ellipsisSuffix = ''; - if (startColumn !== 0) { - ellipsisPrefix = startColumn > line.length - 1 ? ' ' : '…'; - } - if (endColumn < line.length - 1) { - ellipsisSuffix = '…'; - } - const number = startLine + 1 + index; - const gutter = ` ${number.toString().padStart(lineNumberWidth)} | `; - if (number === this.line) { - const gutterSpacing = gutter.replace(/[^|]/g, ' '); - const lineSpacing = ( - ellipsisPrefix + line.slice(startColumn, this.column - 1) - ).replace(/[^\t]/g, ' '); - const spacing = gutterSpacing + lineSpacing; - return `>${gutter}${ellipsisPrefix}${lineSlice}${ellipsisSuffix}\n ${spacing}^`; - } - return ` ${gutter}${ellipsisPrefix}${lineSlice}${ellipsisSuffix}`; - }) - .join('\n'); - return `${this.name}: ${this.message}\n\n${code}\n`; - } -} - -const entityDeclaration = /<!ENTITY\s+(\S+)\s+(?:'([^']+)'|"([^"]+)")\s*>/g; - -const config = { - strict: true, - trim: false, - normalize: false, - lowercase: true, - xmlns: true, - position: true, -}; - -/** - * Convert SVG (XML) string to SVG-as-JS object. - * - * @type {(data: string, from?: string) => XastRoot} - */ -const parseSvg = (data, from) => { - const sax = SAX.parser(config.strict, config); - /** - * @type {XastRoot} - */ - const root = { type: 'root', children: [] }; - /** - * @type {XastParent} - */ - let current = root; - /** - * @type {XastParent[]} - */ - const stack = [root]; - - /** - * @type {(node: XastChild) => void} - */ - const pushToContent = (node) => { - // TODO remove legacy parentNode in v4 - Object.defineProperty(node, 'parentNode', { - writable: true, - value: current, - }); - current.children.push(node); - }; - - /** - * @type {(doctype: string) => void} - */ - sax.ondoctype = (doctype) => { - /** - * @type {XastDoctype} - */ - const node = { - type: 'doctype', - // TODO parse doctype for name, public and system to match xast - name: 'svg', - data: { - doctype, - }, - }; - pushToContent(node); - const subsetStart = doctype.indexOf('['); - if (subsetStart >= 0) { - entityDeclaration.lastIndex = subsetStart; - let entityMatch = entityDeclaration.exec(data); - while (entityMatch != null) { - sax.ENTITIES[entityMatch[1]] = entityMatch[2] || entityMatch[3]; - entityMatch = entityDeclaration.exec(data); - } - } - }; - - /** - * @type {(data: { name: string, body: string }) => void} - */ - sax.onprocessinginstruction = (data) => { - /** - * @type {XastInstruction} - */ - const node = { - type: 'instruction', - name: data.name, - value: data.body, - }; - pushToContent(node); - }; - - /** - * @type {(comment: string) => void} - */ - sax.oncomment = (comment) => { - /** - * @type {XastComment} - */ - const node = { - type: 'comment', - value: comment.trim(), - }; - pushToContent(node); - }; - - /** - * @type {(cdata: string) => void} - */ - sax.oncdata = (cdata) => { - /** - * @type {XastCdata} - */ - const node = { - type: 'cdata', - value: cdata, - }; - pushToContent(node); - }; - - /** - * @type {(data: { name: string, attributes: Record<string, { value: string }>}) => void} - */ - sax.onopentag = (data) => { - /** - * @type {XastElement} - */ - let element = { - type: 'element', - name: data.name, - attributes: {}, - children: [], - }; - for (const [name, attr] of Object.entries(data.attributes)) { - element.attributes[name] = attr.value; - } - pushToContent(element); - current = element; - stack.push(element); - }; - - /** - * @type {(text: string) => void} - */ - sax.ontext = (text) => { - if (current.type === 'element') { - // prevent trimming of meaningful whitespace inside textual tags - if (textElems.has(current.name)) { - /** - * @type {XastText} - */ - const node = { - type: 'text', - value: text, - }; - pushToContent(node); - } else if (/\S/.test(text)) { - /** - * @type {XastText} - */ - const node = { - type: 'text', - value: text.trim(), - }; - pushToContent(node); - } - } - }; - - sax.onclosetag = () => { - stack.pop(); - current = stack[stack.length - 1]; - }; - - /** - * @type {(e: any) => void} - */ - sax.onerror = (e) => { - const error = new SvgoParserError( - e.reason, - e.line + 1, - e.column, - data, - from, - ); - if (e.message.indexOf('Unexpected end') === -1) { - throw error; - } - }; - - sax.write(data).close(); - return root; -}; -exports.parseSvg = parseSvg; |
