-
Notifications
You must be signed in to change notification settings - Fork 108
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
Can't substitute <pre> elements for components #100
Comments
Yeah, this doesn't work which is expected but perhaps undesirable. This is simply because of how the markup for code blocks is generated, which is slightly different to other markdown elements. It should be possible to make this work, I'll take a look at it. |
Found a workaround:Make a custom highlighter function and change the highlight: {
highlighter: (code, lang) => {
if (lang && Prism.languages[lang]) {
const parsed = Prism.highlight(code, Prism.languages[lang]);
const escaped = parsed.replace(/{/g, '{').replace(/}/g, '}');
const langTag = 'language-' + lang;
// This thing below ↓↓↓↓
return `<Components.pre class=${langTag}><code class=${langTag}>${escaped}</code></Components.pre>`;
} else {
const escaped = code.replace(/{/g, '{').replace(/}/g, '}');
return `<Components.pre><code>${escaped}</code></Components.pre>`;
}
},
}, <script context="module">
import { pre } from "./defaults";
export { pre };
</script> MDsveX replaces all html tags with |
This isn't public API and could change at any time, so I wouldn't recommend this approach (although it would work fine as a workaround). I'll have a real fix for this soon. |
I managed to make my own Svelte component receive the direct props from the highlighter this way. This lets me make a single Svelte component for both MDsveX and normal Svelte code. highlight: {
highlighter: (code, lang) => {
return `<Components.pre code={\`${escape(code)}\`} lang={\`${lang}\`} />`;
},
} |
I ended up hacking together a svelte preprocessor for this and that worked out pretty well. I'm not sure if it would scale too well for hundreds or thousands of const mdClipboardCodeblocks = () => {
return {
name: "md-clipboard-codeblocks",
/**
* @param {object} options
* @param {string} options.content
* @param {string} options.filename
*/
markup: ({ content, filename }) => {
if (filename.endsWith(".md")) {
// Add the copy to clipboard import to every .md file has access to it automatically without needing to add an import statement in <script> tags
content = content.replace(/<script>([\s\S]*?)<\/script>/, `<script>\nimport { CopyToClipboard } from "$lib/components";\n$1</script>`);
// Wrap codeblocks with copy to clipboard
if (content.includes("<pre class=\"language-")) {
content = content.replace(/(<pre class=")(language-[^"]*">)([\s\S]*?)(<\/pre>)/g, '$1 relative inline-flex $2<CopyToClipboard class="absolute top-1.5 right-1.5">$3</CopyToClipboard>$4')
}
return { code: content };
}
},
};
};
export default mdClipboardCodeblocks; |
Layouts allow providing Svelte components to be rendered instead of certain HTML elements that markdown generates, but that doesn't seem to apply to
<pre>
or<code>
elements.Perhaps this has something to do with the fact that they undergo special treatment with the default syntax highlighter, but I think this deserves a note in the docs. Or maybe it is possible to substitute them, which would be great!
Steps to reproduce
mdsvex
:yarn add -D mdsvex
rollup.config.js
:src/test.svx
) with the following content:src/layout.svelte
) exporting thepre
element (also createsrc/pre.svelte
with content.<pre><slot /></pre>
to see a dot before every<pre>
element):src/App.svelte
The text was updated successfully, but these errors were encountered: