From 85ede55fdb0623cf2b8003165602d81ead38b860 Mon Sep 17 00:00:00 2001 From: Divyansh Singh <40380293+brc-dd@users.noreply.github.com> Date: Fri, 24 Jul 2026 01:01:12 +0530 Subject: [PATCH] test(markdown): cover attrs/anchor plugin order independence attrs registers its core rule at a fixed position (before linkify) while anchor pushes to the end of the chain, so user-defined ids from curly attributes win regardless of registration order. Remove the comment that claimed the order matters. Co-Authored-By: Claude Fable 5 --- __tests__/unit/node/markdown/markdown.test.ts | 19 +++++++++++++++++++ src/node/markdown/markdown.ts | 2 -- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/__tests__/unit/node/markdown/markdown.test.ts b/__tests__/unit/node/markdown/markdown.test.ts index c042d6ba..0c8e554d 100644 --- a/__tests__/unit/node/markdown/markdown.test.ts +++ b/__tests__/unit/node/markdown/markdown.test.ts @@ -1,3 +1,6 @@ +import { anchor as anchorPlugin } from '@mdit/plugin-anchor' +import attrsPlugin from 'markdown-it-attrs' +import { MarkdownItAsync } from 'markdown-it-async' import { createMarkdownRenderer, disposeMdItInstance, @@ -110,4 +113,20 @@ describe('node/markdown/markdown', () => { ) }) }) + + // attrs applies at a fixed position in the core chain (before linkify), + // while anchor pushes to its end, so anchor always sees user-defined ids + // no matter which plugin is registered first + test('anchor respects ids from attrs regardless of plugin order', async () => { + for (const plugins of [ + [attrsPlugin, anchorPlugin], + [anchorPlugin, attrsPlugin] + ] as const) { + const md = new MarkdownItAsync() + for (const plugin of plugins) md.use(plugin) + expect(await md.renderAsync('## Title {#custom-id}')).toContain( + 'id="custom-id"' + ) + } + }) }) diff --git a/src/node/markdown/markdown.ts b/src/node/markdown/markdown.ts index ecab0bc9..8cb826d1 100644 --- a/src/node/markdown/markdown.ts +++ b/src/node/markdown/markdown.ts @@ -361,8 +361,6 @@ export async function createMarkdownRenderer( mditCjkFriendly(md) } if (options.anchor !== false) { - // must be applied after attrs so that user-defined ids from curly - // attributes take precedence over slugified ones anchorPlugin(md, { slugify, getTokensText: (tokens) => {