diff options
author | Ferdinand Thiessen <rpm@fthiessen.de> | 2022-07-15 12:05:27 +0300 |
---|---|---|
committer | Ferdinand Thiessen <rpm@fthiessen.de> | 2022-07-15 13:34:00 +0300 |
commit | 613b6898c066c7a84c7e0aebfe5a399d13ce1d9e (patch) | |
tree | e14eb2ed63ecb18fe3bd629addb5c8bc712710c6 /src | |
parent | 1b7d876711be312a5230cb4e970eb086c71700fb (diff) |
Fix parsing of whitespace used in task lists
Switch to @hedgedoc/markdown-it-task-lists to fix
parsing of task lists, namely allowing any whitespace
inside the brackets, as by the github markdown specs.
Doing this as markdown-it-task-lists seems orphaned,
while hedgedoc is maintained and the bug is fixed there.
This required adjusting the task-list testcase as the output is slightly different.
Signed-off-by: Ferdinand Thiessen <rpm@fthiessen.de>
Diffstat (limited to 'src')
-rw-r--r-- | src/markdownit/index.js | 2 | ||||
-rw-r--r-- | src/markdownit/splitMixedLists.js | 16 | ||||
-rw-r--r-- | src/nodes/TaskItem.js | 2 | ||||
-rw-r--r-- | src/tests/markdown.spec.js | 17 | ||||
-rw-r--r-- | src/tests/markdownit.spec.js | 4 |
5 files changed, 28 insertions, 13 deletions
diff --git a/src/markdownit/index.js b/src/markdownit/index.js index ca166dbad..e13d1a3aa 100644 --- a/src/markdownit/index.js +++ b/src/markdownit/index.js @@ -1,5 +1,5 @@ import MarkdownIt from 'markdown-it' -import taskLists from 'markdown-it-task-lists' +import taskLists from '@hedgedoc/markdown-it-task-lists' import underline from './underline.js' import splitMixedLists from './splitMixedLists.js' import callouts from './callouts.js' diff --git a/src/markdownit/splitMixedLists.js b/src/markdownit/splitMixedLists.js index cb709af33..5f35e6c1d 100644 --- a/src/markdownit/splitMixedLists.js +++ b/src/markdownit/splitMixedLists.js @@ -24,16 +24,16 @@ * @param {object} md Markdown object */ export default function splitMixedLists(md) { - md.core.ruler.after('github-task-lists', 'split-mixed-task-lists', state => { + md.core.ruler.after('task-lists', 'split-mixed-task-lists', state => { const tokens = state.tokens for (let i = 0; i < tokens.length; i++) { const token = tokens[i] - if (token.attrGet('class') !== 'contains-task-list') { + if (!includesClass(token, 'contains-task-list')) { continue } const firstChild = tokens[i + 1] - const startsWithTask = firstChild.attrGet('class') === 'task-list-item' + const startsWithTask = includesClass(firstChild, 'task-list-item') if (!startsWithTask) { token.attrs.splice(token.attrIndex('class')) if (token.attrs.length === 0) { @@ -42,7 +42,7 @@ export default function splitMixedLists(md) { } const splitBefore = findChildOf(tokens, i, child => { return child.nesting === 1 - && child.attrGet('class') !== firstChild.attrGet('class') + && includesClass(child, 'task-list-item') !== startsWithTask }) if (splitBefore > i) { splitListAt(tokens, splitBefore, state.Token) @@ -54,6 +54,14 @@ export default function splitMixedLists(md) { } /** + * @param {object} token MarkdownIT token + * @param {string} cls Class name to query + */ +function includesClass(token, cls) { + return token.attrGet('class')?.split(' ').includes(cls) || false +} + +/** * @param {Array} tokens - all the tokens in the doc * @param {number} index - index into the tokens array where to split * @param {object} TokenConstructor - constructor provided by Markdown-it diff --git a/src/nodes/TaskItem.js b/src/nodes/TaskItem.js index 74db3e82a..b602e9130 100644 --- a/src/nodes/TaskItem.js +++ b/src/nodes/TaskItem.js @@ -91,7 +91,7 @@ const TaskItem = TipTapTaskItem.extend({ return [ ...this.parent(), wrappingInputRule({ - find: /^\s*([-+*])\s(\[(x|X| ?)\])\s$/, + find: /^\s*([-+*])\s(\[(x|X|\s?)\])\s$/, type: this.type, getAttributes: match => ({ checked: 'xX'.includes(match[match.length - 1]), diff --git a/src/tests/markdown.spec.js b/src/tests/markdown.spec.js index 0f6cbaeed..a682111a3 100644 --- a/src/tests/markdown.spec.js +++ b/src/tests/markdown.spec.js @@ -96,10 +96,15 @@ describe('Markdown though editor', () => { expect(markdownThroughEditor('```\n<?php echo "Hello World";\n```')).toBe('```\n<?php echo "Hello World";\n```') }) test('checkboxes', () => { - expect(markdownThroughEditor('- [ ] [asd](sdf)')).toBe('* [ ] [asd](sdf)') - expect(markdownThroughEditor('- [x] [asd](sdf)')).toBe('* [x] [asd](sdf)') + // Invalid ones but should be syntactical unchanged + expect(markdownThroughEditor('- [F] asd')).toBe('* [F] asd') expect(markdownThroughEditor('- [ [asd](sdf)')).toBe('* [ [asd](sdf)') + // Valid, whitespace is allowed inside the checkbox + expect(markdownThroughEditor('- [\t] asd')).toBe('* [ ] asd') expect(markdownThroughEditor('- [ ] asd')).toBe('* [ ] asd') + // Valid ones + expect(markdownThroughEditor('- [ ] [asd](sdf)')).toBe('* [ ] [asd](sdf)') + expect(markdownThroughEditor('- [x] [asd](sdf)')).toBe('* [x] [asd](sdf)') expect(markdownThroughEditor('- [ ] foo\n- [x] bar')).toBe('* [ ] foo\n* [x] bar') expect(markdownThroughEditor('- [x] foo\n' + ' - [ ] bar\n' + @@ -109,10 +114,12 @@ describe('Markdown though editor', () => { ' * [x] baz\n' + '* [ ] bim') expect(markdownThroughEditor('- [X] asd')).toBe('* [x] asd') - expect(markdownThroughEditor('- [\t] asd')).toBe('* [ ] asd') - expect(markdownThroughEditor('- [ ] asd')).toBe('* [ ] asd') expect(markdownThroughEditor('- [X] asd')).toBe('* [x] asd') - expect(markdownThroughEditor('- [F] asd')).toBe('* [F] asd') + + expect(markdownThroughEditorHtml('<ul class="contains-task-list"><li><input type="checkbox" checked /><label>foo</label></li></ul>')).toBe('* [x] foo') + expect(markdownThroughEditorHtml('<ul class="contains-task-list"><li><input type="checkbox" /><label>test</label></li></ul>')).toBe('* [ ] test') + expect(markdownThroughEditorHtml('<ul class="contains-task-list"><li><input type="checkbox" checked /><div><h2>Test</h2><p><strong>content</strong></p></div></li></ul>')).toBe('* [x] Test\n\n **content**') + expect(markdownThroughEditorHtml('<ul class="contains-task-list"><li><input type="checkbox" checked /><p>Test</p><h1>Block level headline</h1></li></ul>')).toBe('* [x] Test\n\n # Block level headline') }) test('horizontal rule', () => { diff --git a/src/tests/markdownit.spec.js b/src/tests/markdownit.spec.js index 30748860a..05669dab9 100644 --- a/src/tests/markdownit.spec.js +++ b/src/tests/markdownit.spec.js @@ -9,7 +9,7 @@ describe('markdownit', () => { const rendered = markdownit.render('* [ ] task\n* not a task') expect(stripIndent(rendered)).toBe(stripIndent(` <ul class="contains-task-list"> - <li class="task-list-item"><input class="task-list-item-checkbox" disabled="" type="checkbox"> task</li> + <li class="task-list-item "><input class="task-list-item-checkbox" type="checkbox" disabled="" id="task-item-0" />task</li> </ul> <ul> <li>not a task</li> @@ -24,7 +24,7 @@ describe('markdownit', () => { <li>not a task</li> </ul> <ul class="contains-task-list"> - <li class="task-list-item"><input class="task-list-item-checkbox" disabled="" type="checkbox"> task</li> + <li class="task-list-item "><input class="task-list-item-checkbox" type="checkbox" disabled="" id="task-item-1" />task</li> </ul> `)) }) |