Put this in the editor (Ghost v0.6.4)
<script>
var x = 0;
if ( x === 0 ) {
alert("yay");
}
</script>
then publish.
View the blog post in a web browser.
Would expect an alert box saying 'yay'.
However, we get a javascript error.
Inspecting the rendered HTML/JS code and we see
<script>
var x = 0;
if ( x <mark>= 0 ) {
alert("yay");
}
</script>
It looks like some macro replacement magic is taking place, replacing any == characters with <mark>.
Hi @coderfi
The == is used for highlighting, hence the markdown conversion, if you add type="text/javascript" to your script tag this will not happen. Not sure if the conversion should be happening in any case within a tag but certainly that will help you out for now
Been trying to investigate this further, I cannot always reproduce this error and that solution does not work. Some intermittent bug seems to be occurring here. Often the code works fine, I found if I copy and pasted the code a couple of times in the same post then it was more likely to occur...
Hi guys, I've been investigating this issue and the problem is in the highlight extension of the showdown-ghost package. In version 0.3.6, it only escapes <pre> and <code> blocks before applying highlighting. A simple fix for the existing package is to escape <script> blocks in the same manner.
Looks like there are some upcoming changes in showdown-ghost with how extensions are handled so probably best to check out this issue for more info: erisds/showdown#5
Thank, guys, for figuring it out.
I'll try out the new version when I get the chance!
Thanks,
Fi
On Thu, Jul 23, 2015, 5:42 PM Emerson Keenan [email protected]
wrote:
Hi guys, I've been investigating this issue and the problem is in
highlight.js in the showdown-ghost package.In version 0.3.6, it only escapes
andblocks before applying
highlighting.A simple fix for the existing package is to also escape
Hi @ErisDS. From my testing the bug isn't intermittent. What @cobbspur may have noticed is that you actually need an opening == and closing == to match the highlight regex. Standalone == statements should be rendered correctly. Let me know though if you are seeing something different!
I tested it extensively and saw different results intermittently, but I wasn't able to tie it down to any particular pattern.
To add to the clues, I saw the error when only having a single occurrence of ==.
I also used a fresh, vanilla, docker, installation of ghost deployed on an instance at vultr.com and did not explicitly enable any additional extensions (and used only the default settings).
Reading into Issue #5, if we are suspecting extensions as the root cause:
How are extensions loaded and rendered?
Is there a deterministic ordering of execution?
On a uneducated guess, if the problem is intermittent, sounds like the extensions are rendering in a random order.
Is there a way to disable extensions or know which ones are executing (maybe through the JS console log, or a server side log?)
Any progress? At first glance, seems to still be a problem in Ghost v0.7.3
Love to get a solution or temporary work around. Trying add unique code snippets to each post.
@intositeme The work around I'm using is to modify showdown-ghost v0.3.6 to escape <script> blocks before applying highlighting. Assuming you are using Ghost v0.7.6 simply replace node_modules\showdown-ghost\src\extensions\highlight.js with the following and restart Ghost:
/* jshint node:true, browser:true, -W044 */
// Adds highlight syntax as per RedCarpet:
//
// https://github.com/vmg/redcarpet
//
// This is ==highlighted==. It looks like this: <mark>highlighted</mark>
(function () {
var highlight = function () {
return [
{
type: 'html',
filter: function (text) {
var highlightRegex = /(=){2}([\s\S]+?)(=){2}/gim,
extractions = {},
hashID = 0;
function hashId() {
return hashID += 1;
}
// Extract pre|code|script blocks
text = text.replace(/<(pre|code|script)>[\s\S]*?<\/(\1)>/gim, function (x) {
var hash = hashId();
extractions[hash] = x;
return '{gfm-js-extract-' + hash + '}';
}, 'm');
text = text.replace(highlightRegex, function (match, n, content) {
// Check the content isn't just an `=`
if (!/^=+$/.test(content)) {
return '<mark>' + content + '</mark>';
}
return match;
});
// Replace extractions
text = text.replace(/\{gfm-js-extract-([0-9]+)\}/gm, function (x, y) {
return extractions[y];
});
return text;
}
}
];
};
// Client-side export
if (typeof window !== 'undefined' && window.Showdown && window.Showdown.extensions) {
window.Showdown.extensions.highlight = highlight;
}
// Server-side export
if (typeof module !== 'undefined') {
module.exports = highlight;
}
}());
@emersonkeenan Just tried it. Awesome, it works! Thanks!
I am having this issue when using <pre /> and <code /> elements when displaying ==. It happens when I add a class attribute to the <pre > tag (class="line-numbers" for syntax highlighting).
@cerkit This will be caused by the same issue I mentioned above. As the current highlight extension only matches <pre> and <code> blocks the addition of the class attribute will cause it to be processed for highlighting. You will need to modify the extract regex statement to match these <pre class> blocks if you want them to be skipped. The following statement will work for the example you posted:
<(pre.*|code|script)>[\s\S]*?<\/(pre|code|script)>/gim
@emersonkeenan Thanks. I am hosting it with Ghost Pro, so I can't make modifications to the source. I have started removing line numbers from my code on my blog so it won't be an issue. I don't usually refer to them, but I like the way they look.
A somewhat related problem is located here: https://github.com/TryGhost/Ghost/issues/7647
The difference being that this problem only pertains to == attributes within tags. The solution to this problem is to modify how showdown escapes tags and to move the unescape tag method after the HTML extensions are processed, this will likely have unintended consequences with other extensions, although what Ghost uses mostly appears to be LANG based and will be unaffected.
Regardless, fixing this issue should fix the above issue in a more re-usable and generic fashion.
I have the same issue on Ghost Pro, the only way to avoid the problem is to add <pre> tags before and after the <script> tags.