diff --git a/TODO.md b/TODO.md
index a9ae5ef4..7e58b916 100644
--- a/TODO.md
+++ b/TODO.md
@@ -5,12 +5,12 @@
- [x] 段落和换行,两个或两个以上的空格再敲回车,或插入一个\
- [x] 标题,支持 atx 形式的标题,在行首插入 1 到 6 个 #,会生成对应的 h1~6 h 标签。在敲回车后再转换成 HTML,但是在编辑标题的时候,显示会加粗。标题支持嵌套其他 markdown 样式。支持嵌套的样式包括加粗、斜体、行内代码、链接、图片。
- [x] 区块引用 Blockquotes,每行前面都加上 > ,支持嵌套区块引用,支持嵌套其他 markdown 语法,比如标题、列表、代码区块。区块引用会生成 blockquote 标签。
-- [x] 列表,有序列表和无需列表。无序列表使用 *、+、- 作为列表标记。有序列表使用数字加一个英文句点来标记。列表支持嵌套列表。列表支持嵌套区块引用,但仅限于行首,支持嵌套代码区块,但仅限于行首,支持其他 markdown 语法嵌套。
+- [x] 列表,有序列表和无序列表。无序列表使用 *、+、- 作为列表标记。有序列表使用数字加一个英文句点来标记。列表支持嵌套列表。列表支持嵌套区块引用,但仅限于行首,支持嵌套代码区块,但仅限于行首,支持其他 markdown 语法嵌套。
- [x] 代码区块,代码区块中的 markdown 语法不再被转换。
- [x] 分割线,你可以在一行中使用三个以上的 *、-、_ 来创建分割线。
- [x] 链接,markdown 支持两种形式的链接,行内式、参考式。
- [ ] 图片,markdown 支持两种形式的图片,行内式、参考式。
-- [x] Markdown 中使用\*、\_ 来表示强调,使用一个用 em 标签,使用两个用 strong 标签,如果\*、\_ 两边都(?)有空白的话,会被当做普通的符号。
+- [x] Markdown 中使用\*、\_ 来表示强调,使用一个用 em 标签,使用两个用 strong 标签,如果\*、\_ 内侧有空白的话,会被当做普通的符号。
- [x] 代码,如果标记一小段代码,可以用反引号标记:\`。如果文字中已经有反引号,那么使用两个反引号。
- [x] 简单链接、自动连接,使用\<\>包裹的链接会被转换为a 标签,还可以自动识别链接。
- [ ] 反斜线 \ 可以对如下字符转义:
diff --git a/src/editor/config.js b/src/editor/config.js
index 1670666d..4c4f41d2 100644
--- a/src/editor/config.js
+++ b/src/editor/config.js
@@ -63,7 +63,9 @@ export const CLASS_OR_ID = genUpper2LowerKeyHash([
'AG_LANGUAGE',
'AG_LANGUAGE_INPUT',
'AG_TEMP',
- 'AG_LINK_IN_BRACKET'
+ 'AG_LINK_IN_BRACKET',
+ 'AG_BACKLASH',
+ 'AG_BUG' // for remove bug
])
export const codeMirrorConfig = {
diff --git a/src/editor/index.css b/src/editor/index.css
index e4e3ae7f..e0b320a1 100644
--- a/src/editor/index.css
+++ b/src/editor/index.css
@@ -157,6 +157,10 @@ span[role="link"], a[role="link"] {
color: #708;
text-decoration: none;
}
+.ag-backlash {
+ text-decoration: none;
+ color: rgb(51, 51, 51);
+}
.ag-warn {
color: #000;
text-decoration: none;
diff --git a/src/editor/syntax/index.js b/src/editor/syntax/index.js
index b2fc4012..29645f67 100644
--- a/src/editor/syntax/index.js
+++ b/src/editor/syntax/index.js
@@ -3,7 +3,7 @@ import {
findOutMostParagraph, findNearestParagraph, isFirstChildElement,
isOnlyChildElement
} from '../utils/domManipulate'
-
+import { isEven } from '../utils'
import {
LOWERCASE_TAGS,
CLASS_OR_ID,
@@ -20,14 +20,14 @@ const fragments = [
'^`{3,}[^`]*',
'^#{1,6}', // Header
'(\\*{2}|_{2})(?:[^\\s]|[^\\s].*[^\\s])\\1', // strong
- '(\\*{1}|_{1})(?:[^\\s]|[^\\s].*[^\\s])\\2', // em
+ '\\\\*(\\*{1}|_{1})(?:[^\\s]|[^\\s].*[^\\s])\\\\*\\2', // em
'(`{1,3})([^`]+?|.{2,})\\3', // inline code
'\\[[^\\[\\]]+\\]\\(.*?\\)', // link
'\\[\\]\\([^\\(\\)]*?\\)', // no text link
':[^:]+?:', // emoji
'~{2}[^~]+~{2}', // line through
'https?://[^\\s]+(?=\\s|$)', // auto link
- `\\\\(?=[${markedSymbol.join()}]{1})` // eslint-disable-line no-useless-escape
+ `\\\\+(?=[${markedSymbol.join()}]{1})` // eslint-disable-line no-useless-escape
]
const CHOP_REG = new RegExp(fragments.join('|'), 'g') // eslint-disable-line no-useless-escape
@@ -38,8 +38,8 @@ const HEAD_REG = /^#{1,6}/
const STRONG_REG_G = /^(\*{2}|_{2})([^\s]|[^\s].*[^\s])(\1)/g
const STRONG_REG = /^(\*{2}|_{2})(?:[^\s]|[^\s].*[^\s])\1/
-const EM_REG_G = /^(\*{1}|_{1})([^\s]|[^\s].*[^\s])(\1)/g
-const EM_REG = /^(\*{1}|_{1})(?:[^\s]|[^\s].*[^\s])\1/
+const EM_REG_G = /^(\\*)(\*{1}|_{1})([^\s]|[^\s].*?[^\s])(\\*)(\2)/g
+const EM_REG = /^(?:\\*)(\*{1}|_{1})(?:[^\s]|[^\s].*[^\s])(?:\\*)\1/
const INLINE_CODE_REG_G = /^(`{1,3})([^`]+?|.{2,})(\1)/g
const INLINE_CODE_REG = /^(`{1,3})([^`]+?|.{2,})(\1)/
@@ -58,6 +58,9 @@ const HR_REG_G = /(^\*{3,}|^-{3,}|^_{3,})/g
const HR_REG = /^\*{3,}|^-{3,}|^_{3,}/
const CODE_BLOCK_G = /(^`{3,})([^`]*)/g
const CODE_BLOCK = /^`{3,}[^`]*/
+const BACKLASH_REG_G = new RegExp('^(\\\\+)', 'g')
+const BACKLASH_REG = new RegExp('^\\\\+', 'i')
+
// const SIMPLE_LINK_G = /(<)([^<>]+?)(>)/g
// const SIMPLE_LINK = /<[^<>]+?>/g
const LINE_BREAK_BLOCK_REG = /^(?:`{3,}([^`]*))|[\*\-\_]{3,}/ // eslint-disable-line no-useless-escape
@@ -70,6 +73,26 @@ const CHOP_HEADER_REG = /^([*+-]\s(?:\[\s\]\s)?|>\s*|\d+\.\s)/
const conflict = (arr1, arr2) => {
return !(arr1[1] < arr2[0] || arr2[1] < arr1[0])
}
+/**
+ * [backlash => html]
+ * examples:
+ * `\` => `\`
+ * `\\` => `\\`
+ */
+const backlash2html = (backlashes, className) => {
+ const chunks = backlashes.split('')
+ const len = chunks.length
+ let i
+ let result = ''
+ for (i = 0; i < len; i++) {
+ if (isEven(i)) {
+ result += `${chunks[i]}`
+ } else {
+ result += `${chunks[i]}`
+ }
+ }
+ return `${result}` // the extral a tag for fix the bug.
+}
const chunk2html = ({ chunk, index, lastIndex }, { start, end } = {}, outerClsssName) => {
// if no positionState provided, no conflict.
@@ -97,12 +120,23 @@ const chunk2html = ({ chunk, index, lastIndex }, { start, end } = {}, outerClsss
// handle emphasize
if (EM_REG.test(chunk)) {
- return chunk.replace(EM_REG_G, (match, p1, p2, p3) => {
- return (
- `${p1}` +
- `${markedText2Html(p2, undefined, className, 'inline')}` +
- `${p3}`
- )
+ console.log('em')
+ return chunk.replace(EM_REG_G, (match, p1, p2, p3, p4, p5) => {
+ console.log(`p1: ${p1}, p2: ${p2}, p3: ${p3}, p4: ${p4}, p5: ${p5}`)
+ if (isEven(p1.length) && isEven(p4.length)) {
+ return (
+ backlash2html(p1, className) +
+ `${p2}` +
+ `${markedText2Html(p3, undefined, className, 'inline')}${backlash2html(p4, className)}` +
+ `${p5}`
+ )
+ } else {
+ return (
+ `${backlash2html(p1, className)}${p2}` +
+ `${markedText2Html(p3, undefined, className, 'inline')}` +
+ `${backlash2html(p4, className)}${p5}`
+ )
+ }
})
}
// handle inline code: markdown text: `code`
@@ -209,6 +243,12 @@ const chunk2html = ({ chunk, index, lastIndex }, { start, end } = {}, outerClsss
})
}
+ if (BACKLASH_REG.test(chunk)) {
+ return chunk.replace(BACKLASH_REG_G, (match, p1) => {
+ return backlash2html(p1, className)
+ })
+ }
+
// handle picture
// TODO
// handle auto link: markdown text: ``
diff --git a/src/editor/utils/index.js b/src/editor/utils/index.js
index 73c0df0e..6b75d1e4 100644
--- a/src/editor/utils/index.js
+++ b/src/editor/utils/index.js
@@ -19,6 +19,9 @@ export const getUniqueId = set => {
return id
}
+export const isOdd = number => Math.abs(number) % 2 === 1
+export const isEven = number => Math.abs(number) % 2 === 0
+
// https://github.com/jashkenas/underscore
export const throttle = (func, wait = 50) => {
let context