diff --git a/src/nodes/HardBreak.js b/src/nodes/HardBreak.js
index aee34e042b2..d764067a0e7 100644
--- a/src/nodes/HardBreak.js
+++ b/src/nodes/HardBreak.js
@@ -9,7 +9,7 @@ const HardBreak = TipTapHardBreak.extend({
addAttributes() {
return {
syntax: {
- default: ' ',
+ default: 'soft',
rendered: false,
keepOnSplit: true,
parseHTML: (el) => el.getAttribute('data-syntax') || ' ',
@@ -17,6 +17,14 @@ const HardBreak = TipTapHardBreak.extend({
}
},
+ renderHTML({ node, HTMLAttributes }) {
+ if (node.attrs.syntax === 'soft') {
+ // Rendered as inline whitespace, not a visible line break
+ return ['span', { ...HTMLAttributes, 'data-soft-break': '' }, ' ']
+ }
+ return ['br', HTMLAttributes]
+ },
+
addCommands() {
return {
...this?.parent(),
@@ -26,7 +34,18 @@ const HardBreak = TipTapHardBreak.extend({
if (ctx.state.selection.$from.node(d).type.name === 'heading')
return false
}
- return this.parent().setHardBreak()(ctx)
+ // Call upstream setHardBreak, then set syntax property for type 'soft'
+ return ctx.chain()
+ .command(this.parent().setHardBreak())
+ .command(({ tr }) => {
+ const pos = tr.selection.$anchor.pos -1
+ const node = tr.doc.nodeAt(pos)
+ if (node?.type.name === 'hardBreak' && node.attrs.syntax === 'soft') {
+ tr.setNodeMarkup(pos, null, { ...node.attrs, syntax: ' ' })
+ }
+ return true
+ })
+ .run()
},
}
},
@@ -34,11 +53,13 @@ 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) {
- if (node.attrs.syntax !== 'html') {
+ if (node.attrs.syntax === 'soft') {
+ state.write('\n')
+ } else if (node.attrs.syntax === 'html') {
+ state.write('
')
+ } else {
state.write(node.attrs.syntax)
if (!parent.child(i).text?.startsWith('\n')) state.write('\n')
- } else {
- state.write('
')
}
return
}
diff --git a/src/tests/markdown.spec.js b/src/tests/markdown.spec.js
index 357464f9932..46361dfe0d2 100644
--- a/src/tests/markdown.spec.js
+++ b/src/tests/markdown.spec.js
@@ -52,6 +52,9 @@ describe('Markdown though editor', () => {
expect(markdownThroughEditor('- foo\n- bar')).toBe('- foo\n- bar')
expect(markdownThroughEditor('- foo\n\n- bar')).toBe('- foo\n- bar')
expect(markdownThroughEditor('- foo\n\n\n- bar')).toBe('- foo\n- bar')
+ expect(markdownThroughEditor('- foo\n - bar')).toBe('- foo\n - bar')
+ expect(markdownThroughEditor('- foo\n - bar\n- baz')).toBe('- foo\n - bar\n- baz')
+ expect(markdownThroughEditor('- foo\n bar\n baz')).toBe('- foo\n bar\n baz')
})
test('ol', () => {
expect(markdownThroughEditor('1. foo\n2. bar')).toBe('1. foo\n2. bar')