Skip to content

Commit

Permalink
markdown: use " \n" as the representation for LineBreakNode
Browse files Browse the repository at this point in the history
In Markdown, single newlines are irrelevant for presentation.
They are only for the editing convenience of the author.

In HTML and the Lexical composer, a LineBreakNode / `<br>` tag
represent a line break in the presentation of the content.
Currently, the equivalence with single newlines causes the markdown
representation to not be accurate to the composer view or HTML
generated or imported.

In Markdown, you can create a line break in the presentation and
achieve the desired effect by ending a line with two spaces
(followed by a newline). Update the import/export to do this.
  • Loading branch information
robfig committed Oct 10, 2023
1 parent 9a679ec commit 7d994a2
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 16 deletions.
2 changes: 1 addition & 1 deletion packages/lexical-markdown/src/MarkdownExport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ function exportChildren(
}

if ($isLineBreakNode(child)) {
output.push('\n');
output.push(' \n');
} else if ($isTextNode(child)) {
output.push(
exportTextFormat(child, child.getTextContent(), textTransformersIndex),
Expand Down
16 changes: 10 additions & 6 deletions packages/lexical-markdown/src/MarkdownImport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,17 @@ function importBlocks(
const textNode = $createTextNode(lineTextTrimmed);
const elementNode = $createParagraphNode();
elementNode.append(textNode);
if (lineText.endsWith(' ')) {
elementNode.append($createLineBreakNode());
}
rootNode.append(elementNode);

for (const {regExp, replace} of elementTransformers) {
const match = lineText.match(regExp);

if (match) {
textNode.setTextContent(lineText.slice(match[0].length));
replace(elementNode, [textNode], match, true);
textNode.setTextContent(lineText.slice(match[0].length).trimEnd());
replace(elementNode, elementNode.getChildren(), match, true);
break;
}
}
Expand Down Expand Up @@ -157,10 +160,11 @@ function importBlocks(
}

if (targetNode != null && targetNode.getTextContentSize() > 0) {
targetNode.splice(targetNode.getChildrenSize(), 0, [
$createLineBreakNode(),
...elementNode.getChildren(),
]);
targetNode.splice(
targetNode.getChildrenSize(),
0,
elementNode.getChildren(),
);
elementNode.remove();
}
}
Expand Down
6 changes: 1 addition & 5 deletions packages/lexical-markdown/src/MarkdownTransformers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import {
QuoteNode,
} from '@lexical/rich-text';
import {
$createLineBreakNode,
$createTextNode,
$isTextNode,
ElementNode,
Expand Down Expand Up @@ -206,10 +205,7 @@ export const QUOTE: ElementTransformer = {
if (isImport) {
const previousNode = parentNode.getPreviousSibling();
if ($isQuoteNode(previousNode)) {
previousNode.splice(previousNode.getChildrenSize(), 0, [
$createLineBreakNode(),
...children,
]);
previousNode.splice(previousNode.getChildrenSize(), 0, children);
previousNode.select(0, 0);
parentNode.remove();
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,16 @@ describe('Markdown', () => {
{
// Multiline paragraphs
html: '<p><span style="white-space: pre-wrap;">Hello</span><br><span style="white-space: pre-wrap;">world</span><br><span style="white-space: pre-wrap;">!</span></p>',
md: ['Hello', 'world', '!'].join('\n'),
md: ['Hello ', 'world ', '!'].join('\n'),
},
{
html: '<blockquote><span style="white-space: pre-wrap;">Hello</span><br><span style="white-space: pre-wrap;">world!</span></blockquote>',
md: '> Hello\n> world!',
md: '> Hello \n> world!',
},
{
// Miltiline list items
html: '<ul><li value="1"><span style="white-space: pre-wrap;">Hello</span></li><li value="2"><span style="white-space: pre-wrap;">world</span><br><span style="white-space: pre-wrap;">!</span><br><span style="white-space: pre-wrap;">!</span></li></ul>',
md: '- Hello\n- world\n!\n!',
md: '- Hello\n- world \n! \n!',
},
{
html: '<ul><li value="1"><span style="white-space: pre-wrap;">Hello</span></li><li value="2"><span style="white-space: pre-wrap;">world</span></li></ul>',
Expand Down Expand Up @@ -174,7 +174,7 @@ describe('Markdown', () => {
{
// Import only: multiline quote will be prefixed with ">" on each line during export
html: '<blockquote><span style="white-space: pre-wrap;">Hello</span><br><span style="white-space: pre-wrap;">world</span><br><span style="white-space: pre-wrap;">!</span></blockquote>',
md: '> Hello\nworld\n!',
md: '> Hello \nworld \n!',
skipExport: true,
},
{
Expand Down

0 comments on commit 7d994a2

Please sign in to comment.