From 315cb7a38a1645623fc55501429285ab680b8a6a Mon Sep 17 00:00:00 2001 From: wnhlee <40269597+2wheeh@users.noreply.github.com> Date: Mon, 8 Jan 2024 01:06:41 +0900 Subject: [PATCH] fix wrong quotes around inline codes (#6523) * fix wrong way quotes * bump up to clear mdx cache --- plugins/remark-smartypants.js | 47 ++++++++++++++++++++++++++++++++--- src/utils/prepareMDX.js | 2 +- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/plugins/remark-smartypants.js b/plugins/remark-smartypants.js index 7dd1b0c4a..4694ff674 100644 --- a/plugins/remark-smartypants.js +++ b/plugins/remark-smartypants.js @@ -1,3 +1,8 @@ +/*! + * Based on 'silvenon/remark-smartypants' + * https://github.com/silvenon/remark-smartypants/pull/80 + */ + const visit = require('unist-util-visit'); const retext = require('retext'); const smartypants = require('retext-smartypants'); @@ -9,12 +14,48 @@ function check(parent) { } module.exports = function (options) { - const processor = retext().use(smartypants, options); + const processor = retext().use(smartypants, { + ...options, + // Do not replace ellipses, dashes, backticks because they change string + // length, and we couldn't guarantee right splice of text in second visit of + // tree + ellipses: false, + dashes: false, + backticks: false, + }); + + const processor2 = retext().use(smartypants, { + ...options, + // Do not replace quotes because they are already replaced in the first + // processor + quotes: false, + }); function transformer(tree) { - visit(tree, 'text', (node, index, parent) => { - if (check(parent)) node.value = String(processor.processSync(node.value)); + let allText = ''; + let startIndex = 0; + const textOrInlineCodeNodes = []; + + visit(tree, ['text', 'inlineCode'], (node, _, parent) => { + if (check(parent)) { + if (node.type === 'text') allText += node.value; + // for the case when inlineCode contains just one part of quote: `foo'bar` + else allText += 'A'.repeat(node.value.length); + textOrInlineCodeNodes.push(node); + } }); + + // Concat all text into one string, to properly replace quotes around non-"text" nodes + allText = String(processor.processSync(allText)); + + for (const node of textOrInlineCodeNodes) { + const endIndex = startIndex + node.value.length; + if (node.type === 'text') { + const processedText = allText.slice(startIndex, endIndex); + node.value = String(processor2.processSync(processedText)); + } + startIndex = endIndex; + } } return transformer; diff --git a/src/utils/prepareMDX.js b/src/utils/prepareMDX.js index 639d7db90..20a22577d 100644 --- a/src/utils/prepareMDX.js +++ b/src/utils/prepareMDX.js @@ -7,7 +7,7 @@ import {Children} from 'react'; // TODO: This logic could be in MDX plugins instead. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -export const PREPARE_MDX_CACHE_BREAKER = 2; +export const PREPARE_MDX_CACHE_BREAKER = 3; // !!! IMPORTANT !!! Bump this if you change any logic. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~