From 9332d501ad4862517e66c5b4a13eb0db09b3697a Mon Sep 17 00:00:00 2001 From: Evan Jacobs Date: Mon, 20 Jan 2025 17:01:17 -0500 Subject: [PATCH] refactor: improve inline code performance --- .changeset/plenty-dodos-collect.md | 5 +++++ .prettierignore | 1 + __snapshots__/index.compiler.spec.tsx.snap | 6 +++--- fixture.md | 2 +- index.tsx | 15 ++++++++++----- 5 files changed, 20 insertions(+), 9 deletions(-) create mode 100644 .changeset/plenty-dodos-collect.md create mode 100644 .prettierignore diff --git a/.changeset/plenty-dodos-collect.md b/.changeset/plenty-dodos-collect.md new file mode 100644 index 00000000..2ab20106 --- /dev/null +++ b/.changeset/plenty-dodos-collect.md @@ -0,0 +1,5 @@ +--- +'markdown-to-jsx': patch +--- + +Rework inline code syntax handling, handle escaped characters in code blocks correctly so they render without the backslash. diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..0aed9848 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +fixture.md diff --git a/__snapshots__/index.compiler.spec.tsx.snap b/__snapshots__/index.compiler.spec.tsx.snap index ceabbfa8..1ca360b3 100644 --- a/__snapshots__/index.compiler.spec.tsx.snap +++ b/__snapshots__/index.compiler.spec.tsx.snap @@ -924,7 +924,7 @@ line. To avoid this, you can backslash-escape the period:

     
-      1986\\. What a great season.
+      1986. What a great season.
     
   

@@ -1433,7 +1433,7 @@ escape it:

     
-      \\*this text is surrounded by literal asterisks\\*
+      *this text is surrounded by literal asterisks*
     
   

@@ -1688,7 +1688,7 @@ backslashes before the asterisks, like this:

     
-      \\*literal asterisks\\*
+      *literal asterisks*
     
   

diff --git a/fixture.md b/fixture.md index 9434ec56..ee056899 100644 --- a/fixture.md +++ b/fixture.md @@ -745,7 +745,7 @@ escape it:

Code

-To indicate a span of code, wrap it with backtick quotes (`` ` ``). +To indicate a span of code, wrap it with backtick quotes (`\``). Unlike a pre-formatted code block, a code span indicates code within a normal paragraph. For example: diff --git a/index.tsx b/index.tsx index bc1c579b..5f4ea85b 100644 --- a/index.tsx +++ b/index.tsx @@ -190,7 +190,7 @@ const BREAK_THEMATIC_R = /^(?:( *[-*_])){3,} *(?:\n *)+\n/ const CODE_BLOCK_FENCED_R = /^(?: {1,3})?(`{3,}|~{3,}) *(\S+)? *([^\n]*?)?\n([\s\S]*?)(?:\1\n?|$)/ const CODE_BLOCK_R = /^(?: {4}[^\n]+\n*)+(?:\n *)+\n?/ -const CODE_INLINE_R = /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/ +const CODE_INLINE_R = /^(`+)((?:\\`|[^`])+)\1/ const CONSECUTIVE_NEWLINE_R = /^(?:\n *)*\n/ const CR_NEWLINE_R = /\r\n?/g @@ -320,6 +320,7 @@ const TEXT_MARKED_R = new RegExp(`^==${INLINE_SKIP_R}==`) const TEXT_STRIKETHROUGHED_R = new RegExp(`^~~${INLINE_SKIP_R}~~`) const TEXT_ESCAPED_R = /^\\([^0-9A-Za-z\s])/ +const TEXT_UNESCAPE_R = /\\([^0-9A-Za-z\s])/g /** * Always take the first character, then eagerly take text until a double space @@ -460,6 +461,7 @@ function generateListRule( .match(LIST_ITEM_R) let lastItemWasAParagraph = false + const itemContent = items.map(function (item, i) { // We need to see how far indented the item is: const space = LIST_ITEM_PREFIX_R.exec(item)[0].length @@ -495,7 +497,7 @@ function generateListRule( containsBlocks || (isLastItem && lastItemWasAParagraph) lastItemWasAParagraph = thisItemIsAParagraph - // backup our state for restoration afterwards. We're going to + // backup our state for delta afterwards. We're going to // want to set state.list to true, and state.inline depending // on our list's looseness. const oldStateInline = state.inline @@ -1400,7 +1402,10 @@ export function compiler( parse(capture /*, parse, state*/) { return { lang: undefined, - text: capture[0].replace(/^ {4}/gm, '').replace(/\n+$/, ''), + text: capture[0] + .replace(/^ {4}/gm, '') + .replace(/\n+$/, '') + .replaceAll(TEXT_UNESCAPE_R, '$1'), } }, @@ -1430,7 +1435,7 @@ export function compiler( // if capture[3] it's additional metadata attrs: attrStringToMap('code', capture[3] || ''), lang: capture[2] || undefined, - text: capture[4], + text: capture[4].replaceAll(TEXT_UNESCAPE_R, '$1'), type: RuleType.codeBlock, } }, @@ -1441,7 +1446,7 @@ export function compiler( order: Priority.LOW, parse(capture /*, parse, state*/) { return { - text: capture[2], + text: capture[2].replaceAll(TEXT_UNESCAPE_R, '$1'), } }, render(node, output, state) {