-
Notifications
You must be signed in to change notification settings - Fork 12
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
code is not displayed correctly #26
Comments
Seems like it is something with react. Removing react seems to make it work. |
The same problem exists with Svelte. The deprecated way still works perfectly fine: marked.setOptions({
highlight: function(code, language) {
const validLanguage = hljs.getLanguage(language) ? language : 'plaintext';
return hljs.highlight(code, { language: validLanguage }).value;
}
}); Content:
Generates: <pre><code class="language-elixir"><span class="hljs-title class_">IO</span>.puts(<span class="hljs-string">"Hello, world!"</span>)
</code></pre> The new way: marked.use(markedHighlight({
langPrefix: 'hljs language-',
highlight(code, lang) {
const language = hljs.getLanguage(lang) ? lang : 'plaintext';
return hljs.highlight(code, { language }).value;
}
})); Content:
Generates: <pre><code class="hljs language-elixir"><span class=<span class="hljs-string">"hljs-title class_"</span>><span class="hljs-title class_">IO</span></span>.puts <span class=<span class="hljs-string">"hljs-string"</span>>&quot;<span class="hljs-title class_">Hello</span>, world!&quot;</span>
</code></pre> |
Can you create a repo that reproduces this? |
So, it's a weird thing. While trying to reproduce it in a new repo, I realized where it's happening, and it appears to be unrelated to the new way or the legacy way. The code is here: https://github.com/icebaker/myapp Here's what's going on: If you update your code while your server is in development mode, the page automatically updates to reflect your changes. But for some reason, this seems to mess up the code. A simple page refresh brings things back to normal. I've captured this in a video: behavior.mp4Note that, for some reason, this only happens with marked (legacy or new way). If I'm using highlight.js purely, it does not mess up the rendering. |
This looks like an issue in svelte. marked returns the correct html so there is nothing we can change in marked or marked-highlight to fix this. |
Alright, digging deeper into debugging, I've discerned the root cause. Indeed, it's a problem linked to the new technique, yet it doesn't pertain to With On the other hand, with That's the reason it "incorrectly" renders the code—it applies a highlight onto an already highlighted portion. When dealing with marked.setOptions({highlight: ...});
marked.parse(code);
// IO.puts("Hello, world!")
marked.setOptions({highlight: ...});
marked.parse(code);
// IO.puts("Hello, world!")
marked.setOptions({highlight: ...});
marked.parse(code);
// IO.puts("Hello, world!") When dealing with marked.use(markedHighlight({...}));
marked.parse(code);
// IO.puts("Hello, world!")
marked.use(markedHighlight({...}));
marked.parse(code);
// <span class="hljs-title class_">IO</span>.puts(<span class="hljs-string">"Hello, world!"</span>)
marked.use(markedHighlight({...}));
marked.parse(code);
// <span class=<span class="hljs-string">"hljs-title class_"</span>><span class="hljs-title class_">IO</span></span>.puts(<span class=<span class="hljs-string">"hljs-string"</span>>&quot;<span class="hljs-title class_">Hello</span>, world!&quot;</span>) The easiest way to simulate this behavior: import hljs from 'highlight.js';
import * as marked from 'marked';
import { markedHighlight } from 'marked-highlight';
const extension = markedHighlight({
langPrefix: 'hljs language-',
highlight(code, lang) {
const language = hljs.getLanguage(lang) ? lang : 'plaintext';
return hljs.highlight(code, { language }).value;
}
});
marked.use(extension);
marked.use(extension);
marked.use(extension);
marked.parse(code); I believe that most modern reactive frameworks like React and Svelte reported here, have this tendency of calling things multiple times. Just using the same component twice on the same page, or hopping from one page to another in a Single Page Application, could trigger this accumulation of extensions because of the So, my suggestion would be to tweak this approach to make it more compatible with modern frameworks. I think we're likely to see more of this type of issue in the future. Here are some potential approaches that come to mind:
marked.use('extension-a', highlightExtension);
marked.use('extension-b', highlightExtension); Or: marked.use({...highlightExtension, ...{id: 'extension-a'}});
marked.use({...highlightExtension, ...{id: 'extension-b'}}); Thoughts? |
Thanks for sharing; this is great context! So, for those struggling to get this working with reactive frameworks, the simple workaround is just to encapsulate marked into a singleton, and you're good to go: import * as marked from 'marked';
import { markedHighlight } from 'marked-highlight';
import hljs from 'highlight.js';
const Marked = {
instantiated: false,
setup: () => {
marked.setOptions({ mangle: false, headerIds: false });
marked.use(
markedHighlight({
langPrefix: 'hljs language-',
highlight(code, lang) {
const language = hljs.getLanguage(lang) ? lang : 'plaintext';
return hljs.highlight(code, { language }).value;
}
})
);
Marked.instantiated = true;
},
instance: () => {
if (!Marked.instantiated) Marked.setup();
return marked;
}
};
export default Marked; And then: import Marked from 'Marked';
const html = Marked.instance().parse(code); Here's the "fix" in the demo repo: commit d59f1a6 |
Ya or use |
yah, first render is correct, but rerender is not because marked-highlight decodes the part of the code that has already been decrypted. LoL my crazy solution. This not working if markdown has class 'hljs' marked.use(
markedHighlight({
langPrefix: 'hljs language-',
highlight(code, lang) {
if(code.includes('class="hljs') return // 🤣🤣🤣 that crazy
const language = hljs.getLanguage(lang) ? lang : 'plaintext';
return hljs.highlight(code, { language }).value;
}
})
); |
This should be fixed with markedjs/marked#2831 |
Should be fixed in marked v5.1.0 |
my code is:
result:

Can you help me point out where I am wrong?
The text was updated successfully, but these errors were encountered: