coffeehaml 0.7.3 → 0.7.5
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/coffeescript-formatter.js +309 -0
- package/dist/lexer.js +46 -1
- package/dist/options.js +232 -0
- package/dist/parser.js +117 -3
- package/dist/prettier/coffeescript-formatter.js +2 -1
- package/dist/prettier/printer.js +55 -29
- package/dist/printer.js +583 -0
- package/package.json +1 -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
|
+
};
|
package/dist/lexer.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Generated by CoffeeScript 2.7.0
|
|
2
2
|
// lexer.coffee — CoffeeHaml tokenizer
|
|
3
3
|
// Converts raw .chaml source into a token stream with INDENT/DEDENT
|
|
4
|
-
var countIndent, dedentToken, extractBracketed, indentToken, isHamlConstruct, parseModifiersAndAttrs, preMergeBracketLines, tokenizeLine;
|
|
4
|
+
var countIndent, dedentToken, extractBracketed, indentToken, isHamlConstruct, looksLikeBareAttributes, parseModifiersAndAttrs, preMergeBracketLines, tokenizeLine;
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
SourceLocation
|
|
@@ -14,6 +14,7 @@ export var TokenType = {
|
|
|
14
14
|
ID: 'ID',
|
|
15
15
|
ATTRS_PAREN: 'ATTRS_PAREN',
|
|
16
16
|
ATTRS_BRACE: 'ATTRS_BRACE',
|
|
17
|
+
ATTRS_BARE: 'ATTRS_BARE',
|
|
17
18
|
OUTPUT: 'OUTPUT',
|
|
18
19
|
OUTPUT_UNESC: 'OUTPUT_UNESC',
|
|
19
20
|
CONTROL: 'CONTROL',
|
|
@@ -222,6 +223,12 @@ tokenizeLine = function(content, lineStartOffset, _lineLength, filename = null,
|
|
|
222
223
|
value: remaining.slice(2).trimStart(),
|
|
223
224
|
location: loc(trimmedOffset + 2, content.length)
|
|
224
225
|
});
|
|
226
|
+
} else if (looksLikeBareAttributes(remaining)) {
|
|
227
|
+
tokens.push({
|
|
228
|
+
type: TokenType.ATTRS_BARE,
|
|
229
|
+
value: remaining,
|
|
230
|
+
location: loc(trimmedOffset, content.length)
|
|
231
|
+
});
|
|
225
232
|
} else if (!(remaining.startsWith('{') || remaining.startsWith('('))) {
|
|
226
233
|
tokens.push({
|
|
227
234
|
type: TokenType.TEXT,
|
|
@@ -261,6 +268,12 @@ tokenizeLine = function(content, lineStartOffset, _lineLength, filename = null,
|
|
|
261
268
|
value: remaining.slice(2).trimStart(),
|
|
262
269
|
location: loc(trimmedOffset + 2, content.length)
|
|
263
270
|
});
|
|
271
|
+
} else if (looksLikeBareAttributes(remaining)) {
|
|
272
|
+
tokens.push({
|
|
273
|
+
type: TokenType.ATTRS_BARE,
|
|
274
|
+
value: remaining,
|
|
275
|
+
location: loc(trimmedOffset, content.length)
|
|
276
|
+
});
|
|
264
277
|
} else if (!(remaining.startsWith('{') || remaining.startsWith('('))) {
|
|
265
278
|
tokens.push({
|
|
266
279
|
type: TokenType.TEXT,
|
|
@@ -468,6 +481,38 @@ parseModifiersAndAttrs = function(content, startPos, lineStartOffset, filename =
|
|
|
468
481
|
};
|
|
469
482
|
|
|
470
483
|
// ─── Helpers ───────────────────────────────────────────────
|
|
484
|
+
|
|
485
|
+
// Detects bare HTML-style attributes: key="val", key='val', key={expr}
|
|
486
|
+
looksLikeBareAttributes = function(text) {
|
|
487
|
+
var j, len, part, parts, ref;
|
|
488
|
+
if (!(text && text.length > 0)) {
|
|
489
|
+
return false;
|
|
490
|
+
}
|
|
491
|
+
if (!text.includes('=')) {
|
|
492
|
+
// Must contain at least one = sign
|
|
493
|
+
return false;
|
|
494
|
+
}
|
|
495
|
+
// Split on whitespace, skip empty
|
|
496
|
+
parts = (ref = text.match(/\S+/g)) != null ? ref : [];
|
|
497
|
+
if (parts.length === 0) {
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
// At least one part must look like key=value or be {expr}
|
|
501
|
+
for (j = 0, len = parts.length; j < len; j++) {
|
|
502
|
+
part = parts[j];
|
|
503
|
+
if (/^[\w-]+=/.test(part)) { // key="val" or key='val' or key={expr}
|
|
504
|
+
return true;
|
|
505
|
+
}
|
|
506
|
+
if (/^[\w-]+\{/.test(part)) { // key{...} alternative
|
|
507
|
+
return true;
|
|
508
|
+
}
|
|
509
|
+
if (/^=\{/.test(part)) { // ={expr}
|
|
510
|
+
return true;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
return false;
|
|
514
|
+
};
|
|
515
|
+
|
|
471
516
|
isHamlConstruct = function(content) {
|
|
472
517
|
var fc;
|
|
473
518
|
fc = content[0];
|
package/dist/options.js
ADDED
|
@@ -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
|
+
};
|