Skip to content

Commit 40e6887

Browse files
committed
handle trailing content after inline JSX closing tags
1 parent 4d1f469 commit 40e6887

1 file changed

Lines changed: 22 additions & 7 deletions

File tree

plugins/prettier-plugin-mdx-inline/index.mjs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,23 @@
3434
* }],
3535
*/
3636

37+
/**
38+
* Extract the element name from the start of a JSX string.
39+
* e.g., "<code>" → "code", "<GlossaryTooltip term="x">" → "GlossaryTooltip"
40+
*/
41+
function getElementName(value) {
42+
const match = value.trim().match(/^<([a-zA-Z][a-zA-Z0-9]*)/);
43+
return match ? match[1] : null;
44+
}
45+
3746
/**
3847
* Collapse a multi-line JSX element value onto a single line.
3948
*
4049
* Handles:
4150
* - {" "} spacer expressions inserted by prettier
4251
* - Newlines with surrounding whitespace from indentation
4352
* - Multiple consecutive spaces from collapsing
53+
* - Trailing content after the closing tag (e.g., in list items)
4454
*
4555
* Preserves:
4656
* - Attribute values (strings in the opening tag)
@@ -50,6 +60,9 @@ function collapseInlineJsx(value) {
5060
// Remove {" "} spacers — these are prettier artifacts for preserving spaces
5161
let result = value.replace(/\{" "\}/g, " ");
5262

63+
const elementName = getElementName(result);
64+
if (!elementName) return result;
65+
5366
// Find the end of the opening tag by tracking string context.
5467
// We need to skip over attribute values that may contain '>' characters.
5568
let inString = false;
@@ -73,22 +86,24 @@ function collapseInlineJsx(value) {
7386

7487
if (openTagEnd === -1) return result;
7588

76-
// Find the closing tag at the end of the value
77-
const closeTagMatch = result.match(/<\/[a-zA-Z][a-zA-Z0-9]*>\s*$/);
78-
if (!closeTagMatch) return result;
89+
// Find the matching closing tag — it may not be at the very end of the
90+
// value if there is trailing content (e.g., in a list item where the
91+
// description text follows the </code> within the same JSX node).
92+
const closeTag = `</${elementName}>`;
93+
const closeTagIndex = result.indexOf(closeTag, openTagEnd);
94+
if (closeTagIndex === -1) return result;
7995

80-
const closeTagStart = closeTagMatch.index;
8196
const openTag = result.substring(0, openTagEnd + 1);
82-
const content = result.substring(openTagEnd + 1, closeTagStart);
83-
const closeTag = closeTagMatch[0].trim();
97+
const content = result.substring(openTagEnd + 1, closeTagIndex);
98+
const trailing = result.substring(closeTagIndex + closeTag.length);
8499

85100
// Collapse whitespace in the content between tags
86101
const collapsed = content
87102
.replace(/\n\s*/g, " ") // newlines + indentation → single space
88103
.replace(/\s{2,}/g, " ") // multiple spaces → single space
89104
.trim();
90105

91-
return openTag + collapsed + closeTag;
106+
return openTag + collapsed + closeTag + trailing;
92107
}
93108

94109
/**

0 commit comments

Comments
 (0)