[READ-ONLY] a fast, modern browser for the npm registry
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: allow all heading depths in readme and transform them (#1306)

authored by

Alex Savelyev and committed by
GitHub
299a877e d61b472e

+35 -12
+35 -12
server/utils/readme.ts
··· 97 97 return null 98 98 } 99 99 100 - // only allow h3-h6 since we shift README headings down by 2 levels 100 + // allow h1-h6, but replace h1-h2 later since we shift README headings down by 2 levels 101 101 // (page h1 = package name, h2 = "Readme" section, so README h1 → h3) 102 102 const ALLOWED_TAGS = [ 103 + 'h1', 104 + 'h2', 103 105 'h3', 104 106 'h4', 105 107 'h5', ··· 272 274 return { tagName, attribs } 273 275 } 274 276 277 + // README h1 always becomes h3 278 + // For deeper levels, ensure sequential order 279 + // Don't allow jumping more than 1 level deeper than previous 280 + function calculateSemanticDepth(depth: number, lastSemanticLevel: number) { 281 + if (depth === 1) return 3 282 + const maxAllowed = Math.min(lastSemanticLevel + 1, 6) 283 + return Math.min(depth + 2, maxAllowed) 284 + } 285 + 275 286 export async function renderReadmeHtml( 276 287 content: string, 277 288 packageName: string, ··· 301 312 // Calculate the target semantic level based on document structure 302 313 // Start at h3 (since page h1 + section h2 already exist) 303 314 // But ensure we never skip levels - can only go down by 1 or stay same/go up 304 - let semanticLevel: number 305 - if (depth === 1) { 306 - // README h1 always becomes h3 307 - semanticLevel = 3 308 - } else { 309 - // For deeper levels, ensure sequential order 310 - // Don't allow jumping more than 1 level deeper than previous 311 - const maxAllowed = Math.min(lastSemanticLevel + 1, 6) 312 - semanticLevel = Math.min(depth + 2, maxAllowed) 313 - } 314 - 315 + const semanticLevel = calculateSemanticDepth(depth, lastSemanticLevel) 315 316 lastSemanticLevel = semanticLevel 316 317 const text = this.parser.parseInline(tokens) 317 318 ··· 414 415 allowedSchemes: ['http', 'https', 'mailto'], 415 416 // Transform img src URLs (GitHub blob → raw, relative → GitHub raw) 416 417 transformTags: { 418 + h1: (_, attribs) => { 419 + return { tagName: 'h3', attribs: { ...attribs, 'data-level': '1' } } 420 + }, 421 + h2: (_, attribs) => { 422 + return { tagName: 'h4', attribs: { ...attribs, 'data-level': '2' } } 423 + }, 424 + h3: (_, attribs) => { 425 + if (attribs['data-level']) return { tagName: 'h3', attribs: attribs } 426 + return { tagName: 'h5', attribs: { ...attribs, 'data-level': '3' } } 427 + }, 428 + h4: (_, attribs) => { 429 + if (attribs['data-level']) return { tagName: 'h4', attribs: attribs } 430 + return { tagName: 'h6', attribs: { ...attribs, 'data-level': '4' } } 431 + }, 432 + h5: (_, attribs) => { 433 + if (attribs['data-level']) return { tagName: 'h5', attribs: attribs } 434 + return { tagName: 'h6', attribs: { ...attribs, 'data-level': '5' } } 435 + }, 436 + h6: (_, attribs) => { 437 + if (attribs['data-level']) return { tagName: 'h6', attribs: attribs } 438 + return { tagName: 'h6', attribs: { ...attribs, 'data-level': '6' } } 439 + }, 417 440 img: (tagName, attribs) => { 418 441 if (attribs.src) { 419 442 attribs.src = resolveImageUrl(attribs.src, packageName, repoInfo)