switch back to using commonmark for serialising MD when roundtripping

and escape MD correctly when serialising via slate-md-serializer
pull/21833/head
Matthew Hodgson 2018-05-20 14:33:14 +01:00
parent 9aba046f21
commit aac6866779
1 changed files with 36 additions and 24 deletions

View File

@ -182,6 +182,15 @@ export default class MessageComposerInput extends React.Component {
rules: [
{
serialize: (obj, children) => {
if (obj.object === 'string') {
// escape any MD in it. i have no idea why the serializer doesn't
// do this already.
// TODO: this can probably be more robust - it doesn't consider
// indenting or lists for instance.
return children.replace(/([*_~`+])/g, '\\$1')
.replace(/^([>#\|])/g, '\\$1');
}
else if (obj.object === 'inline') {
switch (obj.type) {
case 'pill':
return `[${ obj.data.get('completion') }](${ obj.data.get('href') })`;
@ -190,6 +199,7 @@ export default class MessageComposerInput extends React.Component {
}
}
}
}
]
});
@ -580,27 +590,29 @@ export default class MessageComposerInput extends React.Component {
let editorState = null;
if (enabled) {
// for simplicity when roundtripping, we use slate-md-serializer rather than commonmark
const markdown = this.plainWithMdPills.serialize(this.state.editorState);
// weirdly, the Md serializer can't deserialize '' to a valid Value...
if (markdown !== '') {
// FIXME: the MD deserializer doesn't know how to deserialize pills
// and gives no hooks for doing so, so we should manually fix up
// the editorState first in order to preserve them.
editorState = this.md.deserialize(markdown);
}
else {
editorState = Plain.deserialize('', { defaultBlock: DEFAULT_NODE });
}
// the alternative would be something like:
// for consistency when roundtripping, we could use slate-md-serializer rather than
// commonmark, but then we would lose pills as the MD deserialiser doesn't know about
// them and doesn't have any extensibility hooks.
//
// const sourceWithPills = this.plainWithMdPills.serialize(this.state.editorState);
// const markdown = new Markdown(sourceWithPills);
// editorState = this.html.deserialize(markdown.toHTML());
// The code looks like this:
//
// const markdown = this.plainWithMdPills.serialize(this.state.editorState);
//
// // weirdly, the Md serializer can't deserialize '' to a valid Value...
// if (markdown !== '') {
// editorState = this.md.deserialize(markdown);
// }
// else {
// editorState = Plain.deserialize('', { defaultBlock: DEFAULT_NODE });
// }
// so, instead, we use commonmark proper (which is arguably more logical to the user
// anyway, as they'll expect the RTE view to match what they'll see in the timeline,
// but the HTML->MD conversion is anyone's guess).
const sourceWithPills = this.plainWithMdPills.serialize(this.state.editorState);
const markdown = new Markdown(sourceWithPills);
editorState = this.html.deserialize(markdown.toHTML());
} else {
// let markdown = RichText.stateToMarkdown(this.state.editorState.getCurrentContent());
// value = ContentState.createFromText(markdown);