From d22044a2e93427fb46e4364f226e7777b247a8d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EB=8C=80=EC=97=B0?=
Date: Tue, 14 Jun 2022 14:53:50 +0900
Subject: [PATCH 1/5] wip: convert strong to tag when it is not between spaces
---
.../toMarkdown/toMdConvertorState.ts | 37 ++++++++++++++++++-
.../convertors/toMarkdown/toMdConvertors.ts | 17 +++++++--
apps/editor/src/utils/common.ts | 10 +++++
apps/editor/types/convertor.d.ts | 6 ++-
4 files changed, 62 insertions(+), 8 deletions(-)
diff --git a/apps/editor/src/convertors/toMarkdown/toMdConvertorState.ts b/apps/editor/src/convertors/toMarkdown/toMdConvertorState.ts
index 544a186f58..0d279fbe19 100644
--- a/apps/editor/src/convertors/toMarkdown/toMdConvertorState.ts
+++ b/apps/editor/src/convertors/toMarkdown/toMdConvertorState.ts
@@ -1,6 +1,6 @@
import { Node, Mark } from 'prosemirror-model';
-import { includes, escape, last } from '@/utils/common';
+import { includes, escape, last, isEndWithSpace, isStartWithSpace } from '@/utils/common';
import { WwNodeType, WwMarkType } from '@t/wysiwyg';
import {
@@ -49,11 +49,44 @@ export default class ToMdConvertorState {
return /(^|\n)$/.test(this.result);
}
+ private isBeteewnSpaces(parent: Node, index: number) {
+ const { content } = parent;
+ // const frontText = content.child(index - 1).text;
+ // const rearText = content.child(index + 1).text;
+
+ const isFrontNodeEndWithSpace =
+ index === 0 || isEndWithSpace(content.child(index - 1).text ?? 'a');
+
+ if (index !== 0) {
+ console.log(index, isFrontNodeEndWithSpace);
+ }
+
+ const isRearNodeStartWithSpace =
+ index >= content.childCount - 1 || isStartWithSpace(content.child(index + 1).text ?? 'a');
+
+ if (index - 1 >= 0 && index + 1 <= content.childCount - 1) {
+ console.log(
+ isEndWithSpace(content.child(index - 1).text ?? 'a'),
+ isStartWithSpace(content.child(index + 1).text ?? 'a'),
+ isFrontNodeEndWithSpace,
+ isRearNodeStartWithSpace,
+ content
+ );
+ }
+
+ return isFrontNodeEndWithSpace && isRearNodeStartWithSpace;
+ }
+
private markText(mark: Mark, entering: boolean, parent: Node, index: number) {
const convertor = this.getMarkConvertor(mark);
if (convertor) {
- const { delim, rawHTML } = convertor({ node: mark, parent, index }, entering);
+ if (mark.type.name === 'strong') {
+ // debugger;
+ }
+ const betweenSpace = this.isBeteewnSpaces(parent, entering ? index : index - 1);
+
+ const { delim, rawHTML } = convertor({ node: mark, parent, index }, entering, betweenSpace);
return (rawHTML as string) || (delim as string);
}
diff --git a/apps/editor/src/convertors/toMarkdown/toMdConvertors.ts b/apps/editor/src/convertors/toMarkdown/toMdConvertors.ts
index 71066e7b18..c8655736d1 100644
--- a/apps/editor/src/convertors/toMarkdown/toMdConvertors.ts
+++ b/apps/editor/src/convertors/toMarkdown/toMdConvertors.ts
@@ -208,11 +208,18 @@ export const toMdConvertors: ToMdConvertorMap = {
};
},
- strong({ node }, { entering }) {
+ strong({ node }, { entering }, betweenSpace) {
const { rawHTML } = node.attrs;
+ let delim;
+
+ if (betweenSpace) {
+ delim = '**';
+ } else {
+ delim = entering ? '' : '';
+ }
return {
- delim: '**',
+ delim,
rawHTML: entering ? getOpenRawHTML(rawHTML) : getCloseRawHTML(rawHTML),
};
},
@@ -353,7 +360,7 @@ function createMarkTypeConvertors(convertors: ToMdConvertorMap) {
const markTypes = Object.keys(markTypeOptions) as WwMarkType[];
markTypes.forEach((type) => {
- markTypeConvertors[type] = (nodeInfo, entering) => {
+ markTypeConvertors[type] = (nodeInfo, entering, betweenSpace) => {
const markOption = markTypeOptions[type];
const convertor = convertors[type];
@@ -362,7 +369,9 @@ function createMarkTypeConvertors(convertors: ToMdConvertorMap) {
// When calling the converter without using `delim` and `rawHTML` values,
// the converter is called without parameters.
const runConvertor = convertor && nodeInfo && !isUndefined(entering);
- const params = runConvertor ? convertor!(nodeInfo as MarkInfo, { entering }) : {};
+ const params = runConvertor
+ ? convertor!(nodeInfo as MarkInfo, { entering }, betweenSpace)
+ : {};
return { ...params, ...markOption };
};
diff --git a/apps/editor/src/utils/common.ts b/apps/editor/src/utils/common.ts
index 343eecc8d7..cf1a6034ec 100644
--- a/apps/editor/src/utils/common.ts
+++ b/apps/editor/src/utils/common.ts
@@ -13,6 +13,8 @@ const reEscapeBackSlash = /\\[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~\\]/g;
const reEscapePairedChars = /[*_~`]/g;
const reMdImageSyntax = /!\[.*\]\(.*\)/g;
const reEscapedCharInLinkSyntax = /[[\]]/g; //
+const reEndWithSpace = /(\S*)\s$/g;
+const reStartWithSpace = /^\s(\S*)/g;
const XMLSPECIAL = '[&<>"]';
const reXmlSpecial = new RegExp(XMLSPECIAL, 'g');
@@ -257,3 +259,11 @@ export function assign(targetObj: Record, obj: Record
export function getSortedNumPair(valueA: number, valueB: number) {
return valueA > valueB ? [valueB, valueA] : [valueA, valueB];
}
+
+export function isStartWithSpace(text: string) {
+ return reStartWithSpace.test(text);
+}
+
+export function isEndWithSpace(text: string) {
+ return reEndWithSpace.test(text);
+}
diff --git a/apps/editor/types/convertor.d.ts b/apps/editor/types/convertor.d.ts
index e8ef7d5fc0..d44db7d00d 100644
--- a/apps/editor/types/convertor.d.ts
+++ b/apps/editor/types/convertor.d.ts
@@ -111,7 +111,8 @@ export type ToMdNodeTypeConvertorMap = Partial ToMdConvertorReturnValues & ToMdMarkTypeOption;
export type ToMdMarkTypeConvertorMap = Partial>;
@@ -124,7 +125,8 @@ interface ToMdConvertorContext {
type ToMdConvertor = (
nodeInfo: NodeInfo | MarkInfo,
- context: ToMdConvertorContext
+ context: ToMdConvertorContext,
+ betweenSpace?: boolean
) => ToMdConvertorReturnValues;
export type ToMdConvertorMap = Partial>;
From 627996ab3f877bdeb6490aa6bf1c13beeea22edd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EB=8C=80=EC=97=B0?=
Date: Mon, 20 Jun 2022 16:36:44 +0900
Subject: [PATCH 2/5] fix: convert strong to tag when it is not between spaces
---
.../toMarkdown/toMdConvertorState.ts | 23 ++-----------------
apps/editor/src/utils/common.ts | 6 +++--
2 files changed, 6 insertions(+), 23 deletions(-)
diff --git a/apps/editor/src/convertors/toMarkdown/toMdConvertorState.ts b/apps/editor/src/convertors/toMarkdown/toMdConvertorState.ts
index 0d279fbe19..54beb8cd34 100644
--- a/apps/editor/src/convertors/toMarkdown/toMdConvertorState.ts
+++ b/apps/editor/src/convertors/toMarkdown/toMdConvertorState.ts
@@ -49,31 +49,15 @@ export default class ToMdConvertorState {
return /(^|\n)$/.test(this.result);
}
- private isBeteewnSpaces(parent: Node, index: number) {
+ private isBetweenSpaces(parent: Node, index: number) {
const { content } = parent;
- // const frontText = content.child(index - 1).text;
- // const rearText = content.child(index + 1).text;
const isFrontNodeEndWithSpace =
index === 0 || isEndWithSpace(content.child(index - 1).text ?? 'a');
- if (index !== 0) {
- console.log(index, isFrontNodeEndWithSpace);
- }
-
const isRearNodeStartWithSpace =
index >= content.childCount - 1 || isStartWithSpace(content.child(index + 1).text ?? 'a');
- if (index - 1 >= 0 && index + 1 <= content.childCount - 1) {
- console.log(
- isEndWithSpace(content.child(index - 1).text ?? 'a'),
- isStartWithSpace(content.child(index + 1).text ?? 'a'),
- isFrontNodeEndWithSpace,
- isRearNodeStartWithSpace,
- content
- );
- }
-
return isFrontNodeEndWithSpace && isRearNodeStartWithSpace;
}
@@ -81,10 +65,7 @@ export default class ToMdConvertorState {
const convertor = this.getMarkConvertor(mark);
if (convertor) {
- if (mark.type.name === 'strong') {
- // debugger;
- }
- const betweenSpace = this.isBeteewnSpaces(parent, entering ? index : index - 1);
+ const betweenSpace = this.isBetweenSpaces(parent, entering ? index : index - 1);
const { delim, rawHTML } = convertor({ node: mark, parent, index }, entering, betweenSpace);
diff --git a/apps/editor/src/utils/common.ts b/apps/editor/src/utils/common.ts
index cf1a6034ec..cd38e93083 100644
--- a/apps/editor/src/utils/common.ts
+++ b/apps/editor/src/utils/common.ts
@@ -13,8 +13,6 @@ const reEscapeBackSlash = /\\[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~\\]/g;
const reEscapePairedChars = /[*_~`]/g;
const reMdImageSyntax = /!\[.*\]\(.*\)/g;
const reEscapedCharInLinkSyntax = /[[\]]/g; //
-const reEndWithSpace = /(\S*)\s$/g;
-const reStartWithSpace = /^\s(\S*)/g;
const XMLSPECIAL = '[&<>"]';
const reXmlSpecial = new RegExp(XMLSPECIAL, 'g');
@@ -261,9 +259,13 @@ export function getSortedNumPair(valueA: number, valueB: number) {
}
export function isStartWithSpace(text: string) {
+ const reStartWithSpace = /^\s(\S*)/g;
+
return reStartWithSpace.test(text);
}
export function isEndWithSpace(text: string) {
+ const reEndWithSpace = /(\S*)\s$/g;
+
return reEndWithSpace.test(text);
}
From 11a4b4c38cc9362c3980d403a6e67021cda25859 Mon Sep 17 00:00:00 2001
From: Kim DaeYeon
Date: Tue, 21 Jun 2022 17:19:19 +0900
Subject: [PATCH 3/5] fix: convertor that follows the same rule
---
.../convertors/toMarkdown/toMdConvertors.ts | 22 +++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/apps/editor/src/convertors/toMarkdown/toMdConvertors.ts b/apps/editor/src/convertors/toMarkdown/toMdConvertors.ts
index c8655736d1..b618b3419d 100644
--- a/apps/editor/src/convertors/toMarkdown/toMdConvertors.ts
+++ b/apps/editor/src/convertors/toMarkdown/toMdConvertors.ts
@@ -224,20 +224,34 @@ export const toMdConvertors: ToMdConvertorMap = {
};
},
- emph({ node }, { entering }) {
+ emph({ node }, { entering }, betweenSpace) {
const { rawHTML } = node.attrs;
+ let delim;
+
+ if (betweenSpace) {
+ delim = '*';
+ } else {
+ delim = entering ? '' : '';
+ }
return {
- delim: '*',
+ delim,
rawHTML: entering ? getOpenRawHTML(rawHTML) : getCloseRawHTML(rawHTML),
};
},
- strike({ node }, { entering }) {
+ strike({ node }, { entering }, betweenSpace) {
const { rawHTML } = node.attrs;
+ let delim;
+
+ if (betweenSpace) {
+ delim = '~~';
+ } else {
+ delim = entering ? '' : '';
+ }
return {
- delim: '~~',
+ delim,
rawHTML: entering ? getOpenRawHTML(rawHTML) : getCloseRawHTML(rawHTML),
};
},
From 159e47a9a267e7899a875ab1530ec22d48a205b1 Mon Sep 17 00:00:00 2001
From: jajugoguma
Date: Wed, 22 Jun 2022 15:36:12 +0900
Subject: [PATCH 4/5] test: add test for convertor
---
.../src/__test__/unit/convertor.spec.ts | 41 ++++++++++++++++++-
1 file changed, 39 insertions(+), 2 deletions(-)
diff --git a/apps/editor/src/__test__/unit/convertor.spec.ts b/apps/editor/src/__test__/unit/convertor.spec.ts
index 52702f2650..bef09ec536 100644
--- a/apps/editor/src/__test__/unit/convertor.spec.ts
+++ b/apps/editor/src/__test__/unit/convertor.spec.ts
@@ -2,7 +2,7 @@ import { source, oneLineTrim } from 'common-tags';
import { Context, MdNode, Parser, HTMLConvertorMap } from '@toast-ui/toastmark';
-import { Schema } from 'prosemirror-model';
+import { Node, Schema } from 'prosemirror-model';
import { createSpecs } from '@/wysiwyg/specCreator';
import Convertor from '@/convertors/convertor';
@@ -595,7 +595,20 @@ describe('Convertor', () => {
| ![altText](imgUrl) **mixed**- [linkText](linkUrl) mixed
|
`;
- assertConverting(markdown, `${markdown}\n`);
+ const expected = source`
+ | thead |
+ | ----- |
+ | |
+ | - ordered
|
+ | |
+ | |
+ | - mixed
|
+ | - mixed
|
+ | foobaz |
+ | ![altText](imgUrl) **mixed**- [linkText](linkUrl) mixed
|
+ `;
+
+ assertConverting(markdown, `${expected}\n`);
});
it('table with unmatched html list', () => {
@@ -1061,4 +1074,28 @@ describe('Convertor', () => {
assertConverting(markdown, markdown);
});
});
+
+ it('should convert by using HTML tag when delimiter is not preceded an alphanumeric', () => {
+ const wwNodeJson = {
+ type: 'doc',
+ content: [
+ {
+ type: 'paragraph',
+ content: [
+ {
+ type: 'text',
+ marks: [{ type: 'strong' }],
+ text: '"test"',
+ },
+ { type: 'text', text: 'a' },
+ ],
+ },
+ ],
+ };
+ const wwNode = Node.fromJSON(schema, wwNodeJson);
+
+ const result = convertor.toMarkdownText(wwNode);
+
+ expect(result).toBe(`"test"a`);
+ });
});
From 9dd5e9e592fed3c93c212bcd4542dcc08e29fc92 Mon Sep 17 00:00:00 2001
From: jajugoguma
Date: Mon, 27 Jun 2022 16:55:11 +0900
Subject: [PATCH 5/5] chore: apply code reviews
---
.../toMarkdown/toMdConvertorState.ts | 7 +++++--
.../convertors/toMarkdown/toMdConvertors.ts | 18 ++++++------------
apps/editor/src/utils/constants.ts | 2 ++
3 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/apps/editor/src/convertors/toMarkdown/toMdConvertorState.ts b/apps/editor/src/convertors/toMarkdown/toMdConvertorState.ts
index 54beb8cd34..99991a348f 100644
--- a/apps/editor/src/convertors/toMarkdown/toMdConvertorState.ts
+++ b/apps/editor/src/convertors/toMarkdown/toMdConvertorState.ts
@@ -10,6 +10,7 @@ import {
FirstDelimFn,
InfoForPosSync,
} from '@t/convertor';
+import { DEFAULT_TEXT_NOT_START_OR_END_WITH_SPACE } from '@/utils/constants';
export default class ToMdConvertorState {
private readonly nodeTypeConvertors: ToMdNodeTypeConvertorMap;
@@ -53,10 +54,12 @@ export default class ToMdConvertorState {
const { content } = parent;
const isFrontNodeEndWithSpace =
- index === 0 || isEndWithSpace(content.child(index - 1).text ?? 'a');
+ index === 0 ||
+ isEndWithSpace(content.child(index - 1).text ?? DEFAULT_TEXT_NOT_START_OR_END_WITH_SPACE);
const isRearNodeStartWithSpace =
- index >= content.childCount - 1 || isStartWithSpace(content.child(index + 1).text ?? 'a');
+ index >= content.childCount - 1 ||
+ isStartWithSpace(content.child(index + 1).text ?? DEFAULT_TEXT_NOT_START_OR_END_WITH_SPACE);
return isFrontNodeEndWithSpace && isRearNodeStartWithSpace;
}
diff --git a/apps/editor/src/convertors/toMarkdown/toMdConvertors.ts b/apps/editor/src/convertors/toMarkdown/toMdConvertors.ts
index b618b3419d..8f1a190404 100644
--- a/apps/editor/src/convertors/toMarkdown/toMdConvertors.ts
+++ b/apps/editor/src/convertors/toMarkdown/toMdConvertors.ts
@@ -210,11 +210,9 @@ export const toMdConvertors: ToMdConvertorMap = {
strong({ node }, { entering }, betweenSpace) {
const { rawHTML } = node.attrs;
- let delim;
+ let delim = '**';
- if (betweenSpace) {
- delim = '**';
- } else {
+ if (!betweenSpace) {
delim = entering ? '' : '';
}
@@ -226,11 +224,9 @@ export const toMdConvertors: ToMdConvertorMap = {
emph({ node }, { entering }, betweenSpace) {
const { rawHTML } = node.attrs;
- let delim;
+ let delim = '*';
- if (betweenSpace) {
- delim = '*';
- } else {
+ if (!betweenSpace) {
delim = entering ? '' : '';
}
@@ -242,11 +238,9 @@ export const toMdConvertors: ToMdConvertorMap = {
strike({ node }, { entering }, betweenSpace) {
const { rawHTML } = node.attrs;
- let delim;
+ let delim = '~~';
- if (betweenSpace) {
- delim = '~~';
- } else {
+ if (!betweenSpace) {
delim = entering ? '' : '';
}
diff --git a/apps/editor/src/utils/constants.ts b/apps/editor/src/utils/constants.ts
index 2d6cd54983..78d5adf33f 100644
--- a/apps/editor/src/utils/constants.ts
+++ b/apps/editor/src/utils/constants.ts
@@ -20,3 +20,5 @@ export const reBR = /
/i;
export const reHTMLComment = /|/;
export const ALTERNATIVE_TAG_FOR_BR = '
';
+
+export const DEFAULT_TEXT_NOT_START_OR_END_WITH_SPACE = 'a';