@@ -126,25 +126,85 @@ function isWhitespace(nodePath: NodePath<t.JSXExpressionContainer>) {
126
126
}
127
127
128
128
function normalizeJsxWhitespace ( input : string ) {
129
+ // Handle single-line content
130
+ if ( ! input . includes ( "\n" ) ) {
131
+ // For single-line content, only trim if it appears to be formatting whitespace
132
+ // (e.g., " hello world " should be trimmed to "hello world")
133
+ // But preserve meaningful leading/trailing spaces (e.g., " hello" should stay " hello")
134
+
135
+ // If the content is mostly whitespace with some text, it's likely formatting
136
+ const trimmed = input . trim ( ) ;
137
+ if ( trimmed . length === 0 ) return "" ;
138
+
139
+ // Check if we have excessive whitespace (more than 1 space on each side)
140
+ const leadingMatch = input . match ( / ^ \s * / ) ;
141
+ const trailingMatch = input . match ( / \s * $ / ) ;
142
+ const leadingSpaces = leadingMatch ? leadingMatch [ 0 ] . length : 0 ;
143
+ const trailingSpaces = trailingMatch ? trailingMatch [ 0 ] . length : 0 ;
144
+
145
+ if ( leadingSpaces > 1 || trailingSpaces > 1 ) {
146
+ // This looks like formatting whitespace, collapse it
147
+ return input . replace ( / \s + / g, " " ) . trim ( ) ;
148
+ } else {
149
+ // This looks like meaningful whitespace, preserve it but collapse internal spaces
150
+ return input . replace ( / \s { 2 , } / g, " " ) ;
151
+ }
152
+ }
153
+
154
+ // Handle multi-line content
129
155
const lines = input . split ( "\n" ) ;
130
156
let result = "" ;
157
+
131
158
for ( let i = 0 ; i < lines . length ; i ++ ) {
132
- const line = lines [ i ] . trim ( ) ;
133
- if ( line === "" ) continue ;
134
- if (
135
- i > 0 &&
136
- ( line . startsWith ( "<element:" ) ||
137
- line . startsWith ( "<function:" ) ||
138
- line . startsWith ( "{" ) ||
139
- line . startsWith ( "<expression/>" ) )
159
+ const line = lines [ i ] ;
160
+ const trimmedLine = line . trim ( ) ;
161
+
162
+ // Skip empty lines
163
+ if ( trimmedLine === "" ) continue ;
164
+
165
+ // Check if this line contains a placeholder (explicit whitespace)
166
+ if ( trimmedLine . includes ( WHITESPACE_PLACEHOLDER ) ) {
167
+ // For lines with placeholders, preserve the original spacing
168
+ result += trimmedLine ;
169
+ } else if (
170
+ trimmedLine . startsWith ( "<element:" ) ||
171
+ trimmedLine . startsWith ( "<function:" ) ||
172
+ trimmedLine . startsWith ( "{" ) ||
173
+ trimmedLine . startsWith ( "<expression/>" )
140
174
) {
141
- result += line ;
175
+ // When we encounter an element/function/expression
176
+ // Add space only when:
177
+ // 1. We have existing content AND
178
+ // 2. Result doesn't already end with space or placeholder AND
179
+ // 3. The result ends with a word character (indicating text) AND
180
+ // 4. The element content starts with a space (indicating word continuation)
181
+ const shouldAddSpace =
182
+ result &&
183
+ ! result . endsWith ( " " ) &&
184
+ ! result . endsWith ( WHITESPACE_PLACEHOLDER ) &&
185
+ / \w $ / . test ( result ) &&
186
+ // Check if element content starts with space by looking for "> " pattern
187
+ trimmedLine . includes ( "> " ) ;
188
+
189
+ if ( shouldAddSpace ) {
190
+ result += " " ;
191
+ }
192
+ result += trimmedLine ;
142
193
} else {
143
- if ( result && ! result . endsWith ( " " ) ) result += " " ;
144
- result += line ;
194
+ // For regular text content, ensure proper spacing
195
+ // Only add space if the result doesn't already end with a space or placeholder
196
+ if (
197
+ result &&
198
+ ! result . endsWith ( " " ) &&
199
+ ! result . endsWith ( WHITESPACE_PLACEHOLDER )
200
+ ) {
201
+ result += " " ;
202
+ }
203
+ result += trimmedLine ;
145
204
}
146
205
}
147
- // Collapse multiple spaces
148
- result = result . replace ( / \s + / g, " " ) ;
206
+
207
+ // Collapse multiple spaces but preserve single spaces around placeholders
208
+ result = result . replace ( / \s { 2 , } / g, " " ) ;
149
209
return result . trim ( ) ;
150
210
}
0 commit comments