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 | 5x 5x 15x 5x 7x 5x 5x 9x 5x 8x 8x 8x 8x 8x 29x 29x 29x 23x 23x 13x 13x 13x 13x 13x 16x 16x 2x 2x 2x 14x 5x | const DEBUG_FETCH = process.env.DEBUG_FETCH === '1' || process.env.DEBUG_FETCH === 'true';
const PREFIX_RE = /^[•\-.\s📁📚🏗️🎯🚀]*\s*/i;
function isIndexLabel(label) {
return /^Index\b/i.test((label || '').replace(PREFIX_RE, '').trim());
}
function scanArchParagraph(nn, ctx) {
for (const ch of (nn.children || [])) {
if (ch.type !== 'link' || !ch.url) continue;
const label = (ch.children || []).map(c => c.value || '').join('').trim();
Iif (!isIndexLabel(label)) continue;
const desc = (nn.children || []).filter(c => c.type === 'text').map(c => c.value).join(' ').trim();
return { title: label || 'Architecture Overview', link: ctx.toRawGithub(ch.url), description: ctx.strip(desc) };
}
return null;
}
function scanArchList(nn, ctx) {
for (const li of (nn.children || [])) {
const flat = ctx.parseReadme.flattenNodeText(li || '').replace(/\r?\n/g, ' ');
for (const m of flat.matchAll(/\[([^\]]+)\]\(([^)]+)\)/ig)) {
Eif (isIndexLabel((m[1] || '').trim())) {
return { title: (m[1] || '').trim() || 'Architecture Overview', link: ctx.toRawGithub((m[2] || '').trim()), description: '' };
}
}
}
return null;
}
/**
* Finds a link labelled "Index" under an "Architecture Overview" heading in the README.
* "Index" is the canonical label used for architecture HTML docs in this project's READMEs.
* Falls back to a raw-text scan when the AST contains no matching heading.
*
* @param {object} ast - Parsed README AST
* @param {string} readmeText - Raw README string (fallback)
* @param {object} ctx - Shared context: { toRawGithub, parseReadme, strip }
* @returns {{ title: string, link: string, description: string }|null}
*/
function extractArchitectureOverview(ast, readmeText, ctx) {
try {
Eif (ast && Array.isArray(ast.children)) {
for (let i = 0; i < ast.children.length; i++) {
const n = ast.children[i];
if (n.type !== 'heading' || !/architecture overview/i.test((n.children || []).map(c => c.value || '').join(''))) continue;
let j = i + 1;
while (j < ast.children.length && ast.children[j].type !== 'heading') {
const nn = ast.children[j];
const found = nn.type === 'paragraph' ? scanArchParagraph(nn, ctx) : nn.type === 'list' ? scanArchList(nn, ctx) : null;
Eif (found) return found;
j++;
}
}
}
const idx = readmeText.search(/^\s*#{1,6}\s*.*architecture overview.*$/im);
if (idx !== -1) {
for (const m of readmeText.slice(idx).matchAll(/\[([^\]]+)\]\(([^)]+)\)/ig)) {
Eif (isIndexLabel((m[1] || '').trim())) {
return { title: (m[1] || '').trim(), link: ctx.toRawGithub((m[2] || '').trim()), description: '' };
}
}
}
} catch (e) { if (DEBUG_FETCH) console.log('extractArchitectureOverview error', e && e.message); }
return null;
}
module.exports = { extractArchitectureOverview };
|