@@ -25,6 +25,7 @@ import attrsPlugin from 'markdown-it-attrs'
2525import { full as emojiPlugin } from 'markdown-it-emoji'
2626import type { BuiltinLanguage , BuiltinTheme , Highlighter } from 'shiki'
2727import type { Logger } from 'vite'
28+ import type { Awaitable } from '../shared'
2829import { containerPlugin , type ContainerOptions } from './plugins/containers'
2930import { gitHubAlertsPlugin } from './plugins/githubAlerts'
3031import { highlight as createHighlighter } from './plugins/highlight'
@@ -52,11 +53,11 @@ export interface MarkdownOptions extends Options {
5253 /**
5354 * Setup markdown-it instance before applying plugins
5455 */
55- preConfig ?: ( md : MarkdownItAsync ) => Awaited < void >
56+ preConfig ?: ( md : MarkdownItAsync ) => Awaitable < void >
5657 /**
5758 * Setup markdown-it instance
5859 */
59- config ?: ( md : MarkdownItAsync ) => Awaited < void >
60+ config ?: ( md : MarkdownItAsync ) => Awaitable < void >
6061 /**
6162 * Disable cache (experimental)
6263 */
@@ -268,22 +269,31 @@ export async function createMarkdownRenderer(
268269 . map ( ( t ) => t . content )
269270 . join ( '' )
270271 } ,
271- permalink : anchorPlugin . permalink . linkInsideHeader ( {
272- symbol : '​' ,
273- renderAttrs : ( slug , state ) => {
274- // Find `heading_open` with the id identical to slug
275- const idx = state . tokens . findIndex ( ( token ) => {
276- const attrs = token . attrs
277- const id = attrs ?. find ( ( attr ) => attr [ 0 ] === 'id' )
278- return id && slug === id [ 1 ]
279- } )
280- // Get the actual heading content
281- const title = state . tokens [ idx + 1 ] . content
282- return {
283- 'aria-label' : `Permalink to "${ title } "`
284- }
285- }
286- } ) ,
272+ permalink : ( slug , _ , state , idx ) => {
273+ const title =
274+ state . tokens [ idx + 1 ] ?. children
275+ ?. filter ( ( token ) => [ 'text' , 'code_inline' ] . includes ( token . type ) )
276+ . reduce ( ( acc , t ) => acc + t . content , '' )
277+ . trim ( ) || ''
278+
279+ const linkTokens = [
280+ Object . assign ( new state . Token ( 'text' , '' , 0 ) , { content : ' ' } ) ,
281+ Object . assign ( new state . Token ( 'link_open' , 'a' , 1 ) , {
282+ attrs : [
283+ [ 'class' , 'header-anchor' ] ,
284+ [ 'href' , `#${ slug } ` ] ,
285+ [ 'aria-label' , `Permalink to “${ title } ”` ]
286+ ]
287+ } ) ,
288+ Object . assign ( new state . Token ( 'html_inline' , '' , 0 ) , {
289+ content : '​' ,
290+ meta : { isPermalinkSymbol : true }
291+ } ) ,
292+ new state . Token ( 'link_close' , 'a' , - 1 )
293+ ]
294+
295+ state . tokens [ idx + 1 ] . children ?. push ( ...linkTokens )
296+ } ,
287297 ...options . anchor
288298 } as anchorPlugin . AnchorOptions ) . use ( frontmatterPlugin , {
289299 ...options . frontmatter
0 commit comments