mirror of
https://github.com/marktext/marktext.git
synced 2025-05-10 22:12:29 +08:00
feat: export Markdown but list in blockquote has bug
This commit is contained in:
parent
23fa376152
commit
814bd6d3d5
@ -75,6 +75,13 @@ class ContentState {
|
||||
|
||||
// getBlocks
|
||||
getBlocks () {
|
||||
let key
|
||||
let cm
|
||||
for ([ key, cm ] of this.codeBlocks.entries()) {
|
||||
const value = cm.getValue()
|
||||
const block = this.getBlock(key)
|
||||
if (block) block.text = value
|
||||
}
|
||||
return this.blocks
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ export const setInlineEmoji = (node, emoji, selection) => {
|
||||
}
|
||||
|
||||
class Emoji {
|
||||
constructor (event) {
|
||||
constructor () {
|
||||
this.cache = new Map()
|
||||
}
|
||||
|
||||
|
@ -8,14 +8,16 @@ import { checkEditLanguage, replaceLanguage } from './codeMirror/language'
|
||||
import Emoji, { checkEditEmoji, setInlineEmoji } from './emojis'
|
||||
import floatBox from './floatBox'
|
||||
import { findNearestParagraph, operateClassName } from './utils/domManipulate'
|
||||
import ExportMarkdown from './utils/exportMarkdown'
|
||||
import fs from 'fs'
|
||||
|
||||
class Aganippe {
|
||||
constructor (container, options) {
|
||||
this.container = container
|
||||
this.eventCenter = eventCenter
|
||||
this.floatBox = floatBox
|
||||
this.contentState = new ContentState(this.floatBox)
|
||||
this.emoji = new Emoji(this.eventCenter) // emoji instance: has search(text) clear() methods.
|
||||
this.contentState = new ContentState()
|
||||
this.emoji = new Emoji() // emoji instance: has search(text) clear() methods.
|
||||
|
||||
this.init()
|
||||
}
|
||||
@ -39,6 +41,15 @@ class Aganippe {
|
||||
this.contentState.history.undo()
|
||||
})
|
||||
|
||||
eventCenter.bind('command+s', event => {
|
||||
const blocks = this.contentState.getBlocks()
|
||||
const markdown = new ExportMarkdown(blocks).generate()
|
||||
console.log(blocks)
|
||||
fs.writeFile('./src/editor/output.md', markdown, 'utf-8', (err, data) => {
|
||||
if (err) console.log(err)
|
||||
})
|
||||
})
|
||||
|
||||
// if you dont click the keyboard after 1 second, the garbageCollection will run.
|
||||
eventCenter.attachDOMEvent(container, 'keydown', debounce(() => this.contentState.garbageCollection(), 1000))
|
||||
|
||||
|
5
src/editor/output.md
Normal file
5
src/editor/output.md
Normal file
@ -0,0 +1,5 @@
|
||||
> hello
|
||||
>
|
||||
- > hello
|
||||
>
|
||||
- > owowow
|
@ -56,7 +56,7 @@ class StateRender {
|
||||
if (block.children.length) {
|
||||
return h(blockSelector, block.children.map(child => renderBlock(child)))
|
||||
} else {
|
||||
const children = block.text
|
||||
let children = block.text
|
||||
? tokenizer(block.text).reduce((acc, token) => {
|
||||
const chunk = this[token.type](h, cursor, block, token)
|
||||
return Array.isArray(chunk) ? [...acc, ...chunk] : [...acc, chunk]
|
||||
@ -74,6 +74,7 @@ class StateRender {
|
||||
if (block.type === 'pre') {
|
||||
if (block.lang) Object.assign(data.dataset, { lang: block.lang })
|
||||
blockSelector += `.${CLASS_OR_ID['AG_CODE_BLOCK']}`
|
||||
children = ''
|
||||
}
|
||||
|
||||
if (block.temp) {
|
||||
|
148
src/editor/utils/exportMarkdown.js
Normal file
148
src/editor/utils/exportMarkdown.js
Normal file
@ -0,0 +1,148 @@
|
||||
const LINE_BREAKS = /\n/
|
||||
|
||||
class ExportMarkdown {
|
||||
constructor (blocks) {
|
||||
this.blocks = blocks
|
||||
this.listType = [] // 'ul' or 'ol'
|
||||
this.blockquoteType = []
|
||||
}
|
||||
|
||||
generate () {
|
||||
this.addDepth2Block(this.blocks, 0)
|
||||
return this.translateBlocks2Markdown(this.blocks, 0)
|
||||
}
|
||||
|
||||
translateBlocks2Markdown (blocks, inLen) {
|
||||
const result = []
|
||||
const len = blocks.length
|
||||
const indent = ' '.repeat(inLen)
|
||||
let i
|
||||
for (i = 0; i < len; i++) {
|
||||
const block = blocks[i]
|
||||
switch (block.type) {
|
||||
case 'p':
|
||||
this.insertLineBreak(result, indent)
|
||||
result.push(this.normalizeParagraphText(block, indent))
|
||||
break
|
||||
|
||||
case 'h1':
|
||||
case 'h2':
|
||||
case 'h3':
|
||||
case 'h4':
|
||||
case 'h5':
|
||||
case 'h6':
|
||||
this.insertLineBreak(result, indent)
|
||||
result.push(this.normalizeHeaderText(block, indent))
|
||||
break
|
||||
|
||||
case 'li':
|
||||
this.insertLineBreak(result, indent)
|
||||
result.push(this.normalizeListItem(block, indent))
|
||||
break
|
||||
|
||||
case 'ul':
|
||||
this.insertLineBreak(result, indent)
|
||||
this.listType.push({ type: 'ul' })
|
||||
result.push(this.normalizeList(block, indent))
|
||||
this.listType.pop()
|
||||
break
|
||||
|
||||
case 'ol':
|
||||
this.insertLineBreak(result, indent)
|
||||
const listCount = block.start !== undefined ? block.start : 1
|
||||
this.listType.push({ type: 'ol', listCount })
|
||||
result.push(this.normalizeList(block, indent))
|
||||
this.listType.pop()
|
||||
break
|
||||
|
||||
case 'pre':
|
||||
this.insertLineBreak(result, indent)
|
||||
result.push(this.normalizeCodeBlock(block, indent))
|
||||
break
|
||||
|
||||
case 'blockquote':
|
||||
this.insertLineBreak(result, indent)
|
||||
this.blockquoteType.push({ type: 'blockquote' })
|
||||
result.push(this.normalizeBlockquote(block, indent))
|
||||
this.blockquoteType.pop()
|
||||
break
|
||||
}
|
||||
}
|
||||
console.log(result)
|
||||
return result.join('')
|
||||
}
|
||||
|
||||
insertLineBreak (result, indent) {
|
||||
if (result.length > 0) {
|
||||
const depth = this.blockquoteType.length
|
||||
const blockquotePrefix = depth ? `${'>'.repeat(depth)} ` : ''
|
||||
result.push(blockquotePrefix ? `${indent}${blockquotePrefix}\n` : '\n')
|
||||
}
|
||||
}
|
||||
|
||||
insertBlockquotePrefix (text, indent) {
|
||||
const depth = this.blockquoteType.length
|
||||
const blockquotePrefix = depth ? `${'> '.repeat(depth)}` : ''
|
||||
return `${indent}${blockquotePrefix}${text}\n`
|
||||
}
|
||||
|
||||
normalizeHeaderText (block, indent) {
|
||||
const match = block.text.match(/(#{1,6})(.*)/)
|
||||
const text = `${match[1]} ${match[2].trim()}`
|
||||
return this.insertBlockquotePrefix(text, indent)
|
||||
}
|
||||
|
||||
normalizeParagraphText (block, indent) {
|
||||
return this.insertBlockquotePrefix(block.text, indent)
|
||||
}
|
||||
|
||||
normalizeBlockquote (block, indent) {
|
||||
const { children } = block
|
||||
return this.translateBlocks2Markdown(children, indent.length)
|
||||
}
|
||||
|
||||
normalizeCodeBlock (block, indent) {
|
||||
const result = []
|
||||
const textList = block.text.split(LINE_BREAKS)
|
||||
result.push(this.insertBlockquotePrefix(block.lang ? '```' + block.lang : '```', indent))
|
||||
|
||||
textList.forEach(text => {
|
||||
result.push(this.insertBlockquotePrefix(text, indent))
|
||||
})
|
||||
result.push(this.insertBlockquotePrefix('```', indent))
|
||||
return result.join('')
|
||||
}
|
||||
|
||||
normalizeList (block, indent) {
|
||||
const { children } = block
|
||||
return this.translateBlocks2Markdown(children, indent.length)
|
||||
}
|
||||
|
||||
normalizeListItem (block, indent) {
|
||||
const result = []
|
||||
const listInfo = this.listType[this.listType.length - 1]
|
||||
const itemMarker = listInfo.type === 'ul' ? '- ' : `${listInfo.listCount++}. `
|
||||
const { children } = block
|
||||
|
||||
result.push(`${indent}${itemMarker}`)
|
||||
result.push(this.translateBlocks2Markdown(children, indent.length + itemMarker.length).trimLeft())
|
||||
|
||||
return result.join('')
|
||||
}
|
||||
|
||||
addDepth2Block (blocks, initDepth) {
|
||||
const len = blocks.length
|
||||
let i
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
const block = blocks[i]
|
||||
block.depth = initDepth
|
||||
const { children } = block
|
||||
if (children.length) {
|
||||
this.addDepth2Block(children, initDepth + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default ExportMarkdown
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<ul ref="editor">
|
||||
</ul>
|
||||
<div ref="editor">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
Loading…
Reference in New Issue
Block a user