You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

292 lines
7.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global.svgParser = {}));
}(this, (function (exports) { 'use strict';
function getLocator(source, options) {
if (options === void 0) { options = {}; }
var offsetLine = options.offsetLine || 0;
var offsetColumn = options.offsetColumn || 0;
var originalLines = source.split('\n');
var start = 0;
var lineRanges = originalLines.map(function (line, i) {
var end = start + line.length + 1;
var range = { start: start, end: end, line: i };
start = end;
return range;
});
var i = 0;
function rangeContains(range, index) {
return range.start <= index && index < range.end;
}
function getLocation(range, index) {
return { line: offsetLine + range.line, column: offsetColumn + index - range.start, character: index };
}
function locate(search, startIndex) {
if (typeof search === 'string') {
search = source.indexOf(search, startIndex || 0);
}
var range = lineRanges[i];
var d = search >= range.end ? 1 : -1;
while (range) {
if (rangeContains(range, search))
return getLocation(range, search);
i += d;
range = lineRanges[i];
}
}
return locate;
}
function locate(source, search, options) {
if (typeof options === 'number') {
throw new Error('locate takes a { startIndex, offsetLine, offsetColumn } object as the third argument');
}
return getLocator(source, options)(search, options && options.startIndex);
}
var validNameCharacters = /[a-zA-Z0-9:_-]/;
var whitespace = /[\s\t\r\n]/;
var quotemark = /['"]/;
function repeat(str, i) {
var result = '';
while (i--) { result += str; }
return result;
}
function parse(source) {
var header = '';
var stack = [];
var state = metadata;
var currentElement = null;
var root = null;
function error(message) {
var ref = locate(source, i);
var line = ref.line;
var column = ref.column;
var before = source.slice(0, i);
var beforeLine = /(^|\n).*$/.exec(before)[0].replace(/\t/g, ' ');
var after = source.slice(i);
var afterLine = /.*(\n|$)/.exec(after)[0];
var snippet = "" + beforeLine + afterLine + "\n" + (repeat(' ', beforeLine.length)) + "^";
throw new Error(
(message + " (" + line + ":" + column + "). If this is valid SVG, it's probably a bug in svg-parser. Please raise an issue at https://github.com/Rich-Harris/svg-parser/issues thanks!\n\n" + snippet)
);
}
function metadata() {
while ((i < source.length && source[i] !== '<') || !validNameCharacters.test(source[i + 1])) {
header += source[i++];
}
return neutral();
}
function neutral() {
var text = '';
while (i < source.length && source[i] !== '<') { text += source[i++]; }
if (/\S/.test(text)) {
currentElement.children.push({ type: 'text', value: text });
}
if (source[i] === '<') {
return tag;
}
return neutral;
}
function tag() {
var char = source[i];
if (char === '?') { return neutral; } // <?xml...
if (char === '!') {
if (source.slice(i + 1, i + 3) === '--') { return comment; }
if (source.slice(i + 1, i + 8) === '[CDATA[') { return cdata; }
if (/doctype/i.test(source.slice(i + 1, i + 8))) { return neutral; }
}
if (char === '/') { return closingTag; }
var tagName = getName();
var element = {
type: 'element',
tagName: tagName,
properties: {},
children: []
};
if (currentElement) {
currentElement.children.push(element);
} else {
root = element;
}
var attribute;
while (i < source.length && (attribute = getAttribute())) {
element.properties[attribute.name] = attribute.value;
}
var selfClosing = false;
if (source[i] === '/') {
i += 1;
selfClosing = true;
}
if (source[i] !== '>') {
error('Expected >');
}
if (!selfClosing) {
currentElement = element;
stack.push(element);
}
return neutral;
}
function comment() {
var index = source.indexOf('-->', i);
if (!~index) { error('expected -->'); }
i = index + 2;
return neutral;
}
function cdata() {
var index = source.indexOf(']]>', i);
if (!~index) { error('expected ]]>'); }
currentElement.children.push(source.slice(i + 7, index));
i = index + 2;
return neutral;
}
function closingTag() {
var tagName = getName();
if (!tagName) { error('Expected tag name'); }
if (tagName !== currentElement.tagName) {
error(("Expected closing tag </" + tagName + "> to match opening tag <" + (currentElement.tagName) + ">"));
}
allowSpaces();
if (source[i] !== '>') {
error('Expected >');
}
stack.pop();
currentElement = stack[stack.length - 1];
return neutral;
}
function getName() {
var name = '';
while (i < source.length && validNameCharacters.test(source[i])) { name += source[i++]; }
return name;
}
function getAttribute() {
if (!whitespace.test(source[i])) { return null; }
allowSpaces();
var name = getName();
if (!name) { return null; }
var value = true;
allowSpaces();
if (source[i] === '=') {
i += 1;
allowSpaces();
value = getAttributeValue();
if (!isNaN(value) && value.trim() !== '') { value = +value; } // TODO whitelist numeric attributes?
}
return { name: name, value: value };
}
function getAttributeValue() {
return quotemark.test(source[i]) ? getQuotedAttributeValue() : getUnquotedAttributeValue();
}
function getUnquotedAttributeValue() {
var value = '';
do {
var char = source[i];
if (char === ' ' || char === '>' || char === '/') {
return value;
}
value += char;
i += 1;
} while (i < source.length);
return value;
}
function getQuotedAttributeValue() {
var quotemark = source[i++];
var value = '';
var escaped = false;
while (i < source.length) {
var char = source[i++];
if (char === quotemark && !escaped) {
return value;
}
if (char === '\\' && !escaped) {
escaped = true;
}
value += escaped ? ("\\" + char) : char;
escaped = false;
}
}
function allowSpaces() {
while (i < source.length && whitespace.test(source[i])) { i += 1; }
}
var i = metadata.length;
while (i < source.length) {
if (!state) { error('Unexpected character'); }
state = state();
i += 1;
}
if (state !== neutral) {
error('Unexpected end of input');
}
if (root.tagName === 'svg') { root.metadata = header; }
return {
type: 'root',
children: [root]
};
}
exports.parse = parse;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=svg-parser.umd.js.map