-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Attributes on fenced code block should go on the outer <pre>
, not the inner <code>
#152
Comments
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. |
11ty-syntax-hl doesn't work well with markdown-it-attr. So taking a hint from [this issue](11ty/eleventy-plugin-syntaxhighlight#72), I'm switching to markdown-it-prism, which also renders PrismJS in node. At the same time, I decided to use a custom fence renderer which will render attributes in the `pre` block instead of the `code` block. Relevant issue: arve0/markdown-it-attrs#152. I should also mention markdown-it-prism has a bonus of highlighting inline code blocks.
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:
The text was updated successfully, but these errors were encountered: