All files / src/pipeline/rfcxml term-anchor.js

92.3% Statements 24/26
66.66% Branches 14/21
100% Functions 6/6
92% Lines 23/25

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
};