mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
Improving the showdown extensions
fixes #2381 - renamed the ghost extensions - added new html tests
This commit is contained in:
parent
3ad4c27968
commit
c02fd70c63
8 changed files with 93 additions and 67 deletions
|
@ -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',
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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~~ -> <del>strike-through</del>
|
||||
//
|
||||
// ~~strike-through~~ -> <del>strike-through</del> (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;
|
||||
}
|
||||
}());
|
|
@ -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;
|
||||
}
|
||||
}());
|
|
@ -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: /^<p>fizz <br \/>\nbuzz<\/p>$/},
|
||||
{input: "Hello world\nIt's a fine day", output: /^<p>Hello world <br \/>\nIt\'s a fine day<\/p>$/},
|
||||
{input: "Hello world\nIt is a fine day", output: /^<p>Hello world <br \/>\nIt is a fine day<\/p>$/},
|
||||
{input: "\"first\nsecond", output: /^<p>\"first <br \/>\nsecond<\/p>$/},
|
||||
{input: "\'first\nsecond", output: /^<p>\'first <br \/>\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: /^<p>ruby <br \/>\npython <br \/>\nerlang<\/p>$/},
|
||||
{input: "Hello world\nIt's a fine day\nout", output: /^<p>Hello world <br \/>\nIt\'s a fine day <br \/>\nout<\/p>$/}
|
||||
{input: "Hello world\nIt is a fine day\nout", output: /^<p>Hello world <br \/>\nIt is a fine day <br \/>\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: /^<p>ruby <br \/>\npython <br \/>\nerlang <br \/>\ngo<\/p>$/},
|
||||
{
|
||||
input: "Hello world\nIt's a fine day\noutside\nthe window",
|
||||
output: /^<p>Hello world <br \/>\nIt\'s a fine day <br \/>\noutside <br \/>\nthe window<\/p>$/
|
||||
input: "ruby\npython\nerlang\ngo",
|
||||
output: /^<p>ruby <br \/>\npython <br \/>\nerlang <br \/>\ngo<\/p>$/
|
||||
},
|
||||
{
|
||||
input: "Hello world\nIt is a fine day\noutside\nthe window",
|
||||
output: /^<p>Hello world <br \/>\nIt is a fine day <br \/>\noutside <br \/>\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: /^<h1 id="fizz">fizz<\/h1>\n\n<h1 id="buzz">buzz<\/h1>\n\n<h3 id="baz">baz<\/h3>$/},
|
||||
{input: "* foo\n* bar", output: /^<ul>\n<li>foo<\/li>\n<li>bar<\/li>\n<\/ul>$/}
|
||||
{
|
||||
input: "#fizz\n# buzz\n### baz",
|
||||
output: /^<h1 id="fizz">fizz<\/h1>\n\n<h1 id="buzz">buzz<\/h1>\n\n<h3 id="baz">baz<\/h3>$/
|
||||
},
|
||||
{
|
||||
input: "* foo\n* bar",
|
||||
output: /^<ul>\n<li>foo<\/li>\n<li>bar<\/li>\n<\/ul>$/
|
||||
}
|
||||
],
|
||||
processedMarkup;
|
||||
|
|
@ -4,12 +4,11 @@
|
|||
*/
|
||||
|
||||
/*globals describe, it */
|
||||
var testUtils = require('../utils'),
|
||||
should = require('should'),
|
||||
var testUtils = require('../utils'),
|
||||
should = require('should'),
|
||||
|
||||
// Stuff we are testing
|
||||
ghPath = "../../shared/lib/showdown/extensions/github.js",
|
||||
github = require(ghPath);
|
||||
ghostgfm = require('../../shared/lib/showdown/extensions/ghostgfm');
|
||||
|
||||
function _ExecuteExtension(ext, text) {
|
||||
if (ext.regex) {
|
||||
|
@ -21,20 +20,20 @@ function _ExecuteExtension(ext, text) {
|
|||
}
|
||||
|
||||
function _ConvertPhrase(testPhrase) {
|
||||
return github().reduce(function (text, ext) {
|
||||
return ghostgfm().reduce(function (text, ext) {
|
||||
return _ExecuteExtension(ext, text);
|
||||
}, testPhrase);
|
||||
}
|
||||
|
||||
|
||||
describe("Github showdown extensions", function () {
|
||||
describe("Ghost GFM showdown extension", function () {
|
||||
/*jslint regexp: true */
|
||||
|
||||
it("should export an array of methods for processing", function () {
|
||||
github.should.be.a.function;
|
||||
github().should.be.an.Array;
|
||||
ghostgfm.should.be.a.function;
|
||||
ghostgfm().should.be.an.Array;
|
||||
|
||||
github().forEach(function (processor) {
|
||||
ghostgfm().forEach(function (processor) {
|
||||
processor.should.be.an.Object;
|
||||
processor.should.have.property("type");
|
||||
processor.type.should.be.a.String;
|
||||
|
@ -50,6 +49,14 @@ describe("Github showdown extensions", function () {
|
|||
processedMarkup.should.match(testPhrase.output);
|
||||
});
|
||||
|
||||
it("should allow 4 underscores", function () {
|
||||
var testPhrase = {input: 'Ghost ____', output: /Ghost\s(?:_){4}$/},
|
||||
processedMarkup = _ConvertPhrase(testPhrase.input);
|
||||
|
||||
processedMarkup.should.match(testPhrase.output);
|
||||
});
|
||||
|
||||
|
||||
it("should auto-link URL in text with markdown syntax", function () {
|
||||
var testPhrases = [
|
||||
{
|
|
@ -6,21 +6,20 @@
|
|||
*/
|
||||
|
||||
/*globals describe, it */
|
||||
var testUtils = require('../utils'),
|
||||
should = require('should'),
|
||||
var testUtils = require('../utils'),
|
||||
should = require('should'),
|
||||
|
||||
// Stuff we are testing
|
||||
gdPath = "../../client/assets/lib/showdown/extensions/ghostdown.js",
|
||||
ghostdown = require(gdPath);
|
||||
ghostimagepreview = require('../../shared/lib/showdown/extensions/ghostimagepreview');
|
||||
|
||||
describe("Ghostdown showdown extensions", function () {
|
||||
describe("Ghost Image Preview showdown extension", function () {
|
||||
|
||||
it("should export an array of methods for processing", function () {
|
||||
|
||||
ghostdown.should.be.a.function;
|
||||
ghostdown().should.be.an.instanceof(Array);
|
||||
ghostimagepreview.should.be.a.function;
|
||||
ghostimagepreview().should.be.an.instanceof(Array);
|
||||
|
||||
ghostdown().forEach(function (processor) {
|
||||
ghostimagepreview().forEach(function (processor) {
|
||||
processor.should.be.an.Object;
|
||||
processor.should.have.property("type");
|
||||
processor.should.have.property("filter");
|
||||
|
@ -46,7 +45,7 @@ describe("Ghostdown showdown extensions", function () {
|
|||
]
|
||||
.forEach(function (imageMarkup) {
|
||||
var processedMarkup =
|
||||
ghostdown().reduce(function (prev, processor) {
|
||||
ghostimagepreview().reduce(function (prev, processor) {
|
||||
return processor.filter(prev);
|
||||
}, imageMarkup);
|
||||
|
||||
|
@ -55,15 +54,6 @@ describe("Ghostdown showdown extensions", function () {
|
|||
});
|
||||
});
|
||||
|
||||
it("should allow 4 underscores", function () {
|
||||
var processedMarkup =
|
||||
ghostdown().reduce(function (prev, processor) {
|
||||
return processor.filter(prev);
|
||||
}, "Ghost ____");
|
||||
|
||||
processedMarkup.should.match(/Ghost\s(?:_){4}$/);
|
||||
});
|
||||
|
||||
it("should correctly include an image", function () {
|
||||
[
|
||||
"![image and another,/ image](http://dsurl.stuff)",
|
||||
|
@ -75,7 +65,7 @@ describe("Ghostdown showdown extensions", function () {
|
|||
]
|
||||
.forEach(function (imageMarkup) {
|
||||
var processedMarkup =
|
||||
ghostdown().reduce(function (prev, processor) {
|
||||
ghostimagepreview().reduce(function (prev, processor) {
|
||||
return processor.filter(prev);
|
||||
}, imageMarkup);
|
||||
|
Loading…
Add table
Reference in a new issue