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 | 7x 36x 36x 13x 13x 13x 13x 13x 8x 8x 1x 7x 7x 7x 7x 7x 4x 14x 14x 14x 2x 12x 7x | /**
* RFCXML-safe anchors and display labels for Spec-Up-T terms.
* IETF XML IDs must be XML Names (US-ASCII letter start; letters, digits, _, -, .).
* Spec-Up-T HTML uses `term:slug`; RFCXML uses `term-slug` so the colon is not required.
*/
const { utils } = require('../../utils/regex-patterns');
function slugifyTerm(term) {
const normalized = String(term ?? '')
.trim()
.replace(/\s+/g, '-')
.toLowerCase();
return utils.sanitizeTermId(normalized)
.replaceAll(':', '-')
.replace(/[^A-Za-z0-9._-]/g, '-')
.replace(/-+/g, '-')
.replace(/^-|-$/g, '');
}
function termToAnchor(term) {
const slug = slugifyTerm(term);
const body = slug || 'term';
const prefixed = body.startsWith('term-') ? body : `term-${body}`;
Iif (!/^[A-Za-z]/.test(prefixed)) {
return `term-${prefixed}`;
}
return prefixed;
}
function displayTermLabel(term, aliases = []) {
const extras = (aliases || []).map(alias => String(alias).trim()).filter(Boolean);
if (extras.length === 0) {
return String(term).trim();
}
const primary = extras[0];
const rest = extras.slice(1);
const parenthetical = [...rest, String(term).trim()].filter(Boolean);
Iif (parenthetical.length === 0) {
return primary;
}
return `${primary} (${parenthetical.join(', ')})`;
}
function isXmlName(anchor) {
return /^[A-Za-z][A-Za-z0-9._-]*$/.test(String(anchor ?? ''));
}
function headingToAnchor(text) {
const slug = slugifyTerm(text);
const candidate = slug || 'section';
if (!/^[A-Za-z]/.test(candidate)) {
return `s-${candidate}`;
}
return candidate;
}
module.exports = {
slugifyTerm,
termToAnchor,
displayTermLabel,
isXmlName,
headingToAnchor
};
|