From ef3a94772ba1f0df36f31442307223ada560eb68 Mon Sep 17 00:00:00 2001 From: d3m1d0v Date: Thu, 15 Jun 2023 14:56:54 +0300 Subject: [PATCH] fix: escape whitespaces within superscript and subscript --- src/core/markdown/MarkdownSerializer.js | 11 ++++++++++- src/extensions/markdown/Subscript/Subscript.test.ts | 7 +++++++ .../markdown/Subscript/SubscriptSpecs/index.ts | 13 ++++++++++++- .../markdown/Superscript/Superscript.test.ts | 7 +++++++ .../markdown/Superscript/SuperscriptSpecs/index.ts | 13 ++++++++++++- 5 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/core/markdown/MarkdownSerializer.js b/src/core/markdown/MarkdownSerializer.js index 9ccf3b9d4..4bd6e7ef0 100644 --- a/src/core/markdown/MarkdownSerializer.js +++ b/src/core/markdown/MarkdownSerializer.js @@ -79,6 +79,8 @@ export class MarkdownSerializerState { this.noAutoBlank = false; /** @type {Boolean|undefined} */ this.isAutolink = undefined; + /** @type {Boolean} */ + this.escapeWhitespace = false; // :: Object // The options passed to the serializer. // tightLists:: ?bool @@ -162,7 +164,10 @@ export class MarkdownSerializerState { for (let i = 0; i < lines.length; i++) { const startOfLine = this.atBlank() || this.closed; this.write(); - this.out += escape !== false ? this.esc(lines[i], startOfLine) : lines[i]; + let text = lines[i]; + if (escape !== false) text = this.esc(text, startOfLine) + if (this.escapeWhitespace) text = this.escWhitespace(text); + this.out += text if (i != lines.length - 1) this.out += '\n'; } } @@ -297,6 +302,10 @@ export class MarkdownSerializerState { return str; } + escWhitespace(str) { + return str.replace(/ /g, '\\ '); + } + quote(str) { const wrap = str.indexOf('"') == -1 ? '""' : str.indexOf("'") == -1 ? "''" : '()'; return wrap[0] + str + wrap[1]; diff --git a/src/extensions/markdown/Subscript/Subscript.test.ts b/src/extensions/markdown/Subscript/Subscript.test.ts index 3432e55b6..bd064a662 100644 --- a/src/extensions/markdown/Subscript/Subscript.test.ts +++ b/src/extensions/markdown/Subscript/Subscript.test.ts @@ -26,4 +26,11 @@ describe('Subscript extension', () => { it('should parse html - sub tag', () => { parseDOM(schema, '

subscript

', doc(p(s('subscript')))); }); + + it('should escape whitespaces', () => { + same( + 'Ok, hello~w\\ o\\ r\\ l\\ d~! This world is beautiful!', + doc(p('Ok, hello', s('w o r l d'), '! This world is beautiful!')), + ); + }); }); diff --git a/src/extensions/markdown/Subscript/SubscriptSpecs/index.ts b/src/extensions/markdown/Subscript/SubscriptSpecs/index.ts index fde7e606a..42a5a6e06 100644 --- a/src/extensions/markdown/Subscript/SubscriptSpecs/index.ts +++ b/src/extensions/markdown/Subscript/SubscriptSpecs/index.ts @@ -18,7 +18,18 @@ export const SubscriptSpecs: ExtensionAuto = (builder) => { return ['sub']; }, }, - toYfm: {open: '~', close: '~', mixable: false, expelEnclosingWhitespace: true}, + toYfm: { + open: (state) => { + state.escapeWhitespace = true; + return '~'; + }, + close: (state) => { + state.escapeWhitespace = false; + return '~'; + }, + mixable: false, + expelEnclosingWhitespace: true, + }, fromYfm: {tokenSpec: {name: subscriptMarkName, type: 'mark'}}, })); }; diff --git a/src/extensions/markdown/Superscript/Superscript.test.ts b/src/extensions/markdown/Superscript/Superscript.test.ts index 3e75cf886..2b1281f38 100644 --- a/src/extensions/markdown/Superscript/Superscript.test.ts +++ b/src/extensions/markdown/Superscript/Superscript.test.ts @@ -26,4 +26,11 @@ describe('Superscript extension', () => { it('should parse html - sup tag', () => { parseDOM(schema, '

superscript

', doc(p(s('superscript')))); }); + + it('should escape whitespaces', () => { + same( + 'Ok, hello^w\\ o\\ r\\ l\\ d^! This world is beautiful!', + doc(p('Ok, hello', s('w o r l d'), '! This world is beautiful!')), + ); + }); }); diff --git a/src/extensions/markdown/Superscript/SuperscriptSpecs/index.ts b/src/extensions/markdown/Superscript/SuperscriptSpecs/index.ts index 9a9cace96..748d8047c 100644 --- a/src/extensions/markdown/Superscript/SuperscriptSpecs/index.ts +++ b/src/extensions/markdown/Superscript/SuperscriptSpecs/index.ts @@ -18,7 +18,18 @@ export const SuperscriptSpecs: ExtensionAuto = (builder) => { return ['sup']; }, }, - toYfm: {open: '^', close: '^', mixable: true, expelEnclosingWhitespace: true}, + toYfm: { + open: (state) => { + state.escapeWhitespace = true; + return '^'; + }, + close: (state) => { + state.escapeWhitespace = false; + return '^'; + }, + mixable: true, + expelEnclosingWhitespace: true, + }, fromYfm: {tokenSpec: {name: superscriptMarkName, type: 'mark'}}, })); };