fix: subsequent list paragraphs (#916)

This commit is contained in:
Felix Häusler 2019-04-12 02:08:43 +02:00 committed by Ran Luo
parent 8951879b52
commit 02841ffdf9
5 changed files with 49 additions and 45 deletions

View File

@ -10,8 +10,7 @@
- **codeFontFamily**: The code block font family name. - **codeFontFamily**: The code block font family name.
- **lineHeight**: The line height of the editor. - **lineHeight**: The line height of the editor.
- **tabSize**: The number of spaces a tab is equal to. - **tabSize**: The number of spaces a tab is equal to.
- **listIndentation**: The list indentation of list items (`"dfm"`, `"tab"` or number `1-4`) - **listIndentation**: The list indentation of sub list items or paragraphs (`"dfm"`, `"tab"` or number `1-4`)
- `tab`: Indent subsequent paragraphs by one tab.
- `dfm`: Each subsequent paragraph in a list item must be indented by either 4 spaces or one tab, we are using 4 spaces (used by Bitbucket and Daring Fireball Markdown Spec). - `dfm`: Each subsequent paragraph in a list item must be indented by either 4 spaces or one tab, we are using 4 spaces (used by Bitbucket and Daring Fireball Markdown Spec).
- `number`: Dynamic indent subsequent paragraphs by the given number (1-4) plus list marker width (default). - `number`: Dynamic indent subsequent paragraphs by the given number (1-4) plus list marker width (default).
- **autoPairBracket**: If `true` the editor automatically closes brackets. - **autoPairBracket**: If `true` the editor automatically closes brackets.

View File

@ -165,7 +165,7 @@ class Preference {
if (settings.listIndentation < 1 || settings.listIndentation > 4) { if (settings.listIndentation < 1 || settings.listIndentation > 4) {
settings.listIndentation = 1 settings.listIndentation = 1
} }
} else if (settings.listIndentation !== 'tab' && settings.listIndentation !== 'dfm') { } else if (settings.listIndentation !== 'dfm') {
settings.listIndentation = 1 settings.listIndentation = 1
} }

View File

@ -153,7 +153,7 @@ class Muya {
if (listIndentation < 1 || listIndentation > 4) { if (listIndentation < 1 || listIndentation > 4) {
listIndentation = 1 listIndentation = 1
} }
} else if (listIndentation !== 'tab' && listIndentation !== 'dfm') { } else if (listIndentation !== 'dfm') {
listIndentation = 1 listIndentation = 1
} }
this.contentState.listIndentation = listIndentation this.contentState.listIndentation = listIndentation

View File

@ -16,18 +16,13 @@ class ExportMarkdown {
this.isLooseParentList = true this.isLooseParentList = true
// set and validate settings // set and validate settings
if (listIndentation === 'tab') { this.listIndentation = 'number'
this.listIndentation = '\t' if (listIndentation === 'dfm') {
this.listIndentationCount = null this.listIndentation = 'dfm'
} else if (listIndentation === 'dfm') { this.listIndentationCount = 4
// static 4 spaces
this.listIndentation = ' '
this.listIndentationCount = null
} else if (typeof listIndentation === 'number') { } else if (typeof listIndentation === 'number') {
this.listIndentation = null
this.listIndentationCount = Math.min(Math.max(listIndentation, 1), 4) this.listIndentationCount = Math.min(Math.max(listIndentation, 1), 4)
} else { } else {
this.listIndentation = null
this.listIndentationCount = 1 this.listIndentationCount = 1
} }
} }
@ -36,7 +31,7 @@ class ExportMarkdown {
return this.translateBlocks2Markdown(this.blocks) return this.translateBlocks2Markdown(this.blocks)
} }
translateBlocks2Markdown (blocks, indent = '') { translateBlocks2Markdown (blocks, indent = '', listIndent = '') {
const result = [] const result = []
// helper for CommonMark 264 // helper for CommonMark 264
let lastListBullet = '' let lastListBullet = ''
@ -105,7 +100,7 @@ class ExportMarkdown {
if (insertNewLine) { if (insertNewLine) {
this.insertLineBreak(result, indent) this.insertLineBreak(result, indent)
} }
result.push(this.normalizeListItem(block, indent)) result.push(this.normalizeListItem(block, indent + listIndent))
this.isLooseParentList = true this.isLooseParentList = true
break break
} }
@ -124,7 +119,7 @@ class ExportMarkdown {
} }
this.listType.push({ type: 'ul' }) this.listType.push({ type: 'ul' })
result.push(this.normalizeList(block, indent)) result.push(this.normalizeList(block, indent, listIndent))
this.listType.pop() this.listType.pop()
break break
} }
@ -143,7 +138,7 @@ class ExportMarkdown {
} }
const listCount = block.start !== undefined ? block.start : 1 const listCount = block.start !== undefined ? block.start : 1
this.listType.push({ type: 'ol', listCount }) this.listType.push({ type: 'ol', listCount })
result.push(this.normalizeList(block, indent)) result.push(this.normalizeList(block, indent, listIndent))
this.listType.pop() this.listType.pop()
break break
} }
@ -309,9 +304,9 @@ class ExportMarkdown {
return result.join('\n') + '\n' return result.join('\n') + '\n'
} }
normalizeList (block, indent) { normalizeList (block, indent, listIndent) {
const { children } = block const { children } = block
return this.translateBlocks2Markdown(children, indent) return this.translateBlocks2Markdown(children, indent, listIndent)
} }
normalizeListItem (block, indent) { normalizeListItem (block, indent) {
@ -324,13 +319,34 @@ class ExportMarkdown {
if (isUnorderedList) { if (isUnorderedList) {
itemMarker = bulletMarkerOrDelimiter ? `${bulletMarkerOrDelimiter} ` : '- ' itemMarker = bulletMarkerOrDelimiter ? `${bulletMarkerOrDelimiter} ` : '- '
} else { } else {
// NOTE: GitHub and Bitbucket limit the list count to 99 but this is nowhere defined.
// We limit the number to 99 for Daring Fireball Markdown to prevent indentation issues.
let n = listInfo.listCount
if ((this.listIndentation === 'dfm' && n > 99) || n > 999999999) {
n = 1
}
listInfo.listCount++
const delimiter = bulletMarkerOrDelimiter ? bulletMarkerOrDelimiter : '.' const delimiter = bulletMarkerOrDelimiter ? bulletMarkerOrDelimiter : '.'
itemMarker = `${listInfo.listCount++}${delimiter} ` itemMarker = `${n}${delimiter} `
} }
// We already added one space to the indentation // Subsequent paragraph indentation
const listIndent = this.getListIndentation(itemMarker.length - 1) const newIndent = indent + ' '.repeat(itemMarker.length)
const newIndent = indent + listIndent
// New list indentation. We already added one space to the indentation
let listIndent = ''
const { listIndentation } = this
if (listIndentation === 'dfm') {
listIndent = ' '.repeat(4 - itemMarker.length)
} else if (listIndentation === 'number') {
listIndent = ' '.repeat(this.listIndentationCount - 1)
}
// TODO: Indent subsequent paragraphs by one tab. - not important
// Problem: "translateBlocks2Markdown" use "indent" in spaces to indent elements. How should
// we integrate tabs in blockquotes and subsequent paragraphs and how to combine with spaces?
// I don't know how to combine tabs and spaces and it seems not specified, so work for another day.
if (isUnorderedList && block.listItemType === 'task') { if (isUnorderedList && block.listItemType === 'task') {
const firstChild = children[0] const firstChild = children[0]
@ -339,23 +355,9 @@ class ExportMarkdown {
} }
result.push(`${indent}${itemMarker}`) result.push(`${indent}${itemMarker}`)
result.push(this.translateBlocks2Markdown(children, newIndent).substring(newIndent.length)) result.push(this.translateBlocks2Markdown(children, newIndent, listIndent).substring(newIndent.length))
return result.join('') return result.join('')
} }
getListIndentation (listMarkerWidth) {
// listIndentation:
// tab: Indent subsequent paragraphs by one tab.
// dfm: Each subsequent paragraph in a list item must be indented by either 4 spaces or one tab (used by Bitbucket and Daring Fireball).
// number: Dynamic indent subsequent paragraphs by the given number (1-4) plus list marker width.
if (this.listIndentation) {
return this.listIndentation
} else if (this.listIndentationCount) {
return ' '.repeat(listMarkerWidth + this.listIndentationCount)
}
return ' '.repeat(listMarkerWidth)
}
} }
export default ExportMarkdown export default ExportMarkdown

View File

@ -15,8 +15,9 @@ const createMuyaContext = listIdentation => {
// Muya parser (Markdown to HTML to Markdown) // Muya parser (Markdown to HTML to Markdown)
// //
const verifyMarkdown = (expectedMarkdown, listIdentation) => { const verifyMarkdown = (expectedMarkdown, listIdentation, markdown = '') => {
const markdown = `start if (!markdown) {
markdown = `start
- foo - foo
- foo - foo
@ -41,6 +42,7 @@ sep
141. foo 141. foo
1. foo 1. foo
` `
}
const ctx = createMuyaContext(listIdentation) const ctx = createMuyaContext(listIdentation)
ctx.contentState.importMarkdown(markdown) ctx.contentState.importMarkdown(markdown)
@ -50,7 +52,7 @@ sep
expect(exportedMarkdown).to.equal(expectedMarkdown) expect(exportedMarkdown).to.equal(expectedMarkdown)
} }
describe('Muya tab identation', () => { describe('Muya list identation', () => {
it('Indent by 1 space', () => { it('Indent by 1 space', () => {
const md = `start const md = `start
@ -164,7 +166,7 @@ sep
verifyMarkdown(md, 4) verifyMarkdown(md, 4)
}) })
it('Indent by one tab', () => { /* it('Indent by one tab', () => {
const md = `start const md = `start
- foo - foo
@ -191,7 +193,7 @@ sep
\t\t\t1. foo \t\t\t1. foo
` `
verifyMarkdown(md, "tab") verifyMarkdown(md, "tab")
}) })*/
it('Indent using Daring Fireball Markdown Spec', () => { it('Indent using Daring Fireball Markdown Spec', () => {
const md = `start const md = `start
@ -215,9 +217,10 @@ sep
3. foo 3. foo
3. foo 3. foo
20. foo 20. foo
141. foo 99. foo
1. foo 1. foo
` `
verifyMarkdown(md, "dfm")
verifyMarkdown(md, "dfm", md)
}) })
}) })