diff --git a/packages/richtext-lexical/src/packages/@lexical/markdown/MarkdownExport.ts b/packages/richtext-lexical/src/packages/@lexical/markdown/MarkdownExport.ts index 58d634cb61..edaf0b7900 100644 --- a/packages/richtext-lexical/src/packages/@lexical/markdown/MarkdownExport.ts +++ b/packages/richtext-lexical/src/packages/@lexical/markdown/MarkdownExport.ts @@ -205,6 +205,12 @@ function exportTextFormat( // bring the whitespace back. So our returned string looks like this: " **foo** " const frozenString = textContent.trim() let output = frozenString + + if (!node.hasFormat('code')) { + // Escape any markdown characters in the text content + output = output.replace(/([*_`~\\])/g, '\\$1') + } + // the opening tags to be added to the result let openingTags = '' // the closing tags to be added to the result diff --git a/packages/richtext-lexical/src/packages/@lexical/markdown/MarkdownImport.ts b/packages/richtext-lexical/src/packages/@lexical/markdown/MarkdownImport.ts index aa731b7e10..888d931093 100644 --- a/packages/richtext-lexical/src/packages/@lexical/markdown/MarkdownImport.ts +++ b/packages/richtext-lexical/src/packages/@lexical/markdown/MarkdownImport.ts @@ -29,7 +29,6 @@ import type { Transformer, } from './MarkdownTransformers.js' -import { IS_APPLE_WEBKIT, IS_IOS, IS_SAFARI } from '../../../lexical/utils/environment.js' import { importTextTransformers } from './importTextTransformers.js' import { isEmptyParagraph, transformersByType } from './utils.js' @@ -255,28 +254,26 @@ function createTextFormatTransformersIndex( const tagRegExp = tag.replace(/([*^+])/g, '\\$1') openTagsRegExp.push(tagRegExp) - if (IS_SAFARI || IS_IOS || IS_APPLE_WEBKIT) { - fullMatchRegExpByTag[tag] = new RegExp( - `(${tagRegExp})(?![${tagRegExp}\\s])(.*?[^${tagRegExp}\\s])${tagRegExp}(?!${tagRegExp})`, - ) - } else { + // Single-char tag (e.g. "*"), + if (tag.length === 1) { fullMatchRegExpByTag[tag] = new RegExp( `(? + Escaped \\* + +`, + blockNode: { + fields: { + blockType: 'Banner', + content: textToRichText('Escaped *'), + }, + }, + }, { input: `\`inline code\``, rootChildren: [ @@ -1286,6 +1299,89 @@ Some line [Start of link }, }, }, + { + input: ` + + Some line [Text **bold** \\*normal\\*](/some/link) + +`, + blockNode: { + fields: { + blockType: 'Banner', + content: { + root: { + children: [ + { + children: [ + { + detail: 0, + format: 0, + mode: 'normal', + style: '', + text: 'Some line ', + type: 'text', + version: 1, + }, + { + children: [ + { + detail: 0, + format: 0, + mode: 'normal', + style: '', + text: 'Text ', + type: 'text', + version: 1, + }, + { + detail: 0, + format: 1, + mode: 'normal', + style: '', + text: 'bold', + type: 'text', + version: 1, + }, + { + detail: 0, + format: 0, + mode: 'normal', + style: '', + text: ' *normal*', + type: 'text', + version: 1, + }, + ], + fields: { + linkType: 'custom', + newTab: false, + url: '/some/link', + }, + format: '', + indent: 0, + type: 'link', + version: 3, + }, + ], + direction: null, + format: '', + indent: 0, + textFormat: 0, + textStyle: '', + type: 'paragraph', + version: 1, + }, + ], + direction: null, + format: '', + indent: 0, + type: 'root', + version: 1, + }, + }, + }, + }, + }, { inputAfterConvertFromEditorJSON: `