From a8a1800ae578be88027aa4ec7561ada4d055b888 Mon Sep 17 00:00:00 2001 From: Divyansh Singh <40380293+brc-dd@users.noreply.github.com> Date: Sat, 8 Mar 2025 21:35:06 +0530 Subject: [PATCH 1/3] fix: ignore non-text content in permalink generation and fix types of markdown.config --- src/node/markdown/markdown.ts | 46 +++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/src/node/markdown/markdown.ts b/src/node/markdown/markdown.ts index aca503e2..12de0d11 100644 --- a/src/node/markdown/markdown.ts +++ b/src/node/markdown/markdown.ts @@ -25,6 +25,7 @@ import attrsPlugin from 'markdown-it-attrs' import { full as emojiPlugin } from 'markdown-it-emoji' import type { BuiltinLanguage, BuiltinTheme, Highlighter } from 'shiki' import type { Logger } from 'vite' +import type { Awaitable } from '../shared' import { containerPlugin, type ContainerOptions } from './plugins/containers' import { gitHubAlertsPlugin } from './plugins/githubAlerts' import { highlight as createHighlighter } from './plugins/highlight' @@ -52,11 +53,11 @@ export interface MarkdownOptions extends Options { /** * Setup markdown-it instance before applying plugins */ - preConfig?: (md: MarkdownItAsync) => Awaited + preConfig?: (md: MarkdownItAsync) => Awaitable /** * Setup markdown-it instance */ - config?: (md: MarkdownItAsync) => Awaited + config?: (md: MarkdownItAsync) => Awaitable /** * Disable cache (experimental) */ @@ -268,22 +269,31 @@ export async function createMarkdownRenderer( .map((t) => t.content) .join('') }, - permalink: anchorPlugin.permalink.linkInsideHeader({ - symbol: '​', - renderAttrs: (slug, state) => { - // Find `heading_open` with the id identical to slug - const idx = state.tokens.findIndex((token) => { - const attrs = token.attrs - const id = attrs?.find((attr) => attr[0] === 'id') - return id && slug === id[1] - }) - // Get the actual heading content - const title = state.tokens[idx + 1].content - return { - 'aria-label': `Permalink to "${title}"` - } - } - }), + permalink: (slug, _, state, idx) => { + const title = + state.tokens[idx + 1]?.children + ?.filter((token) => ['text', 'code_inline'].includes(token.type)) + .reduce((acc, t) => acc + t.content, '') + .trim() || '' + + const linkTokens = [ + Object.assign(new state.Token('text', '', 0), { content: ' ' }), + Object.assign(new state.Token('link_open', 'a', 1), { + attrs: [ + ['class', 'header-anchor'], + ['href', `#${slug}`], + ['aria-label', `Permalink to “${title}”`] + ] + }), + Object.assign(new state.Token('html_inline', '', 0), { + content: '​', + meta: { isPermalinkSymbol: true } + }), + new state.Token('link_close', 'a', -1) + ] + + state.tokens[idx + 1].children?.push(...linkTokens) + }, ...options.anchor } as anchorPlugin.AnchorOptions).use(frontmatterPlugin, { ...options.frontmatter From aadc517c69fb239bdda99173bbc123ace567484b Mon Sep 17 00:00:00 2001 From: James ZHANG <1631685+TheNorthMemory@users.noreply.github.com> Date: Sun, 9 Mar 2025 02:28:48 +0800 Subject: [PATCH 2/3] fix: don't hardcode `tabindex` attr in table renderer (#4082) Co-authored-by: Divyansh Singh <40380293+brc-dd@users.noreply.github.com> --- src/node/markdown/markdown.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/node/markdown/markdown.ts b/src/node/markdown/markdown.ts index 12de0d11..fd6bf492 100644 --- a/src/node/markdown/markdown.ts +++ b/src/node/markdown/markdown.ts @@ -246,8 +246,13 @@ export async function createMarkdownRenderer( ) .use(lineNumberPlugin, options.lineNumbers) + const tableOpen = md.renderer.rules.table_open md.renderer.rules.table_open = function (tokens, idx, options, env, self) { - return '\n' + const token = tokens[idx] + if (token.attrIndex('tabindex') < 0) token.attrPush(['tabindex', '0']) + return tableOpen + ? tableOpen(tokens, idx, options, env, self) + : self.renderToken(tokens, idx, options) } if (options.gfmAlerts !== false) { From 8aad617446c03d39a65a0b21e9fce43bc484af1e Mon Sep 17 00:00:00 2001 From: James ZHANG <1631685+TheNorthMemory@users.noreply.github.com> Date: Sun, 9 Mar 2025 02:30:51 +0800 Subject: [PATCH 3/3] fix: properly merge classes in custom containers (#4128) --- src/node/markdown/plugins/containers.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/node/markdown/plugins/containers.ts b/src/node/markdown/plugins/containers.ts index 6b08fc3d..073fb38d 100644 --- a/src/node/markdown/plugins/containers.ts +++ b/src/node/markdown/plugins/containers.ts @@ -62,15 +62,16 @@ function createContainer( { render(tokens, idx, _options, env: MarkdownEnv & { references?: any }) { const token = tokens[idx] - const info = token.info.trim().slice(klass.length).trim() - const attrs = md.renderer.renderAttrs(token) if (token.nesting === 1) { + token.attrJoin('class', `${klass} custom-block`) + const attrs = md.renderer.renderAttrs(token) + const info = token.info.trim().slice(klass.length).trim() const title = md.renderInline(info || defaultTitle, { references: env.references }) if (klass === 'details') - return `
${title}\n` - return `

${title}

\n` + return `
${title}\n` + return `

${title}

\n` } else return klass === 'details' ? `
\n` : `
\n` } }