mirror of
https://github.com/facebook/lexical.git
synced 2025-05-17 23:26:16 +08:00
[RFC][lexical-markdown] Replace whitespace with code point when the string has leading and trailing whitespaces (#7400)
This commit is contained in:
@ -203,10 +203,13 @@ function exportTextFormat(
|
||||
): string {
|
||||
// This function handles the case of a string looking like this: " foo "
|
||||
// Where it would be invalid markdown to generate: "** foo **"
|
||||
// We instead want to trim the whitespace out, apply formatting, and then
|
||||
// bring the whitespace back. So our returned string looks like this: " **foo** "
|
||||
const frozenString = textContent.trim();
|
||||
let output = frozenString;
|
||||
// If the node has no format, we use the original text.
|
||||
// Otherwise, we escape leading and trailing whitespaces to their corresponding code points,
|
||||
// ensuring the returned string maintains its original formatting, e.g., "**   foo   **".
|
||||
let output =
|
||||
node.getFormat() === 0
|
||||
? textContent
|
||||
: escapeLeadingAndTrailingWhitespaces(textContent);
|
||||
|
||||
if (!node.hasFormat('code')) {
|
||||
// Escape any markdown characters in the text content
|
||||
@ -287,7 +290,7 @@ function exportTextFormat(
|
||||
|
||||
output = openingTags + output + closingTagsAfter;
|
||||
// Replace trimmed version of textContent ensuring surrounding whitespace is not modified
|
||||
return closingTagsBefore + textContent.replace(frozenString, () => output);
|
||||
return closingTagsBefore + output;
|
||||
}
|
||||
|
||||
// Get next or previous text sibling a text node, including cases
|
||||
@ -342,3 +345,9 @@ function hasFormat(
|
||||
): boolean {
|
||||
return $isTextNode(node) && node.hasFormat(format);
|
||||
}
|
||||
|
||||
function escapeLeadingAndTrailingWhitespaces(textContent: string) {
|
||||
return textContent.replace(/^\s+|\s+$/g, (match) => {
|
||||
return [...match].map((char) => '&#' + char.codePointAt(0) + ';').join('');
|
||||
});
|
||||
}
|
||||
|
@ -360,14 +360,17 @@ describe('Markdown', () => {
|
||||
{
|
||||
html: '<p><b><strong style="white-space: pre-wrap;">Hello </strong></b><s><b><strong style="white-space: pre-wrap;">world</strong></b></s><span style="white-space: pre-wrap;">!</span></p>',
|
||||
md: '**Hello ~~world~~**!',
|
||||
mdAfterExport: '**Hello ~~world~~**!',
|
||||
},
|
||||
{
|
||||
html: '<p><s><b><strong style="white-space: pre-wrap;">Hello </strong></b></s><s><i><b><strong style="white-space: pre-wrap;">world</strong></b></i></s><s><span style="white-space: pre-wrap;">!</span></s></p>',
|
||||
md: '**~~Hello *world*~~**~~!~~',
|
||||
mdAfterExport: '**~~Hello *world*~~**~~!~~',
|
||||
},
|
||||
{
|
||||
html: '<p><i><em style="white-space: pre-wrap;">Hello </em></i><i><b><strong style="white-space: pre-wrap;">world</strong></b></i><i><em style="white-space: pre-wrap;">!</em></i></p>',
|
||||
md: '*Hello **world**!*',
|
||||
mdAfterExport: '*Hello **world**!*',
|
||||
},
|
||||
{
|
||||
html: '<p><span style="white-space: pre-wrap;">helloworld</span></p>',
|
||||
@ -548,20 +551,26 @@ describe('Markdown', () => {
|
||||
{
|
||||
html: '<p><span style="white-space: pre-wrap;">Text </span><b><strong style="white-space: pre-wrap;">boldstart </strong></b><a href="https://lexical.dev"><b><strong style="white-space: pre-wrap;">text</strong></b></a><b><strong style="white-space: pre-wrap;"> boldend</strong></b><span style="white-space: pre-wrap;"> text</span></p>',
|
||||
md: 'Text **boldstart [text](https://lexical.dev) boldend** text',
|
||||
mdAfterExport:
|
||||
'Text **boldstart [text](https://lexical.dev) boldend** text',
|
||||
},
|
||||
{
|
||||
html: '<p><span style="white-space: pre-wrap;">Text </span><b><strong style="white-space: pre-wrap;">boldstart </strong></b><a href="https://lexical.dev"><b><code spellcheck="false" style="white-space: pre-wrap;"><strong>text</strong></code></b></a><b><strong style="white-space: pre-wrap;"> boldend</strong></b><span style="white-space: pre-wrap;"> text</span></p>',
|
||||
md: 'Text **boldstart [`text`](https://lexical.dev) boldend** text',
|
||||
mdAfterExport:
|
||||
'Text **boldstart [`text`](https://lexical.dev) boldend** text',
|
||||
},
|
||||
{
|
||||
html: '<p><span style="white-space: pre-wrap;">It </span><s><i><b><strong style="white-space: pre-wrap;">works </strong></b></i></s><a href="https://lexical.io"><s><i><b><strong style="white-space: pre-wrap;">with links</strong></b></i></s></a><span style="white-space: pre-wrap;"> too</span></p>',
|
||||
md: 'It ~~___works [with links](https://lexical.io)___~~ too',
|
||||
mdAfterExport: 'It ***~~works [with links](https://lexical.io)~~*** too',
|
||||
mdAfterExport:
|
||||
'It ***~~works [with links](https://lexical.io)~~*** too',
|
||||
},
|
||||
{
|
||||
html: '<p><span style="white-space: pre-wrap;">It </span><s><i><b><strong style="white-space: pre-wrap;">works </strong></b></i></s><a href="https://lexical.io"><s><i><b><strong style="white-space: pre-wrap;">with links</strong></b></i></s></a><s><i><b><strong style="white-space: pre-wrap;"> too</strong></b></i></s><span style="white-space: pre-wrap;">!</span></p>',
|
||||
md: 'It ~~___works [with links](https://lexical.io) too___~~!',
|
||||
mdAfterExport: 'It ***~~works [with links](https://lexical.io) too~~***!',
|
||||
mdAfterExport:
|
||||
'It ***~~works [with links](https://lexical.io) too~~***!',
|
||||
},
|
||||
{
|
||||
html: '<p><a href="https://lexical.dev"><span style="white-space: pre-wrap;">link</span></a><a href="https://lexical.dev"><span style="white-space: pre-wrap;">link2</span></a></p>',
|
||||
@ -609,6 +618,10 @@ describe('Markdown', () => {
|
||||
html: '<p><span style="white-space: pre-wrap;">*Hello* world</span></p>',
|
||||
md: '\\*Hello\\* world',
|
||||
},
|
||||
{
|
||||
html: '<p><b><strong style="white-space: pre-wrap;"> </strong></b></p>',
|
||||
md: '** **',
|
||||
},
|
||||
];
|
||||
|
||||
const HIGHLIGHT_TEXT_MATCH_IMPORT: TextMatchTransformer = {
|
||||
|
@ -133,6 +133,10 @@ export function importTextTransformers(
|
||||
|
||||
// Handle escape characters
|
||||
const textContent = textNode.getTextContent();
|
||||
const escapedText = textContent.replace(/\\([*_`~])/g, '$1');
|
||||
const escapedText = textContent
|
||||
.replace(/\\([*_`~])/g, '$1')
|
||||
.replace(/&#(\d+);/g, (_, codePoint) => {
|
||||
return String.fromCodePoint(codePoint);
|
||||
});
|
||||
textNode.setTextContent(escapedText);
|
||||
}
|
||||
|
Reference in New Issue
Block a user