feat: export tast list

This commit is contained in:
Jocs 2018-01-12 00:41:39 +08:00
parent b2702a8428
commit fc49adc49a
5 changed files with 59 additions and 4 deletions

View File

@ -7,7 +7,7 @@
- [ ] 在通过 Aganippe 打开文件时,无法通过右键选择 Aganippe。严重 bug - [ ] 在通过 Aganippe 打开文件时,无法通过右键选择 Aganippe。严重 bug
- [ ] 在通过 Aganippe 打开文件时,通过右键选择软件,但是打开无内容。(严重 bug - [ ] 在通过 Aganippe 打开文件时,通过右键选择软件,但是打开无内容。(严重 bug
- [ ] 行内样式,链接小括号中的文本没法复制。 - [ ] 行内样式,链接小括号中的文本没法复制。
- [ ] task item: (1)处理方向键 (2)task item 只能和 task item 在一个 ul 中。所以需要优化 update 模块3输出和输入。4复制黏贴(5) 处理 task item 点击 - [ ] task item: ~~(1)处理方向键~~ (2)task item 只能和 task item 在一个 ul 中。所以需要优化 update 模块3输出和输入。4复制黏贴(5) 处理 task item 点击
**菜单** **菜单**

23
package-lock.json generated
View File

@ -16,9 +16,18 @@
"integrity": "sha512-s2ZfgRWXeNUQTQE3O85CDDrU2Uo90pMlMkTxkz85wQOuzVxB8t4cubMPup3WlTPFKHQgb6lDkAHS3ljkUSFO6A==", "integrity": "sha512-s2ZfgRWXeNUQTQE3O85CDDrU2Uo90pMlMkTxkz85wQOuzVxB8t4cubMPup3WlTPFKHQgb6lDkAHS3ljkUSFO6A==",
"dev": true, "dev": true,
"requires": { "requires": {
"7zip-bin-mac": "1.0.1" "7zip-bin-linux": "1.2.0",
"7zip-bin-mac": "1.0.1",
"7zip-bin-win": "2.1.1"
} }
}, },
"7zip-bin-linux": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/7zip-bin-linux/-/7zip-bin-linux-1.2.0.tgz",
"integrity": "sha512-umB98LN18XBGKPw4EKET2zPDqVhEU1mxXA1Gx0BM+DoBt4hnlZPNkpSMNzmuNbQshi9SzLhqlTAyKcAgNrbV3Q==",
"dev": true,
"optional": true
},
"7zip-bin-mac": { "7zip-bin-mac": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/7zip-bin-mac/-/7zip-bin-mac-1.0.1.tgz", "resolved": "https://registry.npmjs.org/7zip-bin-mac/-/7zip-bin-mac-1.0.1.tgz",
@ -26,6 +35,13 @@
"dev": true, "dev": true,
"optional": true "optional": true
}, },
"7zip-bin-win": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/7zip-bin-win/-/7zip-bin-win-2.1.1.tgz",
"integrity": "sha512-6VGEW7PXGroTsoI2QW3b0ea95HJmbVBHvfANKLLMzSzFA1zKqVX5ybNuhmeGpf6vA0x8FJTt6twpprDANsY5WQ==",
"dev": true,
"optional": true
},
"@types/node": { "@types/node": {
"version": "8.0.58", "version": "8.0.58",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.58.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.58.tgz",
@ -8633,6 +8649,11 @@
"uc.micro": "1.0.3" "uc.micro": "1.0.3"
} }
}, },
"markdown-it-task-lists": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/markdown-it-task-lists/-/markdown-it-task-lists-2.1.0.tgz",
"integrity": "sha512-3mT1oQ/brZiV719l3iY/ZIEQLIn60Y9U840l4hh3sA1seHM+ZZjzE5Env1+V1bWqKE1BeVffiuE7qNALzh7r2Q=="
},
"math-expression-evaluator": { "math-expression-evaluator": {
"version": "1.2.17", "version": "1.2.17",
"resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz",

View File

@ -61,6 +61,7 @@
"codemirror": "^5.31.0", "codemirror": "^5.31.0",
"electron-window-state": "^4.1.1", "electron-window-state": "^4.1.1",
"markdown-it": "^8.4.0", "markdown-it": "^8.4.0",
"markdown-it-task-lists": "^2.1.0",
"mousetrap": "^1.6.1", "mousetrap": "^1.6.1",
"parse5": "^3.0.3", "parse5": "^3.0.3",
"snabbdom": "^0.7.0", "snabbdom": "^0.7.0",

View File

@ -14,6 +14,7 @@ class ExportMarkdown {
const result = [] const result = []
const len = blocks.length const len = blocks.length
let i let i
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
const block = blocks[i] const block = blocks[i]
switch (block.type) { switch (block.type) {
@ -62,6 +63,9 @@ class ExportMarkdown {
this.insertLineBreak(result, indent) this.insertLineBreak(result, indent)
result.push(this.normalizeBlockquote(block, indent)) result.push(this.normalizeBlockquote(block, indent))
break break
default:
console.log(block.type)
break
} }
} }
return result.join('') return result.join('')
@ -113,8 +117,20 @@ class ExportMarkdown {
normalizeListItem (block, indent) { normalizeListItem (block, indent) {
const result = [] const result = []
const listInfo = this.listType[this.listType.length - 1] const listInfo = this.listType[this.listType.length - 1]
const itemMarker = listInfo.type === 'ul' ? '- ' : `${listInfo.listCount++}. ` let { children } = block
const { children } = block let itemMarker
if (listInfo.type === 'ul') {
itemMarker = '- '
if (block.isTask) {
const firstChild = children[0]
itemMarker += firstChild.checked ? '[x] ' : '[ ] '
children = children.slice(1)
}
} else {
itemMarker = `${listInfo.listCount++}. `
}
const newIndent = indent + ' '.repeat(itemMarker.length) const newIndent = indent + ' '.repeat(itemMarker.length)
result.push(`${indent}${itemMarker}`) result.push(`${indent}${itemMarker}`)

View File

@ -2,6 +2,7 @@
* translate markdown format to content state used by editor * translate markdown format to content state used by editor
*/ */
import MarkdownIt from 'markdown-it' import MarkdownIt from 'markdown-it'
import taskLists from 'markdown-it-task-lists'
import parse5 from 'parse5' import parse5 from 'parse5'
import TurndownService from 'turndown' import TurndownService from 'turndown'
// To be disabled rules when parse markdown, Because content state don't need to parse inline rules // To be disabled rules when parse markdown, Because content state don't need to parse inline rules
@ -11,6 +12,8 @@ const turndownPluginGfm = require('turndown-plugin-gfm')
const md = new MarkdownIt() const md = new MarkdownIt()
md.disable(INLINE_RULES) md.disable(INLINE_RULES)
// use `taskLists` plugin
md.use(taskLists, { enabled: true })
// turn html to markdown // turn html to markdown
const turndownService = new TurndownService(turndownConfig) const turndownService = new TurndownService(turndownConfig)
const gfm = turndownPluginGfm.gfm const gfm = turndownPluginGfm.gfm
@ -88,6 +91,18 @@ const importRegister = ContentState => {
this.appendChild(parent, block) this.appendChild(parent, block)
break break
case 'input':
const isCheckbox = child.attrs.some(attr => attr.name === 'type' && attr.value === 'checkbox')
const checked = child.attrs.some(attr => attr.name === 'checked' && attr.value === '')
if (isCheckbox && parent.type === 'li') {
parent.isTask = true
block = this.createBlock('input')
block.checked = checked
this.appendChild(parent, block)
}
break
case 'hr': case 'hr':
const initValue = '---' const initValue = '---'
block = this.createBlock(child.nodeName, initValue) block = this.createBlock(child.nodeName, initValue)
@ -95,6 +110,7 @@ const importRegister = ContentState => {
break break
case 'li': case 'li':
console.log(child)
block = this.createBlock('li') block = this.createBlock('li')
this.appendChild(parent, block) this.appendChild(parent, block)
if (child.childNodes.length === 1) { if (child.childNodes.length === 1) {
@ -160,6 +176,7 @@ const importRegister = ContentState => {
} }
ContentState.prototype.importMarkdown = function (markdown) { ContentState.prototype.importMarkdown = function (markdown) {
// empty the blocks and codeBlocks
this.keys = new Set() this.keys = new Set()
this.codeBlocks = new Map() this.codeBlocks = new Map()
this.blocks = this.getStateFragment(markdown) this.blocks = this.getStateFragment(markdown)