(
depth: number,
displayHtml: string,
plainText: string,
slugSource: string,
preservedAttrs = '',
)
| 513 | |
| 514 | // Shared heading processing for both markdown and HTML headings |
| 515 | function processHeading( |
| 516 | depth: number, |
| 517 | displayHtml: string, |
| 518 | plainText: string, |
| 519 | slugSource: string, |
| 520 | preservedAttrs = '', |
| 521 | ) { |
| 522 | const semanticLevel = calculateSemanticDepth(depth, lastSemanticLevel) |
| 523 | lastSemanticLevel = semanticLevel |
| 524 | |
| 525 | let slug = slugify(slugSource) |
| 526 | if (!slug) slug = 'heading' |
| 527 | |
| 528 | const count = usedSlugs.get(slug) ?? 0 |
| 529 | usedSlugs.set(slug, count + 1) |
| 530 | const uniqueSlug = count === 0 ? slug : `${slug}-${count}` |
| 531 | const id = toUserContentId(uniqueSlug) |
| 532 | |
| 533 | if (plainText) { |
| 534 | toc.push({ text: plainText, id, depth }) |
| 535 | } |
| 536 | |
| 537 | // The browser doesn't support anchors within anchors and automatically extracts them from each other, |
| 538 | // causing a hydration error. To prevent this from happening in such cases, we use the anchor separately |
| 539 | if (htmlAnchorRe.test(displayHtml)) { |
| 540 | return `<h${semanticLevel} id="${id}" data-level="${depth}"${preservedAttrs}>${displayHtml}<a href="#${id}"></a></h${semanticLevel}>\n` |
| 541 | } |
| 542 | |
| 543 | return `<h${semanticLevel} id="${id}" data-level="${depth}"${preservedAttrs}><a href="#${id}">${displayHtml}</a></h${semanticLevel}>\n` |
| 544 | } |
| 545 | |
| 546 | const anchorTokenRegex = /^<a(?:\s.+)?\/?>$/ |
| 547 | renderer.heading = function ({ tokens, depth }: Tokens.Heading) { |
no test coverage detected