FEATURE: Replace markdown-it replacements rule. (#12417)
We override the default replacements rule to no longer replace "(c)", "(p)", and "(p)". Additionally, we merged the custom arrows rule into the replacement function.
This commit is contained in:
parent
1a433193d1
commit
da210b6d77
|
@ -1601,4 +1601,74 @@ var bar = 'bar';
|
||||||
assert.cookedOptions(" -->asd ", enabledTypographer, "<p>–>asd</p>");
|
assert.cookedOptions(" -->asd ", enabledTypographer, "<p>–>asd</p>");
|
||||||
assert.cookedOptions(" -->asd", enabledTypographer, "<p>–>asd</p>");
|
assert.cookedOptions(" -->asd", enabledTypographer, "<p>–>asd</p>");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("default typhographic replacements", function (assert) {
|
||||||
|
const enabledTypographer = {
|
||||||
|
siteSettings: { enable_markdown_typographer: true },
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.cookedOptions("(bad)", enabledTypographer, "<p>(bad)</p>");
|
||||||
|
assert.cookedOptions("+-5", enabledTypographer, "<p>±5</p>");
|
||||||
|
assert.cookedOptions(
|
||||||
|
"test.. test... test..... test?..... test!....",
|
||||||
|
enabledTypographer,
|
||||||
|
"<p>test… test… test… test?.. test!..</p>"
|
||||||
|
);
|
||||||
|
assert.cookedOptions(
|
||||||
|
"!!!!!! ???? ,,",
|
||||||
|
enabledTypographer,
|
||||||
|
"<p>!!! ??? ,</p>"
|
||||||
|
);
|
||||||
|
assert.cookedOptions(
|
||||||
|
"!!!!!! ???? ,,",
|
||||||
|
enabledTypographer,
|
||||||
|
"<p>!!! ??? ,</p>"
|
||||||
|
);
|
||||||
|
assert.cookedOptions("(tm) (TM)", enabledTypographer, "<p>™ ™</p>");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("default typhographic replacements - dashes", function (assert) {
|
||||||
|
const enabledTypographer = {
|
||||||
|
siteSettings: { enable_markdown_typographer: true },
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.cookedOptions(
|
||||||
|
"---markdownit --- super---",
|
||||||
|
enabledTypographer,
|
||||||
|
"<p>—markdownit — super—</p>"
|
||||||
|
);
|
||||||
|
assert.cookedOptions(
|
||||||
|
"markdownit---awesome",
|
||||||
|
enabledTypographer,
|
||||||
|
"<p>markdownit—awesome</p>"
|
||||||
|
);
|
||||||
|
assert.cookedOptions("abc ----", enabledTypographer, "<p>abc ----</p>");
|
||||||
|
assert.cookedOptions(
|
||||||
|
"--markdownit -- super--",
|
||||||
|
enabledTypographer,
|
||||||
|
"<p>–markdownit – super–</p>"
|
||||||
|
);
|
||||||
|
assert.cookedOptions(
|
||||||
|
"markdownit--awesome",
|
||||||
|
enabledTypographer,
|
||||||
|
"<p>markdownit–awesome</p>"
|
||||||
|
);
|
||||||
|
assert.cookedOptions("1---2---3", enabledTypographer, "<p>1—2—3</p>");
|
||||||
|
assert.cookedOptions("1--2--3", enabledTypographer, "<p>1–2–3</p>");
|
||||||
|
assert.cookedOptions(
|
||||||
|
"<p>1 – – 3</p>",
|
||||||
|
enabledTypographer,
|
||||||
|
"<p>1 – – 3</p>"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("disabled typhographic replacements", function (assert) {
|
||||||
|
const enabledTypographer = {
|
||||||
|
siteSettings: { enable_markdown_typographer: true },
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.cookedOptions("(c) (C)", enabledTypographer, "<p>(c) (C)</p>");
|
||||||
|
assert.cookedOptions("(r) (R)", enabledTypographer, "<p>(r) (R)</p>");
|
||||||
|
assert.cookedOptions("(p) (P)", enabledTypographer, "<p>(p) (P)</p>");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
// Simple typographic replacements
|
||||||
|
//
|
||||||
|
// (tm) (TM) → ™
|
||||||
|
// +- → ±
|
||||||
|
// ... → … (also ?.... → ?.., !.... → !..)
|
||||||
|
// ???????? → ???, !!!!! → !!!, `,,` → `,`
|
||||||
|
// -- → –, --- → —
|
||||||
|
// --> <-- -> <- to → ← → ←
|
||||||
|
//
|
||||||
|
// Disabled replacements:
|
||||||
|
//
|
||||||
|
// (c) (C) → ©
|
||||||
|
// (r) (R) → ®
|
||||||
|
// (p) (P) -> §
|
||||||
|
|
||||||
|
let RARE_RE = /\+-|\.\.|\?\?\?\?|!!!!|,,|--|-->|<--|->|<-/;
|
||||||
|
let SCOPED_ABBR_RE = /\((tm)\)/gi;
|
||||||
|
|
||||||
|
function replaceScoped(inlineTokens) {
|
||||||
|
let i, token;
|
||||||
|
|
||||||
|
for (i = inlineTokens.length - 1; i >= 0; i--) {
|
||||||
|
token = inlineTokens[i];
|
||||||
|
if (token.type === "text") {
|
||||||
|
token.content = token.content.replace(SCOPED_ABBR_RE, () => {
|
||||||
|
return "™";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function replaceRare(inlineTokens) {
|
||||||
|
let i,
|
||||||
|
token,
|
||||||
|
inside_autolink = 0;
|
||||||
|
|
||||||
|
for (i = inlineTokens.length - 1; i >= 0; i--) {
|
||||||
|
token = inlineTokens[i];
|
||||||
|
|
||||||
|
if (token.type === "text" && !inside_autolink) {
|
||||||
|
if (RARE_RE.test(token.content)) {
|
||||||
|
token.content = token.content
|
||||||
|
.replace(/\+-/g, "±")
|
||||||
|
// Custom arrows
|
||||||
|
.replace(/(^|\s)-{1,2}>(\s|$)/gm, "\u0020\u2192\u0020")
|
||||||
|
.replace(/(^|\s)<-{1,2}(\s|$)/gm, "\u0020\u2190\u0020")
|
||||||
|
// .., ..., ....... -> …
|
||||||
|
// but ?..... & !..... -> ?.. & !..
|
||||||
|
.replace(/\.{2,}/g, "…")
|
||||||
|
.replace(/([?!])…/g, "$1..")
|
||||||
|
.replace(/([?!]){4,}/g, "$1$1$1")
|
||||||
|
.replace(/,{2,}/g, ",")
|
||||||
|
// em-dash
|
||||||
|
.replace(/(^|[^-])---(?=[^-]|$)/gm, "$1\u2014")
|
||||||
|
// en-dash
|
||||||
|
.replace(/(^|\s)--(?=\s|$)/gm, "$1\u2013")
|
||||||
|
.replace(/(^|[^-\s])--(?=[^-\s]|$)/gm, "$1\u2013");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token.type === "link_open" && token.info === "auto") {
|
||||||
|
inside_autolink--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token.type === "link_close" && token.info === "auto") {
|
||||||
|
inside_autolink++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function replace(state) {
|
||||||
|
let blkIdx;
|
||||||
|
|
||||||
|
for (blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) {
|
||||||
|
if (state.tokens[blkIdx].type !== "inline") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SCOPED_ABBR_RE.test(state.tokens[blkIdx].content)) {
|
||||||
|
replaceScoped(state.tokens[blkIdx].children);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RARE_RE.test(state.tokens[blkIdx].content)) {
|
||||||
|
replaceRare(state.tokens[blkIdx].children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setup(helper) {
|
||||||
|
helper.registerPlugin((md) => {
|
||||||
|
if (md.options.typographer) {
|
||||||
|
md.core.ruler.at("replacements", replace);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -1,32 +0,0 @@
|
||||||
function replaceArrows(state) {
|
|
||||||
for (let i = 0; i < state.tokens.length; i++) {
|
|
||||||
let token = state.tokens[i];
|
|
||||||
|
|
||||||
if (token.type !== "inline") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const arrowsRegexp = /-->|<--|->|<-/;
|
|
||||||
if (arrowsRegexp.test(token.content)) {
|
|
||||||
for (let ci = 0; ci < token.children.length; ci++) {
|
|
||||||
let child = token.children[ci];
|
|
||||||
|
|
||||||
if (child.type === "text") {
|
|
||||||
if (arrowsRegexp.test(child.content)) {
|
|
||||||
child.content = child.content
|
|
||||||
.replace(/(^|\s)-{1,2}>(\s|$)/gm, "\u0020\u2192\u0020")
|
|
||||||
.replace(/(^|\s)<-{1,2}(\s|$)/gm, "\u0020\u2190\u0020");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setup(helper) {
|
|
||||||
helper.registerPlugin((md) => {
|
|
||||||
if (md.options.typographer) {
|
|
||||||
md.core.ruler.before("replacements", "typographer-arrow", replaceArrows);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1442,10 +1442,10 @@ HTML
|
||||||
|
|
||||||
it 'supports typographer' do
|
it 'supports typographer' do
|
||||||
SiteSetting.enable_markdown_typographer = true
|
SiteSetting.enable_markdown_typographer = true
|
||||||
expect(PrettyText.cook('(tm)')).to eq('<p>™</p>')
|
expect(PrettyText.cook('->')).to eq('<p> → </p>')
|
||||||
|
|
||||||
SiteSetting.enable_markdown_typographer = false
|
SiteSetting.enable_markdown_typographer = false
|
||||||
expect(PrettyText.cook('(tm)')).to eq('<p>(tm)</p>')
|
expect(PrettyText.cook('->')).to eq('<p>-></p>')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'uses quotation marks from site settings' do
|
it 'uses quotation marks from site settings' do
|
||||||
|
|
Loading…
Reference in New Issue