Skip to content
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

@shikijs/markdown-it doesn't seem to work with markdown-it-attrs #852

Open
3 of 5 tasks
kari opened this issue Nov 28, 2024 · 2 comments
Open
3 of 5 tasks

@shikijs/markdown-it doesn't seem to work with markdown-it-attrs #852

kari opened this issue Nov 28, 2024 · 2 comments

Comments

@kari
Copy link

kari commented Nov 28, 2024

Validations

Describe the bug

Hi,

I'm attempting to use the @shikijs/markdown-it plugin with markdown-it-attrs, but the attributes defined in markdown disappear when using shiki.

import markdownIt from "markdown-it";
import markdownItAttrs from "markdown-it-attrs";
import markdownItShiki from "@shikijs/markdown-it";

const input = "```js {.style-me data-filename=\"markdownit.js\"}\nimport markdownit from \"markdown-it\";\n```";

const md = markdownIt()
	.use(markdownItAttrs);

console.log(md.render(input));
/* Expected: code has class="style-me" and data-filename="markdownit.js"
<pre><code class="style-me language-js" data-filename="markdownit.js">import markdownit from &quot;markdown-it&quot;;
</code></pre>
*/

const mdShiki = markdownIt()
	.use(markdownItAttrs)
  .use(
		await markdownItShiki({ theme: 'vitesse-dark'}),
	);

console.log(mdShiki.render(input));
/* Actual: class only has shiki and vitesse-dark:
<pre class="shiki vitesse-dark" style="background-color:#121212;color:#dbd7caee" tabindex="0"><code class="language-js"><span class="line"><span style="color:#4D9375">import</span><span style="color:#BD976A"> markdownit</span><span style="color:#4D9375"> from</span><span style="color:#C98A7D77"> "</span><span style="color:#C98A7D">markdown-it</span><span style="color:#C98A7D77">"</span><span style="color:#666666">;</span></span></code></pre>
*/

Documentation mentions some past conflict with line highlighting and markdown-it-attrs, but even the suggested changing delimiters doesn't help, see reproduction below.

Reproduction

https://gist.github.com/kari/d83bb38fbf76ba3b3487d023f2363a11

Contributes

  • I am willing to submit a PR to fix this issue
  • I am willing to submit a PR with failing tests
@AleksandrHovhannisyan
Copy link

AleksandrHovhannisyan commented Dec 4, 2024

Can also reproduce. I'm trying to migrate from Prism to Shiki on my blog and I followed the docs' recommendation to use custom delimiters. I'm doing this in my Markdown:

```js [data-property="value"]
```

But all the custom attributes on fenced code blocks are getting swallowed by Shiki. I couldn't figure out a way to extract them in a transform.

@AleksandrHovhannisyan
Copy link

AleksandrHovhannisyan commented Dec 4, 2024

I was curious how some of the out-of-the-box transforms worked, so I looked through the code and found this:

/**
* Allow using `{1,3-5}` in the code snippet meta to mark highlighted lines.
*/
export function transformerMetaHighlight(
options: TransformerMetaHighlightOptions = {},
): ShikiTransformer {
const {
className = 'highlighted',
} = options
return {
name: '@shikijs/transformers:meta-highlight',
line(node, line) {
if (!this.options.meta?.__raw) {
return
}
;(this.meta as any)[symbol] ||= parseMetaHighlightString(this.options.meta.__raw)

Note in particular L45 and L48. The solution for me was to:

  1. Use custom delimiters for markdown-it-attrs (anything other than { and }).
  2. Not use markdown-it-attrs to set custom properties on code blocks.

In a custom transform, you can then access the header string under this.options.meta.__raw, which is typed as string | undefined.

For example, given this input (which doesn't even need the curly braces):

```js {property=value}
```

this.options.meta.__raw will be the string "{property=value}". It's then up to you to process that string (e.g., with regex) however you want inside one of the transformation methods. For example, in pre, line, or postprocess.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants