@purestack/ts-format 1.1.31 → 1.1.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/files.d.mts +2 -7
- package/dist/files.d.mts.map +1 -1
- package/dist/files.mjs +10 -19
- package/dist/files.mjs.map +1 -1
- package/dist/ts-format.d.mts +1 -17
- package/dist/ts-format.d.mts.map +1 -1
- package/dist/ts-format.mjs +9 -17
- package/dist/ts-format.mjs.map +1 -1
- package/package.json +1 -1
package/dist/files.d.mts
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
/*! @purestack/ts-format v1.1.
|
|
1
|
+
/*! @purestack/ts-format v1.1.33 | (c) 2026 Ahmed Yasin Koculu | MIT License */
|
|
2
2
|
|
|
3
|
-
//#region packages/ts-format/src/html.d.ts
|
|
4
3
|
interface HtmlFormattingOptions {
|
|
5
4
|
printWidth: number;
|
|
6
5
|
tabSize: number;
|
|
7
6
|
useTabs: boolean;
|
|
8
7
|
}
|
|
9
|
-
//#endregion
|
|
10
|
-
//#region packages/ts-format/src/source.d.ts
|
|
11
8
|
interface SourceRange {
|
|
12
9
|
start: number;
|
|
13
10
|
end: number;
|
|
@@ -17,8 +14,6 @@ interface FormatOptions extends Partial<HtmlFormattingOptions> {
|
|
|
17
14
|
language?: 'mdx' | 'typescript';
|
|
18
15
|
onlyWithinRange?: SourceRange;
|
|
19
16
|
}
|
|
20
|
-
//#endregion
|
|
21
|
-
//#region packages/ts-format/src/files.d.ts
|
|
22
17
|
export interface FormatFilesOptions extends Omit<FormatOptions, 'filePath' | 'language' | 'onlyWithinRange'> {
|
|
23
18
|
cwd?: string;
|
|
24
19
|
write?: boolean;
|
|
@@ -35,5 +30,5 @@ export declare function formatFiles(inputs?: readonly string[], options?: Format
|
|
|
35
30
|
changed: string[];
|
|
36
31
|
errors: FormatFileError[];
|
|
37
32
|
}>;
|
|
38
|
-
|
|
33
|
+
export {};
|
|
39
34
|
//# sourceMappingURL=files.d.mts.map
|
package/dist/files.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files.d.mts","names":[],"sources":["../src/html.ts","../src/source.ts","../src/files.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"files.d.mts","names":[],"sources":["../src/html.ts","../src/source.ts","../src/files.ts"],"mappings":"A,UAsBiB;EACf;EACA;EACA;;UCvBe;EACf;EACA;;UAWe,sBAAsB,QAAQ;EAC7C;EACA;EACA,kBAAkB;;iBCSH,2BACP,KAAK;EACb;EACA;;EAEA;;iBAGe;EACf;EACA;;;wBAIoB,YACpB,4BACA,UAAS,qBAAuB"}
|
package/dist/files.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @purestack/ts-format v1.1.
|
|
1
|
+
/*! @purestack/ts-format v1.1.33 | (c) 2026 Ahmed Yasin Koculu | MIT License */
|
|
2
2
|
|
|
3
3
|
import { execFile } from "node:child_process";
|
|
4
4
|
import { lstat, readFile, readdir, writeFile } from "node:fs/promises";
|
|
@@ -9,7 +9,7 @@ import postcssPlugin from "prettier/plugins/postcss";
|
|
|
9
9
|
import prettier from "prettier/standalone";
|
|
10
10
|
import ts from "typescript-parser";
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
// packages/ts-format/src/markup.ts
|
|
13
13
|
const VOID_HTML_TAG_NAMES = /* @__PURE__ */ new Set([
|
|
14
14
|
"area",
|
|
15
15
|
"base",
|
|
@@ -117,8 +117,7 @@ function readTagNameEnd(markup, startIndex) {
|
|
|
117
117
|
return index;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
|
|
121
|
-
//#region packages/ts-format/src/expressions.ts
|
|
120
|
+
// packages/ts-format/src/expressions.ts
|
|
122
121
|
/**
|
|
123
122
|
* Protects Regor {{ ... }} expressions while the surrounding markup is
|
|
124
123
|
* formatted as HTML. The expression source is restored byte-for-byte.
|
|
@@ -168,8 +167,7 @@ function createPlaceholder(source, index) {
|
|
|
168
167
|
return placeholder;
|
|
169
168
|
}
|
|
170
169
|
|
|
171
|
-
|
|
172
|
-
//#region packages/ts-format/src/source.ts
|
|
170
|
+
// packages/ts-format/src/source.ts
|
|
173
171
|
function intersects(left, right) {
|
|
174
172
|
return left.start <= right.end && right.start <= left.end;
|
|
175
173
|
}
|
|
@@ -253,8 +251,7 @@ function applySourceEdits(source, edits) {
|
|
|
253
251
|
return parts.join("");
|
|
254
252
|
}
|
|
255
253
|
|
|
256
|
-
|
|
257
|
-
//#region packages/ts-format/src/fences.ts
|
|
254
|
+
// packages/ts-format/src/fences.ts
|
|
258
255
|
function buildMdxFenceDelimiterEdits(document, excludedRanges, options = {}) {
|
|
259
256
|
const edits = [];
|
|
260
257
|
let activeFence;
|
|
@@ -509,8 +506,7 @@ function escapeRegExp$1(value) {
|
|
|
509
506
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
510
507
|
}
|
|
511
508
|
|
|
512
|
-
|
|
513
|
-
//#region packages/ts-format/src/html.ts
|
|
509
|
+
// packages/ts-format/src/html.ts
|
|
514
510
|
const RAW_TEXT_TAG = "script|style|textarea|title|xmp|iframe|noembed|noframes|plaintext";
|
|
515
511
|
const TAG_BODY = `(?:"[^"]*"|'[^']*'|[^"'>])*>`;
|
|
516
512
|
/**
|
|
@@ -541,8 +537,7 @@ function normalizeSelfClosingTagSpacing(formatted) {
|
|
|
541
537
|
return formatted.replace(/\s+/g, (whitespace, offset) => formatted.startsWith("/>", offset + whitespace.length) ? "" : whitespace);
|
|
542
538
|
}
|
|
543
539
|
|
|
544
|
-
|
|
545
|
-
//#region packages/ts-format/src/mdx.ts
|
|
540
|
+
// packages/ts-format/src/mdx.ts
|
|
546
541
|
async function buildMdxFormattingEdits(document, request = {}) {
|
|
547
542
|
const blocks = getMdxMarkupBlocks(document, { includeIncomplete: true }).filter((block) => request.onlyWithinRange ? intersects(block.range, request.onlyWithinRange) : true);
|
|
548
543
|
const edits = [];
|
|
@@ -826,8 +821,7 @@ function findRawTextElementEnd(source, startIndex) {
|
|
|
826
821
|
return tagEnd + 1 + closingTagMatch.index + closingTagMatch[0].length;
|
|
827
822
|
}
|
|
828
823
|
|
|
829
|
-
|
|
830
|
-
//#region packages/ts-format/src/templates.ts
|
|
824
|
+
// packages/ts-format/src/templates.ts
|
|
831
825
|
const SUPPORTED_TEMPLATE_TAG_NAMES = ["html", "svg"];
|
|
832
826
|
async function buildTemplateFormattingEdits(document, request = {}) {
|
|
833
827
|
const templates = getSupportedTaggedTemplates(document).filter((template) => request.onlyWithinRange ? intersects(template.contentRange, request.onlyWithinRange) : true);
|
|
@@ -947,8 +941,7 @@ function restoreTemplateExpressions(formatted, expressions) {
|
|
|
947
941
|
return restored;
|
|
948
942
|
}
|
|
949
943
|
|
|
950
|
-
|
|
951
|
-
//#region packages/ts-format/src/index.ts
|
|
944
|
+
// packages/ts-format/src/index.ts
|
|
952
945
|
/** Formats only component markup and html/svg tagged template contents. */
|
|
953
946
|
async function formatSource(text, options = {}) {
|
|
954
947
|
const source = new SourceText(text, options);
|
|
@@ -962,8 +955,7 @@ async function formatSource(text, options = {}) {
|
|
|
962
955
|
};
|
|
963
956
|
}
|
|
964
957
|
|
|
965
|
-
|
|
966
|
-
//#region packages/ts-format/src/files.ts
|
|
958
|
+
// packages/ts-format/src/files.ts
|
|
967
959
|
const exec = promisify(execFile);
|
|
968
960
|
const caseInsensitivePaths = process.platform === "win32" || process.platform === "darwin";
|
|
969
961
|
const comparablePath = (value) => caseInsensitivePaths ? value.toLowerCase() : value;
|
|
@@ -1071,6 +1063,5 @@ async function formatFiles(inputs = ["."], options = {}) {
|
|
|
1071
1063
|
};
|
|
1072
1064
|
}
|
|
1073
1065
|
|
|
1074
|
-
//#endregion
|
|
1075
1066
|
export { formatFiles };
|
|
1076
1067
|
//# sourceMappingURL=files.mjs.map
|
package/dist/files.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files.mjs","names":["escapeRegExp"],"sources":["../src/markup.ts","../src/expressions.ts","../src/source.ts","../src/fences.ts","../src/html.ts","../src/mdx.ts","../src/templates.ts","../src/index.ts","../src/files.ts"],"sourcesContent":["export const VOID_HTML_TAG_NAMES = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n])\n\nexport interface TagToken {\n end: number\n kind: 'closing' | 'opening'\n name: string\n nameEnd: number\n nameStart: number\n selfClosing: boolean\n start: number\n}\n\nexport function scanTagTokens(markup: string) {\n const tokens: TagToken[] = []\n\n for (let index = 0; index < markup.length; index++) {\n if (markup[index] !== '<') continue\n\n if (markup.startsWith('<!--', index)) {\n const commentEnd = markup.indexOf('-->', index + 4)\n if (commentEnd === -1) break\n index = commentEnd + 2\n continue\n }\n\n const isClosing = markup[index + 1] === '/'\n const nameStart = skipWhitespace(markup, index + (isClosing ? 2 : 1))\n const nameEnd = readTagNameEnd(markup, nameStart)\n if (nameEnd === nameStart) continue\n\n const tagEnd = findTagEnd(markup, nameEnd)\n if (tagEnd === -1) break\n\n const name = markup.slice(nameStart, nameEnd)\n const trailing = markup.slice(nameEnd, tagEnd)\n tokens.push({\n start: index,\n end: tagEnd + 1,\n kind: isClosing ? 'closing' : 'opening',\n name,\n nameStart,\n nameEnd,\n selfClosing: !isClosing && /\\/\\s*$/.test(trailing),\n })\n index = tagEnd\n }\n\n return tokens\n}\n\nexport function isMdxExpressionStart(source: string, index: number) {\n return (\n source[index] === '{' &&\n source[index - 1] !== '{' &&\n source[index + 1] !== '{'\n )\n}\n\nexport function findMdxExpressionEnd(source: string, startIndex: number) {\n let braceDepth = 0\n let quote: '\"' | \"'\" | '`' | undefined\n\n for (let index = startIndex; index < source.length; index++) {\n const current = source[index]\n const previous = source[index - 1]\n\n if (quote) {\n if (current === quote && previous !== '\\\\') {\n quote = undefined\n } else if (\n quote === '`' &&\n current === '$' &&\n source[index + 1] === '{'\n ) {\n const templateExpressionEnd = findMdxExpressionEnd(source, index + 1)\n if (templateExpressionEnd === -1) return -1\n index = templateExpressionEnd - 1\n }\n continue\n }\n\n if (current === '\"' || current === \"'\" || current === '`') {\n quote = current\n continue\n }\n\n if (current === '{') {\n braceDepth++\n continue\n }\n\n if (current !== '}') continue\n\n braceDepth--\n if (braceDepth === 0) return index + 1\n if (braceDepth < 0) return -1\n }\n\n return -1\n}\n\nexport function findTagEnd(markup: string, startIndex: number) {\n let quote: '\"' | \"'\" | undefined\n\n for (let index = startIndex; index < markup.length; index++) {\n const current = markup[index]\n if (quote) {\n if (current === quote && markup[index - 1] !== '\\\\') quote = undefined\n continue\n }\n\n if (current === '\"' || current === \"'\") {\n quote = current\n continue\n }\n\n if (current === '>') return index\n }\n\n return -1\n}\n\nfunction skipWhitespace(markup: string, startIndex: number) {\n let index = startIndex\n while (index < markup.length && /\\s/.test(markup[index])) index++\n return index\n}\n\nfunction readTagNameEnd(markup: string, startIndex: number) {\n let index = startIndex\n while (index < markup.length && /[A-Za-z0-9._:$-]/.test(markup[index])) {\n index++\n }\n return index\n}\n","import { findMdxExpressionEnd } from './markup'\n\nexport interface RegorExpressionPlaceholder {\n placeholder: string\n source: string\n}\n\n/**\n * Protects Regor {{ ... }} expressions while the surrounding markup is\n * formatted as HTML. The expression source is restored byte-for-byte.\n */\nexport function maskRegorExpressions(source: string) {\n const expressions: RegorExpressionPlaceholder[] = []\n let placeholderContent = ''\n let cursor = 0\n\n while (cursor < source.length) {\n const start = source.indexOf('{{', cursor)\n if (start === -1) {\n placeholderContent += source.slice(cursor)\n break\n }\n\n placeholderContent += source.slice(cursor, start)\n\n const end = findRegorExpressionEnd(source, start)\n if (end === -1) {\n // Keep incomplete input untouched rather than guessing its boundary.\n placeholderContent += source.slice(start)\n break\n }\n\n const placeholder = createPlaceholder(source, expressions.length)\n expressions.push({ placeholder, source: source.slice(start, end) })\n placeholderContent += placeholder\n cursor = end\n }\n\n return { expressions, placeholderContent }\n}\n\nexport function restoreRegorExpressions(\n formatted: string,\n expressions: RegorExpressionPlaceholder[],\n) {\n let restored = formatted\n\n for (const expression of expressions) {\n restored = restored.split(expression.placeholder).join(expression.source)\n }\n\n return restored\n}\n\nfunction findRegorExpressionEnd(source: string, start: number) {\n // Reuse the expression scanner already used by MDX. Starting at the first\n // brace makes {{ ... }} two outer brace levels, so nested object literals,\n // quoted braces and template-literal expressions remain balanced correctly.\n const end = findMdxExpressionEnd(source, start)\n if (end === -1) return -1\n\n return source.slice(end - 2, end) === '}}' ? end : -1\n}\n\nfunction createPlaceholder(source: string, index: number) {\n let placeholder = `__PURESTACK_REGOR_EXPR_${index}__`\n\n while (source.includes(placeholder)) {\n placeholder = `_${placeholder}_`\n }\n\n return placeholder\n}\n","import type { HtmlFormattingOptions } from './html'\n\nexport interface SourceRange {\n start: number\n end: number\n}\n\nexport interface SourceEdit extends SourceRange {\n newText: string\n}\n\nexport interface FormatDiagnostic extends SourceRange {\n message: string\n}\n\nexport interface FormatOptions extends Partial<HtmlFormattingOptions> {\n filePath?: string\n language?: 'mdx' | 'typescript'\n onlyWithinRange?: SourceRange\n}\n\nexport function intersects(left: SourceRange, right: SourceRange) {\n return left.start <= right.end && right.start <= left.end\n}\n\n/** Immutable source snapshot. All edit offsets refer to this text. */\nexport class SourceText {\n readonly filePath: string\n readonly options: HtmlFormattingOptions\n readonly diagnostics: FormatDiagnostic[] = []\n private readonly lines: Array<{ text: string; range: SourceRange }> = []\n private readonly eol: '\\n' | '\\r\\n'\n\n constructor(\n readonly text: string,\n options: FormatOptions = {},\n ) {\n this.filePath = options.filePath ?? 'source.mdx'\n this.options = {\n printWidth: options.printWidth ?? 80,\n tabSize: options.tabSize ?? 2,\n useTabs: options.useTabs ?? false,\n }\n for (const value of [this.options.printWidth, this.options.tabSize]) {\n if (!Number.isInteger(value) || value < 1)\n throw new Error('Print width and tab size must be positive integers.')\n }\n this.eol = /\\r\\n/.test(text) ? '\\r\\n' : '\\n'\n let start = 0\n for (const line of text.split('\\n')) {\n const content = line.endsWith('\\r') ? line.slice(0, -1) : line\n this.lines.push({\n text: content,\n range: { start, end: start + content.length },\n })\n start += line.length + 1\n }\n }\n\n get lineCount() {\n return this.lines.length\n }\n\n lineAt(line: number) {\n return this.lines[line]\n }\n\n positionAt(offset: number) {\n const bounded = Math.max(0, Math.min(offset, this.text.length))\n let low = 0\n let high = this.lines.length - 1\n while (low < high) {\n const middle = Math.ceil((low + high) / 2)\n if (this.lines[middle].range.start > bounded) high = middle - 1\n else low = middle\n }\n const line = this.lines[low]\n return {\n line: low,\n character: Math.min(bounded, line.range.end) - line.range.start,\n }\n }\n\n offsetAt(position: { line: number; character: number }) {\n const line =\n this.lines[Math.max(0, Math.min(position.line, this.lines.length - 1))]\n return Math.min(\n line.range.end,\n line.range.start + Math.max(0, position.character),\n )\n }\n\n preserveEol(text: string) {\n return text.replace(/\\r?\\n/g, this.eol)\n }\n\n report(range: SourceRange, error: unknown) {\n this.diagnostics.push({\n ...range,\n message: error instanceof Error ? error.message : String(error),\n })\n }\n}\n\n/** Apply non-overlapping edits against their original snapshot. */\nexport function applySourceEdits(source: string, edits: readonly SourceEdit[]) {\n const ordered = [...edits].sort((a, b) => a.start - b.start || a.end - b.end)\n let cursor = 0\n const parts: string[] = []\n for (const edit of ordered) {\n if (\n edit.start < cursor ||\n edit.end < edit.start ||\n edit.end > source.length\n )\n throw new Error('Formatter returned overlapping or invalid source edits.')\n parts.push(source.slice(cursor, edit.start), edit.newText)\n cursor = edit.end\n }\n parts.push(source.slice(cursor))\n return parts.join('')\n}\n","import { scanTagTokens } from './markup'\nimport {\n intersects,\n type SourceEdit,\n type SourceRange,\n type SourceText,\n} from './source'\n\nexport interface MdxFencePlaceholder {\n placeholder: string\n source: string\n}\n\nexport interface MdxFence {\n length: number\n marker: '`' | '~'\n}\n\nexport interface MdxFenceDelimiter extends MdxFence {\n suffix: string\n}\n\nexport interface MdxFenceDelimiterEditOptions {\n onlyWithinRange?: SourceRange\n}\n\nexport function buildMdxFenceDelimiterEdits(\n document: SourceText,\n excludedRanges: SourceRange[],\n options: MdxFenceDelimiterEditOptions = {},\n) {\n const edits: SourceEdit[] = []\n let activeFence: MdxFence | undefined\n let frontmatterHandled = false\n let inFrontmatter = false\n\n for (let lineIndex = 0; lineIndex < document.lineCount; lineIndex++) {\n const line = document.lineAt(lineIndex)\n const lineText = line.text\n const trimmed = lineText.trim()\n\n if (!frontmatterHandled && lineIndex === 0 && trimmed === '---') {\n frontmatterHandled = true\n inFrontmatter = true\n continue\n }\n\n if (inFrontmatter) {\n if (trimmed === '---') inFrontmatter = false\n continue\n }\n\n if (isLineInsideAnyRange(line.range, excludedRanges)) {\n continue\n }\n\n if (\n options.onlyWithinRange &&\n !intersects(line.range, options.onlyWithinRange)\n ) {\n continue\n }\n\n if (!activeFence) {\n const splitLine = splitLineBeforeInlineMdxFenceOpener(lineText)\n if (splitLine) {\n const replacement = [\n ...splitAdjacentMarkupTags(splitLine.before),\n splitLine.fenceLine,\n ].join('\\n')\n pushLineReplacement(edits, line.range, lineText, replacement)\n\n const delimiter = parseMdxFenceDelimiter(splitLine.fenceLine.trim())\n activeFence = delimiter\n ? { length: delimiter.length, marker: delimiter.marker }\n : undefined\n continue\n }\n\n const delimiter = parseMdxFenceDelimiter(trimmed)\n if (!delimiter) continue\n\n pushLineReplacement(\n edits,\n line.range,\n lineText,\n trimLineStartIndent(lineText),\n )\n activeFence = { length: delimiter.length, marker: delimiter.marker }\n continue\n }\n\n const splitClosingPrefix = splitLineAfterInlineMdxFenceCloser(\n lineText,\n activeFence,\n )\n if (splitClosingPrefix) {\n const replacement = [\n trimLineStartIndent(splitClosingPrefix.fenceLine),\n splitClosingPrefix.after,\n ].join('\\n')\n pushLineReplacement(edits, line.range, lineText, replacement)\n activeFence = undefined\n continue\n }\n\n const splitClosingSuffix = splitLineBeforeInlineMdxFenceCloser(\n lineText,\n activeFence,\n )\n if (splitClosingSuffix) {\n const replacement = [\n splitClosingSuffix.before,\n trimLineStartIndent(splitClosingSuffix.fenceLine),\n ].join('\\n')\n pushLineReplacement(edits, line.range, lineText, replacement)\n activeFence = undefined\n continue\n }\n\n const delimiter = parseMdxFenceDelimiter(trimmed)\n if (!delimiter || !isMdxFenceClosingDelimiter(delimiter, activeFence)) {\n continue\n }\n\n pushLineReplacement(\n edits,\n line.range,\n lineText,\n trimLineStartIndent(lineText),\n )\n activeFence = undefined\n }\n\n return edits.map((edit) => ({\n ...edit,\n newText: document.preserveEol(edit.newText),\n }))\n}\n\nexport function maskMdxFencedRegions(source: string) {\n const fences: MdxFencePlaceholder[] = []\n const lines = splitInlineMdxFenceDelimiters(source).split('\\n')\n const placeholderLines: string[] = []\n\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const openingDelimiter = parseMdxFenceDelimiter(lines[lineIndex].trim())\n if (!openingDelimiter) {\n placeholderLines.push(lines[lineIndex])\n continue\n }\n\n let closingLineIndex = -1\n for (\n let candidateLineIndex = lineIndex + 1;\n candidateLineIndex < lines.length;\n candidateLineIndex++\n ) {\n const closingDelimiter = parseMdxFenceDelimiter(\n lines[candidateLineIndex].trim(),\n )\n if (\n closingDelimiter &&\n isMdxFenceClosingDelimiter(closingDelimiter, openingDelimiter)\n ) {\n closingLineIndex = candidateLineIndex\n break\n }\n }\n\n if (closingLineIndex === -1) {\n placeholderLines.push(lines[lineIndex])\n continue\n }\n\n const placeholder = `<!--PURESTACK_MDX_FENCE_${fences.length}-->`\n fences.push({\n placeholder,\n source: normalizeMdxFenceDelimiterIndent(\n lines.slice(lineIndex, closingLineIndex + 1),\n ),\n })\n placeholderLines.push(placeholder)\n lineIndex = closingLineIndex\n }\n\n return { fences, placeholderContent: placeholderLines.join('\\n') }\n}\n\nexport function restoreMdxFencedRegions(\n formatted: string,\n fences: MdxFencePlaceholder[],\n) {\n let restored = formatted\n\n for (const fence of fences) {\n const standalonePlaceholderPattern = new RegExp(\n `^[\\\\t ]*${escapeRegExp(fence.placeholder)}$`,\n 'gm',\n )\n if (standalonePlaceholderPattern.test(restored)) {\n restored = restored.replace(standalonePlaceholderPattern, fence.source)\n continue\n }\n\n restored = restored.split(fence.placeholder).join(fence.source)\n }\n\n return restored\n}\n\nexport function parseMdxFenceDelimiter(\n trimmed: string,\n): MdxFenceDelimiter | undefined {\n const match = /^(`{3,}|~{3,})(.*)$/.exec(trimmed)\n if (!match) return undefined\n\n return {\n length: match[1].length,\n marker: match[1].startsWith('`') ? '`' : '~',\n suffix: match[2],\n }\n}\n\nexport function parseInlineMdxFenceOpener(trimmed: string) {\n const splitLine = splitLineBeforeInlineMdxFenceOpener(trimmed)\n if (!splitLine) return undefined\n\n return parseMdxFenceDelimiter(splitLine.fenceLine.trim())\n}\n\nexport function parseInlineMdxFenceCloser(\n trimmed: string,\n activeFence: MdxFence,\n) {\n const splitLine = splitLineAfterInlineMdxFenceCloser(trimmed, activeFence)\n if (splitLine) return parseMdxFenceDelimiter(splitLine.fenceLine.trim())\n\n const trailingSplitLine = splitLineBeforeInlineMdxFenceCloser(\n trimmed,\n activeFence,\n )\n if (!trailingSplitLine) return undefined\n\n return parseMdxFenceDelimiter(trailingSplitLine.fenceLine.trim())\n}\n\nexport function isMdxFenceClosingDelimiter(\n delimiter: MdxFenceDelimiter,\n activeFence: MdxFence,\n) {\n return (\n delimiter.marker === activeFence.marker &&\n delimiter.length >= activeFence.length &&\n delimiter.suffix.trim().length === 0\n )\n}\n\nfunction splitInlineMdxFenceDelimiters(source: string) {\n const lines = source.split('\\n')\n const splitLines: string[] = []\n let activeFence: MdxFence | undefined\n\n for (const line of lines) {\n if (!activeFence) {\n const splitLine = splitLineBeforeInlineMdxFenceOpener(line)\n if (splitLine) {\n splitLines.push(\n ...splitAdjacentMarkupTags(splitLine.before),\n splitLine.fenceLine,\n )\n\n const delimiter = parseMdxFenceDelimiter(splitLine.fenceLine.trim())\n activeFence = delimiter\n ? { length: delimiter.length, marker: delimiter.marker }\n : undefined\n continue\n }\n\n splitLines.push(line)\n\n const delimiter = parseMdxFenceDelimiter(line.trim())\n if (!delimiter) continue\n activeFence = { length: delimiter.length, marker: delimiter.marker }\n continue\n }\n\n const splitClosingLine = splitLineAfterInlineMdxFenceCloser(\n line,\n activeFence,\n )\n if (splitClosingLine) {\n splitLines.push(splitClosingLine.fenceLine, splitClosingLine.after)\n activeFence = undefined\n continue\n }\n\n const splitTrailingClosingLine = splitLineBeforeInlineMdxFenceCloser(\n line,\n activeFence,\n )\n if (splitTrailingClosingLine) {\n splitLines.push(\n splitTrailingClosingLine.before,\n splitTrailingClosingLine.fenceLine,\n )\n activeFence = undefined\n continue\n }\n\n splitLines.push(line)\n\n const delimiter = parseMdxFenceDelimiter(line.trim())\n if (!delimiter) continue\n\n if (isMdxFenceClosingDelimiter(delimiter, activeFence)) {\n activeFence = undefined\n }\n }\n\n return splitLines.join('\\n')\n}\n\nfunction splitLineBeforeInlineMdxFenceOpener(line: string) {\n if (parseMdxFenceDelimiter(line.trim())) return undefined\n\n const match = /`{3}|~{3}/.exec(line)\n if (!match) return undefined\n\n const before = line.slice(0, match.index).trimEnd()\n if (before.trim().length === 0) return undefined\n\n return {\n before,\n fenceLine: line.slice(match.index),\n }\n}\n\nfunction splitAdjacentMarkupTags(line: string) {\n const tokens = scanTagTokens(line)\n if (tokens.length < 2) return [line]\n\n let cursor = 0\n const lines: string[] = []\n const indent = /^\\s*/.exec(line)?.[0] ?? ''\n\n for (const token of tokens) {\n if (line.slice(cursor, token.start).trim().length > 0) return [line]\n\n const tag = line.slice(token.start, token.end)\n lines.push(lines.length === 0 ? `${indent}${tag}` : tag)\n cursor = token.end\n }\n\n if (line.slice(cursor).trim().length > 0) return [line]\n\n return lines\n}\n\nfunction splitLineBeforeInlineMdxFenceCloser(\n line: string,\n activeFence: MdxFence,\n) {\n let end = line.length\n while (end > 0 && (line[end - 1] === '\\t' || line[end - 1] === ' ')) end--\n let start = end\n while (start > 0 && line[start - 1] === activeFence.marker) start--\n if (end - start < activeFence.length) return undefined\n\n const before = line.slice(0, start).trimEnd()\n if (before.trim().length === 0) return undefined\n\n return {\n before,\n fenceLine: line.slice(start, end),\n }\n}\n\nfunction splitLineAfterInlineMdxFenceCloser(\n line: string,\n activeFence: MdxFence,\n) {\n const pattern = new RegExp(\n `^([\\\\t ]*${escapeRegExp(activeFence.marker.repeat(activeFence.length))}${escapeRegExp(activeFence.marker)}*)(.*)$`,\n )\n const match = pattern.exec(line)\n if (!match || match[2].trim().length === 0) return undefined\n\n const closingDelimiter = parseMdxFenceDelimiter(match[1].trim())\n if (!closingDelimiter) return undefined\n if (!isMdxFenceClosingDelimiter(closingDelimiter, activeFence)) {\n return undefined\n }\n\n return {\n fenceLine: match[1],\n after: match[2],\n }\n}\n\nfunction normalizeMdxFenceDelimiterIndent(lines: string[]) {\n if (lines.length < 2) return lines.join('\\n')\n\n const normalizedLines = [...lines]\n normalizedLines[0] = trimLineStartIndent(normalizedLines[0])\n normalizedLines[normalizedLines.length - 1] = trimLineStartIndent(\n normalizedLines[normalizedLines.length - 1],\n )\n return normalizedLines.join('\\n')\n}\n\nfunction trimLineStartIndent(line: string) {\n return line.replace(/^[\\t ]+/, '')\n}\n\nfunction pushLineReplacement(\n edits: SourceEdit[],\n range: SourceRange,\n oldText: string,\n newText: string,\n) {\n if (newText === oldText) return\n\n edits.push({ ...range, newText })\n}\n\nfunction isLineInsideAnyRange(line: SourceRange, ranges: SourceRange[]) {\n return ranges.some(\n (range) => line.start >= range.start && line.end <= range.end,\n )\n}\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n","import htmlPlugin from 'prettier/plugins/html'\nimport postcssPlugin from 'prettier/plugins/postcss'\nimport prettier from 'prettier/standalone'\n\nconst RAW_TEXT_TAG =\n 'script|style|textarea|title|xmp|iframe|noembed|noframes|plaintext'\nconst TAG_BODY = `(?:\"[^\"]*\"|'[^']*'|[^\"'>])*>`\n\n/**\n * Skips comments, raw text and opening tags; captures closing tags broken before `>`.\n * Case-sensitive so PascalCase components such as `<Title>` are not raw text.\n */\nconst BROKEN_CLOSING_TAG = new RegExp(\n [\n String.raw`<!--[\\s\\S]*?-->`,\n String.raw`<(${RAW_TEXT_TAG})\\b${TAG_BODY}[\\s\\S]*?</\\1\\s*>`,\n `<[A-Za-z]${TAG_BODY}`,\n String.raw`(</[^\\s>]+)\\s*\\n\\s*>`,\n ].join('|'),\n 'g',\n)\n\nexport interface HtmlFormattingOptions {\n printWidth: number\n tabSize: number\n useTabs: boolean\n}\n\nexport async function formatHtmlFragment(\n source: string,\n options: HtmlFormattingOptions,\n) {\n const formatted = await prettier.format(source, {\n htmlWhitespaceSensitivity: 'css',\n parser: 'html',\n plugins: [htmlPlugin, postcssPlugin],\n printWidth: options.printWidth,\n tabWidth: options.tabSize,\n useTabs: options.useTabs,\n })\n return normalizeClosingTagSpacing(formatted)\n}\n\n/** Keep closing tags readable without inserting whitespace into inline content. */\nexport function normalizeClosingTagSpacing(source: string) {\n return source.replace(\n BROKEN_CLOSING_TAG,\n (match, _rawTextTag: string, closingTag?: string) =>\n closingTag ? `${closingTag}>` : match,\n )\n}\n\nexport function getLineIndent(line: string) {\n const match = /^\\s*/.exec(line)\n return match?.[0] ?? ''\n}\n\nexport function normalizeSelfClosingTagSpacing(formatted: string) {\n // Match each whitespace run once, even when no /> follows it.\n return formatted.replace(/\\s+/g, (whitespace, offset: number) =>\n formatted.startsWith('/>', offset + whitespace.length) ? '' : whitespace,\n )\n}\n","import { maskRegorExpressions, restoreRegorExpressions } from './expressions'\nimport {\n buildMdxFenceDelimiterEdits,\n isMdxFenceClosingDelimiter,\n maskMdxFencedRegions,\n parseInlineMdxFenceCloser,\n parseInlineMdxFenceOpener,\n parseMdxFenceDelimiter,\n restoreMdxFencedRegions,\n} from './fences'\nimport { formatHtmlFragment, normalizeSelfClosingTagSpacing } from './html'\nimport {\n findMdxExpressionEnd,\n findTagEnd,\n isMdxExpressionStart,\n scanTagTokens,\n VOID_HTML_TAG_NAMES,\n} from './markup'\nimport {\n intersects,\n type SourceEdit,\n type SourceRange,\n type SourceText,\n} from './source'\n\nexport interface MdxMarkupBlock {\n content: string\n range: SourceRange\n}\n\ninterface MdxExpressionPlaceholder {\n placeholder: string\n source: string\n}\n\ninterface MdxInlineCodePlaceholder {\n placeholder: string\n source: string\n}\n\ninterface MdxFormattingRequest {\n onlyWithinRange?: SourceRange\n}\n\ninterface MdxMarkupBlockOptions {\n includeIncomplete?: boolean\n}\n\ninterface MdxBlockScanState {\n activeEndLine?: number\n activeLines: string[]\n activeStartLine?: number\n fenceLength?: number\n fenceMarker?: '`' | '~'\n frontmatterHandled: boolean\n inFence: boolean\n inFrontmatter: boolean\n}\n\nexport async function buildMdxFormattingEdits(\n document: SourceText,\n request: MdxFormattingRequest = {},\n) {\n const blocks = getMdxMarkupBlocks(document, {\n includeIncomplete: true,\n }).filter((block) =>\n request.onlyWithinRange\n ? intersects(block.range, request.onlyWithinRange)\n : true,\n )\n\n const edits: SourceEdit[] = []\n const blockRanges = blocks.map((block) => block.range)\n\n for (const block of blocks) {\n const formatted = await formatMdxMarkupBlock(document, block)\n if (!formatted || formatted === block.content) continue\n\n edits.push({ ...block.range, newText: document.preserveEol(formatted) })\n }\n\n edits.push(\n ...buildMdxFenceDelimiterEdits(document, blockRanges, {\n onlyWithinRange: request.onlyWithinRange,\n }),\n )\n\n return edits\n}\n\nexport function getMdxMarkupBlocks(\n document: SourceText,\n options: MdxMarkupBlockOptions = {},\n) {\n const blocks: MdxMarkupBlock[] = []\n const state: MdxBlockScanState = {\n activeEndLine: undefined,\n activeLines: [],\n frontmatterHandled: false,\n inFence: false,\n inFrontmatter: false,\n }\n\n for (let lineIndex = 0; lineIndex < document.lineCount; lineIndex++) {\n const lineText = document.lineAt(lineIndex).text\n const trimmed = lineText.trim()\n\n if (startMdxFrontmatter(lineIndex, trimmed, state)) {\n continue\n }\n\n if (closeMdxFrontmatter(trimmed, state)) {\n continue\n }\n\n collectActiveMarkupBlock(\n blocks,\n document,\n lineIndex,\n lineText,\n trimmed,\n state,\n )\n }\n\n if (\n options.includeIncomplete &&\n state.activeStartLine !== undefined &&\n state.activeEndLine !== undefined\n ) {\n pushActiveBlock(\n blocks,\n document,\n state.activeStartLine,\n state.activeEndLine,\n state.activeLines,\n )\n }\n\n return blocks\n}\n\nfunction pushActiveBlock(\n blocks: MdxMarkupBlock[],\n document: SourceText,\n startLine: number,\n endLine: number,\n lines: string[],\n) {\n const start = document.lineAt(startLine).range.start\n const end = document.lineAt(endLine).range.end\n blocks.push({\n content: lines.join('\\n'),\n range: { start, end },\n })\n}\n\nfunction looksLikeMarkupBlockStart(trimmedLine: string) {\n return /^<[A-Za-z][A-Za-z0-9._:$-]*/.test(trimmedLine)\n}\n\nfunction isCompleteMarkupBlock(markup: string) {\n const { placeholderContent } = maskMdxFencedRegions(markup)\n if (!placeholderContent.includes('<')) return false\n if (hasUnterminatedTag(placeholderContent)) return false\n\n return getUnclosedTagNames(placeholderContent).length === 0\n}\n\nasync function formatMdxMarkupBlock(\n document: SourceText,\n block: MdxMarkupBlock,\n) {\n const formattingOptions = document.options\n const { fences, placeholderContent: fencePlaceholderContent } =\n maskMdxFencedRegions(block.content.trim())\n const { inlineCodeSpans, placeholderContent: inlineCodePlaceholderContent } =\n maskMdxInlineCodeSpans(fencePlaceholderContent)\n const {\n expressions: regorExpressions,\n placeholderContent: regorPlaceholderContent,\n } = maskRegorExpressions(inlineCodePlaceholderContent)\n const { expressions, placeholderContent } = maskMdxExpressions(\n regorPlaceholderContent,\n )\n if (!placeholderContent.includes('<')) return undefined\n\n let formatted: string\n try {\n formatted = await formatHtmlFragment(placeholderContent, formattingOptions)\n } catch (error) {\n document.report(block.range, error)\n return undefined\n }\n\n const restoredExpressions = restoreMdxExpressions(\n normalizeSelfClosingTagSpacing(formatted.trim()),\n expressions,\n )\n const restoredRegorExpressions = restoreRegorExpressions(\n restoredExpressions,\n regorExpressions,\n )\n const restoredInlineCode = restoreMdxInlineCodeSpans(\n restoredRegorExpressions,\n inlineCodeSpans,\n )\n\n return restoreMdxFencedRegions(restoredInlineCode, fences)\n}\n\nfunction maskMdxInlineCodeSpans(source: string) {\n const inlineCodeSpans: MdxInlineCodePlaceholder[] = []\n const lines = source.split('\\n')\n const placeholderLines = lines.map((line) =>\n maskMdxInlineCodeSpansInLine(line, inlineCodeSpans),\n )\n\n return {\n inlineCodeSpans,\n placeholderContent: placeholderLines.join('\\n'),\n }\n}\n\nfunction maskMdxInlineCodeSpansInLine(\n line: string,\n inlineCodeSpans: MdxInlineCodePlaceholder[],\n) {\n let placeholderLine = ''\n\n for (let index = 0; index < line.length; ) {\n const start = line.indexOf('`', index)\n if (start === -1) {\n placeholderLine += line.slice(index)\n break\n }\n\n const tickCount = countRepeatedChar(line, start, '`')\n if (tickCount !== 1) {\n placeholderLine += line.slice(index, start + tickCount)\n index = start + tickCount\n continue\n }\n\n const end = findMdxInlineCodeEnd(line, start + 1)\n if (end === -1) {\n placeholderLine += line.slice(index)\n break\n }\n\n const source = line.slice(start, end + 1)\n const placeholder = createMdxInlineCodePlaceholder(\n inlineCodeSpans.length,\n line,\n start,\n end + 1,\n )\n inlineCodeSpans.push({ placeholder, source })\n placeholderLine += line.slice(index, start)\n placeholderLine += placeholder\n index = end + 1\n }\n\n return placeholderLine\n}\n\nfunction createMdxInlineCodePlaceholder(\n index: number,\n line: string,\n start: number,\n end: number,\n) {\n const lineBefore = line.slice(0, start)\n const lineAfter = line.slice(end)\n if (lineBefore.trim().length === 0 && lineAfter.trim().length === 0) {\n return `<!--PURESTACK_MDX_INLINE_CODE_${index}-->`\n }\n\n return `PURESTACK_MDX_INLINE_CODE_${index}`\n}\n\nfunction restoreMdxInlineCodeSpans(\n formatted: string,\n inlineCodeSpans: MdxInlineCodePlaceholder[],\n) {\n let restored = formatted\n\n for (const inlineCodeSpan of sortLongestPlaceholderFirst(inlineCodeSpans)) {\n restored = restored\n .split(inlineCodeSpan.placeholder)\n .join(inlineCodeSpan.source)\n }\n\n return restored\n}\n\nexport function maskMdxExpressions(source: string) {\n const expressions: MdxExpressionPlaceholder[] = []\n let placeholderContent = ''\n\n for (let index = 0; index < source.length; ) {\n const rawTextEnd = findRawTextElementEnd(source, index)\n if (rawTextEnd !== undefined) {\n placeholderContent += source.slice(index, rawTextEnd)\n index = rawTextEnd\n continue\n }\n\n if (!isMdxExpressionStart(source, index)) {\n placeholderContent += source[index]\n index++\n continue\n }\n\n const expressionEnd = findMdxExpressionEnd(source, index)\n if (expressionEnd === -1) {\n placeholderContent += source[index]\n index++\n continue\n }\n\n const placeholder = `PURESTACK_MDX_EXPR_${expressions.length}`\n expressions.push({\n placeholder,\n source: source.slice(index, expressionEnd),\n })\n placeholderContent += placeholder\n index = expressionEnd\n }\n\n return { expressions, placeholderContent }\n}\n\nfunction restoreMdxExpressions(\n formatted: string,\n expressions: MdxExpressionPlaceholder[],\n) {\n let restored = formatted\n\n for (const expression of sortLongestPlaceholderFirst(expressions)) {\n restored = restored.split(expression.placeholder).join(expression.source)\n }\n\n return restored\n}\n\nfunction hasUnterminatedTag(markup: string) {\n for (let index = 0; index < markup.length; index++) {\n if (markup[index] !== '<') continue\n\n if (markup.startsWith('<!--', index)) {\n const commentEnd = markup.indexOf('-->', index + 4)\n if (commentEnd === -1) return true\n index = commentEnd + 2\n continue\n }\n\n const nextTagEnd = findTagEnd(markup, index + 1)\n if (nextTagEnd === -1) return true\n index = nextTagEnd\n }\n\n return false\n}\n\nfunction startMdxFrontmatter(\n lineIndex: number,\n trimmed: string,\n state: MdxBlockScanState,\n) {\n if (state.frontmatterHandled || lineIndex !== 0 || trimmed !== '---') {\n return false\n }\n\n state.inFrontmatter = true\n state.frontmatterHandled = true\n return true\n}\n\nfunction closeMdxFrontmatter(trimmed: string, state: MdxBlockScanState) {\n if (!state.inFrontmatter) return false\n\n if (trimmed === '---') {\n state.inFrontmatter = false\n }\n\n return true\n}\n\nfunction updateMdxFenceState(trimmed: string, state: MdxBlockScanState) {\n const activeFence =\n state.fenceMarker && state.fenceLength\n ? { length: state.fenceLength, marker: state.fenceMarker }\n : undefined\n const delimiter =\n state.inFence && activeFence\n ? (parseInlineMdxFenceCloser(trimmed, activeFence) ??\n parseMdxFenceDelimiter(trimmed))\n : (parseMdxFenceDelimiter(trimmed) ?? parseInlineMdxFenceOpener(trimmed))\n if (!delimiter) return state.inFence\n\n if (!state.inFence) {\n state.inFence = true\n state.fenceLength = delimiter.length\n state.fenceMarker = delimiter.marker\n return true\n }\n\n if (\n state.fenceMarker &&\n state.fenceLength &&\n isMdxFenceClosingDelimiter(delimiter, {\n length: state.fenceLength,\n marker: state.fenceMarker,\n })\n ) {\n state.inFence = false\n state.fenceLength = undefined\n state.fenceMarker = undefined\n }\n\n return true\n}\n\nfunction collectActiveMarkupBlock(\n blocks: MdxMarkupBlock[],\n document: SourceText,\n lineIndex: number,\n lineText: string,\n trimmed: string,\n state: MdxBlockScanState,\n) {\n if (state.activeStartLine === undefined) {\n if (state.inFence) {\n updateMdxFenceState(trimmed, state)\n return\n }\n\n if (!looksLikeMarkupBlockStart(trimmed)) {\n if (updateMdxFenceState(trimmed, state)) return\n return\n }\n\n state.activeStartLine = lineIndex\n state.activeEndLine = lineIndex\n state.activeLines = [lineText]\n } else {\n state.activeEndLine = lineIndex\n state.activeLines.push(lineText)\n }\n\n updateMdxFenceState(trimmed, state)\n if (state.inFence) return\n if (!isCompleteMarkupBlock(state.activeLines.join('\\n'))) return\n\n pushActiveBlock(\n blocks,\n document,\n state.activeStartLine,\n state.activeEndLine ?? lineIndex,\n state.activeLines,\n )\n state.activeEndLine = undefined\n state.activeStartLine = undefined\n state.activeLines = []\n}\n\nfunction getUnclosedTagNames(markup: string) {\n const stack: string[] = []\n\n for (const token of scanTagTokens(markup)) {\n if (token.kind === 'opening') {\n if (isSelfContainedTag(token.name, token.selfClosing)) continue\n\n stack.push(token.name)\n continue\n }\n\n closeMatchingTag(stack, token.name)\n }\n\n return stack\n}\n\nfunction isSelfContainedTag(tagName: string, selfClosing: boolean) {\n return selfClosing || VOID_HTML_TAG_NAMES.has(tagName.toLowerCase())\n}\n\nfunction closeMatchingTag(stack: string[], tagName: string) {\n for (let index = stack.length - 1; index >= 0; index--) {\n if (stack[index] !== tagName) continue\n stack.splice(index)\n return\n }\n}\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction sortLongestPlaceholderFirst<T extends { placeholder: string }>(\n placeholders: T[],\n) {\n return [...placeholders].sort(\n (left, right) => right.placeholder.length - left.placeholder.length,\n )\n}\n\nfunction findMdxInlineCodeEnd(line: string, startIndex: number) {\n for (let index = startIndex; index < line.length; index++) {\n if (line[index] === '`') return index\n }\n\n return -1\n}\n\nfunction countRepeatedChar(line: string, startIndex: number, char: string) {\n let count = 0\n\n while (line[startIndex + count] === char) {\n count++\n }\n\n return count\n}\n\nfunction findRawTextElementEnd(source: string, startIndex: number) {\n if (source[startIndex] !== '<' || source[startIndex + 1] === '/') {\n return undefined\n }\n\n const tagEnd = findTagEnd(source, startIndex + 1)\n if (tagEnd === -1) return undefined\n\n const openingTag = source.slice(startIndex, tagEnd + 1)\n const tagName = /^<\\s*(script|style)\\b/i.exec(openingTag)?.[1]\n if (!tagName) return undefined\n\n const closingTagPattern = new RegExp(\n `<\\\\/\\\\s*${escapeRegExp(tagName)}\\\\s*>`,\n 'i',\n )\n const closingTagMatch = closingTagPattern.exec(source.slice(tagEnd + 1))\n if (!closingTagMatch) return undefined\n\n return tagEnd + 1 + closingTagMatch.index + closingTagMatch[0].length\n}\n","import type * as TypeScript from 'typescript-parser'\nimport ts from 'typescript-parser'\nimport { maskRegorExpressions, restoreRegorExpressions } from './expressions'\n\nimport { formatHtmlFragment, normalizeSelfClosingTagSpacing } from './html'\nimport {\n intersects,\n type SourceEdit,\n type SourceRange,\n type SourceText,\n} from './source'\n\nexport type SupportedTemplateTagName = 'html' | 'svg'\n\nexport interface SupportedTaggedTemplate {\n content: string\n contentRange: SourceRange\n expressions: TemplateExpressionPlaceholder[]\n interpolationRanges: Array<{ start: number; end: number }>\n placeholderContent: string\n tagName: SupportedTemplateTagName\n}\n\ninterface TemplateExpressionPlaceholder {\n placeholder: string\n source: string\n}\n\nconst SUPPORTED_TEMPLATE_TAG_NAMES: SupportedTemplateTagName[] = ['html', 'svg']\n\ninterface TemplateFormattingRequest {\n onlyWithinRange?: SourceRange\n}\n\nexport async function buildTemplateFormattingEdits(\n document: SourceText,\n request: TemplateFormattingRequest = {},\n) {\n const templates = getSupportedTaggedTemplates(document).filter((template) =>\n request.onlyWithinRange\n ? intersects(template.contentRange, request.onlyWithinRange)\n : true,\n )\n if (templates.length === 0) return []\n\n const edits: SourceEdit[] = []\n\n for (const template of templates) {\n const formatted = await formatTaggedTemplate(document, template)\n if (!formatted || formatted === template.content) continue\n\n edits.push({\n ...template.contentRange,\n newText: document.preserveEol(formatted),\n })\n }\n\n return edits\n}\n\nexport function getSupportedTaggedTemplates(\n document: SourceText,\n): SupportedTaggedTemplate[] {\n const sourceText = document.text\n const sourceFile = ts.createSourceFile(\n document.filePath,\n sourceText,\n ts.ScriptTarget.Latest,\n false,\n ts.ScriptKind.TS,\n )\n const templates: SupportedTaggedTemplate[] = []\n\n visitNode(sourceFile)\n return templates\n\n function visitNode(node: TypeScript.Node) {\n if (ts.isTaggedTemplateExpression(node)) {\n const template = createSupportedTaggedTemplate(node, sourceFile)\n if (template) {\n templates.push(template)\n // The outer template owns its interpolations; never emit overlapping edits.\n return\n }\n }\n\n ts.forEachChild(node, visitNode)\n }\n}\n\nexport function isOffsetInsideSupportedTaggedTemplate(\n sourceFile: TypeScript.SourceFile,\n offset: number,\n) {\n let isInsideTemplate = false\n\n visitNode(sourceFile)\n return isInsideTemplate\n\n function visitNode(node: TypeScript.Node) {\n if (isInsideTemplate) return\n if (offset < node.getStart(sourceFile) || offset >= node.getEnd()) return\n\n if (ts.isTaggedTemplateExpression(node)) {\n const templateTagName = getSupportedTemplateTagName(\n node.tag.getText(sourceFile),\n )\n if (!templateTagName) {\n ts.forEachChild(node, visitNode)\n return\n }\n\n const template = node.template\n if (\n offset >= template.getStart(sourceFile) &&\n offset < template.getEnd()\n ) {\n isInsideTemplate = true\n return\n }\n }\n\n ts.forEachChild(node, visitNode)\n }\n}\n\nfunction createSupportedTaggedTemplate(\n node: TypeScript.TaggedTemplateExpression,\n sourceFile: TypeScript.SourceFile,\n) {\n const tagName = getSupportedTemplateTagName(node.tag.getText(sourceFile))\n if (!tagName) return undefined\n\n const template = node.template\n if (isLikelyPrematureRawBacktickClose(sourceFile.text, template)) {\n return undefined\n }\n\n const innerStart = template.getStart(sourceFile) + 1\n const innerEnd = template.getEnd() - 1\n if (innerEnd < innerStart) return undefined\n\n const contentRange = { start: innerStart, end: innerEnd }\n\n if (ts.isNoSubstitutionTemplateLiteral(template)) {\n const content = sourceFile.text.slice(innerStart, innerEnd)\n return {\n content,\n contentRange,\n expressions: [],\n interpolationRanges: [],\n placeholderContent: content,\n tagName,\n }\n }\n\n const expressions: TemplateExpressionPlaceholder[] = []\n const interpolationRanges: Array<{ start: number; end: number }> = []\n let placeholderContent = sliceTemplateHeadContent(template.head, sourceFile)\n let currentContentOffset = placeholderContent.length\n\n template.templateSpans.forEach((span, index) => {\n const placeholder = `PURESTACK_EXPR_${index}_${tagName.toUpperCase()}`\n const interpolationEnd = span.literal.getStart(sourceFile) - innerStart + 1\n expressions.push({\n placeholder,\n source: sourceFile.text.slice(\n span.expression.getStart(sourceFile),\n span.expression.getEnd(),\n ),\n })\n interpolationRanges.push({\n start: currentContentOffset,\n end: interpolationEnd,\n })\n placeholderContent += placeholder\n const literalContent = sliceTemplateSpanLiteralContent(\n span.literal,\n sourceFile,\n )\n placeholderContent += literalContent\n currentContentOffset = interpolationEnd + literalContent.length\n })\n\n return {\n content: sourceFile.text.slice(innerStart, innerEnd),\n contentRange,\n expressions,\n interpolationRanges,\n placeholderContent,\n tagName,\n }\n}\n\nfunction getSupportedTemplateTagName(tagText: string) {\n const normalizedTag = tagText.trim()\n\n for (const tagName of SUPPORTED_TEMPLATE_TAG_NAMES) {\n if (normalizedTag === tagName || normalizedTag.endsWith(`.${tagName}`)) {\n return tagName\n }\n }\n\n return undefined\n}\n\nfunction isLikelyPrematureRawBacktickClose(\n sourceText: string,\n template: TypeScript.TemplateLiteral,\n) {\n return sourceText.startsWith('``', template.getEnd())\n}\n\nfunction sliceTemplateHeadContent(\n head: TypeScript.TemplateHead,\n sourceFile: TypeScript.SourceFile,\n) {\n return sourceFile.text.slice(head.getStart(sourceFile) + 1, head.getEnd() - 2)\n}\n\nfunction sliceTemplateSpanLiteralContent(\n literal: TypeScript.TemplateMiddle | TypeScript.TemplateTail,\n sourceFile: TypeScript.SourceFile,\n) {\n const endOffset = ts.isTemplateTail(literal) ? 1 : 2\n return sourceFile.text.slice(\n literal.getStart(sourceFile) + 1,\n literal.getEnd() - endOffset,\n )\n}\n\nasync function formatTaggedTemplate(\n document: SourceText,\n template: SupportedTaggedTemplate,\n) {\n const formattingOptions = document.options\n const source = template.placeholderContent.trim()\n const { expressions: regorExpressions, placeholderContent } =\n maskRegorExpressions(source)\n\n if (!placeholderContent.includes('<')) return undefined\n\n let formatted: string\n try {\n formatted = await formatHtmlFragment(placeholderContent, formattingOptions)\n } catch (error) {\n document.report(template.contentRange, error)\n return undefined\n }\n\n const restoredTemplateExpressions = restoreTemplateExpressions(\n normalizeSelfClosingTagSpacing(formatted.trim()),\n template.expressions,\n )\n\n return restoreRegorExpressions(restoredTemplateExpressions, regorExpressions)\n}\n\nfunction restoreTemplateExpressions(\n formatted: string,\n expressions: TemplateExpressionPlaceholder[],\n) {\n let restored = formatted\n\n for (const expression of expressions) {\n restored = restored\n .split(expression.placeholder)\n .join(`\\${${expression.source}}`)\n }\n\n return restored\n}\n","import { buildMdxFormattingEdits } from './mdx'\nimport { applySourceEdits, type FormatOptions, SourceText } from './source'\nimport { buildTemplateFormattingEdits } from './templates'\n\nexport {\n maskRegorExpressions,\n type RegorExpressionPlaceholder,\n restoreRegorExpressions,\n} from './expressions'\nexport * from './fences'\nexport * from './html'\nexport * from './markup'\nexport * from './mdx'\nexport * from './source'\nexport * from './templates'\n\n/** Formats only component markup and html/svg tagged template contents. */\nexport async function formatSource(text: string, options: FormatOptions = {}) {\n const source = new SourceText(text, options)\n const language =\n options.language ??\n (/\\.[cm]?tsx?$/i.test(source.filePath) ? 'typescript' : 'mdx')\n const edits = await (language === 'typescript'\n ? buildTemplateFormattingEdits(source, options)\n : buildMdxFormattingEdits(source, options))\n const code = applySourceEdits(text, edits)\n return {\n code,\n edits,\n diagnostics: source.diagnostics,\n changed: code !== text,\n }\n}\n","import { execFile } from 'node:child_process'\nimport { lstat, readdir, readFile, writeFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport { promisify } from 'node:util'\nimport { formatSource } from './index'\nimport type { FormatOptions } from './source'\n\nconst exec = promisify(execFile)\n// Windows and macOS file systems ignore letter case by default.\nconst caseInsensitivePaths =\n process.platform === 'win32' || process.platform === 'darwin'\nconst comparablePath = (value: string) =>\n caseInsensitivePaths ? value.toLowerCase() : value\nconst extensions = /\\.(?:[cm]?ts|mdx|rmdx)$/i\nconst ignoredDirectories = new Set([\n '.git',\n '.yarn',\n '.tmp',\n '.ts-ssg',\n '.cache',\n 'node_modules',\n 'dist',\n 'out',\n 'coverage',\n 'artifacts',\n])\n\nexport interface FormatFilesOptions\n extends Omit<FormatOptions, 'filePath' | 'language' | 'onlyWithinRange'> {\n cwd?: string\n write?: boolean\n /** Files or directories to omit, relative to cwd. */\n exclude?: readonly string[]\n}\n\nexport interface FormatFileError {\n filePath: string\n message: string\n}\n\n/** Discover source files, honor Git ignores in repositories, and collect all failures. */\nexport async function formatFiles(\n inputs: readonly string[] = ['.'],\n options: FormatFilesOptions = {},\n) {\n const cwd = path.resolve(options.cwd ?? process.cwd())\n const excluded = (options.exclude ?? []).map((entry) =>\n comparablePath(path.resolve(cwd, entry)),\n )\n const files = new Set<string>()\n const errors: FormatFileError[] = []\n const changed: string[] = []\n\n function isExcluded(file: string) {\n const comparable = comparablePath(file)\n return (\n path\n .relative(cwd, file)\n .split(path.sep)\n .some((part) => ignoredDirectories.has(comparablePath(part))) ||\n excluded.some(\n (entry) =>\n comparable === entry || comparable.startsWith(`${entry}${path.sep}`),\n )\n )\n }\n\n function addFile(file: string) {\n if (extensions.test(file) && !isExcluded(file)) files.add(file)\n }\n\n async function walk(directory: string) {\n if (isExcluded(directory)) return\n for (const entry of await readdir(directory, { withFileTypes: true })) {\n const file = path.join(directory, entry.name)\n if (entry.isSymbolicLink()) continue\n if (entry.isDirectory()) await walk(file)\n else if (entry.isFile()) addFile(file)\n }\n }\n\n for (const input of inputs) {\n const target = path.resolve(cwd, input)\n try {\n const entry = await lstat(target)\n if (entry.isSymbolicLink()) continue\n if (entry.isFile()) {\n addFile(target)\n continue\n }\n if (!entry.isDirectory() || isExcluded(target)) continue\n let gitFiles: string[] | undefined\n try {\n const { stdout } = await exec(\n 'git',\n [\n '-C',\n target,\n 'ls-files',\n '--cached',\n '--others',\n '--exclude-standard',\n '-z',\n '--',\n '.',\n ],\n { maxBuffer: 32 * 1024 * 1024 },\n )\n gitFiles = stdout\n .split('\\0')\n .filter(Boolean)\n // Git lists paths relative to -C, so keep the caller's path spelling.\n .map((file) => path.resolve(target, file))\n } catch {\n // Git is optional; a standalone project still has a formatter.\n }\n if (gitFiles) {\n for (const file of gitFiles) addFile(file)\n } else await walk(target)\n } catch (error) {\n errors.push({\n filePath: target,\n message: error instanceof Error ? error.message : String(error),\n })\n }\n }\n\n for (const filePath of [...files].sort()) {\n try {\n // Git may still list deleted files and symlinks. Never follow those into another directory.\n const entry = await lstat(filePath).catch(() => undefined)\n if (!entry?.isFile() || entry.isSymbolicLink()) continue\n const text = await readFile(filePath, 'utf8')\n const result = await formatSource(text, { ...options, filePath })\n if (result.diagnostics.length) {\n for (const diagnostic of result.diagnostics)\n errors.push({ filePath, message: diagnostic.message })\n continue\n }\n if (!result.changed) continue\n if (options.write) {\n if ((await readFile(filePath, 'utf8')) !== text)\n throw new Error(\n 'File changed during formatting; skipped to preserve your edits.',\n )\n await writeFile(filePath, result.code, 'utf8')\n }\n changed.push(filePath)\n } catch (error) {\n errors.push({\n filePath,\n message: error instanceof Error ? error.message : String(error),\n })\n }\n }\n return { checked: files.size, changed, errors }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"files.mjs","names":["escapeRegExp"],"sources":["../src/markup.ts","../src/expressions.ts","../src/source.ts","../src/fences.ts","../src/html.ts","../src/mdx.ts","../src/templates.ts","../src/index.ts","../src/files.ts"],"sourcesContent":["export const VOID_HTML_TAG_NAMES = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n])\n\nexport interface TagToken {\n end: number\n kind: 'closing' | 'opening'\n name: string\n nameEnd: number\n nameStart: number\n selfClosing: boolean\n start: number\n}\n\nexport function scanTagTokens(markup: string) {\n const tokens: TagToken[] = []\n\n for (let index = 0; index < markup.length; index++) {\n if (markup[index] !== '<') continue\n\n if (markup.startsWith('<!--', index)) {\n const commentEnd = markup.indexOf('-->', index + 4)\n if (commentEnd === -1) break\n index = commentEnd + 2\n continue\n }\n\n const isClosing = markup[index + 1] === '/'\n const nameStart = skipWhitespace(markup, index + (isClosing ? 2 : 1))\n const nameEnd = readTagNameEnd(markup, nameStart)\n if (nameEnd === nameStart) continue\n\n const tagEnd = findTagEnd(markup, nameEnd)\n if (tagEnd === -1) break\n\n const name = markup.slice(nameStart, nameEnd)\n const trailing = markup.slice(nameEnd, tagEnd)\n tokens.push({\n start: index,\n end: tagEnd + 1,\n kind: isClosing ? 'closing' : 'opening',\n name,\n nameStart,\n nameEnd,\n selfClosing: !isClosing && /\\/\\s*$/.test(trailing),\n })\n index = tagEnd\n }\n\n return tokens\n}\n\nexport function isMdxExpressionStart(source: string, index: number) {\n return (\n source[index] === '{' &&\n source[index - 1] !== '{' &&\n source[index + 1] !== '{'\n )\n}\n\nexport function findMdxExpressionEnd(source: string, startIndex: number) {\n let braceDepth = 0\n let quote: '\"' | \"'\" | '`' | undefined\n\n for (let index = startIndex; index < source.length; index++) {\n const current = source[index]\n const previous = source[index - 1]\n\n if (quote) {\n if (current === quote && previous !== '\\\\') {\n quote = undefined\n } else if (\n quote === '`' &&\n current === '$' &&\n source[index + 1] === '{'\n ) {\n const templateExpressionEnd = findMdxExpressionEnd(source, index + 1)\n if (templateExpressionEnd === -1) return -1\n index = templateExpressionEnd - 1\n }\n continue\n }\n\n if (current === '\"' || current === \"'\" || current === '`') {\n quote = current\n continue\n }\n\n if (current === '{') {\n braceDepth++\n continue\n }\n\n if (current !== '}') continue\n\n braceDepth--\n if (braceDepth === 0) return index + 1\n if (braceDepth < 0) return -1\n }\n\n return -1\n}\n\nexport function findTagEnd(markup: string, startIndex: number) {\n let quote: '\"' | \"'\" | undefined\n\n for (let index = startIndex; index < markup.length; index++) {\n const current = markup[index]\n if (quote) {\n if (current === quote && markup[index - 1] !== '\\\\') quote = undefined\n continue\n }\n\n if (current === '\"' || current === \"'\") {\n quote = current\n continue\n }\n\n if (current === '>') return index\n }\n\n return -1\n}\n\nfunction skipWhitespace(markup: string, startIndex: number) {\n let index = startIndex\n while (index < markup.length && /\\s/.test(markup[index])) index++\n return index\n}\n\nfunction readTagNameEnd(markup: string, startIndex: number) {\n let index = startIndex\n while (index < markup.length && /[A-Za-z0-9._:$-]/.test(markup[index])) {\n index++\n }\n return index\n}\n","import { findMdxExpressionEnd } from './markup'\n\nexport interface RegorExpressionPlaceholder {\n placeholder: string\n source: string\n}\n\n/**\n * Protects Regor {{ ... }} expressions while the surrounding markup is\n * formatted as HTML. The expression source is restored byte-for-byte.\n */\nexport function maskRegorExpressions(source: string) {\n const expressions: RegorExpressionPlaceholder[] = []\n let placeholderContent = ''\n let cursor = 0\n\n while (cursor < source.length) {\n const start = source.indexOf('{{', cursor)\n if (start === -1) {\n placeholderContent += source.slice(cursor)\n break\n }\n\n placeholderContent += source.slice(cursor, start)\n\n const end = findRegorExpressionEnd(source, start)\n if (end === -1) {\n // Keep incomplete input untouched rather than guessing its boundary.\n placeholderContent += source.slice(start)\n break\n }\n\n const placeholder = createPlaceholder(source, expressions.length)\n expressions.push({ placeholder, source: source.slice(start, end) })\n placeholderContent += placeholder\n cursor = end\n }\n\n return { expressions, placeholderContent }\n}\n\nexport function restoreRegorExpressions(\n formatted: string,\n expressions: RegorExpressionPlaceholder[],\n) {\n let restored = formatted\n\n for (const expression of expressions) {\n restored = restored.split(expression.placeholder).join(expression.source)\n }\n\n return restored\n}\n\nfunction findRegorExpressionEnd(source: string, start: number) {\n // Reuse the expression scanner already used by MDX. Starting at the first\n // brace makes {{ ... }} two outer brace levels, so nested object literals,\n // quoted braces and template-literal expressions remain balanced correctly.\n const end = findMdxExpressionEnd(source, start)\n if (end === -1) return -1\n\n return source.slice(end - 2, end) === '}}' ? end : -1\n}\n\nfunction createPlaceholder(source: string, index: number) {\n let placeholder = `__PURESTACK_REGOR_EXPR_${index}__`\n\n while (source.includes(placeholder)) {\n placeholder = `_${placeholder}_`\n }\n\n return placeholder\n}\n","import type { HtmlFormattingOptions } from './html'\n\nexport interface SourceRange {\n start: number\n end: number\n}\n\nexport interface SourceEdit extends SourceRange {\n newText: string\n}\n\nexport interface FormatDiagnostic extends SourceRange {\n message: string\n}\n\nexport interface FormatOptions extends Partial<HtmlFormattingOptions> {\n filePath?: string\n language?: 'mdx' | 'typescript'\n onlyWithinRange?: SourceRange\n}\n\nexport function intersects(left: SourceRange, right: SourceRange) {\n return left.start <= right.end && right.start <= left.end\n}\n\n/** Immutable source snapshot. All edit offsets refer to this text. */\nexport class SourceText {\n readonly filePath: string\n readonly options: HtmlFormattingOptions\n readonly diagnostics: FormatDiagnostic[] = []\n private readonly lines: Array<{ text: string; range: SourceRange }> = []\n private readonly eol: '\\n' | '\\r\\n'\n\n constructor(\n readonly text: string,\n options: FormatOptions = {},\n ) {\n this.filePath = options.filePath ?? 'source.mdx'\n this.options = {\n printWidth: options.printWidth ?? 80,\n tabSize: options.tabSize ?? 2,\n useTabs: options.useTabs ?? false,\n }\n for (const value of [this.options.printWidth, this.options.tabSize]) {\n if (!Number.isInteger(value) || value < 1)\n throw new Error('Print width and tab size must be positive integers.')\n }\n this.eol = /\\r\\n/.test(text) ? '\\r\\n' : '\\n'\n let start = 0\n for (const line of text.split('\\n')) {\n const content = line.endsWith('\\r') ? line.slice(0, -1) : line\n this.lines.push({\n text: content,\n range: { start, end: start + content.length },\n })\n start += line.length + 1\n }\n }\n\n get lineCount() {\n return this.lines.length\n }\n\n lineAt(line: number) {\n return this.lines[line]\n }\n\n positionAt(offset: number) {\n const bounded = Math.max(0, Math.min(offset, this.text.length))\n let low = 0\n let high = this.lines.length - 1\n while (low < high) {\n const middle = Math.ceil((low + high) / 2)\n if (this.lines[middle].range.start > bounded) high = middle - 1\n else low = middle\n }\n const line = this.lines[low]\n return {\n line: low,\n character: Math.min(bounded, line.range.end) - line.range.start,\n }\n }\n\n offsetAt(position: { line: number; character: number }) {\n const line =\n this.lines[Math.max(0, Math.min(position.line, this.lines.length - 1))]\n return Math.min(\n line.range.end,\n line.range.start + Math.max(0, position.character),\n )\n }\n\n preserveEol(text: string) {\n return text.replace(/\\r?\\n/g, this.eol)\n }\n\n report(range: SourceRange, error: unknown) {\n this.diagnostics.push({\n ...range,\n message: error instanceof Error ? error.message : String(error),\n })\n }\n}\n\n/** Apply non-overlapping edits against their original snapshot. */\nexport function applySourceEdits(source: string, edits: readonly SourceEdit[]) {\n const ordered = [...edits].sort((a, b) => a.start - b.start || a.end - b.end)\n let cursor = 0\n const parts: string[] = []\n for (const edit of ordered) {\n if (\n edit.start < cursor ||\n edit.end < edit.start ||\n edit.end > source.length\n )\n throw new Error('Formatter returned overlapping or invalid source edits.')\n parts.push(source.slice(cursor, edit.start), edit.newText)\n cursor = edit.end\n }\n parts.push(source.slice(cursor))\n return parts.join('')\n}\n","import { scanTagTokens } from './markup'\nimport {\n intersects,\n type SourceEdit,\n type SourceRange,\n type SourceText,\n} from './source'\n\nexport interface MdxFencePlaceholder {\n placeholder: string\n source: string\n}\n\nexport interface MdxFence {\n length: number\n marker: '`' | '~'\n}\n\nexport interface MdxFenceDelimiter extends MdxFence {\n suffix: string\n}\n\nexport interface MdxFenceDelimiterEditOptions {\n onlyWithinRange?: SourceRange\n}\n\nexport function buildMdxFenceDelimiterEdits(\n document: SourceText,\n excludedRanges: SourceRange[],\n options: MdxFenceDelimiterEditOptions = {},\n) {\n const edits: SourceEdit[] = []\n let activeFence: MdxFence | undefined\n let frontmatterHandled = false\n let inFrontmatter = false\n\n for (let lineIndex = 0; lineIndex < document.lineCount; lineIndex++) {\n const line = document.lineAt(lineIndex)\n const lineText = line.text\n const trimmed = lineText.trim()\n\n if (!frontmatterHandled && lineIndex === 0 && trimmed === '---') {\n frontmatterHandled = true\n inFrontmatter = true\n continue\n }\n\n if (inFrontmatter) {\n if (trimmed === '---') inFrontmatter = false\n continue\n }\n\n if (isLineInsideAnyRange(line.range, excludedRanges)) {\n continue\n }\n\n if (\n options.onlyWithinRange &&\n !intersects(line.range, options.onlyWithinRange)\n ) {\n continue\n }\n\n if (!activeFence) {\n const splitLine = splitLineBeforeInlineMdxFenceOpener(lineText)\n if (splitLine) {\n const replacement = [\n ...splitAdjacentMarkupTags(splitLine.before),\n splitLine.fenceLine,\n ].join('\\n')\n pushLineReplacement(edits, line.range, lineText, replacement)\n\n const delimiter = parseMdxFenceDelimiter(splitLine.fenceLine.trim())\n activeFence = delimiter\n ? { length: delimiter.length, marker: delimiter.marker }\n : undefined\n continue\n }\n\n const delimiter = parseMdxFenceDelimiter(trimmed)\n if (!delimiter) continue\n\n pushLineReplacement(\n edits,\n line.range,\n lineText,\n trimLineStartIndent(lineText),\n )\n activeFence = { length: delimiter.length, marker: delimiter.marker }\n continue\n }\n\n const splitClosingPrefix = splitLineAfterInlineMdxFenceCloser(\n lineText,\n activeFence,\n )\n if (splitClosingPrefix) {\n const replacement = [\n trimLineStartIndent(splitClosingPrefix.fenceLine),\n splitClosingPrefix.after,\n ].join('\\n')\n pushLineReplacement(edits, line.range, lineText, replacement)\n activeFence = undefined\n continue\n }\n\n const splitClosingSuffix = splitLineBeforeInlineMdxFenceCloser(\n lineText,\n activeFence,\n )\n if (splitClosingSuffix) {\n const replacement = [\n splitClosingSuffix.before,\n trimLineStartIndent(splitClosingSuffix.fenceLine),\n ].join('\\n')\n pushLineReplacement(edits, line.range, lineText, replacement)\n activeFence = undefined\n continue\n }\n\n const delimiter = parseMdxFenceDelimiter(trimmed)\n if (!delimiter || !isMdxFenceClosingDelimiter(delimiter, activeFence)) {\n continue\n }\n\n pushLineReplacement(\n edits,\n line.range,\n lineText,\n trimLineStartIndent(lineText),\n )\n activeFence = undefined\n }\n\n return edits.map((edit) => ({\n ...edit,\n newText: document.preserveEol(edit.newText),\n }))\n}\n\nexport function maskMdxFencedRegions(source: string) {\n const fences: MdxFencePlaceholder[] = []\n const lines = splitInlineMdxFenceDelimiters(source).split('\\n')\n const placeholderLines: string[] = []\n\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const openingDelimiter = parseMdxFenceDelimiter(lines[lineIndex].trim())\n if (!openingDelimiter) {\n placeholderLines.push(lines[lineIndex])\n continue\n }\n\n let closingLineIndex = -1\n for (\n let candidateLineIndex = lineIndex + 1;\n candidateLineIndex < lines.length;\n candidateLineIndex++\n ) {\n const closingDelimiter = parseMdxFenceDelimiter(\n lines[candidateLineIndex].trim(),\n )\n if (\n closingDelimiter &&\n isMdxFenceClosingDelimiter(closingDelimiter, openingDelimiter)\n ) {\n closingLineIndex = candidateLineIndex\n break\n }\n }\n\n if (closingLineIndex === -1) {\n placeholderLines.push(lines[lineIndex])\n continue\n }\n\n const placeholder = `<!--PURESTACK_MDX_FENCE_${fences.length}-->`\n fences.push({\n placeholder,\n source: normalizeMdxFenceDelimiterIndent(\n lines.slice(lineIndex, closingLineIndex + 1),\n ),\n })\n placeholderLines.push(placeholder)\n lineIndex = closingLineIndex\n }\n\n return { fences, placeholderContent: placeholderLines.join('\\n') }\n}\n\nexport function restoreMdxFencedRegions(\n formatted: string,\n fences: MdxFencePlaceholder[],\n) {\n let restored = formatted\n\n for (const fence of fences) {\n const standalonePlaceholderPattern = new RegExp(\n `^[\\\\t ]*${escapeRegExp(fence.placeholder)}$`,\n 'gm',\n )\n if (standalonePlaceholderPattern.test(restored)) {\n restored = restored.replace(standalonePlaceholderPattern, fence.source)\n continue\n }\n\n restored = restored.split(fence.placeholder).join(fence.source)\n }\n\n return restored\n}\n\nexport function parseMdxFenceDelimiter(\n trimmed: string,\n): MdxFenceDelimiter | undefined {\n const match = /^(`{3,}|~{3,})(.*)$/.exec(trimmed)\n if (!match) return undefined\n\n return {\n length: match[1].length,\n marker: match[1].startsWith('`') ? '`' : '~',\n suffix: match[2],\n }\n}\n\nexport function parseInlineMdxFenceOpener(trimmed: string) {\n const splitLine = splitLineBeforeInlineMdxFenceOpener(trimmed)\n if (!splitLine) return undefined\n\n return parseMdxFenceDelimiter(splitLine.fenceLine.trim())\n}\n\nexport function parseInlineMdxFenceCloser(\n trimmed: string,\n activeFence: MdxFence,\n) {\n const splitLine = splitLineAfterInlineMdxFenceCloser(trimmed, activeFence)\n if (splitLine) return parseMdxFenceDelimiter(splitLine.fenceLine.trim())\n\n const trailingSplitLine = splitLineBeforeInlineMdxFenceCloser(\n trimmed,\n activeFence,\n )\n if (!trailingSplitLine) return undefined\n\n return parseMdxFenceDelimiter(trailingSplitLine.fenceLine.trim())\n}\n\nexport function isMdxFenceClosingDelimiter(\n delimiter: MdxFenceDelimiter,\n activeFence: MdxFence,\n) {\n return (\n delimiter.marker === activeFence.marker &&\n delimiter.length >= activeFence.length &&\n delimiter.suffix.trim().length === 0\n )\n}\n\nfunction splitInlineMdxFenceDelimiters(source: string) {\n const lines = source.split('\\n')\n const splitLines: string[] = []\n let activeFence: MdxFence | undefined\n\n for (const line of lines) {\n if (!activeFence) {\n const splitLine = splitLineBeforeInlineMdxFenceOpener(line)\n if (splitLine) {\n splitLines.push(\n ...splitAdjacentMarkupTags(splitLine.before),\n splitLine.fenceLine,\n )\n\n const delimiter = parseMdxFenceDelimiter(splitLine.fenceLine.trim())\n activeFence = delimiter\n ? { length: delimiter.length, marker: delimiter.marker }\n : undefined\n continue\n }\n\n splitLines.push(line)\n\n const delimiter = parseMdxFenceDelimiter(line.trim())\n if (!delimiter) continue\n activeFence = { length: delimiter.length, marker: delimiter.marker }\n continue\n }\n\n const splitClosingLine = splitLineAfterInlineMdxFenceCloser(\n line,\n activeFence,\n )\n if (splitClosingLine) {\n splitLines.push(splitClosingLine.fenceLine, splitClosingLine.after)\n activeFence = undefined\n continue\n }\n\n const splitTrailingClosingLine = splitLineBeforeInlineMdxFenceCloser(\n line,\n activeFence,\n )\n if (splitTrailingClosingLine) {\n splitLines.push(\n splitTrailingClosingLine.before,\n splitTrailingClosingLine.fenceLine,\n )\n activeFence = undefined\n continue\n }\n\n splitLines.push(line)\n\n const delimiter = parseMdxFenceDelimiter(line.trim())\n if (!delimiter) continue\n\n if (isMdxFenceClosingDelimiter(delimiter, activeFence)) {\n activeFence = undefined\n }\n }\n\n return splitLines.join('\\n')\n}\n\nfunction splitLineBeforeInlineMdxFenceOpener(line: string) {\n if (parseMdxFenceDelimiter(line.trim())) return undefined\n\n const match = /`{3}|~{3}/.exec(line)\n if (!match) return undefined\n\n const before = line.slice(0, match.index).trimEnd()\n if (before.trim().length === 0) return undefined\n\n return {\n before,\n fenceLine: line.slice(match.index),\n }\n}\n\nfunction splitAdjacentMarkupTags(line: string) {\n const tokens = scanTagTokens(line)\n if (tokens.length < 2) return [line]\n\n let cursor = 0\n const lines: string[] = []\n const indent = /^\\s*/.exec(line)?.[0] ?? ''\n\n for (const token of tokens) {\n if (line.slice(cursor, token.start).trim().length > 0) return [line]\n\n const tag = line.slice(token.start, token.end)\n lines.push(lines.length === 0 ? `${indent}${tag}` : tag)\n cursor = token.end\n }\n\n if (line.slice(cursor).trim().length > 0) return [line]\n\n return lines\n}\n\nfunction splitLineBeforeInlineMdxFenceCloser(\n line: string,\n activeFence: MdxFence,\n) {\n let end = line.length\n while (end > 0 && (line[end - 1] === '\\t' || line[end - 1] === ' ')) end--\n let start = end\n while (start > 0 && line[start - 1] === activeFence.marker) start--\n if (end - start < activeFence.length) return undefined\n\n const before = line.slice(0, start).trimEnd()\n if (before.trim().length === 0) return undefined\n\n return {\n before,\n fenceLine: line.slice(start, end),\n }\n}\n\nfunction splitLineAfterInlineMdxFenceCloser(\n line: string,\n activeFence: MdxFence,\n) {\n const pattern = new RegExp(\n `^([\\\\t ]*${escapeRegExp(activeFence.marker.repeat(activeFence.length))}${escapeRegExp(activeFence.marker)}*)(.*)$`,\n )\n const match = pattern.exec(line)\n if (!match || match[2].trim().length === 0) return undefined\n\n const closingDelimiter = parseMdxFenceDelimiter(match[1].trim())\n if (!closingDelimiter) return undefined\n if (!isMdxFenceClosingDelimiter(closingDelimiter, activeFence)) {\n return undefined\n }\n\n return {\n fenceLine: match[1],\n after: match[2],\n }\n}\n\nfunction normalizeMdxFenceDelimiterIndent(lines: string[]) {\n if (lines.length < 2) return lines.join('\\n')\n\n const normalizedLines = [...lines]\n normalizedLines[0] = trimLineStartIndent(normalizedLines[0])\n normalizedLines[normalizedLines.length - 1] = trimLineStartIndent(\n normalizedLines[normalizedLines.length - 1],\n )\n return normalizedLines.join('\\n')\n}\n\nfunction trimLineStartIndent(line: string) {\n return line.replace(/^[\\t ]+/, '')\n}\n\nfunction pushLineReplacement(\n edits: SourceEdit[],\n range: SourceRange,\n oldText: string,\n newText: string,\n) {\n if (newText === oldText) return\n\n edits.push({ ...range, newText })\n}\n\nfunction isLineInsideAnyRange(line: SourceRange, ranges: SourceRange[]) {\n return ranges.some(\n (range) => line.start >= range.start && line.end <= range.end,\n )\n}\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n","import htmlPlugin from 'prettier/plugins/html'\nimport postcssPlugin from 'prettier/plugins/postcss'\nimport prettier from 'prettier/standalone'\n\nconst RAW_TEXT_TAG =\n 'script|style|textarea|title|xmp|iframe|noembed|noframes|plaintext'\nconst TAG_BODY = `(?:\"[^\"]*\"|'[^']*'|[^\"'>])*>`\n\n/**\n * Skips comments, raw text and opening tags; captures closing tags broken before `>`.\n * Case-sensitive so PascalCase components such as `<Title>` are not raw text.\n */\nconst BROKEN_CLOSING_TAG = new RegExp(\n [\n String.raw`<!--[\\s\\S]*?-->`,\n String.raw`<(${RAW_TEXT_TAG})\\b${TAG_BODY}[\\s\\S]*?</\\1\\s*>`,\n `<[A-Za-z]${TAG_BODY}`,\n String.raw`(</[^\\s>]+)\\s*\\n\\s*>`,\n ].join('|'),\n 'g',\n)\n\nexport interface HtmlFormattingOptions {\n printWidth: number\n tabSize: number\n useTabs: boolean\n}\n\nexport async function formatHtmlFragment(\n source: string,\n options: HtmlFormattingOptions,\n) {\n const formatted = await prettier.format(source, {\n htmlWhitespaceSensitivity: 'css',\n parser: 'html',\n plugins: [htmlPlugin, postcssPlugin],\n printWidth: options.printWidth,\n tabWidth: options.tabSize,\n useTabs: options.useTabs,\n })\n return normalizeClosingTagSpacing(formatted)\n}\n\n/** Keep closing tags readable without inserting whitespace into inline content. */\nexport function normalizeClosingTagSpacing(source: string) {\n return source.replace(\n BROKEN_CLOSING_TAG,\n (match, _rawTextTag: string, closingTag?: string) =>\n closingTag ? `${closingTag}>` : match,\n )\n}\n\nexport function getLineIndent(line: string) {\n const match = /^\\s*/.exec(line)\n return match?.[0] ?? ''\n}\n\nexport function normalizeSelfClosingTagSpacing(formatted: string) {\n // Match each whitespace run once, even when no /> follows it.\n return formatted.replace(/\\s+/g, (whitespace, offset: number) =>\n formatted.startsWith('/>', offset + whitespace.length) ? '' : whitespace,\n )\n}\n","import { maskRegorExpressions, restoreRegorExpressions } from './expressions'\nimport {\n buildMdxFenceDelimiterEdits,\n isMdxFenceClosingDelimiter,\n maskMdxFencedRegions,\n parseInlineMdxFenceCloser,\n parseInlineMdxFenceOpener,\n parseMdxFenceDelimiter,\n restoreMdxFencedRegions,\n} from './fences'\nimport { formatHtmlFragment, normalizeSelfClosingTagSpacing } from './html'\nimport {\n findMdxExpressionEnd,\n findTagEnd,\n isMdxExpressionStart,\n scanTagTokens,\n VOID_HTML_TAG_NAMES,\n} from './markup'\nimport {\n intersects,\n type SourceEdit,\n type SourceRange,\n type SourceText,\n} from './source'\n\nexport interface MdxMarkupBlock {\n content: string\n range: SourceRange\n}\n\ninterface MdxExpressionPlaceholder {\n placeholder: string\n source: string\n}\n\ninterface MdxInlineCodePlaceholder {\n placeholder: string\n source: string\n}\n\ninterface MdxFormattingRequest {\n onlyWithinRange?: SourceRange\n}\n\ninterface MdxMarkupBlockOptions {\n includeIncomplete?: boolean\n}\n\ninterface MdxBlockScanState {\n activeEndLine?: number\n activeLines: string[]\n activeStartLine?: number\n fenceLength?: number\n fenceMarker?: '`' | '~'\n frontmatterHandled: boolean\n inFence: boolean\n inFrontmatter: boolean\n}\n\nexport async function buildMdxFormattingEdits(\n document: SourceText,\n request: MdxFormattingRequest = {},\n) {\n const blocks = getMdxMarkupBlocks(document, {\n includeIncomplete: true,\n }).filter((block) =>\n request.onlyWithinRange\n ? intersects(block.range, request.onlyWithinRange)\n : true,\n )\n\n const edits: SourceEdit[] = []\n const blockRanges = blocks.map((block) => block.range)\n\n for (const block of blocks) {\n const formatted = await formatMdxMarkupBlock(document, block)\n if (!formatted || formatted === block.content) continue\n\n edits.push({ ...block.range, newText: document.preserveEol(formatted) })\n }\n\n edits.push(\n ...buildMdxFenceDelimiterEdits(document, blockRanges, {\n onlyWithinRange: request.onlyWithinRange,\n }),\n )\n\n return edits\n}\n\nexport function getMdxMarkupBlocks(\n document: SourceText,\n options: MdxMarkupBlockOptions = {},\n) {\n const blocks: MdxMarkupBlock[] = []\n const state: MdxBlockScanState = {\n activeEndLine: undefined,\n activeLines: [],\n frontmatterHandled: false,\n inFence: false,\n inFrontmatter: false,\n }\n\n for (let lineIndex = 0; lineIndex < document.lineCount; lineIndex++) {\n const lineText = document.lineAt(lineIndex).text\n const trimmed = lineText.trim()\n\n if (startMdxFrontmatter(lineIndex, trimmed, state)) {\n continue\n }\n\n if (closeMdxFrontmatter(trimmed, state)) {\n continue\n }\n\n collectActiveMarkupBlock(\n blocks,\n document,\n lineIndex,\n lineText,\n trimmed,\n state,\n )\n }\n\n if (\n options.includeIncomplete &&\n state.activeStartLine !== undefined &&\n state.activeEndLine !== undefined\n ) {\n pushActiveBlock(\n blocks,\n document,\n state.activeStartLine,\n state.activeEndLine,\n state.activeLines,\n )\n }\n\n return blocks\n}\n\nfunction pushActiveBlock(\n blocks: MdxMarkupBlock[],\n document: SourceText,\n startLine: number,\n endLine: number,\n lines: string[],\n) {\n const start = document.lineAt(startLine).range.start\n const end = document.lineAt(endLine).range.end\n blocks.push({\n content: lines.join('\\n'),\n range: { start, end },\n })\n}\n\nfunction looksLikeMarkupBlockStart(trimmedLine: string) {\n return /^<[A-Za-z][A-Za-z0-9._:$-]*/.test(trimmedLine)\n}\n\nfunction isCompleteMarkupBlock(markup: string) {\n const { placeholderContent } = maskMdxFencedRegions(markup)\n if (!placeholderContent.includes('<')) return false\n if (hasUnterminatedTag(placeholderContent)) return false\n\n return getUnclosedTagNames(placeholderContent).length === 0\n}\n\nasync function formatMdxMarkupBlock(\n document: SourceText,\n block: MdxMarkupBlock,\n) {\n const formattingOptions = document.options\n const { fences, placeholderContent: fencePlaceholderContent } =\n maskMdxFencedRegions(block.content.trim())\n const { inlineCodeSpans, placeholderContent: inlineCodePlaceholderContent } =\n maskMdxInlineCodeSpans(fencePlaceholderContent)\n const {\n expressions: regorExpressions,\n placeholderContent: regorPlaceholderContent,\n } = maskRegorExpressions(inlineCodePlaceholderContent)\n const { expressions, placeholderContent } = maskMdxExpressions(\n regorPlaceholderContent,\n )\n if (!placeholderContent.includes('<')) return undefined\n\n let formatted: string\n try {\n formatted = await formatHtmlFragment(placeholderContent, formattingOptions)\n } catch (error) {\n document.report(block.range, error)\n return undefined\n }\n\n const restoredExpressions = restoreMdxExpressions(\n normalizeSelfClosingTagSpacing(formatted.trim()),\n expressions,\n )\n const restoredRegorExpressions = restoreRegorExpressions(\n restoredExpressions,\n regorExpressions,\n )\n const restoredInlineCode = restoreMdxInlineCodeSpans(\n restoredRegorExpressions,\n inlineCodeSpans,\n )\n\n return restoreMdxFencedRegions(restoredInlineCode, fences)\n}\n\nfunction maskMdxInlineCodeSpans(source: string) {\n const inlineCodeSpans: MdxInlineCodePlaceholder[] = []\n const lines = source.split('\\n')\n const placeholderLines = lines.map((line) =>\n maskMdxInlineCodeSpansInLine(line, inlineCodeSpans),\n )\n\n return {\n inlineCodeSpans,\n placeholderContent: placeholderLines.join('\\n'),\n }\n}\n\nfunction maskMdxInlineCodeSpansInLine(\n line: string,\n inlineCodeSpans: MdxInlineCodePlaceholder[],\n) {\n let placeholderLine = ''\n\n for (let index = 0; index < line.length; ) {\n const start = line.indexOf('`', index)\n if (start === -1) {\n placeholderLine += line.slice(index)\n break\n }\n\n const tickCount = countRepeatedChar(line, start, '`')\n if (tickCount !== 1) {\n placeholderLine += line.slice(index, start + tickCount)\n index = start + tickCount\n continue\n }\n\n const end = findMdxInlineCodeEnd(line, start + 1)\n if (end === -1) {\n placeholderLine += line.slice(index)\n break\n }\n\n const source = line.slice(start, end + 1)\n const placeholder = createMdxInlineCodePlaceholder(\n inlineCodeSpans.length,\n line,\n start,\n end + 1,\n )\n inlineCodeSpans.push({ placeholder, source })\n placeholderLine += line.slice(index, start)\n placeholderLine += placeholder\n index = end + 1\n }\n\n return placeholderLine\n}\n\nfunction createMdxInlineCodePlaceholder(\n index: number,\n line: string,\n start: number,\n end: number,\n) {\n const lineBefore = line.slice(0, start)\n const lineAfter = line.slice(end)\n if (lineBefore.trim().length === 0 && lineAfter.trim().length === 0) {\n return `<!--PURESTACK_MDX_INLINE_CODE_${index}-->`\n }\n\n return `PURESTACK_MDX_INLINE_CODE_${index}`\n}\n\nfunction restoreMdxInlineCodeSpans(\n formatted: string,\n inlineCodeSpans: MdxInlineCodePlaceholder[],\n) {\n let restored = formatted\n\n for (const inlineCodeSpan of sortLongestPlaceholderFirst(inlineCodeSpans)) {\n restored = restored\n .split(inlineCodeSpan.placeholder)\n .join(inlineCodeSpan.source)\n }\n\n return restored\n}\n\nexport function maskMdxExpressions(source: string) {\n const expressions: MdxExpressionPlaceholder[] = []\n let placeholderContent = ''\n\n for (let index = 0; index < source.length; ) {\n const rawTextEnd = findRawTextElementEnd(source, index)\n if (rawTextEnd !== undefined) {\n placeholderContent += source.slice(index, rawTextEnd)\n index = rawTextEnd\n continue\n }\n\n if (!isMdxExpressionStart(source, index)) {\n placeholderContent += source[index]\n index++\n continue\n }\n\n const expressionEnd = findMdxExpressionEnd(source, index)\n if (expressionEnd === -1) {\n placeholderContent += source[index]\n index++\n continue\n }\n\n const placeholder = `PURESTACK_MDX_EXPR_${expressions.length}`\n expressions.push({\n placeholder,\n source: source.slice(index, expressionEnd),\n })\n placeholderContent += placeholder\n index = expressionEnd\n }\n\n return { expressions, placeholderContent }\n}\n\nfunction restoreMdxExpressions(\n formatted: string,\n expressions: MdxExpressionPlaceholder[],\n) {\n let restored = formatted\n\n for (const expression of sortLongestPlaceholderFirst(expressions)) {\n restored = restored.split(expression.placeholder).join(expression.source)\n }\n\n return restored\n}\n\nfunction hasUnterminatedTag(markup: string) {\n for (let index = 0; index < markup.length; index++) {\n if (markup[index] !== '<') continue\n\n if (markup.startsWith('<!--', index)) {\n const commentEnd = markup.indexOf('-->', index + 4)\n if (commentEnd === -1) return true\n index = commentEnd + 2\n continue\n }\n\n const nextTagEnd = findTagEnd(markup, index + 1)\n if (nextTagEnd === -1) return true\n index = nextTagEnd\n }\n\n return false\n}\n\nfunction startMdxFrontmatter(\n lineIndex: number,\n trimmed: string,\n state: MdxBlockScanState,\n) {\n if (state.frontmatterHandled || lineIndex !== 0 || trimmed !== '---') {\n return false\n }\n\n state.inFrontmatter = true\n state.frontmatterHandled = true\n return true\n}\n\nfunction closeMdxFrontmatter(trimmed: string, state: MdxBlockScanState) {\n if (!state.inFrontmatter) return false\n\n if (trimmed === '---') {\n state.inFrontmatter = false\n }\n\n return true\n}\n\nfunction updateMdxFenceState(trimmed: string, state: MdxBlockScanState) {\n const activeFence =\n state.fenceMarker && state.fenceLength\n ? { length: state.fenceLength, marker: state.fenceMarker }\n : undefined\n const delimiter =\n state.inFence && activeFence\n ? (parseInlineMdxFenceCloser(trimmed, activeFence) ??\n parseMdxFenceDelimiter(trimmed))\n : (parseMdxFenceDelimiter(trimmed) ?? parseInlineMdxFenceOpener(trimmed))\n if (!delimiter) return state.inFence\n\n if (!state.inFence) {\n state.inFence = true\n state.fenceLength = delimiter.length\n state.fenceMarker = delimiter.marker\n return true\n }\n\n if (\n state.fenceMarker &&\n state.fenceLength &&\n isMdxFenceClosingDelimiter(delimiter, {\n length: state.fenceLength,\n marker: state.fenceMarker,\n })\n ) {\n state.inFence = false\n state.fenceLength = undefined\n state.fenceMarker = undefined\n }\n\n return true\n}\n\nfunction collectActiveMarkupBlock(\n blocks: MdxMarkupBlock[],\n document: SourceText,\n lineIndex: number,\n lineText: string,\n trimmed: string,\n state: MdxBlockScanState,\n) {\n if (state.activeStartLine === undefined) {\n if (state.inFence) {\n updateMdxFenceState(trimmed, state)\n return\n }\n\n if (!looksLikeMarkupBlockStart(trimmed)) {\n if (updateMdxFenceState(trimmed, state)) return\n return\n }\n\n state.activeStartLine = lineIndex\n state.activeEndLine = lineIndex\n state.activeLines = [lineText]\n } else {\n state.activeEndLine = lineIndex\n state.activeLines.push(lineText)\n }\n\n updateMdxFenceState(trimmed, state)\n if (state.inFence) return\n if (!isCompleteMarkupBlock(state.activeLines.join('\\n'))) return\n\n pushActiveBlock(\n blocks,\n document,\n state.activeStartLine,\n state.activeEndLine ?? lineIndex,\n state.activeLines,\n )\n state.activeEndLine = undefined\n state.activeStartLine = undefined\n state.activeLines = []\n}\n\nfunction getUnclosedTagNames(markup: string) {\n const stack: string[] = []\n\n for (const token of scanTagTokens(markup)) {\n if (token.kind === 'opening') {\n if (isSelfContainedTag(token.name, token.selfClosing)) continue\n\n stack.push(token.name)\n continue\n }\n\n closeMatchingTag(stack, token.name)\n }\n\n return stack\n}\n\nfunction isSelfContainedTag(tagName: string, selfClosing: boolean) {\n return selfClosing || VOID_HTML_TAG_NAMES.has(tagName.toLowerCase())\n}\n\nfunction closeMatchingTag(stack: string[], tagName: string) {\n for (let index = stack.length - 1; index >= 0; index--) {\n if (stack[index] !== tagName) continue\n stack.splice(index)\n return\n }\n}\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction sortLongestPlaceholderFirst<T extends { placeholder: string }>(\n placeholders: T[],\n) {\n return [...placeholders].sort(\n (left, right) => right.placeholder.length - left.placeholder.length,\n )\n}\n\nfunction findMdxInlineCodeEnd(line: string, startIndex: number) {\n for (let index = startIndex; index < line.length; index++) {\n if (line[index] === '`') return index\n }\n\n return -1\n}\n\nfunction countRepeatedChar(line: string, startIndex: number, char: string) {\n let count = 0\n\n while (line[startIndex + count] === char) {\n count++\n }\n\n return count\n}\n\nfunction findRawTextElementEnd(source: string, startIndex: number) {\n if (source[startIndex] !== '<' || source[startIndex + 1] === '/') {\n return undefined\n }\n\n const tagEnd = findTagEnd(source, startIndex + 1)\n if (tagEnd === -1) return undefined\n\n const openingTag = source.slice(startIndex, tagEnd + 1)\n const tagName = /^<\\s*(script|style)\\b/i.exec(openingTag)?.[1]\n if (!tagName) return undefined\n\n const closingTagPattern = new RegExp(\n `<\\\\/\\\\s*${escapeRegExp(tagName)}\\\\s*>`,\n 'i',\n )\n const closingTagMatch = closingTagPattern.exec(source.slice(tagEnd + 1))\n if (!closingTagMatch) return undefined\n\n return tagEnd + 1 + closingTagMatch.index + closingTagMatch[0].length\n}\n","import type * as TypeScript from 'typescript-parser'\nimport ts from 'typescript-parser'\nimport { maskRegorExpressions, restoreRegorExpressions } from './expressions'\n\nimport { formatHtmlFragment, normalizeSelfClosingTagSpacing } from './html'\nimport {\n intersects,\n type SourceEdit,\n type SourceRange,\n type SourceText,\n} from './source'\n\nexport type SupportedTemplateTagName = 'html' | 'svg'\n\nexport interface SupportedTaggedTemplate {\n content: string\n contentRange: SourceRange\n expressions: TemplateExpressionPlaceholder[]\n interpolationRanges: Array<{ start: number; end: number }>\n placeholderContent: string\n tagName: SupportedTemplateTagName\n}\n\ninterface TemplateExpressionPlaceholder {\n placeholder: string\n source: string\n}\n\nconst SUPPORTED_TEMPLATE_TAG_NAMES: SupportedTemplateTagName[] = ['html', 'svg']\n\ninterface TemplateFormattingRequest {\n onlyWithinRange?: SourceRange\n}\n\nexport async function buildTemplateFormattingEdits(\n document: SourceText,\n request: TemplateFormattingRequest = {},\n) {\n const templates = getSupportedTaggedTemplates(document).filter((template) =>\n request.onlyWithinRange\n ? intersects(template.contentRange, request.onlyWithinRange)\n : true,\n )\n if (templates.length === 0) return []\n\n const edits: SourceEdit[] = []\n\n for (const template of templates) {\n const formatted = await formatTaggedTemplate(document, template)\n if (!formatted || formatted === template.content) continue\n\n edits.push({\n ...template.contentRange,\n newText: document.preserveEol(formatted),\n })\n }\n\n return edits\n}\n\nexport function getSupportedTaggedTemplates(\n document: SourceText,\n): SupportedTaggedTemplate[] {\n const sourceText = document.text\n const sourceFile = ts.createSourceFile(\n document.filePath,\n sourceText,\n ts.ScriptTarget.Latest,\n false,\n ts.ScriptKind.TS,\n )\n const templates: SupportedTaggedTemplate[] = []\n\n visitNode(sourceFile)\n return templates\n\n function visitNode(node: TypeScript.Node) {\n if (ts.isTaggedTemplateExpression(node)) {\n const template = createSupportedTaggedTemplate(node, sourceFile)\n if (template) {\n templates.push(template)\n // The outer template owns its interpolations; never emit overlapping edits.\n return\n }\n }\n\n ts.forEachChild(node, visitNode)\n }\n}\n\nexport function isOffsetInsideSupportedTaggedTemplate(\n sourceFile: TypeScript.SourceFile,\n offset: number,\n) {\n let isInsideTemplate = false\n\n visitNode(sourceFile)\n return isInsideTemplate\n\n function visitNode(node: TypeScript.Node) {\n if (isInsideTemplate) return\n if (offset < node.getStart(sourceFile) || offset >= node.getEnd()) return\n\n if (ts.isTaggedTemplateExpression(node)) {\n const templateTagName = getSupportedTemplateTagName(\n node.tag.getText(sourceFile),\n )\n if (!templateTagName) {\n ts.forEachChild(node, visitNode)\n return\n }\n\n const template = node.template\n if (\n offset >= template.getStart(sourceFile) &&\n offset < template.getEnd()\n ) {\n isInsideTemplate = true\n return\n }\n }\n\n ts.forEachChild(node, visitNode)\n }\n}\n\nfunction createSupportedTaggedTemplate(\n node: TypeScript.TaggedTemplateExpression,\n sourceFile: TypeScript.SourceFile,\n) {\n const tagName = getSupportedTemplateTagName(node.tag.getText(sourceFile))\n if (!tagName) return undefined\n\n const template = node.template\n if (isLikelyPrematureRawBacktickClose(sourceFile.text, template)) {\n return undefined\n }\n\n const innerStart = template.getStart(sourceFile) + 1\n const innerEnd = template.getEnd() - 1\n if (innerEnd < innerStart) return undefined\n\n const contentRange = { start: innerStart, end: innerEnd }\n\n if (ts.isNoSubstitutionTemplateLiteral(template)) {\n const content = sourceFile.text.slice(innerStart, innerEnd)\n return {\n content,\n contentRange,\n expressions: [],\n interpolationRanges: [],\n placeholderContent: content,\n tagName,\n }\n }\n\n const expressions: TemplateExpressionPlaceholder[] = []\n const interpolationRanges: Array<{ start: number; end: number }> = []\n let placeholderContent = sliceTemplateHeadContent(template.head, sourceFile)\n let currentContentOffset = placeholderContent.length\n\n template.templateSpans.forEach((span, index) => {\n const placeholder = `PURESTACK_EXPR_${index}_${tagName.toUpperCase()}`\n const interpolationEnd = span.literal.getStart(sourceFile) - innerStart + 1\n expressions.push({\n placeholder,\n source: sourceFile.text.slice(\n span.expression.getStart(sourceFile),\n span.expression.getEnd(),\n ),\n })\n interpolationRanges.push({\n start: currentContentOffset,\n end: interpolationEnd,\n })\n placeholderContent += placeholder\n const literalContent = sliceTemplateSpanLiteralContent(\n span.literal,\n sourceFile,\n )\n placeholderContent += literalContent\n currentContentOffset = interpolationEnd + literalContent.length\n })\n\n return {\n content: sourceFile.text.slice(innerStart, innerEnd),\n contentRange,\n expressions,\n interpolationRanges,\n placeholderContent,\n tagName,\n }\n}\n\nfunction getSupportedTemplateTagName(tagText: string) {\n const normalizedTag = tagText.trim()\n\n for (const tagName of SUPPORTED_TEMPLATE_TAG_NAMES) {\n if (normalizedTag === tagName || normalizedTag.endsWith(`.${tagName}`)) {\n return tagName\n }\n }\n\n return undefined\n}\n\nfunction isLikelyPrematureRawBacktickClose(\n sourceText: string,\n template: TypeScript.TemplateLiteral,\n) {\n return sourceText.startsWith('``', template.getEnd())\n}\n\nfunction sliceTemplateHeadContent(\n head: TypeScript.TemplateHead,\n sourceFile: TypeScript.SourceFile,\n) {\n return sourceFile.text.slice(head.getStart(sourceFile) + 1, head.getEnd() - 2)\n}\n\nfunction sliceTemplateSpanLiteralContent(\n literal: TypeScript.TemplateMiddle | TypeScript.TemplateTail,\n sourceFile: TypeScript.SourceFile,\n) {\n const endOffset = ts.isTemplateTail(literal) ? 1 : 2\n return sourceFile.text.slice(\n literal.getStart(sourceFile) + 1,\n literal.getEnd() - endOffset,\n )\n}\n\nasync function formatTaggedTemplate(\n document: SourceText,\n template: SupportedTaggedTemplate,\n) {\n const formattingOptions = document.options\n const source = template.placeholderContent.trim()\n const { expressions: regorExpressions, placeholderContent } =\n maskRegorExpressions(source)\n\n if (!placeholderContent.includes('<')) return undefined\n\n let formatted: string\n try {\n formatted = await formatHtmlFragment(placeholderContent, formattingOptions)\n } catch (error) {\n document.report(template.contentRange, error)\n return undefined\n }\n\n const restoredTemplateExpressions = restoreTemplateExpressions(\n normalizeSelfClosingTagSpacing(formatted.trim()),\n template.expressions,\n )\n\n return restoreRegorExpressions(restoredTemplateExpressions, regorExpressions)\n}\n\nfunction restoreTemplateExpressions(\n formatted: string,\n expressions: TemplateExpressionPlaceholder[],\n) {\n let restored = formatted\n\n for (const expression of expressions) {\n restored = restored\n .split(expression.placeholder)\n .join(`\\${${expression.source}}`)\n }\n\n return restored\n}\n","import { buildMdxFormattingEdits } from './mdx'\nimport { applySourceEdits, type FormatOptions, SourceText } from './source'\nimport { buildTemplateFormattingEdits } from './templates'\n\nexport {\n maskRegorExpressions,\n type RegorExpressionPlaceholder,\n restoreRegorExpressions,\n} from './expressions'\nexport * from './fences'\nexport * from './html'\nexport * from './markup'\nexport * from './mdx'\nexport * from './source'\nexport * from './templates'\n\n/** Formats only component markup and html/svg tagged template contents. */\nexport async function formatSource(text: string, options: FormatOptions = {}) {\n const source = new SourceText(text, options)\n const language =\n options.language ??\n (/\\.[cm]?tsx?$/i.test(source.filePath) ? 'typescript' : 'mdx')\n const edits = await (language === 'typescript'\n ? buildTemplateFormattingEdits(source, options)\n : buildMdxFormattingEdits(source, options))\n const code = applySourceEdits(text, edits)\n return {\n code,\n edits,\n diagnostics: source.diagnostics,\n changed: code !== text,\n }\n}\n","import { execFile } from 'node:child_process'\nimport { lstat, readdir, readFile, writeFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport { promisify } from 'node:util'\nimport { formatSource } from './index'\nimport type { FormatOptions } from './source'\n\nconst exec = promisify(execFile)\n// Windows and macOS file systems ignore letter case by default.\nconst caseInsensitivePaths =\n process.platform === 'win32' || process.platform === 'darwin'\nconst comparablePath = (value: string) =>\n caseInsensitivePaths ? value.toLowerCase() : value\nconst extensions = /\\.(?:[cm]?ts|mdx|rmdx)$/i\nconst ignoredDirectories = new Set([\n '.git',\n '.yarn',\n '.tmp',\n '.ts-ssg',\n '.cache',\n 'node_modules',\n 'dist',\n 'out',\n 'coverage',\n 'artifacts',\n])\n\nexport interface FormatFilesOptions\n extends Omit<FormatOptions, 'filePath' | 'language' | 'onlyWithinRange'> {\n cwd?: string\n write?: boolean\n /** Files or directories to omit, relative to cwd. */\n exclude?: readonly string[]\n}\n\nexport interface FormatFileError {\n filePath: string\n message: string\n}\n\n/** Discover source files, honor Git ignores in repositories, and collect all failures. */\nexport async function formatFiles(\n inputs: readonly string[] = ['.'],\n options: FormatFilesOptions = {},\n) {\n const cwd = path.resolve(options.cwd ?? process.cwd())\n const excluded = (options.exclude ?? []).map((entry) =>\n comparablePath(path.resolve(cwd, entry)),\n )\n const files = new Set<string>()\n const errors: FormatFileError[] = []\n const changed: string[] = []\n\n function isExcluded(file: string) {\n const comparable = comparablePath(file)\n return (\n path\n .relative(cwd, file)\n .split(path.sep)\n .some((part) => ignoredDirectories.has(comparablePath(part))) ||\n excluded.some(\n (entry) =>\n comparable === entry || comparable.startsWith(`${entry}${path.sep}`),\n )\n )\n }\n\n function addFile(file: string) {\n if (extensions.test(file) && !isExcluded(file)) files.add(file)\n }\n\n async function walk(directory: string) {\n if (isExcluded(directory)) return\n for (const entry of await readdir(directory, { withFileTypes: true })) {\n const file = path.join(directory, entry.name)\n if (entry.isSymbolicLink()) continue\n if (entry.isDirectory()) await walk(file)\n else if (entry.isFile()) addFile(file)\n }\n }\n\n for (const input of inputs) {\n const target = path.resolve(cwd, input)\n try {\n const entry = await lstat(target)\n if (entry.isSymbolicLink()) continue\n if (entry.isFile()) {\n addFile(target)\n continue\n }\n if (!entry.isDirectory() || isExcluded(target)) continue\n let gitFiles: string[] | undefined\n try {\n const { stdout } = await exec(\n 'git',\n [\n '-C',\n target,\n 'ls-files',\n '--cached',\n '--others',\n '--exclude-standard',\n '-z',\n '--',\n '.',\n ],\n { maxBuffer: 32 * 1024 * 1024 },\n )\n gitFiles = stdout\n .split('\\0')\n .filter(Boolean)\n // Git lists paths relative to -C, so keep the caller's path spelling.\n .map((file) => path.resolve(target, file))\n } catch {\n // Git is optional; a standalone project still has a formatter.\n }\n if (gitFiles) {\n for (const file of gitFiles) addFile(file)\n } else await walk(target)\n } catch (error) {\n errors.push({\n filePath: target,\n message: error instanceof Error ? error.message : String(error),\n })\n }\n }\n\n for (const filePath of [...files].sort()) {\n try {\n // Git may still list deleted files and symlinks. Never follow those into another directory.\n const entry = await lstat(filePath).catch(() => undefined)\n if (!entry?.isFile() || entry.isSymbolicLink()) continue\n const text = await readFile(filePath, 'utf8')\n const result = await formatSource(text, { ...options, filePath })\n if (result.diagnostics.length) {\n for (const diagnostic of result.diagnostics)\n errors.push({ filePath, message: diagnostic.message })\n continue\n }\n if (!result.changed) continue\n if (options.write) {\n if ((await readFile(filePath, 'utf8')) !== text)\n throw new Error(\n 'File changed during formatting; skipped to preserve your edits.',\n )\n await writeFile(filePath, result.code, 'utf8')\n }\n changed.push(filePath)\n } catch (error) {\n errors.push({\n filePath,\n message: error instanceof Error ? error.message : String(error),\n })\n }\n }\n return { checked: files.size, changed, errors }\n}\n"],"mappings":"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"}
|
package/dist/ts-format.d.mts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
/*! @purestack/ts-format v1.1.
|
|
1
|
+
/*! @purestack/ts-format v1.1.33 | (c) 2026 Ahmed Yasin Koculu | MIT License */
|
|
2
2
|
|
|
3
3
|
import * as TypeScript from "typescript-parser";
|
|
4
|
-
//#region packages/ts-format/src/html.d.ts
|
|
5
4
|
export interface HtmlFormattingOptions {
|
|
6
5
|
printWidth: number;
|
|
7
6
|
tabSize: number;
|
|
@@ -12,8 +11,6 @@ export declare function formatHtmlFragment(source: string, options: HtmlFormatti
|
|
|
12
11
|
export declare function normalizeClosingTagSpacing(source: string): string;
|
|
13
12
|
export declare function getLineIndent(line: string): string;
|
|
14
13
|
export declare function normalizeSelfClosingTagSpacing(formatted: string): string;
|
|
15
|
-
//#endregion
|
|
16
|
-
//#region packages/ts-format/src/source.d.ts
|
|
17
14
|
export interface SourceRange {
|
|
18
15
|
start: number;
|
|
19
16
|
end: number;
|
|
@@ -57,8 +54,6 @@ export declare class SourceText {
|
|
|
57
54
|
}
|
|
58
55
|
/** Apply non-overlapping edits against their original snapshot. */
|
|
59
56
|
export declare function applySourceEdits(source: string, edits: readonly SourceEdit[]): string;
|
|
60
|
-
//#endregion
|
|
61
|
-
//#region packages/ts-format/src/expressions.d.ts
|
|
62
57
|
interface RegorExpressionPlaceholder {
|
|
63
58
|
placeholder: string;
|
|
64
59
|
source: string;
|
|
@@ -72,8 +67,6 @@ export declare function maskRegorExpressions(source: string): {
|
|
|
72
67
|
placeholderContent: string;
|
|
73
68
|
};
|
|
74
69
|
export declare function restoreRegorExpressions(formatted: string, expressions: RegorExpressionPlaceholder[]): string;
|
|
75
|
-
//#endregion
|
|
76
|
-
//#region packages/ts-format/src/fences.d.ts
|
|
77
70
|
export interface MdxFencePlaceholder {
|
|
78
71
|
placeholder: string;
|
|
79
72
|
source: string;
|
|
@@ -102,8 +95,6 @@ export declare function parseMdxFenceDelimiter(trimmed: string): MdxFenceDelimit
|
|
|
102
95
|
export declare function parseInlineMdxFenceOpener(trimmed: string): MdxFenceDelimiter | undefined;
|
|
103
96
|
export declare function parseInlineMdxFenceCloser(trimmed: string, activeFence: MdxFence): MdxFenceDelimiter | undefined;
|
|
104
97
|
export declare function isMdxFenceClosingDelimiter(delimiter: MdxFenceDelimiter, activeFence: MdxFence): boolean;
|
|
105
|
-
//#endregion
|
|
106
|
-
//#region packages/ts-format/src/markup.d.ts
|
|
107
98
|
export declare const VOID_HTML_TAG_NAMES: Set<string>;
|
|
108
99
|
export interface TagToken {
|
|
109
100
|
end: number;
|
|
@@ -118,8 +109,6 @@ export declare function scanTagTokens(markup: string): TagToken[];
|
|
|
118
109
|
export declare function isMdxExpressionStart(source: string, index: number): boolean;
|
|
119
110
|
export declare function findMdxExpressionEnd(source: string, startIndex: number): number;
|
|
120
111
|
export declare function findTagEnd(markup: string, startIndex: number): number;
|
|
121
|
-
//#endregion
|
|
122
|
-
//#region packages/ts-format/src/mdx.d.ts
|
|
123
112
|
export interface MdxMarkupBlock {
|
|
124
113
|
content: string;
|
|
125
114
|
range: SourceRange;
|
|
@@ -140,8 +129,6 @@ export declare function maskMdxExpressions(source: string): {
|
|
|
140
129
|
expressions: MdxExpressionPlaceholder[];
|
|
141
130
|
placeholderContent: string;
|
|
142
131
|
};
|
|
143
|
-
//#endregion
|
|
144
|
-
//#region packages/ts-format/src/templates.d.ts
|
|
145
132
|
export type SupportedTemplateTagName = 'html' | 'svg';
|
|
146
133
|
export interface SupportedTaggedTemplate {
|
|
147
134
|
content: string;
|
|
@@ -164,8 +151,6 @@ interface TemplateFormattingRequest {
|
|
|
164
151
|
export declare function buildTemplateFormattingEdits(document: SourceText, request?: TemplateFormattingRequest): Promise<SourceEdit[]>;
|
|
165
152
|
export declare function getSupportedTaggedTemplates(document: SourceText): SupportedTaggedTemplate[];
|
|
166
153
|
export declare function isOffsetInsideSupportedTaggedTemplate(sourceFile: TypeScript.SourceFile, offset: number): boolean;
|
|
167
|
-
//#endregion
|
|
168
|
-
//#region packages/ts-format/src/index.d.ts
|
|
169
154
|
/** Formats only component markup and html/svg tagged template contents. */
|
|
170
155
|
export declare function formatSource(text: string, options?: FormatOptions): Promise<{
|
|
171
156
|
code: string;
|
|
@@ -173,6 +158,5 @@ export declare function formatSource(text: string, options?: FormatOptions): Pro
|
|
|
173
158
|
diagnostics: FormatDiagnostic[];
|
|
174
159
|
changed: boolean;
|
|
175
160
|
}>;
|
|
176
|
-
//#endregion
|
|
177
161
|
export type { RegorExpressionPlaceholder };
|
|
178
162
|
//# sourceMappingURL=ts-format.d.mts.map
|
package/dist/ts-format.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ts-format.d.mts","names":["_$__source0.SourceEdit"
|
|
1
|
+
{"version":3,"file":"ts-format.d.mts","names":["_$__source0.SourceEdit"],"sources":["../src/html.ts","../src/source.ts","../src/expressions.ts","../src/fences.ts","../src/markup.ts","../src/mdx.ts","../src/templates.ts","../src/index.ts"],"mappings":";iBAsBiB;EACf;EACA;EACA;;wBAGoB,mBACpB,gBACA,SAAS,wBAAqB;;wBAchB,2BAA2B;wBAQ3B,cAAc;wBAKd,+BAA+B;iBCvD9B;EACf;EACA;;iBAGe,mBAAmB;EAClC;;iBAGe,yBAAyB;EACxC;;iBAGe,sBAAsB,QAAQ;EAC7C;EACA;EACA,kBAAkB;;wBAGJ,WAAW,MAAM,aAAa,OAAO;;qBAKxC;WAQA;WAPF;WACA,SAAS;WACT,aAAa;mBACL;mBACA;EAEjB,YACW,cACT,UAAS;MAwBP;EAIJ,OAAO;IAjC+B;IAAe,OAAA;;EAqCrD,WAAW;IAWP;IACA;;EAIJ,SAAS;IAAY;IAAc;;EASnC,YAAY;EAIZ,OAAO,OAAO,aAAa;;;wBASb,iBAAiB,gBAAgB,gBAAgB;UCvGhD;EACf;EACA;;;;;;wBAOc,qBAAqB;;;;wBA8BrB,wBACd,mBACA,aAAa;iBCnCE;EACf;EACA;;iBAGe;EACf;EACA;;iBAGe,0BAA0B;EACzC;;iBAGe;EACf,kBAAkB;;wBAGJ,4BACd,UAAU,YACV,gBAAgB,eAChB,UAAS;;;;;wBA+GK,qBAAqB;;;;wBAiDrB,wBACd,mBACA,QAAQ;wBAoBM,uBACd,kBACC;wBAWa,0BAA0B,kBAAe;wBAOzC,0BACd,iBACA,aAAa,WAAQ;wBAcP,2BACd,WAAW,mBACX,aAAa;qBCzPF,qBAAmB;iBAiBf;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;wBAGc,cAAc,iBAAc;wBAsC5B,qBAAqB,gBAAgB;wBAQrC,qBAAqB,gBAAgB;wBA2CrC,WAAW,gBAAgB;iBC3F1B;EACf;EACA,OAAO;;UAGC;EACR;EACA;;UAQQ;EACR,kBAAkB;;UAGV;EACR;;wBAcoB,wBACpB,UAAU,YACV,UAAS,uBAAyB,QAAA;wBA6BpB,mBACd,UAAU,YACV,UAAS,wBAA0B;wBA4MrB,mBAAmB;;;;YC5RvB;iBAEK;EACf;EACA,cAAc;EACd,aAAa;EACb,qBAAqB;IAAQ;IAAe;;EAC5C;EACA,SAAS;;UAGD;EACR;EACA;;UAKQ;EACR,kBAAkB;;wBAGE,6BACpB,UAAU,YACV,UAAS,4BAA8B,QAAA;wBAwBzB,4BACd,UAAU,aACT;wBA4Ba,sCACd,YAAY,WAAW,YACvB;;wBC3EoB,aAAa,cAAc,UAAS,gBAAkB;;E,OAAlBA"}
|
package/dist/ts-format.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
/*! @purestack/ts-format v1.1.
|
|
1
|
+
/*! @purestack/ts-format v1.1.33 | (c) 2026 Ahmed Yasin Koculu | MIT License */
|
|
2
2
|
|
|
3
3
|
import htmlPlugin from "prettier/plugins/html";
|
|
4
4
|
import postcssPlugin from "prettier/plugins/postcss";
|
|
5
5
|
import prettier from "prettier/standalone";
|
|
6
6
|
import ts from "typescript-parser";
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
// packages/ts-format/src/markup.ts
|
|
9
9
|
const VOID_HTML_TAG_NAMES = /* @__PURE__ */ new Set([
|
|
10
10
|
"area",
|
|
11
11
|
"base",
|
|
@@ -113,8 +113,7 @@ function readTagNameEnd(markup, startIndex) {
|
|
|
113
113
|
return index;
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
//#region packages/ts-format/src/expressions.ts
|
|
116
|
+
// packages/ts-format/src/expressions.ts
|
|
118
117
|
/**
|
|
119
118
|
* Protects Regor {{ ... }} expressions while the surrounding markup is
|
|
120
119
|
* formatted as HTML. The expression source is restored byte-for-byte.
|
|
@@ -164,8 +163,7 @@ function createPlaceholder(source, index) {
|
|
|
164
163
|
return placeholder;
|
|
165
164
|
}
|
|
166
165
|
|
|
167
|
-
|
|
168
|
-
//#region packages/ts-format/src/source.ts
|
|
166
|
+
// packages/ts-format/src/source.ts
|
|
169
167
|
function intersects(left, right) {
|
|
170
168
|
return left.start <= right.end && right.start <= left.end;
|
|
171
169
|
}
|
|
@@ -249,8 +247,7 @@ function applySourceEdits(source, edits) {
|
|
|
249
247
|
return parts.join("");
|
|
250
248
|
}
|
|
251
249
|
|
|
252
|
-
|
|
253
|
-
//#region packages/ts-format/src/fences.ts
|
|
250
|
+
// packages/ts-format/src/fences.ts
|
|
254
251
|
function buildMdxFenceDelimiterEdits(document, excludedRanges, options = {}) {
|
|
255
252
|
const edits = [];
|
|
256
253
|
let activeFence;
|
|
@@ -505,8 +502,7 @@ function escapeRegExp$1(value) {
|
|
|
505
502
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
506
503
|
}
|
|
507
504
|
|
|
508
|
-
|
|
509
|
-
//#region packages/ts-format/src/html.ts
|
|
505
|
+
// packages/ts-format/src/html.ts
|
|
510
506
|
const RAW_TEXT_TAG = "script|style|textarea|title|xmp|iframe|noembed|noframes|plaintext";
|
|
511
507
|
const TAG_BODY = `(?:"[^"]*"|'[^']*'|[^"'>])*>`;
|
|
512
508
|
/**
|
|
@@ -540,8 +536,7 @@ function normalizeSelfClosingTagSpacing(formatted) {
|
|
|
540
536
|
return formatted.replace(/\s+/g, (whitespace, offset) => formatted.startsWith("/>", offset + whitespace.length) ? "" : whitespace);
|
|
541
537
|
}
|
|
542
538
|
|
|
543
|
-
|
|
544
|
-
//#region packages/ts-format/src/mdx.ts
|
|
539
|
+
// packages/ts-format/src/mdx.ts
|
|
545
540
|
async function buildMdxFormattingEdits(document, request = {}) {
|
|
546
541
|
const blocks = getMdxMarkupBlocks(document, { includeIncomplete: true }).filter((block) => request.onlyWithinRange ? intersects(block.range, request.onlyWithinRange) : true);
|
|
547
542
|
const edits = [];
|
|
@@ -825,8 +820,7 @@ function findRawTextElementEnd(source, startIndex) {
|
|
|
825
820
|
return tagEnd + 1 + closingTagMatch.index + closingTagMatch[0].length;
|
|
826
821
|
}
|
|
827
822
|
|
|
828
|
-
|
|
829
|
-
//#region packages/ts-format/src/templates.ts
|
|
823
|
+
// packages/ts-format/src/templates.ts
|
|
830
824
|
const SUPPORTED_TEMPLATE_TAG_NAMES = ["html", "svg"];
|
|
831
825
|
async function buildTemplateFormattingEdits(document, request = {}) {
|
|
832
826
|
const templates = getSupportedTaggedTemplates(document).filter((template) => request.onlyWithinRange ? intersects(template.contentRange, request.onlyWithinRange) : true);
|
|
@@ -967,8 +961,7 @@ function restoreTemplateExpressions(formatted, expressions) {
|
|
|
967
961
|
return restored;
|
|
968
962
|
}
|
|
969
963
|
|
|
970
|
-
|
|
971
|
-
//#region packages/ts-format/src/index.ts
|
|
964
|
+
// packages/ts-format/src/index.ts
|
|
972
965
|
/** Formats only component markup and html/svg tagged template contents. */
|
|
973
966
|
async function formatSource(text, options = {}) {
|
|
974
967
|
const source = new SourceText(text, options);
|
|
@@ -982,6 +975,5 @@ async function formatSource(text, options = {}) {
|
|
|
982
975
|
};
|
|
983
976
|
}
|
|
984
977
|
|
|
985
|
-
//#endregion
|
|
986
978
|
export { SourceText, VOID_HTML_TAG_NAMES, applySourceEdits, buildMdxFenceDelimiterEdits, buildMdxFormattingEdits, buildTemplateFormattingEdits, findMdxExpressionEnd, findTagEnd, formatHtmlFragment, formatSource, getLineIndent, getMdxMarkupBlocks, getSupportedTaggedTemplates, intersects, isMdxExpressionStart, isMdxFenceClosingDelimiter, isOffsetInsideSupportedTaggedTemplate, maskMdxExpressions, maskMdxFencedRegions, maskRegorExpressions, normalizeClosingTagSpacing, normalizeSelfClosingTagSpacing, parseInlineMdxFenceCloser, parseInlineMdxFenceOpener, parseMdxFenceDelimiter, restoreMdxFencedRegions, restoreRegorExpressions, scanTagTokens };
|
|
987
979
|
//# sourceMappingURL=ts-format.mjs.map
|
package/dist/ts-format.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ts-format.mjs","names":["escapeRegExp"],"sources":["../src/markup.ts","../src/expressions.ts","../src/source.ts","../src/fences.ts","../src/html.ts","../src/mdx.ts","../src/templates.ts","../src/index.ts"],"sourcesContent":["export const VOID_HTML_TAG_NAMES = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n])\n\nexport interface TagToken {\n end: number\n kind: 'closing' | 'opening'\n name: string\n nameEnd: number\n nameStart: number\n selfClosing: boolean\n start: number\n}\n\nexport function scanTagTokens(markup: string) {\n const tokens: TagToken[] = []\n\n for (let index = 0; index < markup.length; index++) {\n if (markup[index] !== '<') continue\n\n if (markup.startsWith('<!--', index)) {\n const commentEnd = markup.indexOf('-->', index + 4)\n if (commentEnd === -1) break\n index = commentEnd + 2\n continue\n }\n\n const isClosing = markup[index + 1] === '/'\n const nameStart = skipWhitespace(markup, index + (isClosing ? 2 : 1))\n const nameEnd = readTagNameEnd(markup, nameStart)\n if (nameEnd === nameStart) continue\n\n const tagEnd = findTagEnd(markup, nameEnd)\n if (tagEnd === -1) break\n\n const name = markup.slice(nameStart, nameEnd)\n const trailing = markup.slice(nameEnd, tagEnd)\n tokens.push({\n start: index,\n end: tagEnd + 1,\n kind: isClosing ? 'closing' : 'opening',\n name,\n nameStart,\n nameEnd,\n selfClosing: !isClosing && /\\/\\s*$/.test(trailing),\n })\n index = tagEnd\n }\n\n return tokens\n}\n\nexport function isMdxExpressionStart(source: string, index: number) {\n return (\n source[index] === '{' &&\n source[index - 1] !== '{' &&\n source[index + 1] !== '{'\n )\n}\n\nexport function findMdxExpressionEnd(source: string, startIndex: number) {\n let braceDepth = 0\n let quote: '\"' | \"'\" | '`' | undefined\n\n for (let index = startIndex; index < source.length; index++) {\n const current = source[index]\n const previous = source[index - 1]\n\n if (quote) {\n if (current === quote && previous !== '\\\\') {\n quote = undefined\n } else if (\n quote === '`' &&\n current === '$' &&\n source[index + 1] === '{'\n ) {\n const templateExpressionEnd = findMdxExpressionEnd(source, index + 1)\n if (templateExpressionEnd === -1) return -1\n index = templateExpressionEnd - 1\n }\n continue\n }\n\n if (current === '\"' || current === \"'\" || current === '`') {\n quote = current\n continue\n }\n\n if (current === '{') {\n braceDepth++\n continue\n }\n\n if (current !== '}') continue\n\n braceDepth--\n if (braceDepth === 0) return index + 1\n if (braceDepth < 0) return -1\n }\n\n return -1\n}\n\nexport function findTagEnd(markup: string, startIndex: number) {\n let quote: '\"' | \"'\" | undefined\n\n for (let index = startIndex; index < markup.length; index++) {\n const current = markup[index]\n if (quote) {\n if (current === quote && markup[index - 1] !== '\\\\') quote = undefined\n continue\n }\n\n if (current === '\"' || current === \"'\") {\n quote = current\n continue\n }\n\n if (current === '>') return index\n }\n\n return -1\n}\n\nfunction skipWhitespace(markup: string, startIndex: number) {\n let index = startIndex\n while (index < markup.length && /\\s/.test(markup[index])) index++\n return index\n}\n\nfunction readTagNameEnd(markup: string, startIndex: number) {\n let index = startIndex\n while (index < markup.length && /[A-Za-z0-9._:$-]/.test(markup[index])) {\n index++\n }\n return index\n}\n","import { findMdxExpressionEnd } from './markup'\n\nexport interface RegorExpressionPlaceholder {\n placeholder: string\n source: string\n}\n\n/**\n * Protects Regor {{ ... }} expressions while the surrounding markup is\n * formatted as HTML. The expression source is restored byte-for-byte.\n */\nexport function maskRegorExpressions(source: string) {\n const expressions: RegorExpressionPlaceholder[] = []\n let placeholderContent = ''\n let cursor = 0\n\n while (cursor < source.length) {\n const start = source.indexOf('{{', cursor)\n if (start === -1) {\n placeholderContent += source.slice(cursor)\n break\n }\n\n placeholderContent += source.slice(cursor, start)\n\n const end = findRegorExpressionEnd(source, start)\n if (end === -1) {\n // Keep incomplete input untouched rather than guessing its boundary.\n placeholderContent += source.slice(start)\n break\n }\n\n const placeholder = createPlaceholder(source, expressions.length)\n expressions.push({ placeholder, source: source.slice(start, end) })\n placeholderContent += placeholder\n cursor = end\n }\n\n return { expressions, placeholderContent }\n}\n\nexport function restoreRegorExpressions(\n formatted: string,\n expressions: RegorExpressionPlaceholder[],\n) {\n let restored = formatted\n\n for (const expression of expressions) {\n restored = restored.split(expression.placeholder).join(expression.source)\n }\n\n return restored\n}\n\nfunction findRegorExpressionEnd(source: string, start: number) {\n // Reuse the expression scanner already used by MDX. Starting at the first\n // brace makes {{ ... }} two outer brace levels, so nested object literals,\n // quoted braces and template-literal expressions remain balanced correctly.\n const end = findMdxExpressionEnd(source, start)\n if (end === -1) return -1\n\n return source.slice(end - 2, end) === '}}' ? end : -1\n}\n\nfunction createPlaceholder(source: string, index: number) {\n let placeholder = `__PURESTACK_REGOR_EXPR_${index}__`\n\n while (source.includes(placeholder)) {\n placeholder = `_${placeholder}_`\n }\n\n return placeholder\n}\n","import type { HtmlFormattingOptions } from './html'\n\nexport interface SourceRange {\n start: number\n end: number\n}\n\nexport interface SourceEdit extends SourceRange {\n newText: string\n}\n\nexport interface FormatDiagnostic extends SourceRange {\n message: string\n}\n\nexport interface FormatOptions extends Partial<HtmlFormattingOptions> {\n filePath?: string\n language?: 'mdx' | 'typescript'\n onlyWithinRange?: SourceRange\n}\n\nexport function intersects(left: SourceRange, right: SourceRange) {\n return left.start <= right.end && right.start <= left.end\n}\n\n/** Immutable source snapshot. All edit offsets refer to this text. */\nexport class SourceText {\n readonly filePath: string\n readonly options: HtmlFormattingOptions\n readonly diagnostics: FormatDiagnostic[] = []\n private readonly lines: Array<{ text: string; range: SourceRange }> = []\n private readonly eol: '\\n' | '\\r\\n'\n\n constructor(\n readonly text: string,\n options: FormatOptions = {},\n ) {\n this.filePath = options.filePath ?? 'source.mdx'\n this.options = {\n printWidth: options.printWidth ?? 80,\n tabSize: options.tabSize ?? 2,\n useTabs: options.useTabs ?? false,\n }\n for (const value of [this.options.printWidth, this.options.tabSize]) {\n if (!Number.isInteger(value) || value < 1)\n throw new Error('Print width and tab size must be positive integers.')\n }\n this.eol = /\\r\\n/.test(text) ? '\\r\\n' : '\\n'\n let start = 0\n for (const line of text.split('\\n')) {\n const content = line.endsWith('\\r') ? line.slice(0, -1) : line\n this.lines.push({\n text: content,\n range: { start, end: start + content.length },\n })\n start += line.length + 1\n }\n }\n\n get lineCount() {\n return this.lines.length\n }\n\n lineAt(line: number) {\n return this.lines[line]\n }\n\n positionAt(offset: number) {\n const bounded = Math.max(0, Math.min(offset, this.text.length))\n let low = 0\n let high = this.lines.length - 1\n while (low < high) {\n const middle = Math.ceil((low + high) / 2)\n if (this.lines[middle].range.start > bounded) high = middle - 1\n else low = middle\n }\n const line = this.lines[low]\n return {\n line: low,\n character: Math.min(bounded, line.range.end) - line.range.start,\n }\n }\n\n offsetAt(position: { line: number; character: number }) {\n const line =\n this.lines[Math.max(0, Math.min(position.line, this.lines.length - 1))]\n return Math.min(\n line.range.end,\n line.range.start + Math.max(0, position.character),\n )\n }\n\n preserveEol(text: string) {\n return text.replace(/\\r?\\n/g, this.eol)\n }\n\n report(range: SourceRange, error: unknown) {\n this.diagnostics.push({\n ...range,\n message: error instanceof Error ? error.message : String(error),\n })\n }\n}\n\n/** Apply non-overlapping edits against their original snapshot. */\nexport function applySourceEdits(source: string, edits: readonly SourceEdit[]) {\n const ordered = [...edits].sort((a, b) => a.start - b.start || a.end - b.end)\n let cursor = 0\n const parts: string[] = []\n for (const edit of ordered) {\n if (\n edit.start < cursor ||\n edit.end < edit.start ||\n edit.end > source.length\n )\n throw new Error('Formatter returned overlapping or invalid source edits.')\n parts.push(source.slice(cursor, edit.start), edit.newText)\n cursor = edit.end\n }\n parts.push(source.slice(cursor))\n return parts.join('')\n}\n","import { scanTagTokens } from './markup'\nimport {\n intersects,\n type SourceEdit,\n type SourceRange,\n type SourceText,\n} from './source'\n\nexport interface MdxFencePlaceholder {\n placeholder: string\n source: string\n}\n\nexport interface MdxFence {\n length: number\n marker: '`' | '~'\n}\n\nexport interface MdxFenceDelimiter extends MdxFence {\n suffix: string\n}\n\nexport interface MdxFenceDelimiterEditOptions {\n onlyWithinRange?: SourceRange\n}\n\nexport function buildMdxFenceDelimiterEdits(\n document: SourceText,\n excludedRanges: SourceRange[],\n options: MdxFenceDelimiterEditOptions = {},\n) {\n const edits: SourceEdit[] = []\n let activeFence: MdxFence | undefined\n let frontmatterHandled = false\n let inFrontmatter = false\n\n for (let lineIndex = 0; lineIndex < document.lineCount; lineIndex++) {\n const line = document.lineAt(lineIndex)\n const lineText = line.text\n const trimmed = lineText.trim()\n\n if (!frontmatterHandled && lineIndex === 0 && trimmed === '---') {\n frontmatterHandled = true\n inFrontmatter = true\n continue\n }\n\n if (inFrontmatter) {\n if (trimmed === '---') inFrontmatter = false\n continue\n }\n\n if (isLineInsideAnyRange(line.range, excludedRanges)) {\n continue\n }\n\n if (\n options.onlyWithinRange &&\n !intersects(line.range, options.onlyWithinRange)\n ) {\n continue\n }\n\n if (!activeFence) {\n const splitLine = splitLineBeforeInlineMdxFenceOpener(lineText)\n if (splitLine) {\n const replacement = [\n ...splitAdjacentMarkupTags(splitLine.before),\n splitLine.fenceLine,\n ].join('\\n')\n pushLineReplacement(edits, line.range, lineText, replacement)\n\n const delimiter = parseMdxFenceDelimiter(splitLine.fenceLine.trim())\n activeFence = delimiter\n ? { length: delimiter.length, marker: delimiter.marker }\n : undefined\n continue\n }\n\n const delimiter = parseMdxFenceDelimiter(trimmed)\n if (!delimiter) continue\n\n pushLineReplacement(\n edits,\n line.range,\n lineText,\n trimLineStartIndent(lineText),\n )\n activeFence = { length: delimiter.length, marker: delimiter.marker }\n continue\n }\n\n const splitClosingPrefix = splitLineAfterInlineMdxFenceCloser(\n lineText,\n activeFence,\n )\n if (splitClosingPrefix) {\n const replacement = [\n trimLineStartIndent(splitClosingPrefix.fenceLine),\n splitClosingPrefix.after,\n ].join('\\n')\n pushLineReplacement(edits, line.range, lineText, replacement)\n activeFence = undefined\n continue\n }\n\n const splitClosingSuffix = splitLineBeforeInlineMdxFenceCloser(\n lineText,\n activeFence,\n )\n if (splitClosingSuffix) {\n const replacement = [\n splitClosingSuffix.before,\n trimLineStartIndent(splitClosingSuffix.fenceLine),\n ].join('\\n')\n pushLineReplacement(edits, line.range, lineText, replacement)\n activeFence = undefined\n continue\n }\n\n const delimiter = parseMdxFenceDelimiter(trimmed)\n if (!delimiter || !isMdxFenceClosingDelimiter(delimiter, activeFence)) {\n continue\n }\n\n pushLineReplacement(\n edits,\n line.range,\n lineText,\n trimLineStartIndent(lineText),\n )\n activeFence = undefined\n }\n\n return edits.map((edit) => ({\n ...edit,\n newText: document.preserveEol(edit.newText),\n }))\n}\n\nexport function maskMdxFencedRegions(source: string) {\n const fences: MdxFencePlaceholder[] = []\n const lines = splitInlineMdxFenceDelimiters(source).split('\\n')\n const placeholderLines: string[] = []\n\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const openingDelimiter = parseMdxFenceDelimiter(lines[lineIndex].trim())\n if (!openingDelimiter) {\n placeholderLines.push(lines[lineIndex])\n continue\n }\n\n let closingLineIndex = -1\n for (\n let candidateLineIndex = lineIndex + 1;\n candidateLineIndex < lines.length;\n candidateLineIndex++\n ) {\n const closingDelimiter = parseMdxFenceDelimiter(\n lines[candidateLineIndex].trim(),\n )\n if (\n closingDelimiter &&\n isMdxFenceClosingDelimiter(closingDelimiter, openingDelimiter)\n ) {\n closingLineIndex = candidateLineIndex\n break\n }\n }\n\n if (closingLineIndex === -1) {\n placeholderLines.push(lines[lineIndex])\n continue\n }\n\n const placeholder = `<!--PURESTACK_MDX_FENCE_${fences.length}-->`\n fences.push({\n placeholder,\n source: normalizeMdxFenceDelimiterIndent(\n lines.slice(lineIndex, closingLineIndex + 1),\n ),\n })\n placeholderLines.push(placeholder)\n lineIndex = closingLineIndex\n }\n\n return { fences, placeholderContent: placeholderLines.join('\\n') }\n}\n\nexport function restoreMdxFencedRegions(\n formatted: string,\n fences: MdxFencePlaceholder[],\n) {\n let restored = formatted\n\n for (const fence of fences) {\n const standalonePlaceholderPattern = new RegExp(\n `^[\\\\t ]*${escapeRegExp(fence.placeholder)}$`,\n 'gm',\n )\n if (standalonePlaceholderPattern.test(restored)) {\n restored = restored.replace(standalonePlaceholderPattern, fence.source)\n continue\n }\n\n restored = restored.split(fence.placeholder).join(fence.source)\n }\n\n return restored\n}\n\nexport function parseMdxFenceDelimiter(\n trimmed: string,\n): MdxFenceDelimiter | undefined {\n const match = /^(`{3,}|~{3,})(.*)$/.exec(trimmed)\n if (!match) return undefined\n\n return {\n length: match[1].length,\n marker: match[1].startsWith('`') ? '`' : '~',\n suffix: match[2],\n }\n}\n\nexport function parseInlineMdxFenceOpener(trimmed: string) {\n const splitLine = splitLineBeforeInlineMdxFenceOpener(trimmed)\n if (!splitLine) return undefined\n\n return parseMdxFenceDelimiter(splitLine.fenceLine.trim())\n}\n\nexport function parseInlineMdxFenceCloser(\n trimmed: string,\n activeFence: MdxFence,\n) {\n const splitLine = splitLineAfterInlineMdxFenceCloser(trimmed, activeFence)\n if (splitLine) return parseMdxFenceDelimiter(splitLine.fenceLine.trim())\n\n const trailingSplitLine = splitLineBeforeInlineMdxFenceCloser(\n trimmed,\n activeFence,\n )\n if (!trailingSplitLine) return undefined\n\n return parseMdxFenceDelimiter(trailingSplitLine.fenceLine.trim())\n}\n\nexport function isMdxFenceClosingDelimiter(\n delimiter: MdxFenceDelimiter,\n activeFence: MdxFence,\n) {\n return (\n delimiter.marker === activeFence.marker &&\n delimiter.length >= activeFence.length &&\n delimiter.suffix.trim().length === 0\n )\n}\n\nfunction splitInlineMdxFenceDelimiters(source: string) {\n const lines = source.split('\\n')\n const splitLines: string[] = []\n let activeFence: MdxFence | undefined\n\n for (const line of lines) {\n if (!activeFence) {\n const splitLine = splitLineBeforeInlineMdxFenceOpener(line)\n if (splitLine) {\n splitLines.push(\n ...splitAdjacentMarkupTags(splitLine.before),\n splitLine.fenceLine,\n )\n\n const delimiter = parseMdxFenceDelimiter(splitLine.fenceLine.trim())\n activeFence = delimiter\n ? { length: delimiter.length, marker: delimiter.marker }\n : undefined\n continue\n }\n\n splitLines.push(line)\n\n const delimiter = parseMdxFenceDelimiter(line.trim())\n if (!delimiter) continue\n activeFence = { length: delimiter.length, marker: delimiter.marker }\n continue\n }\n\n const splitClosingLine = splitLineAfterInlineMdxFenceCloser(\n line,\n activeFence,\n )\n if (splitClosingLine) {\n splitLines.push(splitClosingLine.fenceLine, splitClosingLine.after)\n activeFence = undefined\n continue\n }\n\n const splitTrailingClosingLine = splitLineBeforeInlineMdxFenceCloser(\n line,\n activeFence,\n )\n if (splitTrailingClosingLine) {\n splitLines.push(\n splitTrailingClosingLine.before,\n splitTrailingClosingLine.fenceLine,\n )\n activeFence = undefined\n continue\n }\n\n splitLines.push(line)\n\n const delimiter = parseMdxFenceDelimiter(line.trim())\n if (!delimiter) continue\n\n if (isMdxFenceClosingDelimiter(delimiter, activeFence)) {\n activeFence = undefined\n }\n }\n\n return splitLines.join('\\n')\n}\n\nfunction splitLineBeforeInlineMdxFenceOpener(line: string) {\n if (parseMdxFenceDelimiter(line.trim())) return undefined\n\n const match = /`{3}|~{3}/.exec(line)\n if (!match) return undefined\n\n const before = line.slice(0, match.index).trimEnd()\n if (before.trim().length === 0) return undefined\n\n return {\n before,\n fenceLine: line.slice(match.index),\n }\n}\n\nfunction splitAdjacentMarkupTags(line: string) {\n const tokens = scanTagTokens(line)\n if (tokens.length < 2) return [line]\n\n let cursor = 0\n const lines: string[] = []\n const indent = /^\\s*/.exec(line)?.[0] ?? ''\n\n for (const token of tokens) {\n if (line.slice(cursor, token.start).trim().length > 0) return [line]\n\n const tag = line.slice(token.start, token.end)\n lines.push(lines.length === 0 ? `${indent}${tag}` : tag)\n cursor = token.end\n }\n\n if (line.slice(cursor).trim().length > 0) return [line]\n\n return lines\n}\n\nfunction splitLineBeforeInlineMdxFenceCloser(\n line: string,\n activeFence: MdxFence,\n) {\n let end = line.length\n while (end > 0 && (line[end - 1] === '\\t' || line[end - 1] === ' ')) end--\n let start = end\n while (start > 0 && line[start - 1] === activeFence.marker) start--\n if (end - start < activeFence.length) return undefined\n\n const before = line.slice(0, start).trimEnd()\n if (before.trim().length === 0) return undefined\n\n return {\n before,\n fenceLine: line.slice(start, end),\n }\n}\n\nfunction splitLineAfterInlineMdxFenceCloser(\n line: string,\n activeFence: MdxFence,\n) {\n const pattern = new RegExp(\n `^([\\\\t ]*${escapeRegExp(activeFence.marker.repeat(activeFence.length))}${escapeRegExp(activeFence.marker)}*)(.*)$`,\n )\n const match = pattern.exec(line)\n if (!match || match[2].trim().length === 0) return undefined\n\n const closingDelimiter = parseMdxFenceDelimiter(match[1].trim())\n if (!closingDelimiter) return undefined\n if (!isMdxFenceClosingDelimiter(closingDelimiter, activeFence)) {\n return undefined\n }\n\n return {\n fenceLine: match[1],\n after: match[2],\n }\n}\n\nfunction normalizeMdxFenceDelimiterIndent(lines: string[]) {\n if (lines.length < 2) return lines.join('\\n')\n\n const normalizedLines = [...lines]\n normalizedLines[0] = trimLineStartIndent(normalizedLines[0])\n normalizedLines[normalizedLines.length - 1] = trimLineStartIndent(\n normalizedLines[normalizedLines.length - 1],\n )\n return normalizedLines.join('\\n')\n}\n\nfunction trimLineStartIndent(line: string) {\n return line.replace(/^[\\t ]+/, '')\n}\n\nfunction pushLineReplacement(\n edits: SourceEdit[],\n range: SourceRange,\n oldText: string,\n newText: string,\n) {\n if (newText === oldText) return\n\n edits.push({ ...range, newText })\n}\n\nfunction isLineInsideAnyRange(line: SourceRange, ranges: SourceRange[]) {\n return ranges.some(\n (range) => line.start >= range.start && line.end <= range.end,\n )\n}\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n","import htmlPlugin from 'prettier/plugins/html'\nimport postcssPlugin from 'prettier/plugins/postcss'\nimport prettier from 'prettier/standalone'\n\nconst RAW_TEXT_TAG =\n 'script|style|textarea|title|xmp|iframe|noembed|noframes|plaintext'\nconst TAG_BODY = `(?:\"[^\"]*\"|'[^']*'|[^\"'>])*>`\n\n/**\n * Skips comments, raw text and opening tags; captures closing tags broken before `>`.\n * Case-sensitive so PascalCase components such as `<Title>` are not raw text.\n */\nconst BROKEN_CLOSING_TAG = new RegExp(\n [\n String.raw`<!--[\\s\\S]*?-->`,\n String.raw`<(${RAW_TEXT_TAG})\\b${TAG_BODY}[\\s\\S]*?</\\1\\s*>`,\n `<[A-Za-z]${TAG_BODY}`,\n String.raw`(</[^\\s>]+)\\s*\\n\\s*>`,\n ].join('|'),\n 'g',\n)\n\nexport interface HtmlFormattingOptions {\n printWidth: number\n tabSize: number\n useTabs: boolean\n}\n\nexport async function formatHtmlFragment(\n source: string,\n options: HtmlFormattingOptions,\n) {\n const formatted = await prettier.format(source, {\n htmlWhitespaceSensitivity: 'css',\n parser: 'html',\n plugins: [htmlPlugin, postcssPlugin],\n printWidth: options.printWidth,\n tabWidth: options.tabSize,\n useTabs: options.useTabs,\n })\n return normalizeClosingTagSpacing(formatted)\n}\n\n/** Keep closing tags readable without inserting whitespace into inline content. */\nexport function normalizeClosingTagSpacing(source: string) {\n return source.replace(\n BROKEN_CLOSING_TAG,\n (match, _rawTextTag: string, closingTag?: string) =>\n closingTag ? `${closingTag}>` : match,\n )\n}\n\nexport function getLineIndent(line: string) {\n const match = /^\\s*/.exec(line)\n return match?.[0] ?? ''\n}\n\nexport function normalizeSelfClosingTagSpacing(formatted: string) {\n // Match each whitespace run once, even when no /> follows it.\n return formatted.replace(/\\s+/g, (whitespace, offset: number) =>\n formatted.startsWith('/>', offset + whitespace.length) ? '' : whitespace,\n )\n}\n","import { maskRegorExpressions, restoreRegorExpressions } from './expressions'\nimport {\n buildMdxFenceDelimiterEdits,\n isMdxFenceClosingDelimiter,\n maskMdxFencedRegions,\n parseInlineMdxFenceCloser,\n parseInlineMdxFenceOpener,\n parseMdxFenceDelimiter,\n restoreMdxFencedRegions,\n} from './fences'\nimport { formatHtmlFragment, normalizeSelfClosingTagSpacing } from './html'\nimport {\n findMdxExpressionEnd,\n findTagEnd,\n isMdxExpressionStart,\n scanTagTokens,\n VOID_HTML_TAG_NAMES,\n} from './markup'\nimport {\n intersects,\n type SourceEdit,\n type SourceRange,\n type SourceText,\n} from './source'\n\nexport interface MdxMarkupBlock {\n content: string\n range: SourceRange\n}\n\ninterface MdxExpressionPlaceholder {\n placeholder: string\n source: string\n}\n\ninterface MdxInlineCodePlaceholder {\n placeholder: string\n source: string\n}\n\ninterface MdxFormattingRequest {\n onlyWithinRange?: SourceRange\n}\n\ninterface MdxMarkupBlockOptions {\n includeIncomplete?: boolean\n}\n\ninterface MdxBlockScanState {\n activeEndLine?: number\n activeLines: string[]\n activeStartLine?: number\n fenceLength?: number\n fenceMarker?: '`' | '~'\n frontmatterHandled: boolean\n inFence: boolean\n inFrontmatter: boolean\n}\n\nexport async function buildMdxFormattingEdits(\n document: SourceText,\n request: MdxFormattingRequest = {},\n) {\n const blocks = getMdxMarkupBlocks(document, {\n includeIncomplete: true,\n }).filter((block) =>\n request.onlyWithinRange\n ? intersects(block.range, request.onlyWithinRange)\n : true,\n )\n\n const edits: SourceEdit[] = []\n const blockRanges = blocks.map((block) => block.range)\n\n for (const block of blocks) {\n const formatted = await formatMdxMarkupBlock(document, block)\n if (!formatted || formatted === block.content) continue\n\n edits.push({ ...block.range, newText: document.preserveEol(formatted) })\n }\n\n edits.push(\n ...buildMdxFenceDelimiterEdits(document, blockRanges, {\n onlyWithinRange: request.onlyWithinRange,\n }),\n )\n\n return edits\n}\n\nexport function getMdxMarkupBlocks(\n document: SourceText,\n options: MdxMarkupBlockOptions = {},\n) {\n const blocks: MdxMarkupBlock[] = []\n const state: MdxBlockScanState = {\n activeEndLine: undefined,\n activeLines: [],\n frontmatterHandled: false,\n inFence: false,\n inFrontmatter: false,\n }\n\n for (let lineIndex = 0; lineIndex < document.lineCount; lineIndex++) {\n const lineText = document.lineAt(lineIndex).text\n const trimmed = lineText.trim()\n\n if (startMdxFrontmatter(lineIndex, trimmed, state)) {\n continue\n }\n\n if (closeMdxFrontmatter(trimmed, state)) {\n continue\n }\n\n collectActiveMarkupBlock(\n blocks,\n document,\n lineIndex,\n lineText,\n trimmed,\n state,\n )\n }\n\n if (\n options.includeIncomplete &&\n state.activeStartLine !== undefined &&\n state.activeEndLine !== undefined\n ) {\n pushActiveBlock(\n blocks,\n document,\n state.activeStartLine,\n state.activeEndLine,\n state.activeLines,\n )\n }\n\n return blocks\n}\n\nfunction pushActiveBlock(\n blocks: MdxMarkupBlock[],\n document: SourceText,\n startLine: number,\n endLine: number,\n lines: string[],\n) {\n const start = document.lineAt(startLine).range.start\n const end = document.lineAt(endLine).range.end\n blocks.push({\n content: lines.join('\\n'),\n range: { start, end },\n })\n}\n\nfunction looksLikeMarkupBlockStart(trimmedLine: string) {\n return /^<[A-Za-z][A-Za-z0-9._:$-]*/.test(trimmedLine)\n}\n\nfunction isCompleteMarkupBlock(markup: string) {\n const { placeholderContent } = maskMdxFencedRegions(markup)\n if (!placeholderContent.includes('<')) return false\n if (hasUnterminatedTag(placeholderContent)) return false\n\n return getUnclosedTagNames(placeholderContent).length === 0\n}\n\nasync function formatMdxMarkupBlock(\n document: SourceText,\n block: MdxMarkupBlock,\n) {\n const formattingOptions = document.options\n const { fences, placeholderContent: fencePlaceholderContent } =\n maskMdxFencedRegions(block.content.trim())\n const { inlineCodeSpans, placeholderContent: inlineCodePlaceholderContent } =\n maskMdxInlineCodeSpans(fencePlaceholderContent)\n const {\n expressions: regorExpressions,\n placeholderContent: regorPlaceholderContent,\n } = maskRegorExpressions(inlineCodePlaceholderContent)\n const { expressions, placeholderContent } = maskMdxExpressions(\n regorPlaceholderContent,\n )\n if (!placeholderContent.includes('<')) return undefined\n\n let formatted: string\n try {\n formatted = await formatHtmlFragment(placeholderContent, formattingOptions)\n } catch (error) {\n document.report(block.range, error)\n return undefined\n }\n\n const restoredExpressions = restoreMdxExpressions(\n normalizeSelfClosingTagSpacing(formatted.trim()),\n expressions,\n )\n const restoredRegorExpressions = restoreRegorExpressions(\n restoredExpressions,\n regorExpressions,\n )\n const restoredInlineCode = restoreMdxInlineCodeSpans(\n restoredRegorExpressions,\n inlineCodeSpans,\n )\n\n return restoreMdxFencedRegions(restoredInlineCode, fences)\n}\n\nfunction maskMdxInlineCodeSpans(source: string) {\n const inlineCodeSpans: MdxInlineCodePlaceholder[] = []\n const lines = source.split('\\n')\n const placeholderLines = lines.map((line) =>\n maskMdxInlineCodeSpansInLine(line, inlineCodeSpans),\n )\n\n return {\n inlineCodeSpans,\n placeholderContent: placeholderLines.join('\\n'),\n }\n}\n\nfunction maskMdxInlineCodeSpansInLine(\n line: string,\n inlineCodeSpans: MdxInlineCodePlaceholder[],\n) {\n let placeholderLine = ''\n\n for (let index = 0; index < line.length; ) {\n const start = line.indexOf('`', index)\n if (start === -1) {\n placeholderLine += line.slice(index)\n break\n }\n\n const tickCount = countRepeatedChar(line, start, '`')\n if (tickCount !== 1) {\n placeholderLine += line.slice(index, start + tickCount)\n index = start + tickCount\n continue\n }\n\n const end = findMdxInlineCodeEnd(line, start + 1)\n if (end === -1) {\n placeholderLine += line.slice(index)\n break\n }\n\n const source = line.slice(start, end + 1)\n const placeholder = createMdxInlineCodePlaceholder(\n inlineCodeSpans.length,\n line,\n start,\n end + 1,\n )\n inlineCodeSpans.push({ placeholder, source })\n placeholderLine += line.slice(index, start)\n placeholderLine += placeholder\n index = end + 1\n }\n\n return placeholderLine\n}\n\nfunction createMdxInlineCodePlaceholder(\n index: number,\n line: string,\n start: number,\n end: number,\n) {\n const lineBefore = line.slice(0, start)\n const lineAfter = line.slice(end)\n if (lineBefore.trim().length === 0 && lineAfter.trim().length === 0) {\n return `<!--PURESTACK_MDX_INLINE_CODE_${index}-->`\n }\n\n return `PURESTACK_MDX_INLINE_CODE_${index}`\n}\n\nfunction restoreMdxInlineCodeSpans(\n formatted: string,\n inlineCodeSpans: MdxInlineCodePlaceholder[],\n) {\n let restored = formatted\n\n for (const inlineCodeSpan of sortLongestPlaceholderFirst(inlineCodeSpans)) {\n restored = restored\n .split(inlineCodeSpan.placeholder)\n .join(inlineCodeSpan.source)\n }\n\n return restored\n}\n\nexport function maskMdxExpressions(source: string) {\n const expressions: MdxExpressionPlaceholder[] = []\n let placeholderContent = ''\n\n for (let index = 0; index < source.length; ) {\n const rawTextEnd = findRawTextElementEnd(source, index)\n if (rawTextEnd !== undefined) {\n placeholderContent += source.slice(index, rawTextEnd)\n index = rawTextEnd\n continue\n }\n\n if (!isMdxExpressionStart(source, index)) {\n placeholderContent += source[index]\n index++\n continue\n }\n\n const expressionEnd = findMdxExpressionEnd(source, index)\n if (expressionEnd === -1) {\n placeholderContent += source[index]\n index++\n continue\n }\n\n const placeholder = `PURESTACK_MDX_EXPR_${expressions.length}`\n expressions.push({\n placeholder,\n source: source.slice(index, expressionEnd),\n })\n placeholderContent += placeholder\n index = expressionEnd\n }\n\n return { expressions, placeholderContent }\n}\n\nfunction restoreMdxExpressions(\n formatted: string,\n expressions: MdxExpressionPlaceholder[],\n) {\n let restored = formatted\n\n for (const expression of sortLongestPlaceholderFirst(expressions)) {\n restored = restored.split(expression.placeholder).join(expression.source)\n }\n\n return restored\n}\n\nfunction hasUnterminatedTag(markup: string) {\n for (let index = 0; index < markup.length; index++) {\n if (markup[index] !== '<') continue\n\n if (markup.startsWith('<!--', index)) {\n const commentEnd = markup.indexOf('-->', index + 4)\n if (commentEnd === -1) return true\n index = commentEnd + 2\n continue\n }\n\n const nextTagEnd = findTagEnd(markup, index + 1)\n if (nextTagEnd === -1) return true\n index = nextTagEnd\n }\n\n return false\n}\n\nfunction startMdxFrontmatter(\n lineIndex: number,\n trimmed: string,\n state: MdxBlockScanState,\n) {\n if (state.frontmatterHandled || lineIndex !== 0 || trimmed !== '---') {\n return false\n }\n\n state.inFrontmatter = true\n state.frontmatterHandled = true\n return true\n}\n\nfunction closeMdxFrontmatter(trimmed: string, state: MdxBlockScanState) {\n if (!state.inFrontmatter) return false\n\n if (trimmed === '---') {\n state.inFrontmatter = false\n }\n\n return true\n}\n\nfunction updateMdxFenceState(trimmed: string, state: MdxBlockScanState) {\n const activeFence =\n state.fenceMarker && state.fenceLength\n ? { length: state.fenceLength, marker: state.fenceMarker }\n : undefined\n const delimiter =\n state.inFence && activeFence\n ? (parseInlineMdxFenceCloser(trimmed, activeFence) ??\n parseMdxFenceDelimiter(trimmed))\n : (parseMdxFenceDelimiter(trimmed) ?? parseInlineMdxFenceOpener(trimmed))\n if (!delimiter) return state.inFence\n\n if (!state.inFence) {\n state.inFence = true\n state.fenceLength = delimiter.length\n state.fenceMarker = delimiter.marker\n return true\n }\n\n if (\n state.fenceMarker &&\n state.fenceLength &&\n isMdxFenceClosingDelimiter(delimiter, {\n length: state.fenceLength,\n marker: state.fenceMarker,\n })\n ) {\n state.inFence = false\n state.fenceLength = undefined\n state.fenceMarker = undefined\n }\n\n return true\n}\n\nfunction collectActiveMarkupBlock(\n blocks: MdxMarkupBlock[],\n document: SourceText,\n lineIndex: number,\n lineText: string,\n trimmed: string,\n state: MdxBlockScanState,\n) {\n if (state.activeStartLine === undefined) {\n if (state.inFence) {\n updateMdxFenceState(trimmed, state)\n return\n }\n\n if (!looksLikeMarkupBlockStart(trimmed)) {\n if (updateMdxFenceState(trimmed, state)) return\n return\n }\n\n state.activeStartLine = lineIndex\n state.activeEndLine = lineIndex\n state.activeLines = [lineText]\n } else {\n state.activeEndLine = lineIndex\n state.activeLines.push(lineText)\n }\n\n updateMdxFenceState(trimmed, state)\n if (state.inFence) return\n if (!isCompleteMarkupBlock(state.activeLines.join('\\n'))) return\n\n pushActiveBlock(\n blocks,\n document,\n state.activeStartLine,\n state.activeEndLine ?? lineIndex,\n state.activeLines,\n )\n state.activeEndLine = undefined\n state.activeStartLine = undefined\n state.activeLines = []\n}\n\nfunction getUnclosedTagNames(markup: string) {\n const stack: string[] = []\n\n for (const token of scanTagTokens(markup)) {\n if (token.kind === 'opening') {\n if (isSelfContainedTag(token.name, token.selfClosing)) continue\n\n stack.push(token.name)\n continue\n }\n\n closeMatchingTag(stack, token.name)\n }\n\n return stack\n}\n\nfunction isSelfContainedTag(tagName: string, selfClosing: boolean) {\n return selfClosing || VOID_HTML_TAG_NAMES.has(tagName.toLowerCase())\n}\n\nfunction closeMatchingTag(stack: string[], tagName: string) {\n for (let index = stack.length - 1; index >= 0; index--) {\n if (stack[index] !== tagName) continue\n stack.splice(index)\n return\n }\n}\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction sortLongestPlaceholderFirst<T extends { placeholder: string }>(\n placeholders: T[],\n) {\n return [...placeholders].sort(\n (left, right) => right.placeholder.length - left.placeholder.length,\n )\n}\n\nfunction findMdxInlineCodeEnd(line: string, startIndex: number) {\n for (let index = startIndex; index < line.length; index++) {\n if (line[index] === '`') return index\n }\n\n return -1\n}\n\nfunction countRepeatedChar(line: string, startIndex: number, char: string) {\n let count = 0\n\n while (line[startIndex + count] === char) {\n count++\n }\n\n return count\n}\n\nfunction findRawTextElementEnd(source: string, startIndex: number) {\n if (source[startIndex] !== '<' || source[startIndex + 1] === '/') {\n return undefined\n }\n\n const tagEnd = findTagEnd(source, startIndex + 1)\n if (tagEnd === -1) return undefined\n\n const openingTag = source.slice(startIndex, tagEnd + 1)\n const tagName = /^<\\s*(script|style)\\b/i.exec(openingTag)?.[1]\n if (!tagName) return undefined\n\n const closingTagPattern = new RegExp(\n `<\\\\/\\\\s*${escapeRegExp(tagName)}\\\\s*>`,\n 'i',\n )\n const closingTagMatch = closingTagPattern.exec(source.slice(tagEnd + 1))\n if (!closingTagMatch) return undefined\n\n return tagEnd + 1 + closingTagMatch.index + closingTagMatch[0].length\n}\n","import type * as TypeScript from 'typescript-parser'\nimport ts from 'typescript-parser'\nimport { maskRegorExpressions, restoreRegorExpressions } from './expressions'\n\nimport { formatHtmlFragment, normalizeSelfClosingTagSpacing } from './html'\nimport {\n intersects,\n type SourceEdit,\n type SourceRange,\n type SourceText,\n} from './source'\n\nexport type SupportedTemplateTagName = 'html' | 'svg'\n\nexport interface SupportedTaggedTemplate {\n content: string\n contentRange: SourceRange\n expressions: TemplateExpressionPlaceholder[]\n interpolationRanges: Array<{ start: number; end: number }>\n placeholderContent: string\n tagName: SupportedTemplateTagName\n}\n\ninterface TemplateExpressionPlaceholder {\n placeholder: string\n source: string\n}\n\nconst SUPPORTED_TEMPLATE_TAG_NAMES: SupportedTemplateTagName[] = ['html', 'svg']\n\ninterface TemplateFormattingRequest {\n onlyWithinRange?: SourceRange\n}\n\nexport async function buildTemplateFormattingEdits(\n document: SourceText,\n request: TemplateFormattingRequest = {},\n) {\n const templates = getSupportedTaggedTemplates(document).filter((template) =>\n request.onlyWithinRange\n ? intersects(template.contentRange, request.onlyWithinRange)\n : true,\n )\n if (templates.length === 0) return []\n\n const edits: SourceEdit[] = []\n\n for (const template of templates) {\n const formatted = await formatTaggedTemplate(document, template)\n if (!formatted || formatted === template.content) continue\n\n edits.push({\n ...template.contentRange,\n newText: document.preserveEol(formatted),\n })\n }\n\n return edits\n}\n\nexport function getSupportedTaggedTemplates(\n document: SourceText,\n): SupportedTaggedTemplate[] {\n const sourceText = document.text\n const sourceFile = ts.createSourceFile(\n document.filePath,\n sourceText,\n ts.ScriptTarget.Latest,\n false,\n ts.ScriptKind.TS,\n )\n const templates: SupportedTaggedTemplate[] = []\n\n visitNode(sourceFile)\n return templates\n\n function visitNode(node: TypeScript.Node) {\n if (ts.isTaggedTemplateExpression(node)) {\n const template = createSupportedTaggedTemplate(node, sourceFile)\n if (template) {\n templates.push(template)\n // The outer template owns its interpolations; never emit overlapping edits.\n return\n }\n }\n\n ts.forEachChild(node, visitNode)\n }\n}\n\nexport function isOffsetInsideSupportedTaggedTemplate(\n sourceFile: TypeScript.SourceFile,\n offset: number,\n) {\n let isInsideTemplate = false\n\n visitNode(sourceFile)\n return isInsideTemplate\n\n function visitNode(node: TypeScript.Node) {\n if (isInsideTemplate) return\n if (offset < node.getStart(sourceFile) || offset >= node.getEnd()) return\n\n if (ts.isTaggedTemplateExpression(node)) {\n const templateTagName = getSupportedTemplateTagName(\n node.tag.getText(sourceFile),\n )\n if (!templateTagName) {\n ts.forEachChild(node, visitNode)\n return\n }\n\n const template = node.template\n if (\n offset >= template.getStart(sourceFile) &&\n offset < template.getEnd()\n ) {\n isInsideTemplate = true\n return\n }\n }\n\n ts.forEachChild(node, visitNode)\n }\n}\n\nfunction createSupportedTaggedTemplate(\n node: TypeScript.TaggedTemplateExpression,\n sourceFile: TypeScript.SourceFile,\n) {\n const tagName = getSupportedTemplateTagName(node.tag.getText(sourceFile))\n if (!tagName) return undefined\n\n const template = node.template\n if (isLikelyPrematureRawBacktickClose(sourceFile.text, template)) {\n return undefined\n }\n\n const innerStart = template.getStart(sourceFile) + 1\n const innerEnd = template.getEnd() - 1\n if (innerEnd < innerStart) return undefined\n\n const contentRange = { start: innerStart, end: innerEnd }\n\n if (ts.isNoSubstitutionTemplateLiteral(template)) {\n const content = sourceFile.text.slice(innerStart, innerEnd)\n return {\n content,\n contentRange,\n expressions: [],\n interpolationRanges: [],\n placeholderContent: content,\n tagName,\n }\n }\n\n const expressions: TemplateExpressionPlaceholder[] = []\n const interpolationRanges: Array<{ start: number; end: number }> = []\n let placeholderContent = sliceTemplateHeadContent(template.head, sourceFile)\n let currentContentOffset = placeholderContent.length\n\n template.templateSpans.forEach((span, index) => {\n const placeholder = `PURESTACK_EXPR_${index}_${tagName.toUpperCase()}`\n const interpolationEnd = span.literal.getStart(sourceFile) - innerStart + 1\n expressions.push({\n placeholder,\n source: sourceFile.text.slice(\n span.expression.getStart(sourceFile),\n span.expression.getEnd(),\n ),\n })\n interpolationRanges.push({\n start: currentContentOffset,\n end: interpolationEnd,\n })\n placeholderContent += placeholder\n const literalContent = sliceTemplateSpanLiteralContent(\n span.literal,\n sourceFile,\n )\n placeholderContent += literalContent\n currentContentOffset = interpolationEnd + literalContent.length\n })\n\n return {\n content: sourceFile.text.slice(innerStart, innerEnd),\n contentRange,\n expressions,\n interpolationRanges,\n placeholderContent,\n tagName,\n }\n}\n\nfunction getSupportedTemplateTagName(tagText: string) {\n const normalizedTag = tagText.trim()\n\n for (const tagName of SUPPORTED_TEMPLATE_TAG_NAMES) {\n if (normalizedTag === tagName || normalizedTag.endsWith(`.${tagName}`)) {\n return tagName\n }\n }\n\n return undefined\n}\n\nfunction isLikelyPrematureRawBacktickClose(\n sourceText: string,\n template: TypeScript.TemplateLiteral,\n) {\n return sourceText.startsWith('``', template.getEnd())\n}\n\nfunction sliceTemplateHeadContent(\n head: TypeScript.TemplateHead,\n sourceFile: TypeScript.SourceFile,\n) {\n return sourceFile.text.slice(head.getStart(sourceFile) + 1, head.getEnd() - 2)\n}\n\nfunction sliceTemplateSpanLiteralContent(\n literal: TypeScript.TemplateMiddle | TypeScript.TemplateTail,\n sourceFile: TypeScript.SourceFile,\n) {\n const endOffset = ts.isTemplateTail(literal) ? 1 : 2\n return sourceFile.text.slice(\n literal.getStart(sourceFile) + 1,\n literal.getEnd() - endOffset,\n )\n}\n\nasync function formatTaggedTemplate(\n document: SourceText,\n template: SupportedTaggedTemplate,\n) {\n const formattingOptions = document.options\n const source = template.placeholderContent.trim()\n const { expressions: regorExpressions, placeholderContent } =\n maskRegorExpressions(source)\n\n if (!placeholderContent.includes('<')) return undefined\n\n let formatted: string\n try {\n formatted = await formatHtmlFragment(placeholderContent, formattingOptions)\n } catch (error) {\n document.report(template.contentRange, error)\n return undefined\n }\n\n const restoredTemplateExpressions = restoreTemplateExpressions(\n normalizeSelfClosingTagSpacing(formatted.trim()),\n template.expressions,\n )\n\n return restoreRegorExpressions(restoredTemplateExpressions, regorExpressions)\n}\n\nfunction restoreTemplateExpressions(\n formatted: string,\n expressions: TemplateExpressionPlaceholder[],\n) {\n let restored = formatted\n\n for (const expression of expressions) {\n restored = restored\n .split(expression.placeholder)\n .join(`\\${${expression.source}}`)\n }\n\n return restored\n}\n","import { buildMdxFormattingEdits } from './mdx'\nimport { applySourceEdits, type FormatOptions, SourceText } from './source'\nimport { buildTemplateFormattingEdits } from './templates'\n\nexport {\n maskRegorExpressions,\n type RegorExpressionPlaceholder,\n restoreRegorExpressions,\n} from './expressions'\nexport * from './fences'\nexport * from './html'\nexport * from './markup'\nexport * from './mdx'\nexport * from './source'\nexport * from './templates'\n\n/** Formats only component markup and html/svg tagged template contents. */\nexport async function formatSource(text: string, options: FormatOptions = {}) {\n const source = new SourceText(text, options)\n const language =\n options.language ??\n (/\\.[cm]?tsx?$/i.test(source.filePath) ? 'typescript' : 'mdx')\n const edits = await (language === 'typescript'\n ? buildTemplateFormattingEdits(source, options)\n : buildMdxFormattingEdits(source, options))\n const code = applySourceEdits(text, edits)\n return {\n code,\n edits,\n diagnostics: source.diagnostics,\n changed: code !== text,\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ts-format.mjs","names":["escapeRegExp"],"sources":["../src/markup.ts","../src/expressions.ts","../src/source.ts","../src/fences.ts","../src/html.ts","../src/mdx.ts","../src/templates.ts","../src/index.ts"],"sourcesContent":["export const VOID_HTML_TAG_NAMES = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n])\n\nexport interface TagToken {\n end: number\n kind: 'closing' | 'opening'\n name: string\n nameEnd: number\n nameStart: number\n selfClosing: boolean\n start: number\n}\n\nexport function scanTagTokens(markup: string) {\n const tokens: TagToken[] = []\n\n for (let index = 0; index < markup.length; index++) {\n if (markup[index] !== '<') continue\n\n if (markup.startsWith('<!--', index)) {\n const commentEnd = markup.indexOf('-->', index + 4)\n if (commentEnd === -1) break\n index = commentEnd + 2\n continue\n }\n\n const isClosing = markup[index + 1] === '/'\n const nameStart = skipWhitespace(markup, index + (isClosing ? 2 : 1))\n const nameEnd = readTagNameEnd(markup, nameStart)\n if (nameEnd === nameStart) continue\n\n const tagEnd = findTagEnd(markup, nameEnd)\n if (tagEnd === -1) break\n\n const name = markup.slice(nameStart, nameEnd)\n const trailing = markup.slice(nameEnd, tagEnd)\n tokens.push({\n start: index,\n end: tagEnd + 1,\n kind: isClosing ? 'closing' : 'opening',\n name,\n nameStart,\n nameEnd,\n selfClosing: !isClosing && /\\/\\s*$/.test(trailing),\n })\n index = tagEnd\n }\n\n return tokens\n}\n\nexport function isMdxExpressionStart(source: string, index: number) {\n return (\n source[index] === '{' &&\n source[index - 1] !== '{' &&\n source[index + 1] !== '{'\n )\n}\n\nexport function findMdxExpressionEnd(source: string, startIndex: number) {\n let braceDepth = 0\n let quote: '\"' | \"'\" | '`' | undefined\n\n for (let index = startIndex; index < source.length; index++) {\n const current = source[index]\n const previous = source[index - 1]\n\n if (quote) {\n if (current === quote && previous !== '\\\\') {\n quote = undefined\n } else if (\n quote === '`' &&\n current === '$' &&\n source[index + 1] === '{'\n ) {\n const templateExpressionEnd = findMdxExpressionEnd(source, index + 1)\n if (templateExpressionEnd === -1) return -1\n index = templateExpressionEnd - 1\n }\n continue\n }\n\n if (current === '\"' || current === \"'\" || current === '`') {\n quote = current\n continue\n }\n\n if (current === '{') {\n braceDepth++\n continue\n }\n\n if (current !== '}') continue\n\n braceDepth--\n if (braceDepth === 0) return index + 1\n if (braceDepth < 0) return -1\n }\n\n return -1\n}\n\nexport function findTagEnd(markup: string, startIndex: number) {\n let quote: '\"' | \"'\" | undefined\n\n for (let index = startIndex; index < markup.length; index++) {\n const current = markup[index]\n if (quote) {\n if (current === quote && markup[index - 1] !== '\\\\') quote = undefined\n continue\n }\n\n if (current === '\"' || current === \"'\") {\n quote = current\n continue\n }\n\n if (current === '>') return index\n }\n\n return -1\n}\n\nfunction skipWhitespace(markup: string, startIndex: number) {\n let index = startIndex\n while (index < markup.length && /\\s/.test(markup[index])) index++\n return index\n}\n\nfunction readTagNameEnd(markup: string, startIndex: number) {\n let index = startIndex\n while (index < markup.length && /[A-Za-z0-9._:$-]/.test(markup[index])) {\n index++\n }\n return index\n}\n","import { findMdxExpressionEnd } from './markup'\n\nexport interface RegorExpressionPlaceholder {\n placeholder: string\n source: string\n}\n\n/**\n * Protects Regor {{ ... }} expressions while the surrounding markup is\n * formatted as HTML. The expression source is restored byte-for-byte.\n */\nexport function maskRegorExpressions(source: string) {\n const expressions: RegorExpressionPlaceholder[] = []\n let placeholderContent = ''\n let cursor = 0\n\n while (cursor < source.length) {\n const start = source.indexOf('{{', cursor)\n if (start === -1) {\n placeholderContent += source.slice(cursor)\n break\n }\n\n placeholderContent += source.slice(cursor, start)\n\n const end = findRegorExpressionEnd(source, start)\n if (end === -1) {\n // Keep incomplete input untouched rather than guessing its boundary.\n placeholderContent += source.slice(start)\n break\n }\n\n const placeholder = createPlaceholder(source, expressions.length)\n expressions.push({ placeholder, source: source.slice(start, end) })\n placeholderContent += placeholder\n cursor = end\n }\n\n return { expressions, placeholderContent }\n}\n\nexport function restoreRegorExpressions(\n formatted: string,\n expressions: RegorExpressionPlaceholder[],\n) {\n let restored = formatted\n\n for (const expression of expressions) {\n restored = restored.split(expression.placeholder).join(expression.source)\n }\n\n return restored\n}\n\nfunction findRegorExpressionEnd(source: string, start: number) {\n // Reuse the expression scanner already used by MDX. Starting at the first\n // brace makes {{ ... }} two outer brace levels, so nested object literals,\n // quoted braces and template-literal expressions remain balanced correctly.\n const end = findMdxExpressionEnd(source, start)\n if (end === -1) return -1\n\n return source.slice(end - 2, end) === '}}' ? end : -1\n}\n\nfunction createPlaceholder(source: string, index: number) {\n let placeholder = `__PURESTACK_REGOR_EXPR_${index}__`\n\n while (source.includes(placeholder)) {\n placeholder = `_${placeholder}_`\n }\n\n return placeholder\n}\n","import type { HtmlFormattingOptions } from './html'\n\nexport interface SourceRange {\n start: number\n end: number\n}\n\nexport interface SourceEdit extends SourceRange {\n newText: string\n}\n\nexport interface FormatDiagnostic extends SourceRange {\n message: string\n}\n\nexport interface FormatOptions extends Partial<HtmlFormattingOptions> {\n filePath?: string\n language?: 'mdx' | 'typescript'\n onlyWithinRange?: SourceRange\n}\n\nexport function intersects(left: SourceRange, right: SourceRange) {\n return left.start <= right.end && right.start <= left.end\n}\n\n/** Immutable source snapshot. All edit offsets refer to this text. */\nexport class SourceText {\n readonly filePath: string\n readonly options: HtmlFormattingOptions\n readonly diagnostics: FormatDiagnostic[] = []\n private readonly lines: Array<{ text: string; range: SourceRange }> = []\n private readonly eol: '\\n' | '\\r\\n'\n\n constructor(\n readonly text: string,\n options: FormatOptions = {},\n ) {\n this.filePath = options.filePath ?? 'source.mdx'\n this.options = {\n printWidth: options.printWidth ?? 80,\n tabSize: options.tabSize ?? 2,\n useTabs: options.useTabs ?? false,\n }\n for (const value of [this.options.printWidth, this.options.tabSize]) {\n if (!Number.isInteger(value) || value < 1)\n throw new Error('Print width and tab size must be positive integers.')\n }\n this.eol = /\\r\\n/.test(text) ? '\\r\\n' : '\\n'\n let start = 0\n for (const line of text.split('\\n')) {\n const content = line.endsWith('\\r') ? line.slice(0, -1) : line\n this.lines.push({\n text: content,\n range: { start, end: start + content.length },\n })\n start += line.length + 1\n }\n }\n\n get lineCount() {\n return this.lines.length\n }\n\n lineAt(line: number) {\n return this.lines[line]\n }\n\n positionAt(offset: number) {\n const bounded = Math.max(0, Math.min(offset, this.text.length))\n let low = 0\n let high = this.lines.length - 1\n while (low < high) {\n const middle = Math.ceil((low + high) / 2)\n if (this.lines[middle].range.start > bounded) high = middle - 1\n else low = middle\n }\n const line = this.lines[low]\n return {\n line: low,\n character: Math.min(bounded, line.range.end) - line.range.start,\n }\n }\n\n offsetAt(position: { line: number; character: number }) {\n const line =\n this.lines[Math.max(0, Math.min(position.line, this.lines.length - 1))]\n return Math.min(\n line.range.end,\n line.range.start + Math.max(0, position.character),\n )\n }\n\n preserveEol(text: string) {\n return text.replace(/\\r?\\n/g, this.eol)\n }\n\n report(range: SourceRange, error: unknown) {\n this.diagnostics.push({\n ...range,\n message: error instanceof Error ? error.message : String(error),\n })\n }\n}\n\n/** Apply non-overlapping edits against their original snapshot. */\nexport function applySourceEdits(source: string, edits: readonly SourceEdit[]) {\n const ordered = [...edits].sort((a, b) => a.start - b.start || a.end - b.end)\n let cursor = 0\n const parts: string[] = []\n for (const edit of ordered) {\n if (\n edit.start < cursor ||\n edit.end < edit.start ||\n edit.end > source.length\n )\n throw new Error('Formatter returned overlapping or invalid source edits.')\n parts.push(source.slice(cursor, edit.start), edit.newText)\n cursor = edit.end\n }\n parts.push(source.slice(cursor))\n return parts.join('')\n}\n","import { scanTagTokens } from './markup'\nimport {\n intersects,\n type SourceEdit,\n type SourceRange,\n type SourceText,\n} from './source'\n\nexport interface MdxFencePlaceholder {\n placeholder: string\n source: string\n}\n\nexport interface MdxFence {\n length: number\n marker: '`' | '~'\n}\n\nexport interface MdxFenceDelimiter extends MdxFence {\n suffix: string\n}\n\nexport interface MdxFenceDelimiterEditOptions {\n onlyWithinRange?: SourceRange\n}\n\nexport function buildMdxFenceDelimiterEdits(\n document: SourceText,\n excludedRanges: SourceRange[],\n options: MdxFenceDelimiterEditOptions = {},\n) {\n const edits: SourceEdit[] = []\n let activeFence: MdxFence | undefined\n let frontmatterHandled = false\n let inFrontmatter = false\n\n for (let lineIndex = 0; lineIndex < document.lineCount; lineIndex++) {\n const line = document.lineAt(lineIndex)\n const lineText = line.text\n const trimmed = lineText.trim()\n\n if (!frontmatterHandled && lineIndex === 0 && trimmed === '---') {\n frontmatterHandled = true\n inFrontmatter = true\n continue\n }\n\n if (inFrontmatter) {\n if (trimmed === '---') inFrontmatter = false\n continue\n }\n\n if (isLineInsideAnyRange(line.range, excludedRanges)) {\n continue\n }\n\n if (\n options.onlyWithinRange &&\n !intersects(line.range, options.onlyWithinRange)\n ) {\n continue\n }\n\n if (!activeFence) {\n const splitLine = splitLineBeforeInlineMdxFenceOpener(lineText)\n if (splitLine) {\n const replacement = [\n ...splitAdjacentMarkupTags(splitLine.before),\n splitLine.fenceLine,\n ].join('\\n')\n pushLineReplacement(edits, line.range, lineText, replacement)\n\n const delimiter = parseMdxFenceDelimiter(splitLine.fenceLine.trim())\n activeFence = delimiter\n ? { length: delimiter.length, marker: delimiter.marker }\n : undefined\n continue\n }\n\n const delimiter = parseMdxFenceDelimiter(trimmed)\n if (!delimiter) continue\n\n pushLineReplacement(\n edits,\n line.range,\n lineText,\n trimLineStartIndent(lineText),\n )\n activeFence = { length: delimiter.length, marker: delimiter.marker }\n continue\n }\n\n const splitClosingPrefix = splitLineAfterInlineMdxFenceCloser(\n lineText,\n activeFence,\n )\n if (splitClosingPrefix) {\n const replacement = [\n trimLineStartIndent(splitClosingPrefix.fenceLine),\n splitClosingPrefix.after,\n ].join('\\n')\n pushLineReplacement(edits, line.range, lineText, replacement)\n activeFence = undefined\n continue\n }\n\n const splitClosingSuffix = splitLineBeforeInlineMdxFenceCloser(\n lineText,\n activeFence,\n )\n if (splitClosingSuffix) {\n const replacement = [\n splitClosingSuffix.before,\n trimLineStartIndent(splitClosingSuffix.fenceLine),\n ].join('\\n')\n pushLineReplacement(edits, line.range, lineText, replacement)\n activeFence = undefined\n continue\n }\n\n const delimiter = parseMdxFenceDelimiter(trimmed)\n if (!delimiter || !isMdxFenceClosingDelimiter(delimiter, activeFence)) {\n continue\n }\n\n pushLineReplacement(\n edits,\n line.range,\n lineText,\n trimLineStartIndent(lineText),\n )\n activeFence = undefined\n }\n\n return edits.map((edit) => ({\n ...edit,\n newText: document.preserveEol(edit.newText),\n }))\n}\n\nexport function maskMdxFencedRegions(source: string) {\n const fences: MdxFencePlaceholder[] = []\n const lines = splitInlineMdxFenceDelimiters(source).split('\\n')\n const placeholderLines: string[] = []\n\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const openingDelimiter = parseMdxFenceDelimiter(lines[lineIndex].trim())\n if (!openingDelimiter) {\n placeholderLines.push(lines[lineIndex])\n continue\n }\n\n let closingLineIndex = -1\n for (\n let candidateLineIndex = lineIndex + 1;\n candidateLineIndex < lines.length;\n candidateLineIndex++\n ) {\n const closingDelimiter = parseMdxFenceDelimiter(\n lines[candidateLineIndex].trim(),\n )\n if (\n closingDelimiter &&\n isMdxFenceClosingDelimiter(closingDelimiter, openingDelimiter)\n ) {\n closingLineIndex = candidateLineIndex\n break\n }\n }\n\n if (closingLineIndex === -1) {\n placeholderLines.push(lines[lineIndex])\n continue\n }\n\n const placeholder = `<!--PURESTACK_MDX_FENCE_${fences.length}-->`\n fences.push({\n placeholder,\n source: normalizeMdxFenceDelimiterIndent(\n lines.slice(lineIndex, closingLineIndex + 1),\n ),\n })\n placeholderLines.push(placeholder)\n lineIndex = closingLineIndex\n }\n\n return { fences, placeholderContent: placeholderLines.join('\\n') }\n}\n\nexport function restoreMdxFencedRegions(\n formatted: string,\n fences: MdxFencePlaceholder[],\n) {\n let restored = formatted\n\n for (const fence of fences) {\n const standalonePlaceholderPattern = new RegExp(\n `^[\\\\t ]*${escapeRegExp(fence.placeholder)}$`,\n 'gm',\n )\n if (standalonePlaceholderPattern.test(restored)) {\n restored = restored.replace(standalonePlaceholderPattern, fence.source)\n continue\n }\n\n restored = restored.split(fence.placeholder).join(fence.source)\n }\n\n return restored\n}\n\nexport function parseMdxFenceDelimiter(\n trimmed: string,\n): MdxFenceDelimiter | undefined {\n const match = /^(`{3,}|~{3,})(.*)$/.exec(trimmed)\n if (!match) return undefined\n\n return {\n length: match[1].length,\n marker: match[1].startsWith('`') ? '`' : '~',\n suffix: match[2],\n }\n}\n\nexport function parseInlineMdxFenceOpener(trimmed: string) {\n const splitLine = splitLineBeforeInlineMdxFenceOpener(trimmed)\n if (!splitLine) return undefined\n\n return parseMdxFenceDelimiter(splitLine.fenceLine.trim())\n}\n\nexport function parseInlineMdxFenceCloser(\n trimmed: string,\n activeFence: MdxFence,\n) {\n const splitLine = splitLineAfterInlineMdxFenceCloser(trimmed, activeFence)\n if (splitLine) return parseMdxFenceDelimiter(splitLine.fenceLine.trim())\n\n const trailingSplitLine = splitLineBeforeInlineMdxFenceCloser(\n trimmed,\n activeFence,\n )\n if (!trailingSplitLine) return undefined\n\n return parseMdxFenceDelimiter(trailingSplitLine.fenceLine.trim())\n}\n\nexport function isMdxFenceClosingDelimiter(\n delimiter: MdxFenceDelimiter,\n activeFence: MdxFence,\n) {\n return (\n delimiter.marker === activeFence.marker &&\n delimiter.length >= activeFence.length &&\n delimiter.suffix.trim().length === 0\n )\n}\n\nfunction splitInlineMdxFenceDelimiters(source: string) {\n const lines = source.split('\\n')\n const splitLines: string[] = []\n let activeFence: MdxFence | undefined\n\n for (const line of lines) {\n if (!activeFence) {\n const splitLine = splitLineBeforeInlineMdxFenceOpener(line)\n if (splitLine) {\n splitLines.push(\n ...splitAdjacentMarkupTags(splitLine.before),\n splitLine.fenceLine,\n )\n\n const delimiter = parseMdxFenceDelimiter(splitLine.fenceLine.trim())\n activeFence = delimiter\n ? { length: delimiter.length, marker: delimiter.marker }\n : undefined\n continue\n }\n\n splitLines.push(line)\n\n const delimiter = parseMdxFenceDelimiter(line.trim())\n if (!delimiter) continue\n activeFence = { length: delimiter.length, marker: delimiter.marker }\n continue\n }\n\n const splitClosingLine = splitLineAfterInlineMdxFenceCloser(\n line,\n activeFence,\n )\n if (splitClosingLine) {\n splitLines.push(splitClosingLine.fenceLine, splitClosingLine.after)\n activeFence = undefined\n continue\n }\n\n const splitTrailingClosingLine = splitLineBeforeInlineMdxFenceCloser(\n line,\n activeFence,\n )\n if (splitTrailingClosingLine) {\n splitLines.push(\n splitTrailingClosingLine.before,\n splitTrailingClosingLine.fenceLine,\n )\n activeFence = undefined\n continue\n }\n\n splitLines.push(line)\n\n const delimiter = parseMdxFenceDelimiter(line.trim())\n if (!delimiter) continue\n\n if (isMdxFenceClosingDelimiter(delimiter, activeFence)) {\n activeFence = undefined\n }\n }\n\n return splitLines.join('\\n')\n}\n\nfunction splitLineBeforeInlineMdxFenceOpener(line: string) {\n if (parseMdxFenceDelimiter(line.trim())) return undefined\n\n const match = /`{3}|~{3}/.exec(line)\n if (!match) return undefined\n\n const before = line.slice(0, match.index).trimEnd()\n if (before.trim().length === 0) return undefined\n\n return {\n before,\n fenceLine: line.slice(match.index),\n }\n}\n\nfunction splitAdjacentMarkupTags(line: string) {\n const tokens = scanTagTokens(line)\n if (tokens.length < 2) return [line]\n\n let cursor = 0\n const lines: string[] = []\n const indent = /^\\s*/.exec(line)?.[0] ?? ''\n\n for (const token of tokens) {\n if (line.slice(cursor, token.start).trim().length > 0) return [line]\n\n const tag = line.slice(token.start, token.end)\n lines.push(lines.length === 0 ? `${indent}${tag}` : tag)\n cursor = token.end\n }\n\n if (line.slice(cursor).trim().length > 0) return [line]\n\n return lines\n}\n\nfunction splitLineBeforeInlineMdxFenceCloser(\n line: string,\n activeFence: MdxFence,\n) {\n let end = line.length\n while (end > 0 && (line[end - 1] === '\\t' || line[end - 1] === ' ')) end--\n let start = end\n while (start > 0 && line[start - 1] === activeFence.marker) start--\n if (end - start < activeFence.length) return undefined\n\n const before = line.slice(0, start).trimEnd()\n if (before.trim().length === 0) return undefined\n\n return {\n before,\n fenceLine: line.slice(start, end),\n }\n}\n\nfunction splitLineAfterInlineMdxFenceCloser(\n line: string,\n activeFence: MdxFence,\n) {\n const pattern = new RegExp(\n `^([\\\\t ]*${escapeRegExp(activeFence.marker.repeat(activeFence.length))}${escapeRegExp(activeFence.marker)}*)(.*)$`,\n )\n const match = pattern.exec(line)\n if (!match || match[2].trim().length === 0) return undefined\n\n const closingDelimiter = parseMdxFenceDelimiter(match[1].trim())\n if (!closingDelimiter) return undefined\n if (!isMdxFenceClosingDelimiter(closingDelimiter, activeFence)) {\n return undefined\n }\n\n return {\n fenceLine: match[1],\n after: match[2],\n }\n}\n\nfunction normalizeMdxFenceDelimiterIndent(lines: string[]) {\n if (lines.length < 2) return lines.join('\\n')\n\n const normalizedLines = [...lines]\n normalizedLines[0] = trimLineStartIndent(normalizedLines[0])\n normalizedLines[normalizedLines.length - 1] = trimLineStartIndent(\n normalizedLines[normalizedLines.length - 1],\n )\n return normalizedLines.join('\\n')\n}\n\nfunction trimLineStartIndent(line: string) {\n return line.replace(/^[\\t ]+/, '')\n}\n\nfunction pushLineReplacement(\n edits: SourceEdit[],\n range: SourceRange,\n oldText: string,\n newText: string,\n) {\n if (newText === oldText) return\n\n edits.push({ ...range, newText })\n}\n\nfunction isLineInsideAnyRange(line: SourceRange, ranges: SourceRange[]) {\n return ranges.some(\n (range) => line.start >= range.start && line.end <= range.end,\n )\n}\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n","import htmlPlugin from 'prettier/plugins/html'\nimport postcssPlugin from 'prettier/plugins/postcss'\nimport prettier from 'prettier/standalone'\n\nconst RAW_TEXT_TAG =\n 'script|style|textarea|title|xmp|iframe|noembed|noframes|plaintext'\nconst TAG_BODY = `(?:\"[^\"]*\"|'[^']*'|[^\"'>])*>`\n\n/**\n * Skips comments, raw text and opening tags; captures closing tags broken before `>`.\n * Case-sensitive so PascalCase components such as `<Title>` are not raw text.\n */\nconst BROKEN_CLOSING_TAG = new RegExp(\n [\n String.raw`<!--[\\s\\S]*?-->`,\n String.raw`<(${RAW_TEXT_TAG})\\b${TAG_BODY}[\\s\\S]*?</\\1\\s*>`,\n `<[A-Za-z]${TAG_BODY}`,\n String.raw`(</[^\\s>]+)\\s*\\n\\s*>`,\n ].join('|'),\n 'g',\n)\n\nexport interface HtmlFormattingOptions {\n printWidth: number\n tabSize: number\n useTabs: boolean\n}\n\nexport async function formatHtmlFragment(\n source: string,\n options: HtmlFormattingOptions,\n) {\n const formatted = await prettier.format(source, {\n htmlWhitespaceSensitivity: 'css',\n parser: 'html',\n plugins: [htmlPlugin, postcssPlugin],\n printWidth: options.printWidth,\n tabWidth: options.tabSize,\n useTabs: options.useTabs,\n })\n return normalizeClosingTagSpacing(formatted)\n}\n\n/** Keep closing tags readable without inserting whitespace into inline content. */\nexport function normalizeClosingTagSpacing(source: string) {\n return source.replace(\n BROKEN_CLOSING_TAG,\n (match, _rawTextTag: string, closingTag?: string) =>\n closingTag ? `${closingTag}>` : match,\n )\n}\n\nexport function getLineIndent(line: string) {\n const match = /^\\s*/.exec(line)\n return match?.[0] ?? ''\n}\n\nexport function normalizeSelfClosingTagSpacing(formatted: string) {\n // Match each whitespace run once, even when no /> follows it.\n return formatted.replace(/\\s+/g, (whitespace, offset: number) =>\n formatted.startsWith('/>', offset + whitespace.length) ? '' : whitespace,\n )\n}\n","import { maskRegorExpressions, restoreRegorExpressions } from './expressions'\nimport {\n buildMdxFenceDelimiterEdits,\n isMdxFenceClosingDelimiter,\n maskMdxFencedRegions,\n parseInlineMdxFenceCloser,\n parseInlineMdxFenceOpener,\n parseMdxFenceDelimiter,\n restoreMdxFencedRegions,\n} from './fences'\nimport { formatHtmlFragment, normalizeSelfClosingTagSpacing } from './html'\nimport {\n findMdxExpressionEnd,\n findTagEnd,\n isMdxExpressionStart,\n scanTagTokens,\n VOID_HTML_TAG_NAMES,\n} from './markup'\nimport {\n intersects,\n type SourceEdit,\n type SourceRange,\n type SourceText,\n} from './source'\n\nexport interface MdxMarkupBlock {\n content: string\n range: SourceRange\n}\n\ninterface MdxExpressionPlaceholder {\n placeholder: string\n source: string\n}\n\ninterface MdxInlineCodePlaceholder {\n placeholder: string\n source: string\n}\n\ninterface MdxFormattingRequest {\n onlyWithinRange?: SourceRange\n}\n\ninterface MdxMarkupBlockOptions {\n includeIncomplete?: boolean\n}\n\ninterface MdxBlockScanState {\n activeEndLine?: number\n activeLines: string[]\n activeStartLine?: number\n fenceLength?: number\n fenceMarker?: '`' | '~'\n frontmatterHandled: boolean\n inFence: boolean\n inFrontmatter: boolean\n}\n\nexport async function buildMdxFormattingEdits(\n document: SourceText,\n request: MdxFormattingRequest = {},\n) {\n const blocks = getMdxMarkupBlocks(document, {\n includeIncomplete: true,\n }).filter((block) =>\n request.onlyWithinRange\n ? intersects(block.range, request.onlyWithinRange)\n : true,\n )\n\n const edits: SourceEdit[] = []\n const blockRanges = blocks.map((block) => block.range)\n\n for (const block of blocks) {\n const formatted = await formatMdxMarkupBlock(document, block)\n if (!formatted || formatted === block.content) continue\n\n edits.push({ ...block.range, newText: document.preserveEol(formatted) })\n }\n\n edits.push(\n ...buildMdxFenceDelimiterEdits(document, blockRanges, {\n onlyWithinRange: request.onlyWithinRange,\n }),\n )\n\n return edits\n}\n\nexport function getMdxMarkupBlocks(\n document: SourceText,\n options: MdxMarkupBlockOptions = {},\n) {\n const blocks: MdxMarkupBlock[] = []\n const state: MdxBlockScanState = {\n activeEndLine: undefined,\n activeLines: [],\n frontmatterHandled: false,\n inFence: false,\n inFrontmatter: false,\n }\n\n for (let lineIndex = 0; lineIndex < document.lineCount; lineIndex++) {\n const lineText = document.lineAt(lineIndex).text\n const trimmed = lineText.trim()\n\n if (startMdxFrontmatter(lineIndex, trimmed, state)) {\n continue\n }\n\n if (closeMdxFrontmatter(trimmed, state)) {\n continue\n }\n\n collectActiveMarkupBlock(\n blocks,\n document,\n lineIndex,\n lineText,\n trimmed,\n state,\n )\n }\n\n if (\n options.includeIncomplete &&\n state.activeStartLine !== undefined &&\n state.activeEndLine !== undefined\n ) {\n pushActiveBlock(\n blocks,\n document,\n state.activeStartLine,\n state.activeEndLine,\n state.activeLines,\n )\n }\n\n return blocks\n}\n\nfunction pushActiveBlock(\n blocks: MdxMarkupBlock[],\n document: SourceText,\n startLine: number,\n endLine: number,\n lines: string[],\n) {\n const start = document.lineAt(startLine).range.start\n const end = document.lineAt(endLine).range.end\n blocks.push({\n content: lines.join('\\n'),\n range: { start, end },\n })\n}\n\nfunction looksLikeMarkupBlockStart(trimmedLine: string) {\n return /^<[A-Za-z][A-Za-z0-9._:$-]*/.test(trimmedLine)\n}\n\nfunction isCompleteMarkupBlock(markup: string) {\n const { placeholderContent } = maskMdxFencedRegions(markup)\n if (!placeholderContent.includes('<')) return false\n if (hasUnterminatedTag(placeholderContent)) return false\n\n return getUnclosedTagNames(placeholderContent).length === 0\n}\n\nasync function formatMdxMarkupBlock(\n document: SourceText,\n block: MdxMarkupBlock,\n) {\n const formattingOptions = document.options\n const { fences, placeholderContent: fencePlaceholderContent } =\n maskMdxFencedRegions(block.content.trim())\n const { inlineCodeSpans, placeholderContent: inlineCodePlaceholderContent } =\n maskMdxInlineCodeSpans(fencePlaceholderContent)\n const {\n expressions: regorExpressions,\n placeholderContent: regorPlaceholderContent,\n } = maskRegorExpressions(inlineCodePlaceholderContent)\n const { expressions, placeholderContent } = maskMdxExpressions(\n regorPlaceholderContent,\n )\n if (!placeholderContent.includes('<')) return undefined\n\n let formatted: string\n try {\n formatted = await formatHtmlFragment(placeholderContent, formattingOptions)\n } catch (error) {\n document.report(block.range, error)\n return undefined\n }\n\n const restoredExpressions = restoreMdxExpressions(\n normalizeSelfClosingTagSpacing(formatted.trim()),\n expressions,\n )\n const restoredRegorExpressions = restoreRegorExpressions(\n restoredExpressions,\n regorExpressions,\n )\n const restoredInlineCode = restoreMdxInlineCodeSpans(\n restoredRegorExpressions,\n inlineCodeSpans,\n )\n\n return restoreMdxFencedRegions(restoredInlineCode, fences)\n}\n\nfunction maskMdxInlineCodeSpans(source: string) {\n const inlineCodeSpans: MdxInlineCodePlaceholder[] = []\n const lines = source.split('\\n')\n const placeholderLines = lines.map((line) =>\n maskMdxInlineCodeSpansInLine(line, inlineCodeSpans),\n )\n\n return {\n inlineCodeSpans,\n placeholderContent: placeholderLines.join('\\n'),\n }\n}\n\nfunction maskMdxInlineCodeSpansInLine(\n line: string,\n inlineCodeSpans: MdxInlineCodePlaceholder[],\n) {\n let placeholderLine = ''\n\n for (let index = 0; index < line.length; ) {\n const start = line.indexOf('`', index)\n if (start === -1) {\n placeholderLine += line.slice(index)\n break\n }\n\n const tickCount = countRepeatedChar(line, start, '`')\n if (tickCount !== 1) {\n placeholderLine += line.slice(index, start + tickCount)\n index = start + tickCount\n continue\n }\n\n const end = findMdxInlineCodeEnd(line, start + 1)\n if (end === -1) {\n placeholderLine += line.slice(index)\n break\n }\n\n const source = line.slice(start, end + 1)\n const placeholder = createMdxInlineCodePlaceholder(\n inlineCodeSpans.length,\n line,\n start,\n end + 1,\n )\n inlineCodeSpans.push({ placeholder, source })\n placeholderLine += line.slice(index, start)\n placeholderLine += placeholder\n index = end + 1\n }\n\n return placeholderLine\n}\n\nfunction createMdxInlineCodePlaceholder(\n index: number,\n line: string,\n start: number,\n end: number,\n) {\n const lineBefore = line.slice(0, start)\n const lineAfter = line.slice(end)\n if (lineBefore.trim().length === 0 && lineAfter.trim().length === 0) {\n return `<!--PURESTACK_MDX_INLINE_CODE_${index}-->`\n }\n\n return `PURESTACK_MDX_INLINE_CODE_${index}`\n}\n\nfunction restoreMdxInlineCodeSpans(\n formatted: string,\n inlineCodeSpans: MdxInlineCodePlaceholder[],\n) {\n let restored = formatted\n\n for (const inlineCodeSpan of sortLongestPlaceholderFirst(inlineCodeSpans)) {\n restored = restored\n .split(inlineCodeSpan.placeholder)\n .join(inlineCodeSpan.source)\n }\n\n return restored\n}\n\nexport function maskMdxExpressions(source: string) {\n const expressions: MdxExpressionPlaceholder[] = []\n let placeholderContent = ''\n\n for (let index = 0; index < source.length; ) {\n const rawTextEnd = findRawTextElementEnd(source, index)\n if (rawTextEnd !== undefined) {\n placeholderContent += source.slice(index, rawTextEnd)\n index = rawTextEnd\n continue\n }\n\n if (!isMdxExpressionStart(source, index)) {\n placeholderContent += source[index]\n index++\n continue\n }\n\n const expressionEnd = findMdxExpressionEnd(source, index)\n if (expressionEnd === -1) {\n placeholderContent += source[index]\n index++\n continue\n }\n\n const placeholder = `PURESTACK_MDX_EXPR_${expressions.length}`\n expressions.push({\n placeholder,\n source: source.slice(index, expressionEnd),\n })\n placeholderContent += placeholder\n index = expressionEnd\n }\n\n return { expressions, placeholderContent }\n}\n\nfunction restoreMdxExpressions(\n formatted: string,\n expressions: MdxExpressionPlaceholder[],\n) {\n let restored = formatted\n\n for (const expression of sortLongestPlaceholderFirst(expressions)) {\n restored = restored.split(expression.placeholder).join(expression.source)\n }\n\n return restored\n}\n\nfunction hasUnterminatedTag(markup: string) {\n for (let index = 0; index < markup.length; index++) {\n if (markup[index] !== '<') continue\n\n if (markup.startsWith('<!--', index)) {\n const commentEnd = markup.indexOf('-->', index + 4)\n if (commentEnd === -1) return true\n index = commentEnd + 2\n continue\n }\n\n const nextTagEnd = findTagEnd(markup, index + 1)\n if (nextTagEnd === -1) return true\n index = nextTagEnd\n }\n\n return false\n}\n\nfunction startMdxFrontmatter(\n lineIndex: number,\n trimmed: string,\n state: MdxBlockScanState,\n) {\n if (state.frontmatterHandled || lineIndex !== 0 || trimmed !== '---') {\n return false\n }\n\n state.inFrontmatter = true\n state.frontmatterHandled = true\n return true\n}\n\nfunction closeMdxFrontmatter(trimmed: string, state: MdxBlockScanState) {\n if (!state.inFrontmatter) return false\n\n if (trimmed === '---') {\n state.inFrontmatter = false\n }\n\n return true\n}\n\nfunction updateMdxFenceState(trimmed: string, state: MdxBlockScanState) {\n const activeFence =\n state.fenceMarker && state.fenceLength\n ? { length: state.fenceLength, marker: state.fenceMarker }\n : undefined\n const delimiter =\n state.inFence && activeFence\n ? (parseInlineMdxFenceCloser(trimmed, activeFence) ??\n parseMdxFenceDelimiter(trimmed))\n : (parseMdxFenceDelimiter(trimmed) ?? parseInlineMdxFenceOpener(trimmed))\n if (!delimiter) return state.inFence\n\n if (!state.inFence) {\n state.inFence = true\n state.fenceLength = delimiter.length\n state.fenceMarker = delimiter.marker\n return true\n }\n\n if (\n state.fenceMarker &&\n state.fenceLength &&\n isMdxFenceClosingDelimiter(delimiter, {\n length: state.fenceLength,\n marker: state.fenceMarker,\n })\n ) {\n state.inFence = false\n state.fenceLength = undefined\n state.fenceMarker = undefined\n }\n\n return true\n}\n\nfunction collectActiveMarkupBlock(\n blocks: MdxMarkupBlock[],\n document: SourceText,\n lineIndex: number,\n lineText: string,\n trimmed: string,\n state: MdxBlockScanState,\n) {\n if (state.activeStartLine === undefined) {\n if (state.inFence) {\n updateMdxFenceState(trimmed, state)\n return\n }\n\n if (!looksLikeMarkupBlockStart(trimmed)) {\n if (updateMdxFenceState(trimmed, state)) return\n return\n }\n\n state.activeStartLine = lineIndex\n state.activeEndLine = lineIndex\n state.activeLines = [lineText]\n } else {\n state.activeEndLine = lineIndex\n state.activeLines.push(lineText)\n }\n\n updateMdxFenceState(trimmed, state)\n if (state.inFence) return\n if (!isCompleteMarkupBlock(state.activeLines.join('\\n'))) return\n\n pushActiveBlock(\n blocks,\n document,\n state.activeStartLine,\n state.activeEndLine ?? lineIndex,\n state.activeLines,\n )\n state.activeEndLine = undefined\n state.activeStartLine = undefined\n state.activeLines = []\n}\n\nfunction getUnclosedTagNames(markup: string) {\n const stack: string[] = []\n\n for (const token of scanTagTokens(markup)) {\n if (token.kind === 'opening') {\n if (isSelfContainedTag(token.name, token.selfClosing)) continue\n\n stack.push(token.name)\n continue\n }\n\n closeMatchingTag(stack, token.name)\n }\n\n return stack\n}\n\nfunction isSelfContainedTag(tagName: string, selfClosing: boolean) {\n return selfClosing || VOID_HTML_TAG_NAMES.has(tagName.toLowerCase())\n}\n\nfunction closeMatchingTag(stack: string[], tagName: string) {\n for (let index = stack.length - 1; index >= 0; index--) {\n if (stack[index] !== tagName) continue\n stack.splice(index)\n return\n }\n}\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction sortLongestPlaceholderFirst<T extends { placeholder: string }>(\n placeholders: T[],\n) {\n return [...placeholders].sort(\n (left, right) => right.placeholder.length - left.placeholder.length,\n )\n}\n\nfunction findMdxInlineCodeEnd(line: string, startIndex: number) {\n for (let index = startIndex; index < line.length; index++) {\n if (line[index] === '`') return index\n }\n\n return -1\n}\n\nfunction countRepeatedChar(line: string, startIndex: number, char: string) {\n let count = 0\n\n while (line[startIndex + count] === char) {\n count++\n }\n\n return count\n}\n\nfunction findRawTextElementEnd(source: string, startIndex: number) {\n if (source[startIndex] !== '<' || source[startIndex + 1] === '/') {\n return undefined\n }\n\n const tagEnd = findTagEnd(source, startIndex + 1)\n if (tagEnd === -1) return undefined\n\n const openingTag = source.slice(startIndex, tagEnd + 1)\n const tagName = /^<\\s*(script|style)\\b/i.exec(openingTag)?.[1]\n if (!tagName) return undefined\n\n const closingTagPattern = new RegExp(\n `<\\\\/\\\\s*${escapeRegExp(tagName)}\\\\s*>`,\n 'i',\n )\n const closingTagMatch = closingTagPattern.exec(source.slice(tagEnd + 1))\n if (!closingTagMatch) return undefined\n\n return tagEnd + 1 + closingTagMatch.index + closingTagMatch[0].length\n}\n","import type * as TypeScript from 'typescript-parser'\nimport ts from 'typescript-parser'\nimport { maskRegorExpressions, restoreRegorExpressions } from './expressions'\n\nimport { formatHtmlFragment, normalizeSelfClosingTagSpacing } from './html'\nimport {\n intersects,\n type SourceEdit,\n type SourceRange,\n type SourceText,\n} from './source'\n\nexport type SupportedTemplateTagName = 'html' | 'svg'\n\nexport interface SupportedTaggedTemplate {\n content: string\n contentRange: SourceRange\n expressions: TemplateExpressionPlaceholder[]\n interpolationRanges: Array<{ start: number; end: number }>\n placeholderContent: string\n tagName: SupportedTemplateTagName\n}\n\ninterface TemplateExpressionPlaceholder {\n placeholder: string\n source: string\n}\n\nconst SUPPORTED_TEMPLATE_TAG_NAMES: SupportedTemplateTagName[] = ['html', 'svg']\n\ninterface TemplateFormattingRequest {\n onlyWithinRange?: SourceRange\n}\n\nexport async function buildTemplateFormattingEdits(\n document: SourceText,\n request: TemplateFormattingRequest = {},\n) {\n const templates = getSupportedTaggedTemplates(document).filter((template) =>\n request.onlyWithinRange\n ? intersects(template.contentRange, request.onlyWithinRange)\n : true,\n )\n if (templates.length === 0) return []\n\n const edits: SourceEdit[] = []\n\n for (const template of templates) {\n const formatted = await formatTaggedTemplate(document, template)\n if (!formatted || formatted === template.content) continue\n\n edits.push({\n ...template.contentRange,\n newText: document.preserveEol(formatted),\n })\n }\n\n return edits\n}\n\nexport function getSupportedTaggedTemplates(\n document: SourceText,\n): SupportedTaggedTemplate[] {\n const sourceText = document.text\n const sourceFile = ts.createSourceFile(\n document.filePath,\n sourceText,\n ts.ScriptTarget.Latest,\n false,\n ts.ScriptKind.TS,\n )\n const templates: SupportedTaggedTemplate[] = []\n\n visitNode(sourceFile)\n return templates\n\n function visitNode(node: TypeScript.Node) {\n if (ts.isTaggedTemplateExpression(node)) {\n const template = createSupportedTaggedTemplate(node, sourceFile)\n if (template) {\n templates.push(template)\n // The outer template owns its interpolations; never emit overlapping edits.\n return\n }\n }\n\n ts.forEachChild(node, visitNode)\n }\n}\n\nexport function isOffsetInsideSupportedTaggedTemplate(\n sourceFile: TypeScript.SourceFile,\n offset: number,\n) {\n let isInsideTemplate = false\n\n visitNode(sourceFile)\n return isInsideTemplate\n\n function visitNode(node: TypeScript.Node) {\n if (isInsideTemplate) return\n if (offset < node.getStart(sourceFile) || offset >= node.getEnd()) return\n\n if (ts.isTaggedTemplateExpression(node)) {\n const templateTagName = getSupportedTemplateTagName(\n node.tag.getText(sourceFile),\n )\n if (!templateTagName) {\n ts.forEachChild(node, visitNode)\n return\n }\n\n const template = node.template\n if (\n offset >= template.getStart(sourceFile) &&\n offset < template.getEnd()\n ) {\n isInsideTemplate = true\n return\n }\n }\n\n ts.forEachChild(node, visitNode)\n }\n}\n\nfunction createSupportedTaggedTemplate(\n node: TypeScript.TaggedTemplateExpression,\n sourceFile: TypeScript.SourceFile,\n) {\n const tagName = getSupportedTemplateTagName(node.tag.getText(sourceFile))\n if (!tagName) return undefined\n\n const template = node.template\n if (isLikelyPrematureRawBacktickClose(sourceFile.text, template)) {\n return undefined\n }\n\n const innerStart = template.getStart(sourceFile) + 1\n const innerEnd = template.getEnd() - 1\n if (innerEnd < innerStart) return undefined\n\n const contentRange = { start: innerStart, end: innerEnd }\n\n if (ts.isNoSubstitutionTemplateLiteral(template)) {\n const content = sourceFile.text.slice(innerStart, innerEnd)\n return {\n content,\n contentRange,\n expressions: [],\n interpolationRanges: [],\n placeholderContent: content,\n tagName,\n }\n }\n\n const expressions: TemplateExpressionPlaceholder[] = []\n const interpolationRanges: Array<{ start: number; end: number }> = []\n let placeholderContent = sliceTemplateHeadContent(template.head, sourceFile)\n let currentContentOffset = placeholderContent.length\n\n template.templateSpans.forEach((span, index) => {\n const placeholder = `PURESTACK_EXPR_${index}_${tagName.toUpperCase()}`\n const interpolationEnd = span.literal.getStart(sourceFile) - innerStart + 1\n expressions.push({\n placeholder,\n source: sourceFile.text.slice(\n span.expression.getStart(sourceFile),\n span.expression.getEnd(),\n ),\n })\n interpolationRanges.push({\n start: currentContentOffset,\n end: interpolationEnd,\n })\n placeholderContent += placeholder\n const literalContent = sliceTemplateSpanLiteralContent(\n span.literal,\n sourceFile,\n )\n placeholderContent += literalContent\n currentContentOffset = interpolationEnd + literalContent.length\n })\n\n return {\n content: sourceFile.text.slice(innerStart, innerEnd),\n contentRange,\n expressions,\n interpolationRanges,\n placeholderContent,\n tagName,\n }\n}\n\nfunction getSupportedTemplateTagName(tagText: string) {\n const normalizedTag = tagText.trim()\n\n for (const tagName of SUPPORTED_TEMPLATE_TAG_NAMES) {\n if (normalizedTag === tagName || normalizedTag.endsWith(`.${tagName}`)) {\n return tagName\n }\n }\n\n return undefined\n}\n\nfunction isLikelyPrematureRawBacktickClose(\n sourceText: string,\n template: TypeScript.TemplateLiteral,\n) {\n return sourceText.startsWith('``', template.getEnd())\n}\n\nfunction sliceTemplateHeadContent(\n head: TypeScript.TemplateHead,\n sourceFile: TypeScript.SourceFile,\n) {\n return sourceFile.text.slice(head.getStart(sourceFile) + 1, head.getEnd() - 2)\n}\n\nfunction sliceTemplateSpanLiteralContent(\n literal: TypeScript.TemplateMiddle | TypeScript.TemplateTail,\n sourceFile: TypeScript.SourceFile,\n) {\n const endOffset = ts.isTemplateTail(literal) ? 1 : 2\n return sourceFile.text.slice(\n literal.getStart(sourceFile) + 1,\n literal.getEnd() - endOffset,\n )\n}\n\nasync function formatTaggedTemplate(\n document: SourceText,\n template: SupportedTaggedTemplate,\n) {\n const formattingOptions = document.options\n const source = template.placeholderContent.trim()\n const { expressions: regorExpressions, placeholderContent } =\n maskRegorExpressions(source)\n\n if (!placeholderContent.includes('<')) return undefined\n\n let formatted: string\n try {\n formatted = await formatHtmlFragment(placeholderContent, formattingOptions)\n } catch (error) {\n document.report(template.contentRange, error)\n return undefined\n }\n\n const restoredTemplateExpressions = restoreTemplateExpressions(\n normalizeSelfClosingTagSpacing(formatted.trim()),\n template.expressions,\n )\n\n return restoreRegorExpressions(restoredTemplateExpressions, regorExpressions)\n}\n\nfunction restoreTemplateExpressions(\n formatted: string,\n expressions: TemplateExpressionPlaceholder[],\n) {\n let restored = formatted\n\n for (const expression of expressions) {\n restored = restored\n .split(expression.placeholder)\n .join(`\\${${expression.source}}`)\n }\n\n return restored\n}\n","import { buildMdxFormattingEdits } from './mdx'\nimport { applySourceEdits, type FormatOptions, SourceText } from './source'\nimport { buildTemplateFormattingEdits } from './templates'\n\nexport {\n maskRegorExpressions,\n type RegorExpressionPlaceholder,\n restoreRegorExpressions,\n} from './expressions'\nexport * from './fences'\nexport * from './html'\nexport * from './markup'\nexport * from './mdx'\nexport * from './source'\nexport * from './templates'\n\n/** Formats only component markup and html/svg tagged template contents. */\nexport async function formatSource(text: string, options: FormatOptions = {}) {\n const source = new SourceText(text, options)\n const language =\n options.language ??\n (/\\.[cm]?tsx?$/i.test(source.filePath) ? 'typescript' : 'mdx')\n const edits = await (language === 'typescript'\n ? buildTemplateFormattingEdits(source, options)\n : buildMdxFormattingEdits(source, options))\n const code = applySourceEdits(text, edits)\n return {\n code,\n edits,\n diagnostics: source.diagnostics,\n changed: code !== text,\n }\n}\n"],"mappings":"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"}
|