From 18380b0eb78765f49d86918c86c9fee9e7197135 Mon Sep 17 00:00:00 2001 From: Divyansh Singh <40380293+brc-dd@users.noreply.github.com> Date: Fri, 24 Jul 2026 01:31:24 +0530 Subject: [PATCH] feat(markdown)!: replace markdown-it-attrs with @mdit/plugin-attrs The `fence` rule is disabled by default, replacing the patch we carried to stop curly attributes from consuming code block meta (line highlighting etc.). Drops both attrs patches and `@types/markdown-it-attrs`. BREAKING CHANGE: `markdown.attrs` options are now typed by `@mdit/plugin-attrs`: `leftDelimiter`, `rightDelimiter`, and `allowedAttributes` are renamed to `left`, `right`, and `allowed`. A `rule` option is available for toggling individual attribute rules (VitePress disables `fence` by default). Co-Authored-By: Claude Fable 5 --- __tests__/unit/node/config.test.ts | 4 +- __tests__/unit/node/markdown/markdown.test.ts | 2 +- .../unit/node/markdown/plugins/image.test.ts | 2 +- docs/en/guide/markdown.md | 2 +- docs/ja/guide/markdown.md | 2 +- docs/ru/guide/markdown.md | 2 +- package.json | 3 +- patches/@types__markdown-it-attrs@4.1.3.patch | 23 ------- patches/markdown-it-attrs@4.3.1.patch | 14 ----- pnpm-lock.yaml | 63 ++++++++++--------- pnpm-workspace.yaml | 2 - src/node/markdown/markdown.ts | 19 ++++-- 12 files changed, 57 insertions(+), 81 deletions(-) delete mode 100644 patches/@types__markdown-it-attrs@4.1.3.patch delete mode 100644 patches/markdown-it-attrs@4.3.1.patch diff --git a/__tests__/unit/node/config.test.ts b/__tests__/unit/node/config.test.ts index 4abb8ed6..df4af72c 100644 --- a/__tests__/unit/node/config.test.ts +++ b/__tests__/unit/node/config.test.ts @@ -21,7 +21,7 @@ describe('node/config', () => { { markdown: { attrs: { - allowedAttributes: ['id'] + allowed: ['id'] }, async preConfig() { calls.push('extended-pre') @@ -35,7 +35,7 @@ describe('node/config', () => { expect(merged.markdown?.lineNumbers).toBe(true) expect(merged.markdown?.attrs).toEqual({ - allowedAttributes: ['id'] + allowed: ['id'] }) await merged.markdown?.preConfig?.(md) diff --git a/__tests__/unit/node/markdown/markdown.test.ts b/__tests__/unit/node/markdown/markdown.test.ts index d46c5aad..bb9a5ca7 100644 --- a/__tests__/unit/node/markdown/markdown.test.ts +++ b/__tests__/unit/node/markdown/markdown.test.ts @@ -1,5 +1,5 @@ import { anchor as anchorPlugin } from '@mdit/plugin-anchor' -import attrsPlugin from 'markdown-it-attrs' +import { attrs as attrsPlugin } from '@mdit/plugin-attrs' import { MarkdownItAsync } from 'markdown-it-async' import { createMarkdownRenderer, diff --git a/__tests__/unit/node/markdown/plugins/image.test.ts b/__tests__/unit/node/markdown/plugins/image.test.ts index 1745819d..c6a346cc 100644 --- a/__tests__/unit/node/markdown/plugins/image.test.ts +++ b/__tests__/unit/node/markdown/plugins/image.test.ts @@ -1,6 +1,6 @@ import path from 'node:path' import { MarkdownItAsync } from 'markdown-it-async' -import attrsPlugin from 'markdown-it-attrs' +import { attrs as attrsPlugin } from '@mdit/plugin-attrs' import { imagePlugin, type Options } from 'node/markdown/plugins/image' const srcDir = path.resolve(import.meta.dirname, '../../../../e2e') diff --git a/docs/en/guide/markdown.md b/docs/en/guide/markdown.md index 38966226..5b863ce0 100644 --- a/docs/en/guide/markdown.md +++ b/docs/en/guide/markdown.md @@ -261,7 +261,7 @@ console.log('Hello, VitePress!') ### Additional Attributes -You can add additional attributes to the custom containers. We use [markdown-it-attrs](https://github.com/arve0/markdown-it-attrs) for this feature, and it is supported on almost all markdown elements. For example, you can set the `open` attribute to make the details block open by default: +You can add additional attributes to the custom containers. We use [@mdit/plugin-attrs](https://mdit-plugins.github.io/attrs.html) for this feature, and it is supported on almost all markdown elements. For example, you can set the `open` attribute to make the details block open by default: **Input** diff --git a/docs/ja/guide/markdown.md b/docs/ja/guide/markdown.md index 7feb36b2..8dbbfc0d 100644 --- a/docs/ja/guide/markdown.md +++ b/docs/ja/guide/markdown.md @@ -229,7 +229,7 @@ export default defineConfig({ ### 追加属性 {#additional-attributes} -カスタムコンテナには追加の属性を付与できます。この機能には [markdown-it-attrs](https://github.com/arve0/markdown-it-attrs) を使用しており、ほぼすべての Markdown 要素でサポートされます。たとえば `open` 属性を付けると、details ブロックをデフォルトで開いた状態にできます。 +カスタムコンテナには追加の属性を付与できます。この機能には [@mdit/plugin-attrs](https://mdit-plugins.github.io/attrs.html) を使用しており、ほぼすべての Markdown 要素でサポートされます。たとえば `open` 属性を付けると、details ブロックをデフォルトで開いた状態にできます。 **入力** diff --git a/docs/ru/guide/markdown.md b/docs/ru/guide/markdown.md index 9ad328d3..94803134 100644 --- a/docs/ru/guide/markdown.md +++ b/docs/ru/guide/markdown.md @@ -235,7 +235,7 @@ export default defineConfig({ ### Дополнительные атрибуты {#additional-attributes} -Вы можете добавить дополнительные атрибуты к пользовательским контейнерам. Мы используем [markdown-it-attrs](https://github.com/arve0/markdown-it-attrs) для этой функции, и она поддерживается почти для всех элементов Markdown. Например, можно установить атрибут `open`, чтобы сделать блок подробностей открытым по умолчанию: +Вы можете добавить дополнительные атрибуты к пользовательским контейнерам. Мы используем [@mdit/plugin-attrs](https://mdit-plugins.github.io/attrs.html) для этой функции, и она поддерживается почти для всех элементов Markdown. Например, можно установить атрибут `open`, чтобы сделать блок подробностей открытым по умолчанию: **Разметка** diff --git a/package.json b/package.json index 8f8839af..87facedb 100644 --- a/package.json +++ b/package.json @@ -130,6 +130,7 @@ "@mdit-vue/plugin-toc": "^3.0.2", "@mdit-vue/shared": "^3.0.2", "@mdit/plugin-anchor": "^1.1.1", + "@mdit/plugin-attrs": "^1.0.2", "@mdit/plugin-emoji": "^1.1.0", "@polka/compression": "^1.0.0-next.28", "@rollup/plugin-alias": "^6.0.0", @@ -140,7 +141,6 @@ "@types/cross-spawn": "^6.0.6", "@types/lodash.template": "^4.5.3", "@types/mark.js": "^8.11.12", - "@types/markdown-it-attrs": "^4.1.3", "@types/markdown-it-container": "^4.0.0", "@types/minimist": "^1.2.5", "@types/node": "^25.9.4", @@ -159,7 +159,6 @@ "lru-cache": "^11.5.1", "markdown-it": "^14.2.0", "markdown-it-async": "^2.2.0", - "markdown-it-attrs": "4.3.1", "markdown-it-cjk-friendly": "^2.0.2", "markdown-it-container": "^4.0.0", "markdown-it-mathjax3": "^4.3.2", diff --git a/patches/@types__markdown-it-attrs@4.1.3.patch b/patches/@types__markdown-it-attrs@4.1.3.patch deleted file mode 100644 index 4ea21c1d..00000000 --- a/patches/@types__markdown-it-attrs@4.1.3.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git a/index.d.ts b/index.d.ts -index 41d4a858c6ece5a61a2088733cf8b333b45603d8..2cb19bcd8fc76ae82ebe87af742916e17f49334b 100644 ---- a/index.d.ts -+++ b/index.d.ts -@@ -1,3 +1,15 @@ --import MarkdownIt = require("markdown-it"); --declare function attrs(md: MarkdownIt): void; --export = attrs; -+import type MarkdownIt from 'markdown-it' -+ -+export interface MarkdownItAttrsOptions { -+ /** left delimiter, default is `{`(left curly bracket) */ -+ leftDelimiter?: string -+ /** right delimiter, default is `}`(right curly bracket) */ -+ rightDelimiter?: string -+ /** rule of allowed attribute, empty means no limit */ -+ allowedAttributes?: (string | RegExp)[] -+} -+ -+export default function attrsPlugin( -+ md: MarkdownIt, -+ options?: MarkdownItAttrsOptions -+): void diff --git a/patches/markdown-it-attrs@4.3.1.patch b/patches/markdown-it-attrs@4.3.1.patch deleted file mode 100644 index 5a630c14..00000000 --- a/patches/markdown-it-attrs@4.3.1.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/patterns.js b/patterns.js -index e56a3b785df29e726194f2b30e86bb19a78ef902..e1f6211b92cbb2bbbe2a3c317dd9e5f1f41ab8d1 100644 ---- a/patterns.js -+++ b/patterns.js -@@ -28,7 +28,8 @@ module.exports = options => { - { - shift: 0, - block: true, -- info: utils.hasDelimiters('end', options) -+ info: utils.hasDelimiters('end', options), -+ markup: (str) => !/^[`~]{3,}$/.test(str) - } - ], - transform: (tokens, i) => { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6bd80091..0d3bb5dd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,15 +8,9 @@ overrides: ora>string-width: ^5 patchedDependencies: - '@types/markdown-it-attrs': - hash: ef05082c7886d283042ddf9103f1408fc36fd8665ef278c82b3da0659441dfb6 - path: patches/@types__markdown-it-attrs@4.1.3.patch '@types/mdurl@2.0.0': hash: 3460e7d18ce390685cf4b8d8237fb20df9ad952c1336f479995a508a6395bfa4 path: patches/@types__mdurl@2.0.0.patch - markdown-it-attrs@4.3.1: - hash: 12883b753541724964b5246a739df34c4b76db10415bbb63c35dce408cfe977e - path: patches/markdown-it-attrs@4.3.1.patch importers: @@ -116,6 +110,9 @@ importers: '@mdit/plugin-anchor': specifier: ^1.1.1 version: 1.1.1(markdown-it@14.2.0) + '@mdit/plugin-attrs': + specifier: ^1.0.2 + version: 1.0.2(markdown-it@14.2.0) '@mdit/plugin-emoji': specifier: ^1.1.0 version: 1.1.0(markdown-it@14.2.0) @@ -146,9 +143,6 @@ importers: '@types/mark.js': specifier: ^8.11.12 version: 8.11.12 - '@types/markdown-it-attrs': - specifier: ^4.1.3 - version: 4.1.3(patch_hash=ef05082c7886d283042ddf9103f1408fc36fd8665ef278c82b3da0659441dfb6) '@types/markdown-it-container': specifier: ^4.0.0 version: 4.0.0 @@ -203,9 +197,6 @@ importers: markdown-it-async: specifier: ^2.2.0 version: 2.2.0 - markdown-it-attrs: - specifier: 4.3.1 - version: 4.3.1(patch_hash=12883b753541724964b5246a739df34c4b76db10415bbb63c35dce408cfe977e)(markdown-it@14.2.0) markdown-it-cjk-friendly: specifier: ^2.0.2 version: 2.0.2(@types/markdown-it@14.1.2)(markdown-it@14.2.0) @@ -637,11 +628,29 @@ packages: resolution: {integrity: sha512-00aAZ0F0NLik6I6Yba2emGbHLxv+QYrPH00qQ5dFKXlAo1Ll2RHDXwY7nN2WAfrx2pP+WrvSRFTGFCNGdzBDHw==} engines: {node: '>=20.0.0'} + '@mdit/helper@1.0.1': + resolution: {integrity: sha512-zAzShsRZmkqjuoOFg6/zTCYVpvghj9a30Cl/eOGkE0xzRJJJG8T18eqb2lgceQhjVLWHK02HNVkzyfNHc429lQ==} + engines: {node: '>=22'} + peerDependencies: + markdown-it: ^14.2.0 + peerDependenciesMeta: + markdown-it: + optional: true + '@mdit/plugin-anchor@1.1.1': resolution: {integrity: sha512-42m7dxzvfLbo3YnteMB70aXFQ1TtnalyNLyPUDj5rr1FqTNf8pnHjQbgmf6FCjshg6BrfLVx7zpHJ7UUehQ/fA==} peerDependencies: markdown-it: ^14.2.0 + '@mdit/plugin-attrs@1.0.2': + resolution: {integrity: sha512-R9bvWt/MqyMAZ0povWkEh9n55+cQff+bXh9GZnd6Av+mPdE+L/k6jCOAyKzjUEWhQ8qqd5Keyqtn7h62gZq/VA==} + engines: {node: '>=22'} + peerDependencies: + markdown-it: ^14.2.0 + peerDependenciesMeta: + markdown-it: + optional: true + '@mdit/plugin-emoji@1.1.0': resolution: {integrity: sha512-rdGhZ0OVhK0EhiVpw8v22BdTq7XZ6Adrcbq3hR2Cx/YwGnL+kSXFtcGOeJXphiSics7oNgpIKdNyl974z7Cj1A==} engines: {node: '>=22'} @@ -1064,9 +1073,6 @@ packages: '@types/mark.js@8.11.12': resolution: {integrity: sha512-244ZnaIBpz4c6xutliAnYVZp6xJlmC569jZqnR3ElO1Y01ooYASSVQEqpd2x0A2UfrgVMs5V9/9tUAdZaDMytQ==} - '@types/markdown-it-attrs@4.1.3': - resolution: {integrity: sha512-1JsseFdHD6rQHsPcy4W3xx/whxvZ09Z+CqPpnOtrGtpmkFW07N11q7oM383//LtoKv54yn+HGnk6r4ZHUTHJVg==} - '@types/markdown-it-container@4.0.0': resolution: {integrity: sha512-GmD8OECLfzPHv8VyvFRzslqdwXoDBJ2H40fxXFjrarbqvJZSB/BJKZXN5e3k7Mx7GQanSNzTYhzeS3H9o0gAOw==} @@ -2043,12 +2049,6 @@ packages: markdown-it-async@2.2.0: resolution: {integrity: sha512-sITME+kf799vMeO/ww/CjH6q+c05f6TLpn6VOmmWCGNqPJzSh+uFgZoMB9s0plNtW6afy63qglNAC3MhrhP/gg==} - markdown-it-attrs@4.3.1: - resolution: {integrity: sha512-/ko6cba+H6gdZ0DOw7BbNMZtfuJTRp9g/IrGIuz8lYc/EfnmWRpaR3CFPnNbVz0LDvF8Gf1hFGPqrQqq7De0rg==} - engines: {node: '>=6'} - peerDependencies: - markdown-it: '>= 9.0.0' - markdown-it-cjk-friendly@2.0.2: resolution: {integrity: sha512-KXCl6sd129UqkAiRDb+NcAHrxC9xRa2WsGIsMMvtp2y1YlbeIaNYzArX2zfDoGhOjsyNMfJrGO7xGBss27YQSA==} engines: {node: '>=18'} @@ -3235,11 +3235,24 @@ snapshots: '@mdit-vue/types@3.0.2': {} + '@mdit/helper@1.0.1(markdown-it@14.2.0)': + dependencies: + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.2.0 + '@mdit/plugin-anchor@1.1.1(markdown-it@14.2.0)': dependencies: '@types/markdown-it': 14.1.2 markdown-it: 14.2.0 + '@mdit/plugin-attrs@1.0.2(markdown-it@14.2.0)': + dependencies: + '@mdit/helper': 1.0.1(markdown-it@14.2.0) + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.2.0 + '@mdit/plugin-emoji@1.1.0(markdown-it@14.2.0)': dependencies: '@types/markdown-it': 14.1.2 @@ -3547,10 +3560,6 @@ snapshots: dependencies: '@types/jquery': 4.0.1 - '@types/markdown-it-attrs@4.1.3(patch_hash=ef05082c7886d283042ddf9103f1408fc36fd8665ef278c82b3da0659441dfb6)': - dependencies: - '@types/markdown-it': 14.1.2 - '@types/markdown-it-container@4.0.0': dependencies: '@types/markdown-it': 14.1.2 @@ -4510,10 +4519,6 @@ snapshots: '@types/markdown-it': 14.1.2 markdown-it: 14.2.0 - markdown-it-attrs@4.3.1(patch_hash=12883b753541724964b5246a739df34c4b76db10415bbb63c35dce408cfe977e)(markdown-it@14.2.0): - dependencies: - markdown-it: 14.2.0 - markdown-it-cjk-friendly@2.0.2(@types/markdown-it@14.1.2)(markdown-it@14.2.0): dependencies: get-east-asian-width: 1.6.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 4a7f5533..1ca32ca7 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -15,8 +15,6 @@ overrides: ora>string-width: ^5 patchedDependencies: - '@types/markdown-it-attrs': patches/@types__markdown-it-attrs@4.1.3.patch '@types/mdurl@2.0.0': patches/@types__mdurl@2.0.0.patch - markdown-it-attrs@4.3.1: patches/markdown-it-attrs@4.3.1.patch shellEmulator: true diff --git a/src/node/markdown/markdown.ts b/src/node/markdown/markdown.ts index 0dc61d98..59d5b799 100644 --- a/src/node/markdown/markdown.ts +++ b/src/node/markdown/markdown.ts @@ -15,6 +15,10 @@ import { titlePlugin } from '@mdit-vue/plugin-title' import { tocPlugin, type TocPluginOptions } from '@mdit-vue/plugin-toc' import { slugify as defaultSlugify } from '@mdit-vue/shared' import { anchor as anchorPlugin, type AnchorOptions } from '@mdit/plugin-anchor' +import { + attrs as attrsPlugin, + type MarkdownItAttrsOptions +} from '@mdit/plugin-attrs' import { fullEmoji as emojiPlugin } from '@mdit/plugin-emoji' import type { CodeToHastOptions, @@ -23,7 +27,6 @@ import type { ThemeRegistrationAny } from '@shikijs/types' import { MarkdownItAsync, type MarkdownItAsyncOptions } from 'markdown-it-async' -import attrsPlugin, { type MarkdownItAttrsOptions } from 'markdown-it-attrs' import mditCjkFriendly from 'markdown-it-cjk-friendly' import path from 'node:path' import type { BuiltinLanguage, BuiltinTheme, Highlighter } from 'shiki' @@ -178,8 +181,11 @@ export interface MarkdownOptions extends MarkdownItAsyncOptions { /* ==================== Markdown Extensions ==================== */ /** - * Options for `markdown-it-attrs`. Set to `false` to disable. - * @see https://github.com/arve0/markdown-it-attrs + * Options for `@mdit/plugin-attrs`. Set to `false` to disable. The `fence` + * rule is off by default so that curly attributes never consume code block + * meta (e.g. line highlighting) - add classes to code blocks using shiki + * transformers instead. + * @see https://mdit-plugins.github.io/attrs.html */ attrs?: MarkdownItAttrsOptions | false /** @@ -349,7 +355,12 @@ export async function createMarkdownRenderer( // community plugins if (options.attrs !== false) { - attrsPlugin(md, options.attrs) + attrsPlugin(md, { + // no `fence` - code block meta (e.g. line highlighting) must reach + // the highlighter intact + rule: ['inline', 'table', 'list', 'heading', 'hr', 'softbreak', 'block'], + ...options.attrs + }) } if (options.emoji !== false) { emojiPlugin(md, options.emoji)