Koenig - ^superscript^ and ~subscript~ text expansion support

refs https://github.com/TryGhost/Ghost/issues/9623
- added additional text expansions for `^sup^` and `~sub~` that also work inside of words
- added sub and sub expansions to the special formats list so that <kbd>Backspace</kbd> undoes the expansion
This commit is contained in:
Kevin Ansfield 2018-06-01 17:53:15 +01:00
parent 1ebdfac55d
commit dc6064b567
2 changed files with 83 additions and 36 deletions

View File

@ -67,7 +67,9 @@ export const NO_CURSOR_MOVEMENT = 0;
// text expansion style when backspacing over final char of markup
export const SPECIAL_MARKUPS = {
S: '~~',
CODE: '`'
CODE: '`',
SUP: '^',
SUB: '~'
};
function arrayToMap(array) {

View File

@ -113,41 +113,6 @@ export default function (editor, koenig) {
/* inline markdown ------------------------------------------------------ */
// We don't want to run all our content rules on every text entry event,
// instead we check to see if this text entry event could match a content
// rule, and only then run the rules. Right now we only want to match
// content ending with *, _, ), ~, and `. This could increase as we support
// more markdown.
editor.onTextInput({
name: 'inline_markdown',
match: /[*_)~`]$/,
run(editor, matches) {
let text = editor.range.head.section.textUntil(editor.range.head);
switch (matches[0]) {
case '*':
matchStrongStar(editor, text);
matchEmStar(editor, text);
break;
case '_':
matchStrongUnderscore(editor, text);
matchEmUnderscore(editor, text);
break;
case ')':
matchLink(editor, text);
matchImage(editor, text);
break;
case '~':
matchStrikethrough(editor, text);
break;
case '`':
matchCode(editor, text);
break;
}
}
});
// --\s = en dash
// ---. = em dash —
// separate to the grouped replacement functions because we're matching on
@ -197,6 +162,45 @@ export default function (editor, koenig) {
}
});
// We don't want to run all our content rules on every text entry event,
// instead we check to see if this text entry event could match a content
// rule, and only then run the rules. Right now we only want to match
// content ending with *, _, ), ~, and `. This could increase as we support
// more markdown.
editor.onTextInput({
name: 'inline_markdown',
match: /[*_)~`^]$/,
run(editor, matches) {
let text = editor.range.head.section.textUntil(editor.range.head);
switch (matches[0]) {
case '*':
matchStrongStar(editor, text);
matchEmStar(editor, text);
break;
case '_':
matchStrongUnderscore(editor, text);
matchEmUnderscore(editor, text);
break;
case ')':
matchLink(editor, text);
matchImage(editor, text);
break;
case '~':
matchSub(editor, text);
matchStrikethrough(editor, text);
break;
case '`':
matchCode(editor, text);
break;
case '^':
matchSup(editor, text);
break;
}
}
});
function matchStrongStar(editor, text) {
let {range} = editor;
let matches = text.match(/(?:^|\s)\*\*([^\s*]+|[^\s*][^*]*[^\s])\*\*/);
@ -291,6 +295,27 @@ export default function (editor, koenig) {
}
}
function matchSub(editor, text) {
let {range} = editor;
let matches = text.match(/(^|[^~])~([^\s~]+|[^\s~][^~]*[^\s])~/);
console.log(matches);
if (matches) {
let match = matches[0].trim();
range = range.extend(-(match.length - matches[1].trim().length));
editor.run((postEditor) => {
let position = postEditor.deleteRange(range);
let sub = postEditor.builder.createMarkup('sub');
postEditor.insertTextWithMarkup(position, matches[2], [sub]);
});
// must be scheduled so that the toggle isn't reset automatically
run.schedule('actions', this, function () {
editor.toggleMarkup('sub');
});
}
}
function matchStrikethrough(editor, text) {
let {range} = editor;
let matches = text.match(/(?:^|\s)~~([^\s~]+|[^\s~][^~]*[^\s])~~/);
@ -331,6 +356,26 @@ export default function (editor, koenig) {
}
}
function matchSup(editor, text) {
let {range} = editor;
let matches = text.match(/\^([^\s^]+|[^\s^][^^]*[^\s^])\^/);
if (matches) {
let match = matches[0].trim();
range = range.extend(-(match.length));
editor.run((postEditor) => {
let position = postEditor.deleteRange(range);
let sup = postEditor.builder.createMarkup('sup');
postEditor.insertTextWithMarkup(position, matches[1], [sup]);
});
// must be scheduled so that the toggle isn't reset automatically
run.schedule('actions', this, function () {
editor.toggleMarkup('sup');
});
}
}
function matchLink(editor, text) {
let {range} = editor;
let matches = text.match(/(?:^|\s)\[([^\s\]]+|[^\s\]][^\]]*[^\s\]])\]\(([^\s)]+|[^\s)][^)]*[^\s)])\)/);