mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-23 22:11:09 +03:00
Merge pull request #2256 from caerphoto/1795-typography
Add support for typographically-correct punctuation
This commit is contained in:
commit
c64148f361
@ -382,6 +382,7 @@ var path = require('path'),
|
||||
'core/client/assets/vendor/codemirror/mode/gfm/gfm.js',
|
||||
'core/client/assets/vendor/showdown/showdown.js',
|
||||
'core/client/assets/vendor/showdown/extensions/ghostdown.js',
|
||||
'core/shared/vendor/showdown/extensions/typography.js',
|
||||
'core/shared/vendor/showdown/extensions/github.js',
|
||||
'core/client/assets/vendor/shortcuts.js',
|
||||
'core/client/assets/vendor/validator-client.js',
|
||||
@ -437,6 +438,7 @@ var path = require('path'),
|
||||
'core/client/assets/vendor/codemirror/mode/gfm/gfm.js',
|
||||
'core/client/assets/vendor/showdown/showdown.js',
|
||||
'core/client/assets/vendor/showdown/extensions/ghostdown.js',
|
||||
'core/shared/vendor/showdown/extensions/typography.js',
|
||||
'core/shared/vendor/showdown/extensions/github.js',
|
||||
'core/client/assets/vendor/shortcuts.js',
|
||||
'core/client/assets/vendor/validator-client.js',
|
||||
|
@ -449,7 +449,7 @@
|
||||
initMarkdown: function () {
|
||||
var self = this;
|
||||
|
||||
this.converter = new Showdown.converter({extensions: ['ghostdown', 'github']});
|
||||
this.converter = new Showdown.converter({extensions: ['typography', 'ghostdown', 'github']});
|
||||
this.editor = CodeMirror.fromTextArea(document.getElementById('entry-markdown'), {
|
||||
mode: 'gfm',
|
||||
tabMode: 'indent',
|
||||
|
@ -4,7 +4,8 @@ var _ = require('lodash'),
|
||||
errors = require('../errorHandling'),
|
||||
Showdown = require('showdown'),
|
||||
github = require('../../shared/vendor/showdown/extensions/github'),
|
||||
converter = new Showdown.converter({extensions: [github]}),
|
||||
typography = require('../../shared/vendor/showdown/extensions/typography'),
|
||||
converter = new Showdown.converter({extensions: [typography, github]}),
|
||||
User = require('./user').User,
|
||||
Tag = require('./tag').Tag,
|
||||
Tags = require('./tag').Tags,
|
||||
@ -453,4 +454,4 @@ Posts = ghostBookshelf.Collection.extend({
|
||||
module.exports = {
|
||||
Post: Post,
|
||||
Posts: Posts
|
||||
};
|
||||
};
|
||||
|
114
core/shared/vendor/showdown/extensions/typography.js
vendored
Normal file
114
core/shared/vendor/showdown/extensions/typography.js
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
/*global module */
|
||||
//
|
||||
// Replaces straight quotes with curly ones, -- and --- with en dash and em
|
||||
// dash respectively, and ... with horizontal ellipses.
|
||||
//
|
||||
|
||||
(function () {
|
||||
var typography = function () {
|
||||
return [
|
||||
{
|
||||
type: "lang",
|
||||
filter: function (text) {
|
||||
var fCodeblocks = {}, nCodeblocks = {}, iCodeblocks = {},
|
||||
e = {
|
||||
endash: '\u2009\u2013\u2009', // U+2009 = thin space
|
||||
emdash: '\u2014',
|
||||
lsquo: '\u2018',
|
||||
rsquo: '\u2019',
|
||||
ldquo: '\u201c',
|
||||
rdquo: '\u201d',
|
||||
hellip: '\u2026'
|
||||
},
|
||||
|
||||
i;
|
||||
|
||||
// Extract fenced code blocks.
|
||||
i = -1;
|
||||
text = text.replace(/```((?:.|\n)+?)```/g,
|
||||
function (match, code) {
|
||||
i += 1;
|
||||
fCodeblocks[i] = "```" + code + "```";
|
||||
return "{typog-fcb-" + i + "}";
|
||||
});
|
||||
|
||||
// Extract indented code blocks.
|
||||
i = -1;
|
||||
text = text.replace(/((\n+([ ]{4}|\t).+)+)/g,
|
||||
function (match, code) {
|
||||
i += 1;
|
||||
nCodeblocks[i] = " " + code;
|
||||
return "{typog-ncb-" + i + "}";
|
||||
});
|
||||
|
||||
// Extract inline code blocks
|
||||
i = -1;
|
||||
text = text.replace(/`(.+)`/g, function (match, code) {
|
||||
i += 1;
|
||||
iCodeblocks[i] = "`" + code + "`";
|
||||
return "{typog-icb-" + i + "}";
|
||||
});
|
||||
|
||||
// Perform typographic symbol replacement.
|
||||
|
||||
// Double quotes. There might be a reason this doesn't use
|
||||
// the same \b matching style as the single quotes, but I
|
||||
// can't remember what it is :(
|
||||
text = text.
|
||||
// Opening quotes
|
||||
replace(/"([\w'])/g, e.ldquo + "$1").
|
||||
// All the rest
|
||||
replace(/"/g, e.rdquo);
|
||||
|
||||
// Single quotes/apostrophes
|
||||
text = text.
|
||||
// Apostrophes first
|
||||
replace(/\b'\b/g, e.rsquo).
|
||||
// Opening quotes
|
||||
replace(/'\b/g, e.lsquo).
|
||||
// All the rest
|
||||
replace(/'/g, e.rsquo);
|
||||
|
||||
// Dashes
|
||||
text = text.
|
||||
// Don't replace lines containing only hyphens
|
||||
replace(/^-+$/gm, "{typog-hr}").
|
||||
replace(/---/g, e.emdash).
|
||||
replace(/ -- /g, e.endash).
|
||||
replace(/{typog-hr}/g, "----");
|
||||
|
||||
// Ellipses.
|
||||
text = text.replace(/\.{3}/g, e.hellip);
|
||||
|
||||
|
||||
// Restore fenced code blocks.
|
||||
text = text.replace(/{typog-fcb-([0-9]+)}/g, function (x, y) {
|
||||
return fCodeblocks[y];
|
||||
});
|
||||
|
||||
// Restore indented code blocks.
|
||||
text = text.replace(/{typog-ncb-([0-9]+)}/g, function (x, y) {
|
||||
return nCodeblocks[y];
|
||||
});
|
||||
|
||||
// Restore inline code blocks.
|
||||
text = text.replace(/{typog-icb-([0-9]+)}/g, function (x, y) {
|
||||
return iCodeblocks[y];
|
||||
});
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
// Client-side export
|
||||
if (typeof window !== 'undefined' && window.Showdown && window.Showdown.extensions) {
|
||||
window.Showdown.extensions.typography = typography;
|
||||
}
|
||||
// Server-side export
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = typography;
|
||||
}
|
||||
}());
|
||||
|
@ -10,7 +10,7 @@ CasperTest.begin('Ensure that RSS is available', 11, function suite(test) {
|
||||
siteDescription = '<description><![CDATA[Just a blogging platform.]]></description>',
|
||||
siteUrl = '<link>http://127.0.0.1:2369/</link>',
|
||||
postTitle = '<![CDATA[Welcome to Ghost]]>',
|
||||
postStart = '<description><![CDATA[<p>You\'re live!',
|
||||
postStart = '<description><![CDATA[<p>You’re live!',
|
||||
postEnd = 'you think :)</p>]]></description>',
|
||||
postLink = '<link>http://127.0.0.1:2369/welcome-to-ghost/</link>',
|
||||
postCreator = '<dc:creator><![CDATA[Test User]]>';
|
||||
|
Loading…
Reference in New Issue
Block a user