summaryrefslogtreecommitdiff
path: root/node_modules/svgo/lib/stringifier.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/svgo/lib/stringifier.js')
-rw-r--r--node_modules/svgo/lib/stringifier.js295
1 files changed, 0 insertions, 295 deletions
diff --git a/node_modules/svgo/lib/stringifier.js b/node_modules/svgo/lib/stringifier.js
deleted file mode 100644
index 1a710869..00000000
--- a/node_modules/svgo/lib/stringifier.js
+++ /dev/null
@@ -1,295 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import('./types').XastParent} XastParent
- * @typedef {import('./types').XastRoot} XastRoot
- * @typedef {import('./types').XastElement} XastElement
- * @typedef {import('./types').XastInstruction} XastInstruction
- * @typedef {import('./types').XastDoctype} XastDoctype
- * @typedef {import('./types').XastText} XastText
- * @typedef {import('./types').XastCdata} XastCdata
- * @typedef {import('./types').XastComment} XastComment
- * @typedef {import('./types').StringifyOptions} StringifyOptions
- */
-
-const { textElems } = require('../plugins/_collections');
-
-/**
- * @typedef {{
- * indent: string,
- * textContext: ?XastElement,
- * indentLevel: number,
- * }} State
- */
-
-/**
- * @typedef {Required<StringifyOptions>} Options
- */
-
-/**
- * @type {(char: string) => string}
- */
-const encodeEntity = (char) => {
- return entities[char];
-};
-
-/** @type {Options} */
-const defaults = {
- doctypeStart: '<!DOCTYPE',
- doctypeEnd: '>',
- procInstStart: '<?',
- procInstEnd: '?>',
- tagOpenStart: '<',
- tagOpenEnd: '>',
- tagCloseStart: '</',
- tagCloseEnd: '>',
- tagShortStart: '<',
- tagShortEnd: '/>',
- attrStart: '="',
- attrEnd: '"',
- commentStart: '<!--',
- commentEnd: '-->',
- cdataStart: '<![CDATA[',
- cdataEnd: ']]>',
- textStart: '',
- textEnd: '',
- indent: 4,
- regEntities: /[&'"<>]/g,
- regValEntities: /[&"<>]/g,
- encodeEntity,
- pretty: false,
- useShortTags: true,
- eol: 'lf',
- finalNewline: false,
-};
-
-/** @type {Record<string, string>} */
-const entities = {
- '&': '&amp;',
- "'": '&apos;',
- '"': '&quot;',
- '>': '&gt;',
- '<': '&lt;',
-};
-
-/**
- * convert XAST to SVG string
- *
- * @type {(data: XastRoot, config: StringifyOptions) => string}
- */
-const stringifySvg = (data, userOptions = {}) => {
- /**
- * @type {Options}
- */
- const config = { ...defaults, ...userOptions };
- const indent = config.indent;
- let newIndent = ' ';
- if (typeof indent === 'number' && Number.isNaN(indent) === false) {
- newIndent = indent < 0 ? '\t' : ' '.repeat(indent);
- } else if (typeof indent === 'string') {
- newIndent = indent;
- }
- /**
- * @type {State}
- */
- const state = {
- indent: newIndent,
- textContext: null,
- indentLevel: 0,
- };
- const eol = config.eol === 'crlf' ? '\r\n' : '\n';
- if (config.pretty) {
- config.doctypeEnd += eol;
- config.procInstEnd += eol;
- config.commentEnd += eol;
- config.cdataEnd += eol;
- config.tagShortEnd += eol;
- config.tagOpenEnd += eol;
- config.tagCloseEnd += eol;
- config.textEnd += eol;
- }
- let svg = stringifyNode(data, config, state);
- if (config.finalNewline && svg.length > 0 && !svg.endsWith('\n')) {
- svg += eol;
- }
- return svg;
-};
-exports.stringifySvg = stringifySvg;
-
-/**
- * @type {(node: XastParent, config: Options, state: State) => string}
- */
-const stringifyNode = (data, config, state) => {
- let svg = '';
- state.indentLevel += 1;
- for (const item of data.children) {
- if (item.type === 'element') {
- svg += stringifyElement(item, config, state);
- }
- if (item.type === 'text') {
- svg += stringifyText(item, config, state);
- }
- if (item.type === 'doctype') {
- svg += stringifyDoctype(item, config);
- }
- if (item.type === 'instruction') {
- svg += stringifyInstruction(item, config);
- }
- if (item.type === 'comment') {
- svg += stringifyComment(item, config);
- }
- if (item.type === 'cdata') {
- svg += stringifyCdata(item, config, state);
- }
- }
- state.indentLevel -= 1;
- return svg;
-};
-
-/**
- * create indent string in accordance with the current node level.
- *
- * @type {(config: Options, state: State) => string}
- */
-const createIndent = (config, state) => {
- let indent = '';
- if (config.pretty && state.textContext == null) {
- indent = state.indent.repeat(state.indentLevel - 1);
- }
- return indent;
-};
-
-/**
- * @type {(node: XastDoctype, config: Options) => string}
- */
-const stringifyDoctype = (node, config) => {
- return config.doctypeStart + node.data.doctype + config.doctypeEnd;
-};
-
-/**
- * @type {(node: XastInstruction, config: Options) => string}
- */
-const stringifyInstruction = (node, config) => {
- return (
- config.procInstStart + node.name + ' ' + node.value + config.procInstEnd
- );
-};
-
-/**
- * @type {(node: XastComment, config: Options) => string}
- */
-const stringifyComment = (node, config) => {
- return config.commentStart + node.value + config.commentEnd;
-};
-
-/**
- * @type {(node: XastCdata, config: Options, state: State) => string}
- */
-const stringifyCdata = (node, config, state) => {
- return (
- createIndent(config, state) +
- config.cdataStart +
- node.value +
- config.cdataEnd
- );
-};
-
-/**
- * @type {(node: XastElement, config: Options, state: State) => string}
- */
-const stringifyElement = (node, config, state) => {
- // empty element and short tag
- if (node.children.length === 0) {
- if (config.useShortTags) {
- return (
- createIndent(config, state) +
- config.tagShortStart +
- node.name +
- stringifyAttributes(node, config) +
- config.tagShortEnd
- );
- } else {
- return (
- createIndent(config, state) +
- config.tagShortStart +
- node.name +
- stringifyAttributes(node, config) +
- config.tagOpenEnd +
- config.tagCloseStart +
- node.name +
- config.tagCloseEnd
- );
- }
- // non-empty element
- } else {
- let tagOpenStart = config.tagOpenStart;
- let tagOpenEnd = config.tagOpenEnd;
- let tagCloseStart = config.tagCloseStart;
- let tagCloseEnd = config.tagCloseEnd;
- let openIndent = createIndent(config, state);
- let closeIndent = createIndent(config, state);
-
- if (state.textContext) {
- tagOpenStart = defaults.tagOpenStart;
- tagOpenEnd = defaults.tagOpenEnd;
- tagCloseStart = defaults.tagCloseStart;
- tagCloseEnd = defaults.tagCloseEnd;
- openIndent = '';
- } else if (textElems.has(node.name)) {
- tagOpenEnd = defaults.tagOpenEnd;
- tagCloseStart = defaults.tagCloseStart;
- closeIndent = '';
- state.textContext = node;
- }
-
- const children = stringifyNode(node, config, state);
-
- if (state.textContext === node) {
- state.textContext = null;
- }
-
- return (
- openIndent +
- tagOpenStart +
- node.name +
- stringifyAttributes(node, config) +
- tagOpenEnd +
- children +
- closeIndent +
- tagCloseStart +
- node.name +
- tagCloseEnd
- );
- }
-};
-
-/**
- * @type {(node: XastElement, config: Options) => string}
- */
-const stringifyAttributes = (node, config) => {
- let attrs = '';
- for (const [name, value] of Object.entries(node.attributes)) {
- // TODO remove attributes without values support in v3
- if (value !== undefined) {
- const encodedValue = value
- .toString()
- .replace(config.regValEntities, config.encodeEntity);
- attrs += ' ' + name + config.attrStart + encodedValue + config.attrEnd;
- } else {
- attrs += ' ' + name;
- }
- }
- return attrs;
-};
-
-/**
- * @type {(node: XastText, config: Options, state: State) => string}
- */
-const stringifyText = (node, config, state) => {
- return (
- createIndent(config, state) +
- config.textStart +
- node.value.replace(config.regEntities, config.encodeEntity) +
- (state.textContext ? '' : config.textEnd)
- );
-};