-
-
Notifications
You must be signed in to change notification settings - Fork 593
Inline markdown symbols like *, _ don't apply when not surrounded by whitespace. #110
Comments
It totally depends on how you type it, as you've seen the markdown syntax is only converted into an actual bold mark after hitting the space character. It could also be changed to convert to a mark on the final "*" character. The key here is that the editor doesn't just take anything that looks like markdown and render it as markdown, characters that look like markdown but are in the regular content are escaped for this reason. TLDR: Depending on how those examples above were typed they could be considered a feature and not a bug. |
I do understand that this is intended behavior in the current design and that in many circumstances it may be more intuitive (even if not in line with the markdown spec). However, I do think the mark conversion should also happen for the I realize the
This was my initial thought and in my opinion would be the way to go if not for the fact that the final character is ambiguous in the case of bold/italic (i.e. when typing |
The only hill I'm willing to die on here is that the content of the document should never change on reload – ie. If I see There's a slate autoReplace plugin which I think could manage this behavior as you've described, we'd essentially define a plugin for each individual mark type and have it convert on the last character. I think this is probably the way to go rather than hacking at the existing implementation – could even convert one mark at a time. |
I 100% agree that the document state should remain consistent between reloads. I did come up with this solution that seems to solve the problem without introducing too much complexity by toggling the mark on a range trimmed to exclude that whitespace: import {Range} from 'slate';
export default function KeyboardShortcuts() {
/**
* Map the given keyboard event to the relevant mark to be toggled.
*
* @param {Event} ev keyboard event
* @param {Editor} editor
* @param {function} next middleware.
* @return {*|void|Range|*}
*/
function onKeyDown(ev, editor, next) {
if (!isModKey(ev)) return next();
switch (ev.key) {
case 'b':
ev.preventDefault();
return toggleMark(editor, 'bold', next);
case 'i':
ev.preventDefault();
return toggleMark(editor, 'italic', next);
case 'u':
ev.preventDefault();
return toggleMark(editor, 'underlined', next);
case 'd':
ev.preventDefault();
return toggleMark(editor, 'deleted', next);
case 'k':
ev.preventDefault();
return editor.wrapLink('');
default:
return next();
}
}
/**
* Get a range for the current selection excluding any leading or trailing
* whitespace (including newlines).
*
* @param {Editor} editor Reference to SlateJS Editor
* @return {Range} for current selection including whitespace.
*/
function getSelectionRangeExcludingWhitespace(editor) {
const selectedText = value.fragment.text;
const selectionRange = Range.create(editor.value.selection);
const leadingSpace = /^\s*/.exec(selectedText)[0];
const trailingSpace = /\s*$/.exec(selectedText)[0];
const numLeadingSpaces = leadingSpace.length;
const numTrailingSpaces = trailingSpace.length;
return selectionRange
.moveStartForward(numLeadingSpaces)
.moveEndBackward(numTrailingSpaces);
}
/**
* If we're not in a heading, remove any code marks in the current selection
* and wrap the selected text with mark of `type`.
*
* @param {Editor} editor.
* @param {String} type of mark to be applied.
* @param {function} next middleware.
* @return {Range} for current selection including whitespace.
*/
function toggleMark(editor, type, next) {
const {value} = editor;
// don't allow formatting of main document title
if (value.startBlock.type === 'heading1') return next();
const trimmedSelection = getSelectionRangeExcludingWhitespace(editor);
editor.removeMark('code').toggleMarkAtRange(trimmedSelection, type);
}
return {onKeyDown};
} Let me know what you think. |
It looks neat enough, but isn't the original issue around the inline shortcuts? Not keyboard shortcuts? |
Example input:
this is **bold**.
should render "this is bold." in editor but instead renders "this is **bold**".
This happens whenever the markdown inline shortcuts are not surrounded by whitespace or at the beginning or end of the block. The underlying issue is from the logic defined in MarkdownShortcuts at
rich-markdown-editor/src/plugins/MarkdownShortcuts.js
Line 113 in 63ad0c4
Let me know if I can provide other examples or a PR.
The text was updated successfully, but these errors were encountered: