From efb27a52f5aed9771cb5e4a019e8a3125dfb7d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Mon, 30 May 2022 11:43:59 +0200 Subject: [PATCH] Implement toMarkdown for hard break instead of replacing after markdown transformation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- src/EditorFactory.js | 3 +-- src/extensions/HardBreak.js | 37 +++++++++++++++++++++++++++++++++++++ src/extensions/Markdown.js | 1 - src/extensions/index.js | 2 ++ src/tests/markdown.spec.js | 10 ++++++++++ 5 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 src/extensions/HardBreak.js diff --git a/src/EditorFactory.js b/src/EditorFactory.js index 5cf714080..4de8e7145 100644 --- a/src/EditorFactory.js +++ b/src/EditorFactory.js @@ -24,7 +24,6 @@ import Document from '@tiptap/extension-document' import Paragraph from '@tiptap/extension-paragraph' import Text from '@tiptap/extension-text' -import HardBreak from '@tiptap/extension-hard-break' import History from '@tiptap/extension-history' import Blockquote from '@tiptap/extension-blockquote' import Placeholder from '@tiptap/extension-placeholder' @@ -53,7 +52,7 @@ import { TaskItem, Callout, } from './nodes/index.js' -import { Markdown, Emoji } from './extensions/index.js' +import { HardBreak, Markdown, Emoji } from './extensions/index.js' import { translate as t } from '@nextcloud/l10n' import { listLanguages, registerLanguage } from 'lowlight/lib/core' import { emojiSearch } from '@nextcloud/vue/dist/Functions/emoji' diff --git a/src/extensions/HardBreak.js b/src/extensions/HardBreak.js new file mode 100644 index 000000000..60c7518ee --- /dev/null +++ b/src/extensions/HardBreak.js @@ -0,0 +1,37 @@ +/* + * @copyright Copyright (c) 2022 Julius Härtl + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * +*/ + +import TipTapHardBreak from '@tiptap/extension-hard-break' + +const HardBreak = TipTapHardBreak.extend({ + + toMarkdown(state, node, parent, index) { + for (let i = index + 1; i < parent.childCount; i++) { + if (parent.child(i).type !== node.type) { + state.write(' \n') + return + } + } + }, +}) + +export default HardBreak diff --git a/src/extensions/Markdown.js b/src/extensions/Markdown.js index 7eae9c83a..c7faa5caf 100644 --- a/src/extensions/Markdown.js +++ b/src/extensions/Markdown.js @@ -79,7 +79,6 @@ const createMarkdownSerializer = ({ nodes, marks }) => { ), serialize(content, options) { return this.serializer.serialize(content, { ...options, tightLists: true }) - .split('\\\n').join(' \n') .split('\\[').join('[') .split('\\]').join(']') }, diff --git a/src/extensions/index.js b/src/extensions/index.js index 998fff30c..d6ce69a8c 100644 --- a/src/extensions/index.js +++ b/src/extensions/index.js @@ -21,6 +21,7 @@ */ import Emoji from './Emoji.js' +import HardBreak from './HardBreak.js' import Keymap from './Keymap.js' import UserColor from './UserColor.js' import Collaboration from './Collaboration.js' @@ -28,6 +29,7 @@ import Markdown from './Markdown.js' export { Emoji, + HardBreak, Keymap, UserColor, Collaboration, diff --git a/src/tests/markdown.spec.js b/src/tests/markdown.spec.js index 2e862c13b..828bfd5c2 100644 --- a/src/tests/markdown.spec.js +++ b/src/tests/markdown.spec.js @@ -58,6 +58,11 @@ describe('Markdown though editor', () => { expect(markdownThroughEditor('#### Test')).toBe('#### Test') expect(markdownThroughEditor('##### Test')).toBe('##### Test') }) + test('hard breaks', () => { + expect(markdownThroughEditor('hard \nbreak')).toBe('hard \nbreak') + expect(markdownThroughEditor('hard\\\nbreak')).toBe('hard \nbreak') + expect(markdownThroughEditor('no\nbreak')).toBe('no break') + }) test('inline format', () => { expect(markdownThroughEditor('**Test**')).toBe('**Test**') expect(markdownThroughEditor('__Test__')).toBe('__Test__') @@ -131,6 +136,11 @@ describe('Markdown serializer from html', () => { test('paragraph', () => { expect(markdownThroughEditorHtml('

hello

world

')).toBe('hello\n\nworld') }) + test('hard line breaks', () => { + expect(markdownThroughEditorHtml('

hard
break

')).toBe('hard \nbreak') + expect(markdownThroughEditorHtml('

hard
break

')).toBe('hard \nbreak') + expect(markdownThroughEditorHtml('

no\nbreak

')).toBe('no break') + }) test('links', () => { expect(markdownThroughEditorHtml('test')).toBe('[test](foo)') })