123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- (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
|