( source: string, nodePath: any, reservedKeysByParent: Map<string, Set<string>>, )
| 1228 | } |
| 1229 | |
| 1230 | function buildDuplicateSplice( |
| 1231 | source: string, |
| 1232 | nodePath: any, |
| 1233 | reservedKeysByParent: Map<string, Set<string>>, |
| 1234 | ): SourceSplice | null { |
| 1235 | const node = nodePath.node; |
| 1236 | const start = node.start; |
| 1237 | const end = node.end; |
| 1238 | if (start == null || end == null) return null; |
| 1239 | const subtreeText = source.slice(start, end); |
| 1240 | const processedText = deduplicateKey(subtreeText, nodePath, reservedKeysByParent); |
| 1241 | |
| 1242 | // Determine if this is an inline child (e.g. <a> inside <p>) or a block-level sibling. |
| 1243 | // Check if the element is on its own line: if the text between the previous newline |
| 1244 | // and the element start is only whitespace, it's block-level and gets newline+indent. |
| 1245 | // Otherwise it's inline and gets inserted with the same separator that follows it. |
| 1246 | const lineStart = source.lastIndexOf("\n", start) + 1; |
| 1247 | const textBeforeOnLine = source.slice(lineStart, start); |
| 1248 | const isBlockLevel = textBeforeOnLine.trim() === ""; |
| 1249 | |
| 1250 | if (isBlockLevel) { |
| 1251 | const indent = textBeforeOnLine; |
| 1252 | return { offset: end, insert: "\n" + indent + processedText }; |
| 1253 | } |
| 1254 | |
| 1255 | // Inline element — reuse the separator that currently follows the element |
| 1256 | // so duplicates preserve punctuation and spacing within prose. |
| 1257 | const separator = extractInlineDuplicateSeparator(source, nodePath); |
| 1258 | |
| 1259 | return { offset: end, insert: separator + processedText }; |
| 1260 | } |
| 1261 | |
| 1262 | export function executeBatch( |
| 1263 | operations: BatchOperation[], |
no test coverage detected