fix: disable markdown-it-attrs for fenced code blocks

BREAKING CHANGE: `markdown-it-attrs` is disabled for fenced code blocks. For most users no change is required. If you want to add classes to code blocks, do it using shiki transformers instead.
pull/4910/merge
Divyansh Singh 3 weeks ago
parent a6e6e59905
commit 0899618556

@ -0,0 +1,14 @@
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) => {

@ -18,6 +18,9 @@ patchedDependencies:
markdown-it-anchor@9.2.0:
hash: cdc28e7c329be30688ad192126ba505446611fbe526ad51483e4b1287aa35cf9
path: patches/markdown-it-anchor@9.2.0.patch
markdown-it-attrs@4.3.1:
hash: 12883b753541724964b5246a739df34c4b76db10415bbb63c35dce408cfe977e
path: patches/markdown-it-attrs@4.3.1.patch
importers:
@ -206,7 +209,7 @@ importers:
version: 2.2.0
markdown-it-attrs:
specifier: ^4.3.1
version: 4.3.1(markdown-it@14.1.0)
version: 4.3.1(patch_hash=12883b753541724964b5246a739df34c4b76db10415bbb63c35dce408cfe977e)(markdown-it@14.1.0)
markdown-it-cjk-friendly:
specifier: ^1.3.2
version: 1.3.2(@types/markdown-it@14.1.2)(markdown-it@14.1.0)
@ -4984,7 +4987,7 @@ snapshots:
'@types/markdown-it': 14.1.2
markdown-it: 14.1.0
markdown-it-attrs@4.3.1(markdown-it@14.1.0):
markdown-it-attrs@4.3.1(patch_hash=12883b753541724964b5246a739df34c4b76db10415bbb63c35dce408cfe977e)(markdown-it@14.1.0):
dependencies:
markdown-it: 14.1.0

@ -17,5 +17,6 @@ patchedDependencies:
'@types/markdown-it-attrs': patches/@types__markdown-it-attrs.patch
'@types/mdurl@2.0.0': patches/@types__mdurl@2.0.0.patch
markdown-it-anchor@9.2.0: patches/markdown-it-anchor@9.2.0.patch
markdown-it-attrs@4.3.1: patches/markdown-it-attrs@4.3.1.patch
shellEmulator: true

@ -30,7 +30,6 @@ import type { Awaitable } from '../shared'
import { containerPlugin, type ContainerOptions } from './plugins/containers'
import { gitHubAlertsPlugin } from './plugins/githubAlerts'
import { highlight as createHighlighter } from './plugins/highlight'
import { highlightLinePlugin } from './plugins/highlightLines'
import { imagePlugin, type Options as ImageOptions } from './plugins/image'
import { lineNumberPlugin } from './plugins/lineNumbers'
import { linkPlugin } from './plugins/link'
@ -271,7 +270,6 @@ export async function createMarkdownRenderer(
// custom plugins
componentPlugin(md, options.component)
highlightLinePlugin(md)
preWrapperPlugin(md, {
codeCopyButtonTitle,
languageLabel: options.languageLabel

@ -100,8 +100,16 @@ export async function highlight(
const vueRE = /-vue$/
return [
async (str: string, lang: string, attrs: string) => {
lang = langRE.exec(lang)?.[0].toLowerCase() || defaultLang
async (str, lang, attrs) => {
const match = langRE.exec(lang)
if (match) {
const orig = lang
lang = match[0].toLowerCase()
attrs = orig.slice(lang.length).replace(/(?<!=)\{/g, ' {') + ' ' + attrs
attrs = attrs.trim().replace(/\s+/g, ' ')
}
lang ||= defaultLang
const vPre = !vueRE.test(lang)
if (!vPre) lang = lang.slice(0, -4)

@ -1,50 +0,0 @@
// Modified from https://github.com/egoist/markdown-it-highlight-lines
// Now this plugin is only used to normalize line attrs.
// The else part of line highlights logic is in './highlight.ts'.
import type { MarkdownItAsync } from 'markdown-it-async'
const RE = /{([\d,-]+)}/
export const highlightLinePlugin = (md: MarkdownItAsync) => {
const fence = md.renderer.rules.fence!
md.renderer.rules.fence = (...args) => {
const [tokens, idx] = args
const token = tokens[idx]
// due to use of markdown-it-attrs, the {0} syntax would have been
// converted to attrs on the token
const attr = token.attrs && token.attrs[0]
let lines = null
if (!attr) {
// markdown-it-attrs maybe disabled
const rawInfo = token.info
if (!rawInfo || !RE.test(rawInfo)) {
return fence(...args)
}
const langName = rawInfo.replace(RE, '').trim()
// ensure the next plugin get the correct lang
token.info = langName
lines = RE.exec(rawInfo)![1]
}
if (!lines) {
lines = attr![0]
if (!lines || !/[\d,-]+/.test(lines)) {
return fence(...args)
}
}
token.info += '{' + lines + '}'
// ensure there is a space between the lang and the line numbers
token.info = token.info.replace(/(?<!=)\{/g, ' {')
return fence(...args)
}
}
Loading…
Cancel
Save