xml-formatter
Advanced tools
Comparing version 2.1.3 to 2.2.0
@@ -245,36 +245,50 @@ require=(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ | ||
* @typedef {Object} XMLFormatterOptions | ||
* @property {string} [indentation=' '] The value used for indentation | ||
* @property {String} [indentation=' '] The value used for indentation | ||
* @property {function(node): boolean} [filter] Return false to exclude the node. | ||
* @property {boolean} [collapseContent=false] True to keep content in the same line as the element. Only works if element contains at least one text node | ||
* @property {string} [lineSeparator='\r\n'] The line separator to use | ||
* @property {string} [whiteSpaceAtEndOfSelfclosingTag=false] to either end ad self closing tag with `<tag/>` or `<tag />` | ||
* @property {Boolean} [collapseContent=false] True to keep content in the same line as the element. Only works if element contains at least one text node | ||
* @property {String} [lineSeparator='\r\n'] The line separator to use | ||
* @property {String} [whiteSpaceAtEndOfSelfclosingTag=false] to either end ad self closing tag with `<tag/>` or `<tag />` | ||
*/ | ||
/** | ||
* @typedef {Object} XMLFormatterState | ||
* @param {String} content | ||
* @param {Number} level | ||
* @param {XMLFormatterOptions} options | ||
*/ | ||
/** | ||
* | ||
* @param {*} output | ||
* @param {XMLFormatterState} state | ||
* @return {void} | ||
*/ | ||
function newLine(output) { | ||
output.content += output.options.lineSeparator; | ||
function newLine(state) { | ||
state.content += state.options.lineSeparator; | ||
let i; | ||
for (i = 0; i < output.level; i++) { | ||
output.content += output.options.indentation; | ||
for (i = 0; i < state.level; i++) { | ||
state.content += state.options.indentation; | ||
} | ||
} | ||
function appendContent(output, content) { | ||
output.content += content; | ||
/** | ||
* @param {XMLFormatterState} state | ||
* @param {String} content | ||
* @return {void} | ||
*/ | ||
function appendContent(state, content) { | ||
state.content += content; | ||
} | ||
/** | ||
* @param {XMLFormatterOptions} options | ||
* @param {Object} node | ||
* @param {XMLFormatterState} state | ||
* @param {Boolean} preserveSpace | ||
* @return {void} | ||
*/ | ||
function processNode(node, output, preserveSpace, options) { | ||
function processNode(node, state, preserveSpace) { | ||
if (typeof node.content === 'string') { | ||
processContentNode(node, output, preserveSpace); | ||
processContentNode(node, state, preserveSpace); | ||
} else if (node.type === 'Element') { | ||
processElement(node, output, preserveSpace, options); | ||
processElementNode(node, state, preserveSpace); | ||
} else if (node.type === 'ProcessingInstruction') { | ||
processProcessingIntruction(node, output, preserveSpace); | ||
processProcessingIntruction(node, state, preserveSpace); | ||
} else { | ||
@@ -285,3 +299,9 @@ throw new Error('Unknown node type: ' + node.type); | ||
function processContentNode(node, output, preserveSpace) { | ||
/** | ||
* @param {Object} node | ||
* @param {XMLFormatterState} state | ||
* @param {Boolean} preserveSpace | ||
* @return {void} | ||
*/ | ||
function processContentNode(node, state, preserveSpace) { | ||
if (!preserveSpace) { | ||
@@ -291,6 +311,6 @@ node.content = node.content.trim(); | ||
if (node.content.length > 0) { | ||
if (!preserveSpace && output.content.length > 0) { | ||
newLine(output); | ||
if (!preserveSpace && state.content.length > 0) { | ||
newLine(state); | ||
} | ||
appendContent(output, node.content); | ||
appendContent(state, node.content); | ||
} | ||
@@ -300,28 +320,31 @@ } | ||
/** | ||
* @param {XMLFormatterOptions} options | ||
* @param {Object} node | ||
* @param {XMLFormatterState} state | ||
* @param {Boolean} preserveSpace | ||
* @return {void} | ||
*/ | ||
function processElement(node, output, preserveSpace, options) { | ||
if (!preserveSpace && output.content.length > 0) { | ||
newLine(output); | ||
function processElementNode(node, state, preserveSpace) { | ||
if (!preserveSpace && state.content.length > 0) { | ||
newLine(state); | ||
} | ||
appendContent(output, '<' + node.name); | ||
processAttributes(output, node.attributes); | ||
appendContent(state, '<' + node.name); | ||
processAttributes(state, node.attributes); | ||
if (node.children === null) { | ||
const selfClosingNodeClosingTag = options.whiteSpaceAtEndOfSelfclosingTag ? ' />' : '/>' | ||
const selfClosingNodeClosingTag = state.options.whiteSpaceAtEndOfSelfclosingTag ? ' />' : '/>' | ||
// self-closing node | ||
appendContent(output, selfClosingNodeClosingTag); | ||
appendContent(state, selfClosingNodeClosingTag); | ||
} else if (node.children.length === 0) { | ||
// empty node | ||
appendContent(output, '></' + node.name + '>'); | ||
appendContent(state, '></' + node.name + '>'); | ||
} else { | ||
appendContent(output, '>'); | ||
appendContent(state, '>'); | ||
output.level++; | ||
state.level++; | ||
let nodePreserveSpace = node.attributes['xml:space'] === 'preserve'; | ||
if (!nodePreserveSpace && output.options.collapseContent) { | ||
if (!nodePreserveSpace && state.options.collapseContent) { | ||
@@ -338,27 +361,37 @@ const containsTextNodes = node.children.some(function(child) { | ||
node.children.forEach(function(child) { | ||
processNode(child, output, preserveSpace || nodePreserveSpace, options); | ||
processNode(child, state, preserveSpace || nodePreserveSpace, state.options); | ||
}); | ||
output.level--; | ||
state.level--; | ||
if (!preserveSpace && !nodePreserveSpace) { | ||
newLine(output); | ||
newLine(state); | ||
} | ||
appendContent(output, '</' + node.name + '>'); | ||
appendContent(state, '</' + node.name + '>'); | ||
} | ||
} | ||
function processAttributes(output, attributes) { | ||
/** | ||
* @param {XMLFormatterState} state | ||
* @param {Record<String, String>} attributes | ||
* @return {void} | ||
*/ | ||
function processAttributes(state, attributes) { | ||
Object.keys(attributes).forEach(function(attr) { | ||
appendContent(output, ' ' + attr + '="' + attributes[attr] + '"'); | ||
appendContent(state, ' ' + attr + '="' + attributes[attr] + '"'); | ||
}); | ||
} | ||
function processProcessingIntruction(node, output) { | ||
if (output.content.length > 0) { | ||
newLine(output); | ||
/** | ||
* @param {Object} node | ||
* @param {XMLFormatterState} state | ||
* @return {void} | ||
*/ | ||
function processProcessingIntruction(node, state) { | ||
if (state.content.length > 0) { | ||
newLine(state); | ||
} | ||
appendContent(output, '<?' + node.name); | ||
processAttributes(output, node.attributes); | ||
appendContent(output, '?>'); | ||
appendContent(state, '<?' + node.name); | ||
processAttributes(state, node.attributes); | ||
appendContent(state, '?>'); | ||
} | ||
@@ -372,12 +405,5 @@ | ||
* @param {XMLFormatterOptions} options | ||
* @config {String} [indentation=' '] The value used for indentation | ||
* @config {function(node): boolean} [filter] Return false to exclude the node. | ||
* @config {Boolean} [collapseContent=false] True to keep content in the same line as the element. Only works if element contains at least one text node | ||
* @config {String} [lineSeparator='\r\n'] The line separator to use | ||
* @config {string} [whiteSpaceAtEndOfSelfclosingTag=false] to either end with `<tag/>` or `<tag />` | ||
* @returns {string} | ||
*/ | ||
function format(xml, options = {}) { | ||
options = options || {}; | ||
options.indentation = options.indentation || ' '; | ||
@@ -388,15 +414,15 @@ options.collapseContent = options.collapseContent === true; | ||
const parse = require('xml-parser-xo'); | ||
const parsedXml = parse(xml, {filter: options.filter}); | ||
const output = {content: '', level: 0, options: options}; | ||
const parser = require('xml-parser-xo'); | ||
const parsedXml = parser(xml, {filter: options.filter}); | ||
const state = {content: '', level: 0, options: options}; | ||
if (parsedXml.declaration) { | ||
processProcessingIntruction(parsedXml.declaration, output); | ||
processProcessingIntruction(parsedXml.declaration, state); | ||
} | ||
parsedXml.children.forEach(function(child) { | ||
processNode(child, output, false, options); | ||
processNode(child, state, false); | ||
}); | ||
return output.content; | ||
return state.content; | ||
} | ||
@@ -403,0 +429,0 @@ |
142
index.js
/** | ||
* @typedef {Object} XMLFormatterOptions | ||
* @property {string} [indentation=' '] The value used for indentation | ||
* @property {String} [indentation=' '] The value used for indentation | ||
* @property {function(node): boolean} [filter] Return false to exclude the node. | ||
* @property {boolean} [collapseContent=false] True to keep content in the same line as the element. Only works if element contains at least one text node | ||
* @property {string} [lineSeparator='\r\n'] The line separator to use | ||
* @property {string} [whiteSpaceAtEndOfSelfclosingTag=false] to either end ad self closing tag with `<tag/>` or `<tag />` | ||
* @property {Boolean} [collapseContent=false] True to keep content in the same line as the element. Only works if element contains at least one text node | ||
* @property {String} [lineSeparator='\r\n'] The line separator to use | ||
* @property {String} [whiteSpaceAtEndOfSelfclosingTag=false] to either end ad self closing tag with `<tag/>` or `<tag />` | ||
*/ | ||
/** | ||
* @typedef {Object} XMLFormatterState | ||
* @param {String} content | ||
* @param {Number} level | ||
* @param {XMLFormatterOptions} options | ||
*/ | ||
/** | ||
* | ||
* @param {*} output | ||
* @param {XMLFormatterState} state | ||
* @return {void} | ||
*/ | ||
function newLine(output) { | ||
output.content += output.options.lineSeparator; | ||
function newLine(state) { | ||
state.content += state.options.lineSeparator; | ||
let i; | ||
for (i = 0; i < output.level; i++) { | ||
output.content += output.options.indentation; | ||
for (i = 0; i < state.level; i++) { | ||
state.content += state.options.indentation; | ||
} | ||
} | ||
function appendContent(output, content) { | ||
output.content += content; | ||
/** | ||
* @param {XMLFormatterState} state | ||
* @param {String} content | ||
* @return {void} | ||
*/ | ||
function appendContent(state, content) { | ||
state.content += content; | ||
} | ||
/** | ||
* @param {XMLFormatterOptions} options | ||
* @param {Object} node | ||
* @param {XMLFormatterState} state | ||
* @param {Boolean} preserveSpace | ||
* @return {void} | ||
*/ | ||
function processNode(node, output, preserveSpace, options) { | ||
function processNode(node, state, preserveSpace) { | ||
if (typeof node.content === 'string') { | ||
processContentNode(node, output, preserveSpace); | ||
processContentNode(node, state, preserveSpace); | ||
} else if (node.type === 'Element') { | ||
processElement(node, output, preserveSpace, options); | ||
processElementNode(node, state, preserveSpace); | ||
} else if (node.type === 'ProcessingInstruction') { | ||
processProcessingIntruction(node, output, preserveSpace); | ||
processProcessingIntruction(node, state, preserveSpace); | ||
} else { | ||
@@ -42,3 +56,9 @@ throw new Error('Unknown node type: ' + node.type); | ||
function processContentNode(node, output, preserveSpace) { | ||
/** | ||
* @param {Object} node | ||
* @param {XMLFormatterState} state | ||
* @param {Boolean} preserveSpace | ||
* @return {void} | ||
*/ | ||
function processContentNode(node, state, preserveSpace) { | ||
if (!preserveSpace) { | ||
@@ -48,6 +68,6 @@ node.content = node.content.trim(); | ||
if (node.content.length > 0) { | ||
if (!preserveSpace && output.content.length > 0) { | ||
newLine(output); | ||
if (!preserveSpace && state.content.length > 0) { | ||
newLine(state); | ||
} | ||
appendContent(output, node.content); | ||
appendContent(state, node.content); | ||
} | ||
@@ -57,28 +77,31 @@ } | ||
/** | ||
* @param {XMLFormatterOptions} options | ||
* @param {Object} node | ||
* @param {XMLFormatterState} state | ||
* @param {Boolean} preserveSpace | ||
* @return {void} | ||
*/ | ||
function processElement(node, output, preserveSpace, options) { | ||
if (!preserveSpace && output.content.length > 0) { | ||
newLine(output); | ||
function processElementNode(node, state, preserveSpace) { | ||
if (!preserveSpace && state.content.length > 0) { | ||
newLine(state); | ||
} | ||
appendContent(output, '<' + node.name); | ||
processAttributes(output, node.attributes); | ||
appendContent(state, '<' + node.name); | ||
processAttributes(state, node.attributes); | ||
if (node.children === null) { | ||
const selfClosingNodeClosingTag = options.whiteSpaceAtEndOfSelfclosingTag ? ' />' : '/>' | ||
const selfClosingNodeClosingTag = state.options.whiteSpaceAtEndOfSelfclosingTag ? ' />' : '/>' | ||
// self-closing node | ||
appendContent(output, selfClosingNodeClosingTag); | ||
appendContent(state, selfClosingNodeClosingTag); | ||
} else if (node.children.length === 0) { | ||
// empty node | ||
appendContent(output, '></' + node.name + '>'); | ||
appendContent(state, '></' + node.name + '>'); | ||
} else { | ||
appendContent(output, '>'); | ||
appendContent(state, '>'); | ||
output.level++; | ||
state.level++; | ||
let nodePreserveSpace = node.attributes['xml:space'] === 'preserve'; | ||
if (!nodePreserveSpace && output.options.collapseContent) { | ||
if (!nodePreserveSpace && state.options.collapseContent) { | ||
@@ -95,27 +118,37 @@ const containsTextNodes = node.children.some(function(child) { | ||
node.children.forEach(function(child) { | ||
processNode(child, output, preserveSpace || nodePreserveSpace, options); | ||
processNode(child, state, preserveSpace || nodePreserveSpace, state.options); | ||
}); | ||
output.level--; | ||
state.level--; | ||
if (!preserveSpace && !nodePreserveSpace) { | ||
newLine(output); | ||
newLine(state); | ||
} | ||
appendContent(output, '</' + node.name + '>'); | ||
appendContent(state, '</' + node.name + '>'); | ||
} | ||
} | ||
function processAttributes(output, attributes) { | ||
/** | ||
* @param {XMLFormatterState} state | ||
* @param {Record<String, String>} attributes | ||
* @return {void} | ||
*/ | ||
function processAttributes(state, attributes) { | ||
Object.keys(attributes).forEach(function(attr) { | ||
appendContent(output, ' ' + attr + '="' + attributes[attr] + '"'); | ||
appendContent(state, ' ' + attr + '="' + attributes[attr] + '"'); | ||
}); | ||
} | ||
function processProcessingIntruction(node, output) { | ||
if (output.content.length > 0) { | ||
newLine(output); | ||
/** | ||
* @param {Object} node | ||
* @param {XMLFormatterState} state | ||
* @return {void} | ||
*/ | ||
function processProcessingIntruction(node, state) { | ||
if (state.content.length > 0) { | ||
newLine(state); | ||
} | ||
appendContent(output, '<?' + node.name); | ||
processAttributes(output, node.attributes); | ||
appendContent(output, '?>'); | ||
appendContent(state, '<?' + node.name); | ||
processAttributes(state, node.attributes); | ||
appendContent(state, '?>'); | ||
} | ||
@@ -129,12 +162,5 @@ | ||
* @param {XMLFormatterOptions} options | ||
* @config {String} [indentation=' '] The value used for indentation | ||
* @config {function(node): boolean} [filter] Return false to exclude the node. | ||
* @config {Boolean} [collapseContent=false] True to keep content in the same line as the element. Only works if element contains at least one text node | ||
* @config {String} [lineSeparator='\r\n'] The line separator to use | ||
* @config {string} [whiteSpaceAtEndOfSelfclosingTag=false] to either end with `<tag/>` or `<tag />` | ||
* @returns {string} | ||
*/ | ||
function format(xml, options = {}) { | ||
options = options || {}; | ||
options.indentation = options.indentation || ' '; | ||
@@ -145,15 +171,15 @@ options.collapseContent = options.collapseContent === true; | ||
const parse = require('xml-parser-xo'); | ||
const parsedXml = parse(xml, {filter: options.filter}); | ||
const output = {content: '', level: 0, options: options}; | ||
const parser = require('xml-parser-xo'); | ||
const parsedXml = parser(xml, {filter: options.filter}); | ||
const state = {content: '', level: 0, options: options}; | ||
if (parsedXml.declaration) { | ||
processProcessingIntruction(parsedXml.declaration, output); | ||
processProcessingIntruction(parsedXml.declaration, state); | ||
} | ||
parsedXml.children.forEach(function(child) { | ||
processNode(child, output, false, options); | ||
processNode(child, state, false); | ||
}); | ||
return output.content; | ||
return state.content; | ||
} | ||
@@ -160,0 +186,0 @@ |
{ | ||
"name": "xml-formatter", | ||
"version": "2.1.3", | ||
"version": "2.2.0", | ||
"repository": "github:chrisbottin/xml-formatter", | ||
@@ -34,3 +34,3 @@ "bugs": { | ||
"dependencies": { | ||
"xml-parser-xo": "^3.0.0" | ||
"xml-parser-xo": "^3.1.0" | ||
}, | ||
@@ -37,0 +37,0 @@ "devDependencies": { |
@@ -24,3 +24,3 @@ | ||
var format = require('xml-formatter'); | ||
var xml = '<root>content><p xml:space="preserve">This is <b>some</b> content.</content></p>'; | ||
var xml = '<root><content><p xml:space="preserve">This is <b>some</b> content.</content></p>'; | ||
@@ -27,0 +27,0 @@ var formattedXml = format(xml); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
526
21286
6
Updatedxml-parser-xo@^3.1.0