Open LeaVerou opened 1 year ago
Hi 👋 I believe that is a common issue that has been reported multiple times, addressed in the readme: https://github.com/arve0/markdown-it-attrs#custom-rendering
This plug-in do not alter original rendering from markdown-it.
Let me know if I’m wrong (away from computer right now 🏖️).
Got this to work by copying and modifying the original fence rule.
md.renderer.rules.fence = function (tokens, idx, options, env, slf) {
const token = tokens[idx]
const info = token.info ? unescapeAll(token.info).trim() : ''
let langName = ''
let langAttrs = ''
if (info) {
const arr = info.split(/(\s+)/g)
langName = arr[0]
langAttrs = arr.slice(2).join('')
}
let highlighted
if (options.highlight) {
highlighted = options.highlight(token.content, langName, langAttrs) || escapeHtml(token.content)
} else {
highlighted = escapeHtml(token.content)
}
if (highlighted.indexOf('<pre') === 0) {
return highlighted + '\n'
}
// If language exists, inject class gently, without modifying original token.
// May be, one day we will add .deepClone() for token and simplify this part, but
// now we prefer to keep things local.
if (info) {
const i = token.attrIndex('class')
const tmpAttrs = token.attrs ? token.attrs.slice() : []
if (i < 0) {
tmpAttrs.push(['class', options.langPrefix + langName])
} else {
tmpAttrs[i] = tmpAttrs[i].slice()
tmpAttrs[i][1] += ' ' + options.langPrefix + langName
}
// Fake token just to render attributes
const tmpToken = {
attrs: tmpAttrs
}
- return `<pre><code${slf.renderAttrs(tmpToken)}>${highlighted}</code></pre>\n`
+ return `<pre${slf.renderAttrs(tmpToken)}><code class="${options.langPrefix}${langName}">${highlighted}</code></pre>\n`
}
- return `<pre><code${slf.renderAttrs(token)}>${highlighted}</code></pre>\n`
+ return `<pre${slf.renderAttrs(token)}><code>${highlighted}</code></pre>\n`
}
A bit of a dirty hack, but should be more robust than the example presented in the Custom Rendering section (which I tried, but it missed various features). This should also be more performant compared to calling the default rule then replacing with regex.
In general, it seems reasonable that when a Markdown structure returns multiple nested elements, that setting attributes on it would go on the container, rather than any descendant. Currently, setting attributes on a fenced code block sets them on the inner
<code>
element instead of the outer<pre>
.Markdown-it versions:
Example input:
Current output:
Expected output: