diff --git a/js/format/Gpx.js b/js/format/Gpx.js index 79326af..dc0baf6 100644 --- a/js/format/Gpx.js +++ b/js/format/Gpx.js @@ -104,23 +104,45 @@ BR.Gpx = { const newline = '\n'; // Remove all the newlines and then remove all the spaces between tags - xml = xml.replace(/\s*(\r\n|\n|\r)\s*/gm, ' ').replace(/>\s+<'); - - // break into lines - const reg = /(>)(<)(\/?)/g; - let pad = 0; - + xml = xml.replace(/>\s*(\r\n|\n|\r)\s*<').replace(/>\s+<'); xml = xml.replace('', ''); - xml = xml.replace(reg, `$1${newline}$2$3`); - let lines = xml.split(newline); + // break into lines, keeping defined tags on a single line + const reg = /><(\/?)([\w!?][^ />]*)/g; + const singleLineTagList = ['trkpt', 'wpt']; + let lines = []; + let singleLineTag = null; + let startIndex = 0; + let match; + while ((match = reg.exec(xml)) !== null) { + const tag = match[2]; + if (singleLineTag) { + if (singleLineTag === tag) { + singleLineTag = null; + } + } else { + if (singleLineTagList.includes(tag)) { + singleLineTag = tag; + } + let endIndex = match.index + 1; + lines.push(xml.substring(startIndex, endIndex)); + startIndex = endIndex; + } + } + lines.push(xml.substring(startIndex)); + + // indent + const startTextEnd = /.+<\/\w[^>]*>$/; + const endTag = /^<\/\w/; + const startTag = /^<\w[^>]*[^\/]>.*$/; + let pad = 0; lines = lines.map((node, index) => { let indent = 0; - if (node.match(/.+<\/\w[^>]*>$/)) { + if (node.match(startTextEnd)) { indent = 0; - } else if (node.match(/^<\/\w/) && pad > 0) { + } else if (node.match(endTag) && pad > 0) { pad -= 1; - } else if (node.match(/^<\w[^>]*[^\/]>.*$/)) { + } else if (node.match(startTag)) { indent = 1; } else { indent = 0; @@ -131,10 +153,10 @@ BR.Gpx = { return PADDING.repeat(pad - indent) + node; }); + // break gpx attributes into separate lines for (const [i, line] of lines.entries()) { - // break gpx attributes into separate lines - if (line.includes('