From c02fd70c6385394ba9433d75d0273d9dd3cb5d1a Mon Sep 17 00:00:00 2001 From: Hannah Wolfe Date: Thu, 20 Mar 2014 13:52:16 +0000 Subject: [PATCH] Improving the showdown extensions fixes #2381 - renamed the ghost extensions - added new html tests --- Gruntfile.js | 8 ++--- core/client/assets/lib/editor/htmlPreview.js | 2 +- core/server/models/post.js | 4 +-- .../extensions/{github.js => ghostgfm.js} | 33 +++++++++++++---- .../showdown/extensions/ghostimagepreview.js} | 24 ++++++------- ....js => showdown_client_integrated_spec.js} | 36 ++++++++++++------- ..._gfm_spec.js => showdown_ghostGFM_spec.js} | 25 ++++++++----- ....js => showdown_ghostimagepreview_spec.js} | 28 +++++---------- 8 files changed, 93 insertions(+), 67 deletions(-) rename core/shared/lib/showdown/extensions/{github.js => ghostgfm.js} (85%) rename core/{client/assets/lib/showdown/extensions/ghostdown.js => shared/lib/showdown/extensions/ghostimagepreview.js} (81%) rename core/test/unit/{client_showdown_int_spec.js => showdown_client_integrated_spec.js} (93%) rename core/test/unit/{shared_gfm_spec.js => showdown_ghostGFM_spec.js} (94%) rename core/test/unit/{client_ghostdown_spec.js => showdown_ghostimagepreview_spec.js} (72%) diff --git a/Gruntfile.js b/Gruntfile.js index 5c6975fd6a..58d8fe81eb 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -460,8 +460,8 @@ var path = require('path'), 'bower_components/showdown/src/showdown.js', 'bower_components/validator-js/validator.js', - 'core/client/assets/lib/showdown/extensions/ghostdown.js', - 'core/shared/lib/showdown/extensions/github.js', + 'core/shared/lib/showdown/extensions/ghostimagepreview.js', + 'core/shared/lib/showdown/extensions/ghostgfm.js', // ToDo: Remove or replace 'core/client/assets/vendor/shortcuts.js', @@ -522,8 +522,8 @@ var path = require('path'), 'bower_components/showdown/src/showdown.js', 'bower_components/validator-js/validator.js', - 'core/client/assets/lib/showdown/extensions/ghostdown.js', - 'core/shared/lib/showdown/extensions/github.js', + 'core/shared/lib/showdown/extensions/ghostimagepreview.js', + 'core/shared/lib/showdown/extensions/ghostgfm.js', // ToDo: Remove or replace 'core/client/assets/vendor/shortcuts.js', diff --git a/core/client/assets/lib/editor/htmlPreview.js b/core/client/assets/lib/editor/htmlPreview.js index af4bb22ac6..52f6d7239d 100644 --- a/core/client/assets/lib/editor/htmlPreview.js +++ b/core/client/assets/lib/editor/htmlPreview.js @@ -9,7 +9,7 @@ 'use strict'; var HTMLPreview = function (markdown, uploadMgr) { - var converter = new Showdown.converter({extensions: ['ghostdown', 'github']}), + var converter = new Showdown.converter({extensions: ['ghostimagepreview', 'ghostgfm']}), preview = document.getElementsByClassName('rendered-markdown')[0], update; diff --git a/core/server/models/post.js b/core/server/models/post.js index 6e265f6697..c47b05a1cc 100644 --- a/core/server/models/post.js +++ b/core/server/models/post.js @@ -3,8 +3,8 @@ var _ = require('lodash'), when = require('when'), errors = require('../errorHandling'), Showdown = require('showdown'), - github = require('../../shared/lib/showdown/extensions/github'), - converter = new Showdown.converter({extensions: [github]}), + ghostgfm = require('../../shared/lib/showdown/extensions/ghostgfm'), + converter = new Showdown.converter({extensions: [ghostgfm]}), User = require('./user').User, Tag = require('./tag').Tag, Tags = require('./tag').Tags, diff --git a/core/shared/lib/showdown/extensions/github.js b/core/shared/lib/showdown/extensions/ghostgfm.js similarity index 85% rename from core/shared/lib/showdown/extensions/github.js rename to core/shared/lib/showdown/extensions/ghostgfm.js index 150a2f99e1..781e3627d0 100644 --- a/core/shared/lib/showdown/extensions/github.js +++ b/core/shared/lib/showdown/extensions/ghostgfm.js @@ -1,10 +1,16 @@ +/* jshint node:true, browser:true */ + +// Ghost GFM +// Taken and extended from the Showdown Github Extension (WIP) +// Makes a number of pre and post-processing changes to the way markdown is handled // -// Github Extension (WIP) -// ~~strike-through~~ -> strike-through -// +// ~~strike-through~~ -> strike-through (Pre) +// GFM newlines & underscores (Pre) +// 4 or more underscores (Pre) +// autolinking / custom image handling (Post) (function () { - var github = function (converter) { + var ghostgfm = function () { return [ { // strike-through @@ -73,6 +79,17 @@ return text; } }, + + // 4 or more inline underscores e.g. Ghost rocks my _____! + { + type: 'lang', + filter: function (text) { + return text.replace(/([^_\n\r])(_{4,})/g, function (match, prefix, underscores) { + return prefix + underscores.replace(/_/g, '_'); + }); + } + }, + { // GFM autolinking & custom image handling, happens AFTER showdown type : 'html', @@ -131,7 +148,11 @@ }; // Client-side export - if (typeof window !== 'undefined' && window.Showdown && window.Showdown.extensions) { window.Showdown.extensions.github = github; } + if (typeof window !== 'undefined' && window.Showdown && window.Showdown.extensions) { + window.Showdown.extensions.ghostgfm = ghostgfm; + } // Server-side export - if (typeof module !== 'undefined') module.exports = github; + if (typeof module !== 'undefined') { + module.exports = ghostgfm; + } }()); diff --git a/core/client/assets/lib/showdown/extensions/ghostdown.js b/core/shared/lib/showdown/extensions/ghostimagepreview.js similarity index 81% rename from core/client/assets/lib/showdown/extensions/ghostdown.js rename to core/shared/lib/showdown/extensions/ghostimagepreview.js index 9c6fb9cebf..2932b806a4 100644 --- a/core/client/assets/lib/showdown/extensions/ghostdown.js +++ b/core/shared/lib/showdown/extensions/ghostimagepreview.js @@ -1,7 +1,15 @@ /* jshint node:true, browser:true */ + +// Ghost Image Preview +// +// Manages the conversion of image markdown `![]()` from markdown into the HTML image preview +// This provides a dropzone and other interface elements for adding images +// Is only used in the admin client. + + var Ghost = Ghost || {}; (function () { - var ghostdown = function () { + var ghostimagepreview = function () { return [ // ![] image syntax { @@ -33,26 +41,16 @@ var Ghost = Ghost || {}; return output; }); } - }, - - // 4 or more inline underscores e.g. Ghost rocks my _____! - { - type: 'lang', - filter: function (text) { - return text.replace(/([^_\n\r])(_{4,})/g, function (match, prefix, underscores) { - return prefix + underscores.replace(/_/g, '_'); - }); - } } ]; }; // Client-side export if (typeof window !== 'undefined' && window.Showdown && window.Showdown.extensions) { - window.Showdown.extensions.ghostdown = ghostdown; + window.Showdown.extensions.ghostimagepreview = ghostimagepreview; } // Server-side export if (typeof module !== 'undefined') { - module.exports = ghostdown; + module.exports = ghostimagepreview; } }()); diff --git a/core/test/unit/client_showdown_int_spec.js b/core/test/unit/showdown_client_integrated_spec.js similarity index 93% rename from core/test/unit/client_showdown_int_spec.js rename to core/test/unit/showdown_client_integrated_spec.js index 1f44313003..0f4cefeab4 100644 --- a/core/test/unit/client_showdown_int_spec.js +++ b/core/test/unit/showdown_client_integrated_spec.js @@ -5,14 +5,15 @@ */ /*globals describe, it */ -var testUtils = require('../utils'), - should = require('should'), +var testUtils = require('../utils'), + should = require('should'), // Stuff we are testing - Showdown = require('showdown'), - github = require('../../shared/lib/showdown/extensions/github'), - ghostdown = require('../../client/assets/lib/showdown/extensions/ghostdown'), - converter = new Showdown.converter({extensions: [ghostdown, github]}); + Showdown = require('showdown'), + ghostgfm = require('../../shared/lib/showdown/extensions/ghostgfm'), + ghostimagepreview = require('../../shared/lib/showdown/extensions/ghostimagepreview'), + + converter = new Showdown.converter({extensions: [ghostimagepreview, ghostgfm]}); describe("Showdown client side converter", function () { /*jslint regexp: true */ @@ -107,7 +108,7 @@ describe("Showdown client side converter", function () { it("should turn newlines into br tags in simple cases", function () { var testPhrases = [ {input: "fizz\nbuzz", output: /^

fizz
\nbuzz<\/p>$/}, - {input: "Hello world\nIt's a fine day", output: /^

Hello world
\nIt\'s a fine day<\/p>$/}, + {input: "Hello world\nIt is a fine day", output: /^

Hello world
\nIt is a fine day<\/p>$/}, {input: "\"first\nsecond", output: /^

\"first
\nsecond<\/p>$/}, {input: "\'first\nsecond", output: /^

\'first
\nsecond<\/p>$/} ], @@ -122,7 +123,7 @@ describe("Showdown client side converter", function () { it("should convert newlines in all groups", function () { var testPhrases = [ {input: "ruby\npython\nerlang", output: /^

ruby
\npython
\nerlang<\/p>$/}, - {input: "Hello world\nIt's a fine day\nout", output: /^

Hello world
\nIt\'s a fine day
\nout<\/p>$/} + {input: "Hello world\nIt is a fine day\nout", output: /^

Hello world
\nIt is a fine day
\nout<\/p>$/} ], processedMarkup; @@ -134,10 +135,13 @@ describe("Showdown client side converter", function () { it("should convert newlines in even long groups", function () { var testPhrases = [ - {input: "ruby\npython\nerlang\ngo", output: /^

ruby
\npython
\nerlang
\ngo<\/p>$/}, { - input: "Hello world\nIt's a fine day\noutside\nthe window", - output: /^

Hello world
\nIt\'s a fine day
\noutside
\nthe window<\/p>$/ + input: "ruby\npython\nerlang\ngo", + output: /^

ruby
\npython
\nerlang
\ngo<\/p>$/ + }, + { + input: "Hello world\nIt is a fine day\noutside\nthe window", + output: /^

Hello world
\nIt is a fine day
\noutside
\nthe window<\/p>$/ } ], processedMarkup; @@ -150,8 +154,14 @@ describe("Showdown client side converter", function () { it("should not convert newlines in lists", function () { var testPhrases = [ - {input: "#fizz\n# buzz\n### baz", output: /^

fizz<\/h1>\n\n

buzz<\/h1>\n\n

baz<\/h3>$/}, - {input: "* foo\n* bar", output: /^