diff --git a/Gruntfile.js b/Gruntfile.js index 298d813a38..1c81bb8e3c 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -590,7 +590,8 @@ var _ = require('lodash'), 'core/shared/lib/showdown/extensions/ghostimagepreview.js', 'core/shared/lib/showdown/extensions/ghostgfm.js', - 'core/shared/lib/showdown/extensions/ghostfootnotes.js' + 'core/shared/lib/showdown/extensions/ghostfootnotes.js', + 'core/shared/lib/showdown/extensions/ghosthighlight.js' ] }, @@ -626,7 +627,8 @@ var _ = require('lodash'), 'core/shared/lib/showdown/extensions/ghostimagepreview.js', 'core/shared/lib/showdown/extensions/ghostgfm.js', - 'core/shared/lib/showdown/extensions/ghostfootnotes.js' + 'core/shared/lib/showdown/extensions/ghostfootnotes.js', + 'core/shared/lib/showdown/extensions/ghosthighlight.js' ] } }, diff --git a/core/client/assets/sass/patterns/global.scss b/core/client/assets/sass/patterns/global.scss index 7ca1789ab2..1e2e35ca44 100644 --- a/core/client/assets/sass/patterns/global.scss +++ b/core/client/assets/sass/patterns/global.scss @@ -101,7 +101,7 @@ ul ol, ol ul { } mark { - background-color: #ffc336; + background-color: #fdffb6; } a { diff --git a/core/client/helpers/gh-format-markdown.js b/core/client/helpers/gh-format-markdown.js index 69be7fc13d..03dabc2f8d 100644 --- a/core/client/helpers/gh-format-markdown.js +++ b/core/client/helpers/gh-format-markdown.js @@ -4,7 +4,7 @@ import cajaSanitizers from 'ghost/utils/caja-sanitizers'; var showdown, formatMarkdown; -showdown = new Showdown.converter({extensions: ['ghostimagepreview', 'ghostgfm', 'footnotes']}); +showdown = new Showdown.converter({extensions: ['ghostimagepreview', 'ghostgfm', 'footnotes', 'highlight']}); formatMarkdown = Ember.Handlebars.makeBoundHelper(function (markdown) { var escapedhtml = ''; diff --git a/core/server/models/post.js b/core/server/models/post.js index 8a1483b142..d57ee03bf9 100644 --- a/core/server/models/post.js +++ b/core/server/models/post.js @@ -5,8 +5,9 @@ var _ = require('lodash'), errors = require('../errors'), Showdown = require('showdown-ghost'), ghostgfm = require('../../shared/lib/showdown/extensions/ghostgfm'), - ghostfootnotes = require('../../shared/lib/showdown/extensions/ghostfootnotes'), - converter = new Showdown.converter({extensions: [ghostgfm, ghostfootnotes]}), + footnotes = require('../../shared/lib/showdown/extensions/ghostfootnotes'), + highlight = require('../../shared/lib/showdown/extensions/ghosthighlight'), + converter = new Showdown.converter({extensions: [ghostgfm, footnotes, highlight]}), ghostBookshelf = require('./base'), xmlrpc = require('../xmlrpc'), sitemap = require('../data/sitemap'), diff --git a/core/shared/lib/showdown/extensions/ghosthighlight.js b/core/shared/lib/showdown/extensions/ghosthighlight.js new file mode 100644 index 0000000000..b867b0183b --- /dev/null +++ b/core/shared/lib/showdown/extensions/ghosthighlight.js @@ -0,0 +1,71 @@ +/* jshint node:true, browser:true, -W044 */ + +// Adds highlight syntax as per RedCarpet: +// +// https://github.com/vmg/redcarpet +// +// This is ==highlighted==. It looks like this: highlighted + +(function () { + var highlight = function () { + return [ + { + type: 'html', + filter: function (text) { + var highlightRegex = /(=){2}([\s\S]+?)(=){2}/gim, + preExtractions = {}, + codeExtractions = {}, + hashID = 0; + + function hashId() { + return hashID += 1; + } + + // Extract pre blocks + text = text.replace(/
[\s\S]*?<\/pre>/gim, function (x) {
+ var hash = hashId();
+ preExtractions[hash] = x;
+ return '{gfm-js-extract-pre-' + hash + '}';
+ }, 'm');
+
+ // Extract code blocks
+ text = text.replace(/[\s\S]*?<\/code>/gim, function (x) {
+ var hash = hashId();
+ codeExtractions[hash] = x;
+ return '{gfm-js-extract-code-' + hash + '}';
+ }, 'm');
+
+ text = text.replace(highlightRegex, function (match, n, content) {
+ // Check the content isn't just an `=`
+ if (!/^=+$/.test(content)) {
+ return '' + content + '';
+ }
+
+ return match;
+ });
+
+ // replace pre extractions
+ text = text.replace(/\{gfm-js-extract-pre-([0-9]+)\}/gm, function (x, y) {
+ return preExtractions[y];
+ });
+
+ // replace code extractions
+ text = text.replace(/\{gfm-js-extract-code-([0-9]+)\}/gm, function (x, y) {
+ return codeExtractions[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;
+ }
+}());
diff --git a/core/test/unit/showdown_client_integrated_spec.js b/core/test/unit/showdown_client_integrated_spec.js
index 04f180896c..023fe22589 100644
--- a/core/test/unit/showdown_client_integrated_spec.js
+++ b/core/test/unit/showdown_client_integrated_spec.js
@@ -12,9 +12,10 @@ var should = require('should'),
Showdown = require('showdown-ghost'),
ghostgfm = require('../../shared/lib/showdown/extensions/ghostgfm'),
ghostimagepreview = require('../../shared/lib/showdown/extensions/ghostimagepreview'),
- ghostfootnotes = require('../../shared/lib/showdown/extensions/ghostfootnotes'),
+ footnotes = require('../../shared/lib/showdown/extensions/ghostfootnotes'),
+ highlight = require('../../shared/lib/showdown/extensions/ghosthighlight'),
- converter = new Showdown.converter({extensions: [ghostimagepreview, ghostgfm, ghostfootnotes]});
+ converter = new Showdown.converter({extensions: [ghostimagepreview, ghostgfm, footnotes, highlight]});
// To stop jshint complaining
should.equal(true, true);
@@ -532,6 +533,95 @@ describe('Showdown client side converter', function () {
});
});
+ it('should replace showdown highlight with html', function () {
+ var testPhrases = [
+ {
+ input: '==foo_bar==',
+ output: /^foo_bar<\/mark><\/p>$/
+ },
+ {
+ input: 'My stuff that has a ==highlight== in the middle.',
+ output: /^My stuff that has a highlight<\/mark> in the middle.<\/p>$/
+ },
+ {
+ input: 'My stuff that has a ==multiple word highlight== in the middle.',
+ output: /^My stuff that has a multiple word highlight<\/mark> in the middle.<\/p>$/
+ },
+ {
+ input: 'My stuff that has a ==multiple word **bold** highlight== in the middle.',
+ output: /^My stuff that has a multiple word bold<\/strong> highlight<\/mark> in the middle.<\/p>$/
+ },
+ {
+ input: 'My stuff that has a ==multiple word and\n line broken highlight== in the middle.',
+ output: /^My stuff that has a multiple word and
\n line broken highlight<\/mark> in the middle.<\/p>$/
+ },
+ {
+ input: 'Test ==Highlighting with a [link](https://ghost.org) in the middle== of it.',
+ output: /^Test Highlighting with a link<\/a> in the middle<\/mark> of it.<\/p>$/
+ },
+ {
+ input: '==[link](http://ghost.org)==',
+ output: /^link<\/a><\/mark><\/p>$/
+ },
+ {
+ input: '[==link==](http://ghost.org)',
+ output: /^