@f12io/maple-language-core 0.0.2

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.
Files changed (53) hide show
  1. package/README.md +42 -0
  2. package/dist/LanguageService.d.ts +104 -0
  3. package/dist/LanguageService.js +16 -0
  4. package/dist/LanguageService.js.map +1 -0
  5. package/dist/extractor.helper.d.ts +66 -0
  6. package/dist/extractor.helper.js +319 -0
  7. package/dist/extractor.helper.js.map +1 -0
  8. package/dist/formatter.d.ts +26 -0
  9. package/dist/formatter.js +206 -0
  10. package/dist/formatter.js.map +1 -0
  11. package/dist/index.d.ts +15 -0
  12. package/dist/index.js +50 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/language-definitions.d.ts +9 -0
  15. package/dist/language-definitions.js +35 -0
  16. package/dist/language-definitions.js.map +1 -0
  17. package/dist/languages/AngularLanguageService.d.ts +6 -0
  18. package/dist/languages/AngularLanguageService.js +66 -0
  19. package/dist/languages/AngularLanguageService.js.map +1 -0
  20. package/dist/languages/BaseLanguageService.d.ts +80 -0
  21. package/dist/languages/BaseLanguageService.js +409 -0
  22. package/dist/languages/BaseLanguageService.js.map +1 -0
  23. package/dist/languages/HtmlLanguageService.d.ts +5 -0
  24. package/dist/languages/HtmlLanguageService.js +29 -0
  25. package/dist/languages/HtmlLanguageService.js.map +1 -0
  26. package/dist/languages/JavascriptLanguageService.d.ts +10 -0
  27. package/dist/languages/JavascriptLanguageService.js +95 -0
  28. package/dist/languages/JavascriptLanguageService.js.map +1 -0
  29. package/dist/languages/PhpLanguageService.d.ts +22 -0
  30. package/dist/languages/PhpLanguageService.js +242 -0
  31. package/dist/languages/PhpLanguageService.js.map +1 -0
  32. package/dist/languages/RazorLanguageService.d.ts +33 -0
  33. package/dist/languages/RazorLanguageService.js +338 -0
  34. package/dist/languages/RazorLanguageService.js.map +1 -0
  35. package/dist/languages/ReactLanguageService.d.ts +6 -0
  36. package/dist/languages/ReactLanguageService.js +31 -0
  37. package/dist/languages/ReactLanguageService.js.map +1 -0
  38. package/dist/languages/SvelteLanguageService.d.ts +9 -0
  39. package/dist/languages/SvelteLanguageService.js +65 -0
  40. package/dist/languages/SvelteLanguageService.js.map +1 -0
  41. package/dist/languages/TwigLanguageService.d.ts +4 -0
  42. package/dist/languages/TwigLanguageService.js +12 -0
  43. package/dist/languages/TwigLanguageService.js.map +1 -0
  44. package/dist/languages/VueLanguageService.d.ts +6 -0
  45. package/dist/languages/VueLanguageService.js +36 -0
  46. package/dist/languages/VueLanguageService.js.map +1 -0
  47. package/dist/regex.d.ts +63 -0
  48. package/dist/regex.js +92 -0
  49. package/dist/regex.js.map +1 -0
  50. package/dist/registry.d.ts +7 -0
  51. package/dist/registry.js +86 -0
  52. package/dist/registry.js.map +1 -0
  53. package/package.json +38 -0
package/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # @f12io/maple-language-core
2
+
3
+ Editor-agnostic language tooling for [Maple CSS](https://github.com/f12io/maple):
4
+ region discovery, class extraction, string grammar, and the class layout
5
+ engine. This package is the single source of truth consumed by the
6
+ [Maple VS Code extension](https://github.com/f12io/maple-vscode-extension)
7
+ and [`@f12io/prettier-plugin-maple`](https://www.npmjs.com/package/@f12io/prettier-plugin-maple).
8
+
9
+ ## What it provides
10
+
11
+ - **`LanguageServiceRegistry.getService(languageId)`** — a language service
12
+ for `html`, `javascript(react)`, `typescript(react)`, `vue`, `svelte`,
13
+ `php`, `razor`, `aspnetcorerazor`, and `twig`.
14
+ - **`service.collectRegions(text)`** — every maple region in a document
15
+ (class attributes, `className={...}`, `clsx()`/`cva()` arguments,
16
+ `/* maple */` opt-in expressions, framework bindings), typed as raw class
17
+ text or code expressions.
18
+ - **`service.extractClasses(text)`** — class instances with exact document
19
+ offsets, interpolation-aware per language (JS template literals, C#
20
+ interpolated strings, PHP blocks, Razor expressions).
21
+ - **`formatClasses` / `computeFormattingEdits` / `formatText`** — the layout
22
+ engine: wraps class lists by property group, preserves ternary and
23
+ concatenation structure, and upgrades string delimiters only when the host
24
+ language allows multi-line strings.
25
+
26
+ ## Usage
27
+
28
+ ```ts
29
+ import {
30
+ LanguageServiceRegistry,
31
+ formatText,
32
+ } from '@f12io/maple-language-core';
33
+
34
+ const service = LanguageServiceRegistry.getService('javascriptreact');
35
+ const instances = service.extractClasses(source);
36
+
37
+ const formatted = formatText(source, 'javascriptreact', 4);
38
+ ```
39
+
40
+ ## License
41
+
42
+ Released under the [Root Source License (ROOT)](https://github.com/f12io/maple-vscode-extension/blob/main/LICENSE), an MIT-style permissive license with an additional distribution condition for systems that can recreate the source on demand. © [f12.io](https://f12.io)
@@ -0,0 +1,104 @@
1
+ export interface ClassInstance {
2
+ value: string;
3
+ start: number;
4
+ end: number;
5
+ tagName?: string;
6
+ }
7
+ /** A [start, end) offset range whose contents are excluded via disable comments. */
8
+ export interface DisabledBlock {
9
+ start: number;
10
+ end: number;
11
+ }
12
+ /** Keeps the first instance seen for each start offset. */
13
+ export declare function dedupeInstancesByStart(instances: Array<ClassInstance>): Array<ClassInstance>;
14
+ /** A string literal located by a language service's `matchStringLiteral`. */
15
+ export interface StringLiteralMatch {
16
+ /** Index of the opening delimiter (including any prefix, e.g. `$@`) */
17
+ start: number;
18
+ contentStart: number;
19
+ contentEnd: number;
20
+ /** Index just after the closing delimiter */
21
+ endIndex: number;
22
+ /** The opening delimiter as written: `$@"`, `$"`, `"`, `'` or `` ` `` */
23
+ rawDelimiter: string;
24
+ /** Content contains interpolation holes this service can parse */
25
+ isInterpolated: boolean;
26
+ }
27
+ /**
28
+ * A document range that holds maple classes. This is the single source of
29
+ * truth for "where do maple strings live" — extraction, formatting, and every
30
+ * feature built on them consume the same regions.
31
+ */
32
+ export interface MapleRegion {
33
+ start: number;
34
+ end: number;
35
+ /**
36
+ * `class-text`: the range is raw class text (a class attribute value).
37
+ * `expression`: the range is code whose string literals are maple
38
+ * (opt-in expressions, clsx/cva arguments, className={...}, :class="...").
39
+ */
40
+ kind: 'class-text' | 'expression';
41
+ /**
42
+ * Anchor offset of the construct that produced the region (attribute or
43
+ * call start). Used for tag-name lookup, disable-comment checks, and
44
+ * formatter indentation.
45
+ */
46
+ anchor: number;
47
+ /** Extract unquoted object keys as classes (clsx objects, :class objects) */
48
+ includeObjectKeys?: boolean;
49
+ /**
50
+ * False when the host syntax cannot hold multi-line string literals
51
+ * (e.g. Angular template expressions); the formatter then only applies
52
+ * single-line normalizations. Defaults to true.
53
+ */
54
+ allowMultilineLiterals?: boolean;
55
+ }
56
+ /** Callback invoked for each interpolated string found during extraction. */
57
+ export type StringExtractionCallback = (value: string, offset: number, text: string, matchIndex: number, literal?: StringLiteralMatch) => void;
58
+ export interface Token {
59
+ value: string;
60
+ start: number;
61
+ end: number;
62
+ hasInterpolation?: boolean;
63
+ }
64
+ export interface ILanguageService {
65
+ languageIds: Array<string>;
66
+ extractClasses(text: string): Array<ClassInstance>;
67
+ /**
68
+ * Reports every maple region in the document. Single implementation per
69
+ * language; extraction and formatting both consume it.
70
+ */
71
+ collectRegions(text: string): Array<MapleRegion>;
72
+ tokenizeClassesWithIndices(str: string): Array<Token>;
73
+ /**
74
+ * Resolves source-escaped class text to what the framework actually renders
75
+ * into the DOM (e.g. Razor renders `@@md:p-2` as `@md:p-2`). Used where the
76
+ * runtime CSS matters (hover), not for document ranges.
77
+ */
78
+ getRenderedClassText(word: string): string;
79
+ /**
80
+ * Returns the delimiters to use when a formatted string must span multiple
81
+ * lines, or undefined when the string cannot legally hold newlines in this
82
+ * language (the formatter then leaves it untouched). `rawQuote` is the
83
+ * opening delimiter as written ($@", $", ", ' or `).
84
+ */
85
+ getMultilineStringDelimiters(rawQuote: string, content: string): {
86
+ open: string;
87
+ close: string;
88
+ } | undefined;
89
+ /**
90
+ * Matches a string literal of this language starting at `index`, or
91
+ * undefined when no (terminated) literal starts there. This is the single
92
+ * place a language's string grammar lives — generic helpers delegate here
93
+ * instead of hardcoding delimiter knowledge.
94
+ */
95
+ matchStringLiteral(text: string, index: number): StringLiteralMatch | undefined;
96
+ /**
97
+ * Formats a bare class-bearing expression (e.g. a ternary with string
98
+ * arms), preserving its structure — the same treatment interpolations get
99
+ * inside class attributes. Returns undefined when the expression has no
100
+ * structure this language knows how to format.
101
+ */
102
+ formatExpression(expr: string, baseIndent: string, maxClassesPerLine: number, formatClassesFn: (value: string, indent: string, maxClasses: number) => string): string | undefined;
103
+ formatInterpolation(cls: string, baseIndent: string, maxClassesPerLine: number, formatClassesFn: (value: string, indent: string, maxClasses: number) => string): string;
104
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dedupeInstancesByStart = dedupeInstancesByStart;
4
+ /** Keeps the first instance seen for each start offset. */
5
+ function dedupeInstancesByStart(instances) {
6
+ const uniqueInstances = [];
7
+ const seenStarts = new Set();
8
+ for (const instance of instances) {
9
+ if (!seenStarts.has(instance.start)) {
10
+ seenStarts.add(instance.start);
11
+ uniqueInstances.push(instance);
12
+ }
13
+ }
14
+ return uniqueInstances;
15
+ }
16
+ //# sourceMappingURL=LanguageService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LanguageService.js","sourceRoot":"","sources":["../src/LanguageService.ts"],"names":[],"mappings":";;AAcA,wDAcC;AAfD,2DAA2D;AAC3D,SAAgB,sBAAsB,CACpC,SAA+B;IAE/B,MAAM,eAAe,GAAyB,EAAE,CAAC;IACjD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IAErC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACpC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC/B,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC"}
@@ -0,0 +1,66 @@
1
+ import { ClassInstance, ILanguageService, StringExtractionCallback, StringLiteralMatch } from './LanguageService';
2
+ export declare function isQuote(char: string): boolean;
3
+ /**
4
+ * Upper bound on how far a single scan may advance before giving up.
5
+ * Guards every hand-rolled scanner against runaway scans on malformed input
6
+ * (e.g. an unterminated attribute in a huge minified file).
7
+ */
8
+ export declare const MAX_SCAN_LENGTH = 5000;
9
+ /**
10
+ * Skips a quoted string literal. `index` must hold the opening quote (`'` or
11
+ * `"`); backslash escapes are honored, so an escaped quote does not close the
12
+ * string. Returns the index just after the closing quote, or the scan bound
13
+ * when the string is unterminated.
14
+ */
15
+ export declare function skipStringLiteral(text: string, index: number): number;
16
+ export declare function findClosingQuote(text: string, startIndex: number, quote: string): number;
17
+ export declare function getTagNameBackwards(text: string, index: number): string | undefined;
18
+ export declare function isCommentedOut(text: string, index: number): boolean;
19
+ export declare function isLineDisabled(text: string, index: number): boolean;
20
+ export declare function getDisabledBlocks(text: string): Array<{
21
+ start: number;
22
+ end: number;
23
+ }>;
24
+ export declare function shouldSkipMatch(text: string, index: number, disabledBlocks?: Array<{
25
+ start: number;
26
+ end: number;
27
+ }>): boolean;
28
+ export declare function pushInstance(instances: Array<ClassInstance>, value: string, start: number, text: string, matchIndex: number, disabledBlocks?: Array<{
29
+ start: number;
30
+ end: number;
31
+ }>): void;
32
+ export declare function extractUnquotedObjectKeys(expr: string, exprStart: number, text: string, matchIndex: number, instances: Array<ClassInstance>, disabledBlocks?: Array<{
33
+ start: number;
34
+ end: number;
35
+ }>): void;
36
+ export interface OptInRegion {
37
+ /** Index of the opt-in comment match */
38
+ matchIndex: number;
39
+ /** Start of the opted-in expression (first non-whitespace after comment) */
40
+ regionStart: number;
41
+ /** End of the opted-in expression (exclusive of the terminator) */
42
+ regionEnd: number;
43
+ /** Every string literal found in the region, in document order */
44
+ literals: Array<StringLiteralMatch>;
45
+ }
46
+ /**
47
+ * Locates all string literals opted in by a maple comment. The comment marks
48
+ * the whole following expression — like a class attribute, every string
49
+ * literal in it is maple (ternary arms, concatenation parts, ...). String
50
+ * boundaries are delegated to the language service, so each language's
51
+ * string grammar lives in exactly one place.
52
+ *
53
+ * The region ends at a `;` or `,` at bracket depth 0, at a closing bracket
54
+ * that was never opened inside the region, or at a plain assignment `=`
55
+ * (guarding against swallowing the next statement in semicolon-less code;
56
+ * comparison/arrow operators like `==`, `=>`, `<=` do not terminate).
57
+ */
58
+ export declare function findOptInRegions(service: ILanguageService, text: string): Array<OptInRegion>;
59
+ export declare function extractStringLiterals(service: ILanguageService, expr: string, exprStart: number, text: string, matchIndex: number, instances: Array<ClassInstance>, disabledBlocks?: Array<{
60
+ start: number;
61
+ end: number;
62
+ }>, extractCallback?: StringExtractionCallback): void;
63
+ export declare function getExactWordRangeAtPosition(document: any, position: any): {
64
+ wordRange: any | undefined;
65
+ currentWord: string;
66
+ };
@@ -0,0 +1,319 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_SCAN_LENGTH = void 0;
4
+ exports.isQuote = isQuote;
5
+ exports.skipStringLiteral = skipStringLiteral;
6
+ exports.findClosingQuote = findClosingQuote;
7
+ exports.getTagNameBackwards = getTagNameBackwards;
8
+ exports.isCommentedOut = isCommentedOut;
9
+ exports.isLineDisabled = isLineDisabled;
10
+ exports.getDisabledBlocks = getDisabledBlocks;
11
+ exports.shouldSkipMatch = shouldSkipMatch;
12
+ exports.pushInstance = pushInstance;
13
+ exports.extractUnquotedObjectKeys = extractUnquotedObjectKeys;
14
+ exports.findOptInRegions = findOptInRegions;
15
+ exports.extractStringLiterals = extractStringLiterals;
16
+ exports.getExactWordRangeAtPosition = getExactWordRangeAtPosition;
17
+ const regex_1 = require("./regex");
18
+ function isQuote(char) {
19
+ return char === '"' || char === "'" || char === '`';
20
+ }
21
+ /**
22
+ * Upper bound on how far a single scan may advance before giving up.
23
+ * Guards every hand-rolled scanner against runaway scans on malformed input
24
+ * (e.g. an unterminated attribute in a huge minified file).
25
+ */
26
+ exports.MAX_SCAN_LENGTH = 5000;
27
+ /**
28
+ * Skips a quoted string literal. `index` must hold the opening quote (`'` or
29
+ * `"`); backslash escapes are honored, so an escaped quote does not close the
30
+ * string. Returns the index just after the closing quote, or the scan bound
31
+ * when the string is unterminated.
32
+ */
33
+ function skipStringLiteral(text, index) {
34
+ const quote = text[index];
35
+ const limit = Math.min(text.length, index + exports.MAX_SCAN_LENGTH);
36
+ let i = index + 1;
37
+ while (i < limit) {
38
+ if (text[i] === '\\') {
39
+ i += 2;
40
+ continue;
41
+ }
42
+ if (text[i] === quote) {
43
+ return i + 1;
44
+ }
45
+ i++;
46
+ }
47
+ return limit;
48
+ }
49
+ function findClosingQuote(text, startIndex, quote) {
50
+ let parenDepth = 0;
51
+ let braceDepth = 0;
52
+ let i = startIndex;
53
+ while (i < text.length) {
54
+ const char = text[i];
55
+ const prevChar = i > 0 ? text[i - 1] : '';
56
+ if (prevChar === '\\') {
57
+ i++;
58
+ continue;
59
+ }
60
+ if (parenDepth > 0 && (char === '"' || char === "'")) {
61
+ // Inside a Razor @(...) expression a quote starts a C# string literal,
62
+ // which may legally contain parens, braces, or the attribute's own
63
+ // quote char. Skip it entirely.
64
+ i = skipStringLiteral(text, i);
65
+ continue;
66
+ }
67
+ if (char === '(' && prevChar === '@') {
68
+ parenDepth++;
69
+ }
70
+ else if (char === '(' && parenDepth > 0) {
71
+ parenDepth++;
72
+ }
73
+ else if (char === ')') {
74
+ if (parenDepth > 0)
75
+ parenDepth--;
76
+ }
77
+ else if (char === '{') {
78
+ braceDepth++;
79
+ }
80
+ else if (char === '}') {
81
+ if (braceDepth > 0)
82
+ braceDepth--;
83
+ }
84
+ else if (char === quote) {
85
+ if (parenDepth === 0 && braceDepth === 0) {
86
+ return i;
87
+ }
88
+ }
89
+ if (i - startIndex > exports.MAX_SCAN_LENGTH) {
90
+ return -1; // safety timeout
91
+ }
92
+ i++;
93
+ }
94
+ return -1;
95
+ }
96
+ function getTagNameBackwards(text, index) {
97
+ const prefix = text.substring(0, index);
98
+ const lastOpen = prefix.lastIndexOf('<');
99
+ const lastClose = prefix.lastIndexOf('>');
100
+ if (lastOpen !== -1 && lastOpen > lastClose) {
101
+ const match = text.substring(lastOpen + 1).match(regex_1.START_TAG_NAME_REGEX);
102
+ if (match) {
103
+ return match[1].toLowerCase();
104
+ }
105
+ }
106
+ return undefined;
107
+ }
108
+ function isCommentedOut(text, index) {
109
+ const lastNewline = text.lastIndexOf('\n', index);
110
+ const lineToMatch = text.substring(lastNewline + 1, index);
111
+ if (lineToMatch.includes('//'))
112
+ return true;
113
+ if (lineToMatch.includes('<!--'))
114
+ return true;
115
+ if (regex_1.START_COMMENT_STAR_REGEX.test(lineToMatch))
116
+ return true;
117
+ const lastSlashStar = lineToMatch.lastIndexOf('/*');
118
+ if (lastSlashStar !== -1) {
119
+ const lastStarSlash = lineToMatch.lastIndexOf('*/');
120
+ if (lastStarSlash < lastSlashStar) {
121
+ return true;
122
+ }
123
+ }
124
+ return false;
125
+ }
126
+ function isLineDisabled(text, index) {
127
+ const lastNewline = text.lastIndexOf('\n', index);
128
+ let nextNewline = text.indexOf('\n', index);
129
+ if (nextNewline === -1)
130
+ nextNewline = text.length;
131
+ const fullLine = text.substring(lastNewline + 1, nextNewline);
132
+ if (fullLine.includes('maple-disable-line'))
133
+ return true;
134
+ if (lastNewline !== -1) {
135
+ const prevNewline = text.lastIndexOf('\n', lastNewline - 1);
136
+ const prevLine = text.substring(prevNewline + 1, lastNewline);
137
+ if (prevLine.includes('maple-disable-next-line'))
138
+ return true;
139
+ }
140
+ return false;
141
+ }
142
+ function getDisabledBlocks(text) {
143
+ const blocks = [];
144
+ const disableMatches = [...text.matchAll(regex_1.DISABLE_REGEX)];
145
+ const enableMatches = [...text.matchAll(regex_1.ENABLE_REGEX)];
146
+ let currentEnd = 0;
147
+ for (const disableMatch of disableMatches) {
148
+ const start = disableMatch.index;
149
+ if (start < currentEnd)
150
+ continue;
151
+ const enableMatch = enableMatches.find((m) => m.index > start);
152
+ const end = enableMatch
153
+ ? enableMatch.index + enableMatch[0].length
154
+ : text.length;
155
+ blocks.push({ start, end });
156
+ currentEnd = end;
157
+ }
158
+ return blocks;
159
+ }
160
+ function shouldSkipMatch(text, index, disabledBlocks = []) {
161
+ if (isCommentedOut(text, index) || isLineDisabled(text, index))
162
+ return true;
163
+ for (const block of disabledBlocks) {
164
+ if (index >= block.start && index <= block.end)
165
+ return true;
166
+ }
167
+ return false;
168
+ }
169
+ function pushInstance(instances, value, start, text, matchIndex, disabledBlocks = []) {
170
+ if (shouldSkipMatch(text, start, disabledBlocks))
171
+ return;
172
+ instances.push({
173
+ value,
174
+ start,
175
+ end: start + value.length,
176
+ tagName: getTagNameBackwards(text, matchIndex),
177
+ });
178
+ }
179
+ function extractUnquotedObjectKeys(expr, exprStart, text, matchIndex, instances, disabledBlocks = []) {
180
+ for (const keyMatch of expr.matchAll(regex_1.OBJECT_KEY_REGEX)) {
181
+ const value = keyMatch[1];
182
+ const keyIdx = keyMatch[0].indexOf(value);
183
+ const start = exprStart + keyMatch.index + keyIdx;
184
+ pushInstance(instances, value, start, text, matchIndex, disabledBlocks);
185
+ }
186
+ }
187
+ /**
188
+ * Locates all string literals opted in by a maple comment. The comment marks
189
+ * the whole following expression — like a class attribute, every string
190
+ * literal in it is maple (ternary arms, concatenation parts, ...). String
191
+ * boundaries are delegated to the language service, so each language's
192
+ * string grammar lives in exactly one place.
193
+ *
194
+ * The region ends at a `;` or `,` at bracket depth 0, at a closing bracket
195
+ * that was never opened inside the region, or at a plain assignment `=`
196
+ * (guarding against swallowing the next statement in semicolon-less code;
197
+ * comparison/arrow operators like `==`, `=>`, `<=` do not terminate).
198
+ */
199
+ function findOptInRegions(service, text) {
200
+ const results = [];
201
+ let currentEnd = 0;
202
+ for (const match of text.matchAll(regex_1.OPT_IN_COMMENT_REGEX)) {
203
+ if (match.index < currentEnd)
204
+ continue;
205
+ let i = match.index + match[0].length;
206
+ while (i < text.length && text[i].trim() === '')
207
+ i++;
208
+ // Objects (/* maple */ { ... }) are handled by the object opt-in path
209
+ if (text[i] === '{')
210
+ continue;
211
+ const regionStart = i;
212
+ const regionLimit = Math.min(text.length, i + exports.MAX_SCAN_LENGTH);
213
+ const literals = [];
214
+ let depth = 0;
215
+ while (i < regionLimit) {
216
+ const literal = service.matchStringLiteral(text, i);
217
+ if (literal) {
218
+ literals.push(literal);
219
+ i = literal.endIndex;
220
+ continue;
221
+ }
222
+ const ch = text[i];
223
+ if (ch === '(' || ch === '[' || ch === '{') {
224
+ depth++;
225
+ }
226
+ else if (ch === ')' || ch === ']' || ch === '}') {
227
+ if (depth === 0)
228
+ break; // closes a bracket opened before the region
229
+ depth--;
230
+ }
231
+ else if (depth === 0 && (ch === ';' || ch === ',')) {
232
+ break;
233
+ }
234
+ else if (depth === 0 &&
235
+ ch === '=' &&
236
+ text[i + 1] !== '=' &&
237
+ text[i + 1] !== '>' &&
238
+ !'=<>!+-*/%&|^'.includes(text[i - 1] ?? '')) {
239
+ break; // plain assignment: the next statement has begun
240
+ }
241
+ i++;
242
+ }
243
+ if (literals.length > 0) {
244
+ results.push({
245
+ matchIndex: match.index,
246
+ regionStart,
247
+ regionEnd: i,
248
+ literals,
249
+ });
250
+ }
251
+ currentEnd = i;
252
+ }
253
+ return results;
254
+ }
255
+ function extractStringLiterals(service, expr, exprStart, text, matchIndex, instances, disabledBlocks = [], extractCallback) {
256
+ let j = 0;
257
+ while (j < expr.length) {
258
+ const literal = service.matchStringLiteral(expr, j);
259
+ if (!literal) {
260
+ j++;
261
+ continue;
262
+ }
263
+ const value = expr.substring(literal.contentStart, literal.contentEnd);
264
+ const start = exprStart + literal.contentStart;
265
+ if (literal.isInterpolated) {
266
+ extractCallback?.(value, start, text, matchIndex, literal);
267
+ }
268
+ else {
269
+ pushInstance(instances, value, start, text, matchIndex, disabledBlocks);
270
+ }
271
+ j = literal.endIndex;
272
+ }
273
+ }
274
+ function getExactWordRangeAtPosition(document, position) {
275
+ const wordRange = document.getWordRangeAtPosition(position, regex_1.MAPLE_CLASS_REGEX_NON_GLOBAL);
276
+ const currentWord = wordRange ? document.getText(wordRange) : '';
277
+ if (!wordRange) {
278
+ return { wordRange: undefined, currentWord: '' };
279
+ }
280
+ const cursorOffsetInWord = position.character - wordRange.start.character;
281
+ const tokens = currentWord.split(regex_1.TOKEN_SPLIT_REGEX);
282
+ let currentOffset = 0;
283
+ let finalRange = wordRange;
284
+ let finalWord = '';
285
+ for (const token of tokens) {
286
+ const start = currentOffset;
287
+ const end = currentOffset + token.length;
288
+ if (cursorOffsetInWord > start && cursorOffsetInWord <= end) {
289
+ if (!isQuote(token) && token.trim() !== '') {
290
+ finalWord = token;
291
+ finalRange = wordRange.with(wordRange.start.translate(0, start), wordRange.start.translate(0, end));
292
+ }
293
+ else {
294
+ finalRange = undefined;
295
+ finalWord = '';
296
+ }
297
+ break;
298
+ }
299
+ else if (cursorOffsetInWord === 0 && start === 0) {
300
+ if (!isQuote(token) && token.trim() !== '') {
301
+ finalWord = token;
302
+ finalRange = wordRange.with(wordRange.start.translate(0, start), wordRange.start.translate(0, end));
303
+ break;
304
+ }
305
+ }
306
+ currentOffset = end;
307
+ }
308
+ if (finalWord && finalRange) {
309
+ // Strip trailing HTML characters if it still bled (e.g. `bgc-red>`)
310
+ const cleanWord = finalWord.replace(/[><]+$/, '').replace(/<![\-]*$/, '');
311
+ if (cleanWord !== finalWord) {
312
+ const diff = finalWord.length - cleanWord.length;
313
+ finalRange = finalRange.with(undefined, finalRange.end.translate(0, -diff));
314
+ finalWord = cleanWord;
315
+ }
316
+ }
317
+ return { wordRange: finalRange, currentWord: finalWord };
318
+ }
319
+ //# sourceMappingURL=extractor.helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractor.helper.js","sourceRoot":"","sources":["../src/extractor.helper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { ILanguageService } from './LanguageService';
2
+ /** A plain text replacement, editor-agnostic. Offsets refer to the input text. */
3
+ export interface TextReplacement {
4
+ start: number;
5
+ end: number;
6
+ newText: string;
7
+ }
8
+ /**
9
+ * Formats a maple class string: wraps onto multiple lines when it exceeds
10
+ * `maxClassesPerLine`, grouping classes by property type, and recursing into
11
+ * interpolation expressions via the language service.
12
+ */
13
+ export declare function formatClasses(classStr: string, baseIndent: string, maxClassesPerLine: number, service: ILanguageService): string;
14
+ /**
15
+ * Computes formatting replacements for every maple region in the document —
16
+ * class attributes, opt-in expressions, and framework-specific regions — as
17
+ * plain offsets, usable from any host (VS Code, Prettier, CLI).
18
+ */
19
+ export declare function computeFormattingEdits(text: string, service: ILanguageService, maxClassesPerLine: number): Array<TextReplacement>;
20
+ /** Applies non-overlapping replacements to a string. */
21
+ export declare function applyTextEdits(text: string, edits: Array<TextReplacement>): string;
22
+ /**
23
+ * Formats every maple region in a document and returns the new text.
24
+ * Convenience entry point for non-editor hosts (Prettier plugin, CLI).
25
+ */
26
+ export declare function formatText(text: string, languageId: string, maxClassesPerLine: number): string;