coffeehaml 0.6.0 → 0.7.1
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/README.md +21 -5
- package/dist/ast.js +334 -123
- package/dist/cli.js +363 -291
- package/dist/compiler.js +126 -89
- package/dist/emitter.js +771 -736
- package/dist/errors.js +5 -2
- package/dist/expressions.js +211 -154
- package/dist/index.js +22 -4
- package/dist/lexer.js +536 -340
- package/dist/parser.js +533 -432
- package/dist/prettier/coffeescript-formatter.js +309 -0
- package/dist/prettier/index.js +105 -0
- package/dist/prettier/options.js +232 -0
- package/dist/prettier/printer.js +559 -0
- package/dist/src/ast.js +338 -0
- package/dist/src/cli.js +430 -0
- package/dist/src/compiler.js +132 -0
- package/dist/src/emitter.js +791 -0
- package/dist/src/errors.js +5 -0
- package/dist/src/expressions.js +223 -0
- package/dist/src/index.js +22 -0
- package/dist/src/lexer.js +504 -0
- package/dist/src/parser.js +575 -0
- package/dist/src/types.js +122 -0
- package/dist/src/vite-plugin.js +78 -0
- package/dist/types.js +122 -12
- package/dist/vite-plugin.js +78 -63
- package/docs/examples.md +201 -1
- package/docs/grammar.md +90 -1
- package/docs/index.html +260 -37
- package/package.json +12 -10
- package/syntaxes/CoffeeHaml.tmLanguage +815 -868
- package/syntaxes/coffeehaml.tmLanguage.json +352 -161
- package/dist/ast.d.ts +0 -117
- package/dist/ast.d.ts.map +0 -1
- package/dist/ast.js.map +0 -1
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/compiler.d.ts +0 -10
- package/dist/compiler.d.ts.map +0 -1
- package/dist/compiler.js.map +0 -1
- package/dist/emitter.d.ts +0 -4
- package/dist/emitter.d.ts.map +0 -1
- package/dist/emitter.js.map +0 -1
- package/dist/errors.d.ts +0 -3
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/expressions.d.ts +0 -22
- package/dist/expressions.d.ts.map +0 -1
- package/dist/expressions.js.map +0 -1
- package/dist/index.d.ts +0 -5
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lexer.d.ts +0 -30
- package/dist/lexer.d.ts.map +0 -1
- package/dist/lexer.js.map +0 -1
- package/dist/parser.d.ts +0 -10
- package/dist/parser.d.ts.map +0 -1
- package/dist/parser.js.map +0 -1
- package/dist/types.d.ts +0 -76
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/vite-plugin.d.ts +0 -7
- package/dist/vite-plugin.d.ts.map +0 -1
- package/dist/vite-plugin.js.map +0 -1
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
// Generated by CoffeeScript 2.7.0
|
|
2
|
+
// coffeescript-formatter.coffee — CoffeeScript token-based expression formatter
|
|
3
|
+
var DEFAULT_OPTS, EXPR_STARTERS, FOR_KEYWORDS, KEYWORD_SPACE_AFTER, NO_SPACE_AFTER, NO_SPACE_BEFORE, SPACE_AFTER, SPACE_BOTH, _require, getTokenText, hasImplicitTokens, hasMethodChain, isUnaryOp, lineWrap, loadCoffeeScript, needsSpaceBetween, normalizeSpacing, wrapMethodChain;
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
createRequire
|
|
7
|
+
} from 'module';
|
|
8
|
+
|
|
9
|
+
_require = createRequire(import.meta.url);
|
|
10
|
+
|
|
11
|
+
loadCoffeeScript = function() {
|
|
12
|
+
try {
|
|
13
|
+
return _require('coffeescript');
|
|
14
|
+
} catch (error) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// ─── Token types ──────────────────────────────────────────
|
|
20
|
+
// CSToken: { type, value, range, generated?, originalText? }
|
|
21
|
+
|
|
22
|
+
// ─── Spacing categories ───────────────────────────────────
|
|
23
|
+
NO_SPACE_BEFORE = new Set([',', ':', ';', '.', '?.', '::', ')', ']', '}', 'CALL_END', 'PARAM_END', 'INDEX_END', 'POST_IF', 'POST_FOR', 'POST_WHILE', 'TERMINATOR']);
|
|
24
|
+
|
|
25
|
+
NO_SPACE_AFTER = new Set(['.', '?.', '::', '...', '..', '(', '[', '{', 'CALL_START', 'PARAM_START', 'INDEX_START', 'STRING_START', 'INTERPOLATION_START', 'INDENT', '@']);
|
|
26
|
+
|
|
27
|
+
SPACE_AFTER = new Set([',', ':']);
|
|
28
|
+
|
|
29
|
+
SPACE_BOTH = new Set(['=', '?=', '+', '-', 'MATH', '**', 'SHIFT', '&', '|', '^', '&&', '||', '?', '=>', '->', 'COMPARE', 'COMPOUND_ASSIGN', 'RELATION', 'FOR', 'ELSE', 'IF', 'WHILE']);
|
|
30
|
+
|
|
31
|
+
KEYWORD_SPACE_AFTER = new Set(['RETURN', 'THROW', 'NEW', 'TYPEOF', 'INSTANCEOF', 'DELETE', 'CLASS', 'EXTENDS', 'DEFAULT', 'IMPORT', 'EXPORT', 'AWAIT', 'YIELD', 'BREAK', 'CONTINUE', 'SWITCH']);
|
|
32
|
+
|
|
33
|
+
FOR_KEYWORDS = new Set(['FORIN', 'FOROF', 'WHEN', 'BY']);
|
|
34
|
+
|
|
35
|
+
EXPR_STARTERS = new Set(['(', '[', '{', ',', ':', '=', '?=', '+', '-', 'MATH', '**', 'SHIFT', '&', '|', '^', '&&', '||', '?', '=>', '->', 'COMPARE', 'COMPOUND_ASSIGN', 'RETURN', 'INDENT', 'OUTDENT', 'TERMINATOR', 'FOR', 'FORIN', 'FOROF', 'WHILE', 'IF', 'ELSE', 'THROW', 'NEW', 'TYPEOF', 'INSTANCEOF', 'DELETE', 'EXTENDS', 'DEFAULT', 'CALL_START', 'PARAM_START', 'INDEX_START', 'UNARY']);
|
|
36
|
+
|
|
37
|
+
DEFAULT_OPTS = {
|
|
38
|
+
printWidth: 80,
|
|
39
|
+
methodChainAlign: true,
|
|
40
|
+
enabled: true
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// ─── Public API ───────────────────────────────────────────
|
|
44
|
+
export var formatCoffeeScript = function(source, options = {}) {
|
|
45
|
+
var cs, normalized, opts, rawTokens, tokens;
|
|
46
|
+
opts = {...DEFAULT_OPTS, ...options};
|
|
47
|
+
if (!opts.enabled) {
|
|
48
|
+
return source;
|
|
49
|
+
}
|
|
50
|
+
if (!(source && source.trim() !== '')) {
|
|
51
|
+
return source;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
cs = loadCoffeeScript();
|
|
55
|
+
if (!(cs && typeof cs.tokens === 'function')) {
|
|
56
|
+
return source;
|
|
57
|
+
}
|
|
58
|
+
rawTokens = cs.tokens(source);
|
|
59
|
+
if (!(rawTokens && rawTokens.length > 0)) {
|
|
60
|
+
return source;
|
|
61
|
+
}
|
|
62
|
+
tokens = rawTokens.map(function(t) {
|
|
63
|
+
var ref, ref1, ref2, ref3;
|
|
64
|
+
return {
|
|
65
|
+
type: t[0],
|
|
66
|
+
value: t[1],
|
|
67
|
+
range: (ref = (ref1 = t[2]) != null ? ref1.range : void 0) != null ? ref : [0, 0],
|
|
68
|
+
generated: !!((ref2 = t[2]) != null ? ref2.generated : void 0),
|
|
69
|
+
originalText: ((ref3 = t[2]) != null ? ref3.range : void 0) && t[2].range[0] < t[2].range[1] ? source.slice(t[2].range[0], t[2].range[1]) : t[1]
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
if (hasImplicitTokens(tokens)) {
|
|
73
|
+
return source;
|
|
74
|
+
}
|
|
75
|
+
normalized = normalizeSpacing(tokens, source);
|
|
76
|
+
if (normalized.length > opts.printWidth) {
|
|
77
|
+
return lineWrap(normalized, opts, source);
|
|
78
|
+
}
|
|
79
|
+
return normalized;
|
|
80
|
+
} catch (error) {
|
|
81
|
+
return source;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// ─── Block formatting ─────────────────────────────────────
|
|
86
|
+
export var formatCoffeeScriptBlock = function(source, options = {}) {
|
|
87
|
+
var formatted, lines, opts;
|
|
88
|
+
opts = {...DEFAULT_OPTS, ...options};
|
|
89
|
+
if (!opts.enabled) {
|
|
90
|
+
return source;
|
|
91
|
+
}
|
|
92
|
+
if (!(source && source.trim() !== '')) {
|
|
93
|
+
return source;
|
|
94
|
+
}
|
|
95
|
+
lines = source.split('\n');
|
|
96
|
+
formatted = lines.map(function(line) {
|
|
97
|
+
var formattedExpr, leading, ref, ref1, trimmed;
|
|
98
|
+
trimmed = line.trim();
|
|
99
|
+
if (!trimmed) {
|
|
100
|
+
return '';
|
|
101
|
+
}
|
|
102
|
+
leading = (ref = (ref1 = line.match(/^(\s*)/)) != null ? ref1[1] : void 0) != null ? ref : '';
|
|
103
|
+
try {
|
|
104
|
+
formattedExpr = formatCoffeeScript(trimmed, options);
|
|
105
|
+
return leading + formattedExpr;
|
|
106
|
+
} catch (error) {
|
|
107
|
+
return line;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
return formatted.join('\n');
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// ─── Implicit token detection ─────────────────────────────
|
|
114
|
+
hasImplicitTokens = function(tokens) {
|
|
115
|
+
var j, len, ref, t;
|
|
116
|
+
for (j = 0, len = tokens.length; j < len; j++) {
|
|
117
|
+
t = tokens[j];
|
|
118
|
+
if ((ref = t.type) === 'INDENT' || ref === 'OUTDENT' || ref === 'TERMINATOR') {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (t.generated) {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
if (t.range && t.range[0] >= t.range[1]) {
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// ─── Spacing normalization ────────────────────────────────
|
|
132
|
+
normalizeSpacing = function(tokens, originalSource = null) {
|
|
133
|
+
var afterPrevIsExprStart, cur, j, len, parts, prevVisible, prevWasAtExprStart, ref, ref1, ref2, text, trimmed;
|
|
134
|
+
parts = [];
|
|
135
|
+
prevVisible = null;
|
|
136
|
+
prevWasAtExprStart = true;
|
|
137
|
+
afterPrevIsExprStart = true;
|
|
138
|
+
for (j = 0, len = tokens.length; j < len; j++) {
|
|
139
|
+
cur = tokens[j];
|
|
140
|
+
// Skip implicit CALL/PARAM tokens
|
|
141
|
+
if ((ref = cur.type) === 'CALL_START' || ref === 'CALL_END') {
|
|
142
|
+
if (cur.generated) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (cur.range && cur.range[0] >= cur.range[1]) {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if ((ref1 = cur.type) === 'PARAM_START' || ref1 === 'PARAM_END') {
|
|
150
|
+
if (cur.generated) {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (cur.range && cur.range[0] >= cur.range[1]) {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Handle INDENT — represents inline then/when/else/etc from CoffeeScript
|
|
158
|
+
if (cur.type === 'INDENT') {
|
|
159
|
+
text = getTokenText(cur, originalSource);
|
|
160
|
+
trimmed = text != null ? text.trim() : void 0;
|
|
161
|
+
if (trimmed && trimmed !== '') {
|
|
162
|
+
parts.push(' ' + trimmed + ' ');
|
|
163
|
+
prevWasAtExprStart = false;
|
|
164
|
+
afterPrevIsExprStart = true;
|
|
165
|
+
prevVisible = cur;
|
|
166
|
+
}
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (cur.type === 'OUTDENT') {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
// Skip TERMINATOR
|
|
173
|
+
if (cur.type === 'TERMINATOR') {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
// Space before this token
|
|
177
|
+
if (prevVisible && ((ref2 = prevVisible.type) !== 'INDENT' && ref2 !== 'OUTDENT')) {
|
|
178
|
+
if (needsSpaceBetween(prevVisible, cur, prevWasAtExprStart)) {
|
|
179
|
+
parts.push(' ');
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
parts.push(getTokenText(cur, originalSource));
|
|
183
|
+
prevWasAtExprStart = afterPrevIsExprStart;
|
|
184
|
+
afterPrevIsExprStart = EXPR_STARTERS.has(cur.type);
|
|
185
|
+
prevVisible = cur;
|
|
186
|
+
}
|
|
187
|
+
return parts.join('');
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
getTokenText = function(token, originalSource = null) {
|
|
191
|
+
if (token.generated) {
|
|
192
|
+
return token.value;
|
|
193
|
+
}
|
|
194
|
+
if (!(token.range && token.range[0] < token.range[1])) {
|
|
195
|
+
return token.value;
|
|
196
|
+
}
|
|
197
|
+
if (originalSource) {
|
|
198
|
+
return originalSource.slice(token.range[0], token.range[1]);
|
|
199
|
+
}
|
|
200
|
+
return token.value;
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
needsSpaceBetween = function(prev, cur, prevAtExprStart) {
|
|
204
|
+
var text;
|
|
205
|
+
if (NO_SPACE_AFTER.has(prev.type)) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
if (NO_SPACE_BEFORE.has(cur.type)) {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
if (prev.type === '@') {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
if (SPACE_AFTER.has(prev.type)) {
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
if (FOR_KEYWORDS.has(prev.type) || FOR_KEYWORDS.has(cur.type)) {
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
if (KEYWORD_SPACE_AFTER.has(prev.type)) {
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
if (prev.type === 'UNARY') {
|
|
224
|
+
text = prev.originalText || prev.value;
|
|
225
|
+
if (text === '!' || text === '!!') {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
if (SPACE_BOTH.has(prev.type) || SPACE_BOTH.has(cur.type)) {
|
|
231
|
+
if (isUnaryOp(prev, prevAtExprStart)) {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
if (prev.type === 'IDENTIFIER' && cur.type === 'IDENTIFIER') {
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
return false;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
isUnaryOp = function(prev, prevAtExprStart) {
|
|
243
|
+
var ref;
|
|
244
|
+
if ((ref = prev.type) !== '+' && ref !== '-') {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
if (prevAtExprStart) {
|
|
248
|
+
return true;
|
|
249
|
+
}
|
|
250
|
+
if (prev.range && prev.range[0] === 0) {
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
return false;
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
// ─── Line wrapping ────────────────────────────────────────
|
|
257
|
+
lineWrap = function(source, opts, fallback) {
|
|
258
|
+
if (opts.methodChainAlign && hasMethodChain(source)) {
|
|
259
|
+
return wrapMethodChain(source, opts);
|
|
260
|
+
}
|
|
261
|
+
return fallback;
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
hasMethodChain = function(source) {
|
|
265
|
+
return (source.match(/\.[a-zA-Z_$]/g) || []).length >= 2;
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
wrapMethodChain = function(source, _opts) {
|
|
269
|
+
var ch, chars, current, depth, i, indent, result;
|
|
270
|
+
indent = ' ';
|
|
271
|
+
result = [];
|
|
272
|
+
chars = [...source];
|
|
273
|
+
depth = 0;
|
|
274
|
+
current = '';
|
|
275
|
+
i = 0;
|
|
276
|
+
while (i < chars.length) {
|
|
277
|
+
ch = chars[i];
|
|
278
|
+
if (ch === '(' || ch === '[' || ch === '{') {
|
|
279
|
+
depth++;
|
|
280
|
+
}
|
|
281
|
+
if (ch === ')' || ch === ']' || ch === '}') {
|
|
282
|
+
depth--;
|
|
283
|
+
}
|
|
284
|
+
if (ch === '.' && depth === 0 && i > 0 && chars[i - 1] !== '?' && current.trim().length > 0) {
|
|
285
|
+
if (result.length === 0) {
|
|
286
|
+
result.push(current.trimEnd());
|
|
287
|
+
} else {
|
|
288
|
+
result.push(indent + current.trimEnd());
|
|
289
|
+
}
|
|
290
|
+
current = ch;
|
|
291
|
+
i++;
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
current += ch;
|
|
295
|
+
i++;
|
|
296
|
+
}
|
|
297
|
+
if (current.trim().length > 0) {
|
|
298
|
+
if (result.length === 0) {
|
|
299
|
+
result.push(current.trim());
|
|
300
|
+
} else {
|
|
301
|
+
result.push(indent + current.trim());
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
if (result.length > 1) {
|
|
305
|
+
return result.join('\n');
|
|
306
|
+
} else {
|
|
307
|
+
return source;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// Generated by CoffeeScript 2.7.0
|
|
2
|
+
// index.coffee — CoffeeHaml Prettier Plugin entry point
|
|
3
|
+
var _parsers, _printers, coffeeHamlLanguage, coffeeHamlParser, coffeeHamlPrinter, plugin;
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
tokenize
|
|
7
|
+
} from '../lexer.js';
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
parse
|
|
11
|
+
} from '../parser.js';
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
print,
|
|
15
|
+
embedCoffeeScript
|
|
16
|
+
} from './printer.js';
|
|
17
|
+
|
|
18
|
+
import {
|
|
19
|
+
options,
|
|
20
|
+
defaultOptions
|
|
21
|
+
} from './options.js';
|
|
22
|
+
|
|
23
|
+
// ─── Language ──────────────────────────────────────────────
|
|
24
|
+
coffeeHamlLanguage = {
|
|
25
|
+
name: 'CoffeeHaml',
|
|
26
|
+
parsers: ['coffeehaml'],
|
|
27
|
+
extensions: ['.chaml', '.coffeehaml'],
|
|
28
|
+
vscodeLanguageIds: ['coffeehaml']
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// ─── Parser ────────────────────────────────────────────────
|
|
32
|
+
coffeeHamlParser = {
|
|
33
|
+
parse: function(text, _options) {
|
|
34
|
+
var result, tokens;
|
|
35
|
+
tokens = tokenize(text);
|
|
36
|
+
result = parse(tokens);
|
|
37
|
+
if (result.errors.length > 0 && result.document.children.length === 0) {
|
|
38
|
+
throw new Error('CoffeeHaml parse errors:\n' + result.errors.map(function(e) {
|
|
39
|
+
return ` ${e.message}`;
|
|
40
|
+
}).join('\n'));
|
|
41
|
+
}
|
|
42
|
+
return result.document;
|
|
43
|
+
},
|
|
44
|
+
astFormat: 'coffeehaml-ast',
|
|
45
|
+
locStart: function(node) {
|
|
46
|
+
var ref, ref1;
|
|
47
|
+
return (ref = node != null ? (ref1 = node.location) != null ? ref1.offset : void 0 : void 0) != null ? ref : 0;
|
|
48
|
+
},
|
|
49
|
+
locEnd: function(node) {
|
|
50
|
+
if (!(node != null ? node.location : void 0)) {
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
return node.location.offset + node.location.length;
|
|
54
|
+
},
|
|
55
|
+
hasPragma: function(text) {
|
|
56
|
+
return /\/\*\*\s*@format\s*\*\//.test(text) || /^\/\s*@format/.test(text);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// ─── Printer ───────────────────────────────────────────────
|
|
61
|
+
coffeeHamlPrinter = {
|
|
62
|
+
print: function(path, options, printFn, _args) {
|
|
63
|
+
var opts;
|
|
64
|
+
opts = options;
|
|
65
|
+
if (options.originalText) {
|
|
66
|
+
opts.originalText = options.originalText;
|
|
67
|
+
}
|
|
68
|
+
return print(path, opts, printFn);
|
|
69
|
+
},
|
|
70
|
+
embed: function(path, _options) {
|
|
71
|
+
var ref;
|
|
72
|
+
return (ref = embedCoffeeScript(path, print)) != null ? ref : null;
|
|
73
|
+
},
|
|
74
|
+
insertPragma: function(text) {
|
|
75
|
+
return '/** @format */\n' + text;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// ─── Export ────────────────────────────────────────────────
|
|
80
|
+
_parsers = {};
|
|
81
|
+
|
|
82
|
+
_parsers.coffeehaml = coffeeHamlParser;
|
|
83
|
+
|
|
84
|
+
_printers = {};
|
|
85
|
+
|
|
86
|
+
_printers['coffeehaml-ast'] = coffeeHamlPrinter;
|
|
87
|
+
|
|
88
|
+
plugin = {
|
|
89
|
+
languages: [coffeeHamlLanguage],
|
|
90
|
+
parsers: _parsers,
|
|
91
|
+
printers: _printers,
|
|
92
|
+
options,
|
|
93
|
+
defaultOptions
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export default plugin;
|
|
97
|
+
|
|
98
|
+
export {
|
|
99
|
+
options,
|
|
100
|
+
defaultOptions
|
|
101
|
+
} from './options.js';
|
|
102
|
+
|
|
103
|
+
export {
|
|
104
|
+
print
|
|
105
|
+
} from './printer.js';
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// Generated by CoffeeScript 2.7.0
|
|
2
|
+
// options.coffee — CoffeeHaml Prettier formatting options
|
|
3
|
+
export var CAT = {
|
|
4
|
+
STRUCTURE: 'CoffeeHaml: Structure',
|
|
5
|
+
ATTRIBUTES: 'CoffeeHaml: Attributes',
|
|
6
|
+
COFFEESCRIPT: 'CoffeeHaml: CoffeeScript',
|
|
7
|
+
WHITESPACE: 'CoffeeHaml: Whitespace',
|
|
8
|
+
CONTROL_FLOW: 'CoffeeHaml: Control Flow',
|
|
9
|
+
COMMENTS: 'CoffeeHaml: Comments'
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export var options = {
|
|
13
|
+
tagCase: {
|
|
14
|
+
category: CAT.STRUCTURE,
|
|
15
|
+
type: 'choice',
|
|
16
|
+
description: 'Normalize HTML tag casing. Component tags (%MyComponent) never affected.',
|
|
17
|
+
choices: [
|
|
18
|
+
{
|
|
19
|
+
value: 'preserve',
|
|
20
|
+
description: 'Leave tag case as written'
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
value: 'lowercase',
|
|
24
|
+
description: '%DIV to %div (HTML tags only)'
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
implicitDivExpansion: {
|
|
29
|
+
category: CAT.STRUCTURE,
|
|
30
|
+
type: 'boolean',
|
|
31
|
+
description: 'Expand .class to %div.class (anti-idiomatic in HAML).'
|
|
32
|
+
},
|
|
33
|
+
maxChainLength: {
|
|
34
|
+
category: CAT.STRUCTURE,
|
|
35
|
+
type: 'int',
|
|
36
|
+
description: 'Max .class chain length before breaking into indented hierarchy. 0 = always break.'
|
|
37
|
+
},
|
|
38
|
+
inlineThreshold: {
|
|
39
|
+
category: CAT.STRUCTURE,
|
|
40
|
+
type: 'int',
|
|
41
|
+
description: 'Try single-line if estimated width <= this. -1 = never inline children.'
|
|
42
|
+
},
|
|
43
|
+
voidElementStyle: {
|
|
44
|
+
category: CAT.STRUCTURE,
|
|
45
|
+
type: 'choice',
|
|
46
|
+
description: 'How void elements (%br, %img, etc.) are formatted.',
|
|
47
|
+
choices: [
|
|
48
|
+
{
|
|
49
|
+
value: 'self-closing',
|
|
50
|
+
description: 'Self-closing (no children)'
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
value: 'explicit',
|
|
54
|
+
description: 'Preserve %br/ syntax, otherwise self-close'
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
attributeStyle: {
|
|
59
|
+
category: CAT.ATTRIBUTES,
|
|
60
|
+
type: 'choice',
|
|
61
|
+
description: 'Enforce attribute syntax: {braces}, (parens), bare, or preserve.',
|
|
62
|
+
choices: [
|
|
63
|
+
{
|
|
64
|
+
value: 'preserve',
|
|
65
|
+
description: 'Keep as written'
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
value: 'braces',
|
|
69
|
+
description: 'Convert to {CoffeeScript} style'
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
value: 'parens',
|
|
73
|
+
description: 'Convert to HTML (parens) style'
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
value: 'bare',
|
|
77
|
+
description: 'Convert to bare HAML style'
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
attributeMultilineThreshold: {
|
|
82
|
+
category: CAT.ATTRIBUTES,
|
|
83
|
+
type: 'int',
|
|
84
|
+
description: 'Break attributes across lines when count >= this. 0 = always multiline.'
|
|
85
|
+
},
|
|
86
|
+
attributeSort: {
|
|
87
|
+
category: CAT.ATTRIBUTES,
|
|
88
|
+
type: 'choice',
|
|
89
|
+
description: 'Sort attribute keys (spread attributes always last).',
|
|
90
|
+
choices: [
|
|
91
|
+
{
|
|
92
|
+
value: 'none',
|
|
93
|
+
description: 'Preserve author order'
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
value: 'alphabetical',
|
|
97
|
+
description: 'Sort A to Z'
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
value: 'idiomatic',
|
|
101
|
+
description: 'id first, class second, rest A to Z'
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
},
|
|
105
|
+
quoteStyle: {
|
|
106
|
+
category: CAT.ATTRIBUTES,
|
|
107
|
+
type: 'choice',
|
|
108
|
+
description: 'Quote style for bare/HAML attributes.',
|
|
109
|
+
choices: [
|
|
110
|
+
{
|
|
111
|
+
value: 'preserve',
|
|
112
|
+
description: 'Keep as written'
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
value: 'double',
|
|
116
|
+
description: 'Force double quotes'
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
value: 'single',
|
|
120
|
+
description: 'Force single quotes'
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
coffeeScriptFormat: {
|
|
125
|
+
category: CAT.COFFEESCRIPT,
|
|
126
|
+
type: 'boolean',
|
|
127
|
+
description: 'Format CoffeeScript expressions using prettier/plugins/coffeescript.'
|
|
128
|
+
},
|
|
129
|
+
methodChainAlign: {
|
|
130
|
+
category: CAT.COFFEESCRIPT,
|
|
131
|
+
type: 'boolean',
|
|
132
|
+
description: 'Align .method chains on newlines for = expressions.'
|
|
133
|
+
},
|
|
134
|
+
blankLineHandling: {
|
|
135
|
+
category: CAT.WHITESPACE,
|
|
136
|
+
type: 'choice',
|
|
137
|
+
description: 'How blank lines between sibling elements are treated.',
|
|
138
|
+
choices: [
|
|
139
|
+
{
|
|
140
|
+
value: 'preserve',
|
|
141
|
+
description: 'Keep single; collapse multiples'
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
value: 'collapse',
|
|
145
|
+
description: 'Remove all blank lines between siblings'
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
value: 'respect',
|
|
149
|
+
description: 'Keep exactly as written'
|
|
150
|
+
}
|
|
151
|
+
]
|
|
152
|
+
},
|
|
153
|
+
trailingWhitespace: {
|
|
154
|
+
category: CAT.WHITESPACE,
|
|
155
|
+
type: 'choice',
|
|
156
|
+
description: 'Handle trailing whitespace.',
|
|
157
|
+
choices: [
|
|
158
|
+
{
|
|
159
|
+
value: 'remove',
|
|
160
|
+
description: 'Strip trailing whitespace'
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
value: 'preserve',
|
|
164
|
+
description: 'Leave as written'
|
|
165
|
+
}
|
|
166
|
+
]
|
|
167
|
+
},
|
|
168
|
+
continuationStyle: {
|
|
169
|
+
category: CAT.CONTROL_FLOW,
|
|
170
|
+
type: 'choice',
|
|
171
|
+
description: 'How \\ continuations are formatted.',
|
|
172
|
+
choices: [
|
|
173
|
+
{
|
|
174
|
+
value: 'preserve',
|
|
175
|
+
description: 'Keep as written'
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
value: 'indent',
|
|
179
|
+
description: 'Always use indented continuation'
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
value: 'backslash',
|
|
183
|
+
description: 'Always use \\ continuation'
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
},
|
|
187
|
+
controlFlowInline: {
|
|
188
|
+
category: CAT.CONTROL_FLOW,
|
|
189
|
+
type: 'boolean',
|
|
190
|
+
description: 'Allow - if x then .ok one-liners (anti-Prettier by default).'
|
|
191
|
+
},
|
|
192
|
+
statementMerging: {
|
|
193
|
+
category: CAT.CONTROL_FLOW,
|
|
194
|
+
type: 'choice',
|
|
195
|
+
description: 'Merge consecutive - lines into a single indented block. Only childless statements.',
|
|
196
|
+
choices: [
|
|
197
|
+
{
|
|
198
|
+
value: 'preserve',
|
|
199
|
+
description: 'Keep each - line separate'
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
value: 'merge',
|
|
203
|
+
description: 'Merge consecutive childless statements into one indented block'
|
|
204
|
+
}
|
|
205
|
+
]
|
|
206
|
+
},
|
|
207
|
+
commentFormat: {
|
|
208
|
+
category: CAT.COMMENTS,
|
|
209
|
+
type: 'boolean',
|
|
210
|
+
description: 'Reflow/word-wrap comment text (experimental).'
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
export var defaultOptions = {
|
|
215
|
+
tagCase: 'preserve',
|
|
216
|
+
implicitDivExpansion: false,
|
|
217
|
+
maxChainLength: 4,
|
|
218
|
+
inlineThreshold: -1,
|
|
219
|
+
voidElementStyle: 'self-closing',
|
|
220
|
+
attributeStyle: 'preserve',
|
|
221
|
+
attributeMultilineThreshold: 1,
|
|
222
|
+
attributeSort: 'none',
|
|
223
|
+
quoteStyle: 'preserve',
|
|
224
|
+
coffeeScriptFormat: true,
|
|
225
|
+
methodChainAlign: true,
|
|
226
|
+
blankLineHandling: 'preserve',
|
|
227
|
+
trailingWhitespace: 'remove',
|
|
228
|
+
continuationStyle: 'indent',
|
|
229
|
+
controlFlowInline: false,
|
|
230
|
+
statementMerging: 'preserve',
|
|
231
|
+
commentFormat: false
|
|
232
|
+
};
|