Skip to content

Commit db35e5b

Browse files
authored
fix: escape whitespaces within superscript and subscript (#104)
1 parent 3415a3f commit db35e5b

File tree

5 files changed

+48
-3
lines changed

5 files changed

+48
-3
lines changed

src/core/markdown/MarkdownSerializer.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ export class MarkdownSerializerState {
7979
this.noAutoBlank = false;
8080
/** @type {Boolean|undefined} */
8181
this.isAutolink = undefined;
82+
/** @type {Boolean} */
83+
this.escapeWhitespace = false;
8284
// :: Object
8385
// The options passed to the serializer.
8486
// tightLists:: ?bool
@@ -162,7 +164,10 @@ export class MarkdownSerializerState {
162164
for (let i = 0; i < lines.length; i++) {
163165
const startOfLine = this.atBlank() || this.closed;
164166
this.write();
165-
this.out += escape !== false ? this.esc(lines[i], startOfLine) : lines[i];
167+
let text = lines[i];
168+
if (escape !== false) text = this.esc(text, startOfLine)
169+
if (this.escapeWhitespace) text = this.escWhitespace(text);
170+
this.out += text
166171
if (i != lines.length - 1) this.out += '\n';
167172
}
168173
}
@@ -297,6 +302,10 @@ export class MarkdownSerializerState {
297302
return str;
298303
}
299304

305+
escWhitespace(str) {
306+
return str.replace(/ /g, '\\ ');
307+
}
308+
300309
quote(str) {
301310
const wrap = str.indexOf('"') == -1 ? '""' : str.indexOf("'") == -1 ? "''" : '()';
302311
return wrap[0] + str + wrap[1];

src/extensions/markdown/Subscript/Subscript.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,11 @@ describe('Subscript extension', () => {
2626
it('should parse html - sub tag', () => {
2727
parseDOM(schema, '<p><sub>subscript</sub></p>', doc(p(s('subscript'))));
2828
});
29+
30+
it('should escape whitespaces', () => {
31+
same(
32+
'Ok, hello~w\\ o\\ r\\ l\\ d~! This world is beautiful!',
33+
doc(p('Ok, hello', s('w o r l d'), '! This world is beautiful!')),
34+
);
35+
});
2936
});

src/extensions/markdown/Subscript/SubscriptSpecs/index.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,18 @@ export const SubscriptSpecs: ExtensionAuto = (builder) => {
1818
return ['sub'];
1919
},
2020
},
21-
toYfm: {open: '~', close: '~', mixable: false, expelEnclosingWhitespace: true},
21+
toYfm: {
22+
open: (state) => {
23+
state.escapeWhitespace = true;
24+
return '~';
25+
},
26+
close: (state) => {
27+
state.escapeWhitespace = false;
28+
return '~';
29+
},
30+
mixable: false,
31+
expelEnclosingWhitespace: true,
32+
},
2233
fromYfm: {tokenSpec: {name: subscriptMarkName, type: 'mark'}},
2334
}));
2435
};

src/extensions/markdown/Superscript/Superscript.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,11 @@ describe('Superscript extension', () => {
2626
it('should parse html - sup tag', () => {
2727
parseDOM(schema, '<p><sup>superscript</sup></p>', doc(p(s('superscript'))));
2828
});
29+
30+
it('should escape whitespaces', () => {
31+
same(
32+
'Ok, hello^w\\ o\\ r\\ l\\ d^! This world is beautiful!',
33+
doc(p('Ok, hello', s('w o r l d'), '! This world is beautiful!')),
34+
);
35+
});
2936
});

src/extensions/markdown/Superscript/SuperscriptSpecs/index.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,18 @@ export const SuperscriptSpecs: ExtensionAuto = (builder) => {
1818
return ['sup'];
1919
},
2020
},
21-
toYfm: {open: '^', close: '^', mixable: true, expelEnclosingWhitespace: true},
21+
toYfm: {
22+
open: (state) => {
23+
state.escapeWhitespace = true;
24+
return '^';
25+
},
26+
close: (state) => {
27+
state.escapeWhitespace = false;
28+
return '^';
29+
},
30+
mixable: true,
31+
expelEnclosingWhitespace: true,
32+
},
2233
fromYfm: {tokenSpec: {name: superscriptMarkName, type: 'mark'}},
2334
}));
2435
};

0 commit comments

Comments
 (0)