Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | 7x 212x 211x 84x 152x 152x 86x 84x 1x 83x 55x 55x 319x 151x 151x 151x 12x 139x 139x 3x 136x 82x 54x 7x | /**
* Minimal RFCXML helpers: escaping, attribute formatting, and element assembly.
*/
const ESCAPED_TAG_PLACEHOLDER = '__SPEC_UP_ESCAPED_TAG__';
function restoreEscapes(text) {
return String(text ?? '').replaceAll(ESCAPED_TAG_PLACEHOLDER, '[[');
}
function escapeXml(text) {
return restoreEscapes(text)
.replaceAll('&', '&')
.replaceAll('<', '<')
.replaceAll('>', '>');
}
function escapeAttr(text) {
return escapeXml(text).replaceAll('"', '"').replaceAll("'", ''');
}
function formatAttrs(attrs) {
Iif (!attrs) {
return '';
}
return Object.entries(attrs)
.filter(([, value]) => value !== undefined && value !== null && value !== false)
.map(([key, value]) => {
if (value === true) {
return ` ${key}="true"`;
}
return ` ${key}="${escapeAttr(String(value))}"`;
})
.join('');
}
function indentBlock(text, level) {
const pad = ' '.repeat(level);
return String(text)
.split('\n')
.map(line => (line.length ? pad + line : line))
.join('\n');
}
/**
* Build an XML element. `content` may be a string, an array of strings, or omitted (empty element).
*/
function el(name, attrs, content) {
const attrStr = formatAttrs(typeof attrs === 'object' && !Array.isArray(attrs) ? attrs : {});
const body = arguments.length === 2 && (typeof attrs === 'string' || Array.isArray(attrs))
? attrs
: content;
if (body === undefined || body === null || body === '') {
return `<${name}${attrStr}/>`;
}
const inner = Array.isArray(body) ? body.filter(part => part != null && part !== '').join('\n') : String(body);
if (name === 'sourcecode' || name === 'artwork') {
return `<${name}${attrStr}>\n${inner}\n</${name}>`;
}
if (!inner.includes('\n')) {
return `<${name}${attrStr}>${inner}</${name}>`;
}
return `<${name}${attrStr}>\n${indentBlock(inner, 1)}\n</${name}>`;
}
module.exports = {
ESCAPED_TAG_PLACEHOLDER,
restoreEscapes,
escapeXml,
escapeAttr,
formatAttrs,
indentBlock,
el
};
|