mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-29 15:12:58 +03:00
✨ 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:
parent
1ebdfac55d
commit
dc6064b567
@ -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) {
|
||||
|
@ -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)])\)/);
|
||||
|
Loading…
Reference in New Issue
Block a user