remark
remark copied to clipboard
`wrapLines` breaks some code highlighting; fix included
Where wrapLines
splits the code content on \n
and wraps it in <div>
s if the highlighter opens a <span>
on one line and doesn't close it until the next line the browser will auto-close the span in the first div and the second line won't inherit the styles. This causes code formatting to appear broken - I thought it was an issue with highlight.js so switched out for prism as seen in #444 but it persisted.
https://github.com/gnab/remark/blob/868781c84457bd1f0e0c1ee657423136fdbe3c75/src/remark/views/slideView.js#L281-L292
I've managed to work around the issue by pre-empting this in my highlightBlock
override and closing spans out at the end of a line and re-opening them at the beginning of the next line. ES6 code to achieve this is here:
function parseLanguage(lang) {
return {
js: 'jsx',
}[lang] || lang;
}
remark.highlighter.engine.highlightBlock = block => {
const language = parseLanguage(block.className.split(" ")[0]);
const prismLang = Prism.languages[language];
if (prismLang) {
block.parentNode.className = `${block.parentNode.className} language-${language}`;
const html = Prism.highlight(block.textContent, prismLang);
const lines = html.split(`\n`);
let currentSpan = null;
for (var i = 0; i < lines.length; i++) {
let line = lines[i];
if (currentSpan) {
line = currentSpan + line;
currentSpan = null;
}
const openTags = [];
const re = /(<span[^>]*>|<\/span>)/gi;
let matches;
while ((matches = re.exec(line)) != null) {
const tag = matches[1];
if (tag[1] === '/') {
openTags.pop();
} else {
openTags.push(tag);
}
}
currentSpan = openTags.join('');
line = line + ('</' + 'span>').repeat(openTags.length);
lines[i] = line;
}
block.innerHTML = lines.join('\n');
} else {
console.warn(`Language '${language}' not supported?`)
}
};
Perhaps you'd consider incorporating the part from const lines = html.split...
to lines.join('\n')
into the wrapLines
function directly?
(I absolutely love this presentation framework by the way, have been using it for years and extoll the virtues of it everywhere I present ❤️ - I've even got an awesome setup now with Browsersync where when you save your markdown file the browser automatically replaces all the slides instantly and jumps to the first edited slide which has increased my productivity significantly!)
For those interested in my workflow, check out this script:
https://github.com/GraphQLTraining/lightweight-graphql-react/blob/gh-pages/browsersync
And the corresponding main
function in the index.html file:
https://github.com/GraphQLTraining/lightweight-graphql-react/blob/gh-pages/index.html
Thank you so much for sharing your setup @benjie - I am literally 2x more productive with it. @gnab How do you feel about adding this to remark as a default dev experience? It's sort of magical.
Oh, this is great, @benjie! I wish I didn't have to hack remark to make it highlight 'jsx' properly. I would settle for an option to disable "highlight.js" and the remark code blocks altogether so I could simply link in my preferred highlighter (prism.js) for my <pre> <code>
tags. Or something like that.
I'm using your changes to (remark.prism.js) to have the syntax highlight and it works fine. Thank you. Do you know if it will be possible to have some plugins like line-numbers working too ? Thank you.