prettier-plugin-wolfram 0.7.9 → 0.7.11
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
CHANGED
|
@@ -129,6 +129,7 @@ Typical `.prettierrc` example:
|
|
|
129
129
|
"alignRuleValues": false,
|
|
130
130
|
"documentationCommentColumn": 0,
|
|
131
131
|
"documentationCommentPadding": 2,
|
|
132
|
+
"documentationCommentMarkers": false,
|
|
132
133
|
"topLevelSpacingMode": "declarations",
|
|
133
134
|
"preserveTildeInfixFunctions": "",
|
|
134
135
|
"moduleVarsBreakThreshold": 40,
|
|
@@ -158,6 +159,7 @@ this plugin.
|
|
|
158
159
|
| `wolfram.alignRuleValues` | boolean | `false` | Vertically aligns `Rule` and `RuleDelayed` values in multiline argument, list, and association layouts. |
|
|
159
160
|
| `wolfram.documentationCommentColumn` | integer | `0` | Column for trailing documentation comments. `0` computes a column per contiguous block. |
|
|
160
161
|
| `wolfram.documentationCommentPadding` | integer | `2` | Minimum spaces between code and an aligned trailing documentation comment when the column is computed automatically. |
|
|
162
|
+
| `wolfram.documentationCommentMarkers` | boolean | `false` | Treats trailing comments beginning with `<` as documentation comments aligned at `printWidth`. |
|
|
161
163
|
| `wolfram.topLevelSpacingMode` | string | `"declarations"` | Top-level blank-line policy. Allowed values are `declarations`, `all`, and `none`. |
|
|
162
164
|
| `wolfram.preserveTildeInfixFunctions` | string | `""` | Comma-separated function names that stay in `x ~ f ~ y` form instead of normalizing to `f[x, y]`. |
|
|
163
165
|
| `wolfram.moduleVarsBreakThreshold` | integer | `40` | Character count at which block-structure variable lists break across lines. |
|
package/package.json
CHANGED
package/src/options.js
CHANGED
|
@@ -109,6 +109,13 @@ export const wolframOptions = {
|
|
|
109
109
|
description:
|
|
110
110
|
"Minimum spaces between code and an aligned trailing documentation comment in auto mode.",
|
|
111
111
|
},
|
|
112
|
+
documentationCommentMarkers: {
|
|
113
|
+
type: "boolean",
|
|
114
|
+
default: false,
|
|
115
|
+
legacyName: "wolframDocumentationCommentMarkers",
|
|
116
|
+
description:
|
|
117
|
+
"Treat trailing comments beginning with < as documentation comments aligned at printWidth.",
|
|
118
|
+
},
|
|
112
119
|
topLevelSpacingMode: {
|
|
113
120
|
type: "string",
|
|
114
121
|
default: "declarations",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { doc } from "prettier";
|
|
2
2
|
import { normalizeWolframOptions } from "../options.js";
|
|
3
3
|
import { sameLineCommentSeparator } from "./commentSpacing.js";
|
|
4
|
+
import { sourceLineGap } from "./sourceLines.js";
|
|
4
5
|
|
|
5
6
|
export function joinDocsWithSpace(docs) {
|
|
6
7
|
const nonEmptyDocs = docs.filter(
|
|
@@ -19,7 +20,15 @@ export function isDocumentationCommentMarkerText(text) {
|
|
|
19
20
|
return /^\(\*\s*</u.test(String(text ?? ""));
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
function documentationCommentMarkersEnabled(options) {
|
|
24
|
+
return (
|
|
25
|
+
normalizeWolframOptions(options).wolframDocumentationCommentMarkers ===
|
|
26
|
+
true
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function hasDocumentationCommentMarker(comment, options) {
|
|
31
|
+
if (!documentationCommentMarkersEnabled(options)) return false;
|
|
23
32
|
const node = comment?.node ?? comment;
|
|
24
33
|
return (
|
|
25
34
|
node?.kind === "Token`Comment" &&
|
|
@@ -27,6 +36,25 @@ export function hasDocumentationCommentMarker(comment) {
|
|
|
27
36
|
);
|
|
28
37
|
}
|
|
29
38
|
|
|
39
|
+
function hasMarkedDocumentationCommentEntry(entry, options) {
|
|
40
|
+
return (entry?.trailingComments ?? []).some((comment) =>
|
|
41
|
+
hasDocumentationCommentMarker(comment, options),
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function isCommaEntry(entry) {
|
|
46
|
+
return entry?.node?.type === "LeafNode" && entry.node.kind === "Token`Comma";
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function canAttachMarkedTrailingComment(previousEntry, commentEntry, options) {
|
|
50
|
+
return (
|
|
51
|
+
previousEntry &&
|
|
52
|
+
!isCommaEntry(previousEntry) &&
|
|
53
|
+
hasDocumentationCommentMarker(commentEntry, options) &&
|
|
54
|
+
sourceLineGap(previousEntry.node, commentEntry.node, options) === 0
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
30
58
|
function normalizeDocumentationCommentMarker(text) {
|
|
31
59
|
return String(text).replace(/^\(\*\s*<\s*/u, "(* < ");
|
|
32
60
|
}
|
|
@@ -34,6 +62,7 @@ function normalizeDocumentationCommentMarker(text) {
|
|
|
34
62
|
function normalizedCommentDoc(comment, options) {
|
|
35
63
|
const rendered = renderFlatDoc(comment.doc, options);
|
|
36
64
|
if (
|
|
65
|
+
!documentationCommentMarkersEnabled(options) ||
|
|
37
66
|
!isDocumentationCommentMarkerText(rendered) ||
|
|
38
67
|
rendered.includes("\n")
|
|
39
68
|
) {
|
|
@@ -62,6 +91,30 @@ export function joinCommentDocs(comments, options) {
|
|
|
62
91
|
return joined;
|
|
63
92
|
}
|
|
64
93
|
|
|
94
|
+
export function withMarkedTrailingCommentDocs(entries, options) {
|
|
95
|
+
const result = [];
|
|
96
|
+
|
|
97
|
+
for (const entry of entries) {
|
|
98
|
+
const previousEntry = result[result.length - 1];
|
|
99
|
+
if (canAttachMarkedTrailingComment(previousEntry, entry, options)) {
|
|
100
|
+
previousEntry.trailingComments ??= [];
|
|
101
|
+
previousEntry.trailingComments.push({
|
|
102
|
+
node: entry.node,
|
|
103
|
+
doc: entry.doc,
|
|
104
|
+
});
|
|
105
|
+
previousEntry.trailingCommentDoc = joinCommentDocs(
|
|
106
|
+
previousEntry.trailingComments,
|
|
107
|
+
options,
|
|
108
|
+
);
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
result.push(entry);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
|
|
65
118
|
export function renderFlatDoc(docNode, options) {
|
|
66
119
|
const rendered = doc.printer.printDocToString(docNode, {
|
|
67
120
|
printWidth: 100000,
|
|
@@ -76,10 +129,18 @@ export function documentationCommentColumn(
|
|
|
76
129
|
entries,
|
|
77
130
|
options,
|
|
78
131
|
suffixForEntry = () => "",
|
|
132
|
+
columnOffset = 0,
|
|
79
133
|
) {
|
|
80
134
|
options = normalizeWolframOptions(options);
|
|
81
135
|
const manual = options.wolframDocumentationCommentColumn ?? 0;
|
|
82
|
-
if (manual > 0) return manual;
|
|
136
|
+
if (manual > 0) return Math.max(1, manual - columnOffset);
|
|
137
|
+
if (
|
|
138
|
+
entries.some((entry) =>
|
|
139
|
+
hasMarkedDocumentationCommentEntry(entry, options),
|
|
140
|
+
)
|
|
141
|
+
) {
|
|
142
|
+
return Math.max(1, (options.printWidth ?? 80) - columnOffset);
|
|
143
|
+
}
|
|
83
144
|
const padding = Math.max(
|
|
84
145
|
1,
|
|
85
146
|
options.wolframDocumentationCommentPadding ?? 2,
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
// src/translator/nodes/call.js
|
|
2
2
|
import { doc } from "prettier";
|
|
3
3
|
const { builders } = doc;
|
|
4
|
-
import { isComment, isTrivia } from "./leaf.js";
|
|
4
|
+
import { isComment, isTrivia, stringLineIndentDepth } from "./leaf.js";
|
|
5
5
|
import { alignedRuleDoc, withAlignedRuleValues } from "../ruleAlignment.js";
|
|
6
6
|
import { commentBoundarySeparator } from "../commentSpacing.js";
|
|
7
|
+
import {
|
|
8
|
+
documentationCommentColumn,
|
|
9
|
+
withAlignedTrailingComment,
|
|
10
|
+
withMarkedTrailingCommentDocs,
|
|
11
|
+
} from "../docComments.js";
|
|
7
12
|
import { normalizeWolframOptions } from "../../options.js";
|
|
8
|
-
const { group, indent, softline, line } = builders;
|
|
13
|
+
const { group, indent, softline, line, hardline } = builders;
|
|
9
14
|
|
|
10
15
|
const BRACKET_KINDS = new Set(["Token`OpenSquare", "Token`CloseSquare"]);
|
|
11
16
|
|
|
@@ -14,7 +19,7 @@ function isBracketToken(node) {
|
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
function isCommaToken(node) {
|
|
17
|
-
return node
|
|
22
|
+
return node?.type === "LeafNode" && node.kind === "Token`Comma";
|
|
18
23
|
}
|
|
19
24
|
|
|
20
25
|
function nextContentEntry(entries, startIndex) {
|
|
@@ -154,19 +159,48 @@ function printedEntries(path, print, entries) {
|
|
|
154
159
|
}));
|
|
155
160
|
}
|
|
156
161
|
|
|
157
|
-
function sequenceDocs(
|
|
162
|
+
function sequenceDocs(rawEntries, options, itemKind, columnOffset = 0) {
|
|
163
|
+
const entries = withMarkedTrailingCommentDocs(rawEntries, options);
|
|
158
164
|
const docs = [];
|
|
159
165
|
const commaGap = options.wolframSpaceAfterComma ? line : softline;
|
|
160
166
|
const alignmentGroupId = entries.some((entry) => entry.alignedRuleDoc)
|
|
161
167
|
? Symbol("wolfram-align-rule-values")
|
|
162
168
|
: null;
|
|
169
|
+
for (let i = 0; i < entries.length; i++) {
|
|
170
|
+
if (entries[i].trailingCommentDoc) {
|
|
171
|
+
entries[i].trailingCommentSuffix = trailingCommentSuffix(
|
|
172
|
+
entries,
|
|
173
|
+
i,
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
const trailingCommentEntries = entries.filter(
|
|
178
|
+
(entry) => entry.trailingCommentDoc,
|
|
179
|
+
);
|
|
180
|
+
const trailingCommentColumn =
|
|
181
|
+
trailingCommentEntries.length > 0
|
|
182
|
+
? documentationCommentColumn(
|
|
183
|
+
trailingCommentEntries,
|
|
184
|
+
options,
|
|
185
|
+
(entry) => entry.trailingCommentSuffix ?? "",
|
|
186
|
+
columnOffset,
|
|
187
|
+
)
|
|
188
|
+
: null;
|
|
163
189
|
let previousKind = null;
|
|
164
190
|
|
|
165
191
|
for (let i = 0; i < entries.length; i++) {
|
|
166
192
|
const entry = entries[i];
|
|
167
193
|
if (isCommaToken(entry.node)) {
|
|
168
|
-
if (previousKind === null || previousKind === "comma") continue;
|
|
169
194
|
const previousEntry = previousContentEntry(entries, i);
|
|
195
|
+
if (
|
|
196
|
+
previousEntry?.trailingCommentDoc &&
|
|
197
|
+
previousEntry.trailingCommentSuffix === ","
|
|
198
|
+
) {
|
|
199
|
+
previousKind = "comma";
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (previousKind === null || previousKind === "comma") continue;
|
|
170
204
|
const followingEntry = nextContentEntry(entries, i);
|
|
171
205
|
const separator =
|
|
172
206
|
followingEntry &&
|
|
@@ -192,7 +226,27 @@ function sequenceDocs(entries, options, itemKind) {
|
|
|
192
226
|
);
|
|
193
227
|
}
|
|
194
228
|
|
|
195
|
-
|
|
229
|
+
const entryDoc = alignedRuleDoc(entry, alignmentGroupId);
|
|
230
|
+
if (entry.trailingCommentDoc) {
|
|
231
|
+
docs.push(
|
|
232
|
+
withAlignedTrailingComment(
|
|
233
|
+
{ ...entry, doc: entryDoc },
|
|
234
|
+
options,
|
|
235
|
+
trailingCommentColumn,
|
|
236
|
+
entry.trailingCommentSuffix ?? "",
|
|
237
|
+
),
|
|
238
|
+
);
|
|
239
|
+
if (
|
|
240
|
+
entry.trailingCommentSuffix === "," &&
|
|
241
|
+
nextContentEntry(entries, i)
|
|
242
|
+
) {
|
|
243
|
+
docs.push(hardline);
|
|
244
|
+
previousKind = "comma";
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
docs.push(entryDoc);
|
|
249
|
+
}
|
|
196
250
|
previousKind = isComment(entry.node) ? "comment" : itemKind;
|
|
197
251
|
}
|
|
198
252
|
|
|
@@ -205,6 +259,14 @@ function grouped(contents, alignmentGroupId) {
|
|
|
205
259
|
: group(contents);
|
|
206
260
|
}
|
|
207
261
|
|
|
262
|
+
function contentColumnOffset(path, options) {
|
|
263
|
+
return stringLineIndentDepth(path) * (options.tabWidth ?? 2);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function trailingCommentSuffix(entries, index) {
|
|
267
|
+
return isCommaToken(entries[index + 1]?.node) ? "," : "";
|
|
268
|
+
}
|
|
269
|
+
|
|
208
270
|
function printPartCall(path, options, print, node, head) {
|
|
209
271
|
const partEntry = partGroupEntry(node);
|
|
210
272
|
if (!partEntry) return null;
|
|
@@ -223,7 +285,12 @@ function printPartCall(path, options, print, node, head) {
|
|
|
223
285
|
|
|
224
286
|
if (args.length === 0) return [head, "[[]]"];
|
|
225
287
|
|
|
226
|
-
const { docs, alignmentGroupId } = sequenceDocs(
|
|
288
|
+
const { docs, alignmentGroupId } = sequenceDocs(
|
|
289
|
+
entries,
|
|
290
|
+
options,
|
|
291
|
+
"part",
|
|
292
|
+
contentColumnOffset(path, options),
|
|
293
|
+
);
|
|
227
294
|
return grouped(
|
|
228
295
|
[head, "[[", indent([softline, ...docs]), softline, "]]"],
|
|
229
296
|
alignmentGroupId,
|
|
@@ -246,7 +313,12 @@ export function printCall(path, options, print, node) {
|
|
|
246
313
|
|
|
247
314
|
if (args.length === 0) return [head, "[]"];
|
|
248
315
|
|
|
249
|
-
const { docs, alignmentGroupId } = sequenceDocs(
|
|
316
|
+
const { docs, alignmentGroupId } = sequenceDocs(
|
|
317
|
+
entries,
|
|
318
|
+
options,
|
|
319
|
+
"arg",
|
|
320
|
+
contentColumnOffset(path, options),
|
|
321
|
+
);
|
|
250
322
|
const contents = [head, "[", indent([softline, ...docs]), softline, "]"];
|
|
251
323
|
|
|
252
324
|
return grouped(contents, alignmentGroupId);
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
// src/translator/nodes/group.js
|
|
2
2
|
import { doc } from "prettier";
|
|
3
3
|
const { builders } = doc;
|
|
4
|
-
import { isComment, isTrivia } from "./leaf.js";
|
|
4
|
+
import { isComment, isTrivia, stringLineIndentDepth } from "./leaf.js";
|
|
5
5
|
import { alignedRuleDoc, withAlignedRuleValues } from "../ruleAlignment.js";
|
|
6
6
|
import { commentBoundarySeparator } from "../commentSpacing.js";
|
|
7
|
+
import {
|
|
8
|
+
documentationCommentColumn,
|
|
9
|
+
withAlignedTrailingComment,
|
|
10
|
+
withMarkedTrailingCommentDocs,
|
|
11
|
+
} from "../docComments.js";
|
|
7
12
|
import { normalizeWolframOptions } from "../../options.js";
|
|
8
|
-
const { group, indent, softline, line } = builders;
|
|
13
|
+
const { group, indent, softline, line, hardline } = builders;
|
|
9
14
|
|
|
10
15
|
const GROUP_DELIMITERS = {
|
|
11
16
|
GroupSquare: ["[", "]"],
|
|
@@ -32,7 +37,7 @@ function isBracketToken(node) {
|
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
function isCommaToken(node) {
|
|
35
|
-
return node
|
|
40
|
+
return node?.type === "LeafNode" && node.kind === "Token`Comma";
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
function nextContentEntry(entries, startIndex) {
|
|
@@ -96,14 +101,25 @@ function sequenceEntries(path, print, node) {
|
|
|
96
101
|
}, []);
|
|
97
102
|
}
|
|
98
103
|
|
|
104
|
+
function contentColumnOffset(path, options) {
|
|
105
|
+
return stringLineIndentDepth(path) * (options.tabWidth ?? 2);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function trailingCommentSuffix(entries, index) {
|
|
109
|
+
return isCommaToken(entries[index + 1]?.node) ? "," : "";
|
|
110
|
+
}
|
|
111
|
+
|
|
99
112
|
export function printGroup(path, options, print, node) {
|
|
100
113
|
options = normalizeWolframOptions(options);
|
|
101
114
|
const [open, close] = GROUP_DELIMITERS[node.kind] ?? ["{", "}"];
|
|
102
|
-
const entries =
|
|
103
|
-
|
|
104
|
-
|
|
115
|
+
const entries = withMarkedTrailingCommentDocs(
|
|
116
|
+
withAlignedRuleValues(
|
|
117
|
+
sequenceEntries(path, print, node),
|
|
118
|
+
path,
|
|
119
|
+
options,
|
|
120
|
+
print,
|
|
121
|
+
),
|
|
105
122
|
options,
|
|
106
|
-
print,
|
|
107
123
|
);
|
|
108
124
|
|
|
109
125
|
if (entries.length === 0) return `${open}${close}`;
|
|
@@ -113,13 +129,41 @@ export function printGroup(path, options, print, node) {
|
|
|
113
129
|
const alignmentGroupId = entries.some((entry) => entry.alignedRuleDoc)
|
|
114
130
|
? Symbol("wolfram-align-rule-values")
|
|
115
131
|
: null;
|
|
132
|
+
for (let i = 0; i < entries.length; i++) {
|
|
133
|
+
if (entries[i].trailingCommentDoc) {
|
|
134
|
+
entries[i].trailingCommentSuffix = trailingCommentSuffix(
|
|
135
|
+
entries,
|
|
136
|
+
i,
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const trailingCommentEntries = entries.filter(
|
|
141
|
+
(entry) => entry.trailingCommentDoc,
|
|
142
|
+
);
|
|
143
|
+
const trailingCommentColumn =
|
|
144
|
+
trailingCommentEntries.length > 0
|
|
145
|
+
? documentationCommentColumn(
|
|
146
|
+
trailingCommentEntries,
|
|
147
|
+
options,
|
|
148
|
+
(entry) => entry.trailingCommentSuffix ?? "",
|
|
149
|
+
contentColumnOffset(path, options),
|
|
150
|
+
)
|
|
151
|
+
: null;
|
|
116
152
|
let previousKind = null;
|
|
117
153
|
|
|
118
154
|
for (let i = 0; i < entries.length; i++) {
|
|
119
155
|
const entry = entries[i];
|
|
120
156
|
if (isCommaToken(entry.node)) {
|
|
121
|
-
if (previousKind === null || previousKind === "comma") continue;
|
|
122
157
|
const previousEntry = previousContentEntry(entries, i);
|
|
158
|
+
if (
|
|
159
|
+
previousEntry?.trailingCommentDoc &&
|
|
160
|
+
previousEntry.trailingCommentSuffix === ","
|
|
161
|
+
) {
|
|
162
|
+
previousKind = "comma";
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (previousKind === null || previousKind === "comma") continue;
|
|
123
167
|
const followingEntry = nextContentEntry(entries, i);
|
|
124
168
|
const separator =
|
|
125
169
|
followingEntry &&
|
|
@@ -145,7 +189,27 @@ export function printGroup(path, options, print, node) {
|
|
|
145
189
|
);
|
|
146
190
|
}
|
|
147
191
|
|
|
148
|
-
|
|
192
|
+
const entryDoc = alignedRuleDoc(entry, alignmentGroupId);
|
|
193
|
+
if (entry.trailingCommentDoc) {
|
|
194
|
+
docs.push(
|
|
195
|
+
withAlignedTrailingComment(
|
|
196
|
+
{ ...entry, doc: entryDoc },
|
|
197
|
+
options,
|
|
198
|
+
trailingCommentColumn,
|
|
199
|
+
entry.trailingCommentSuffix ?? "",
|
|
200
|
+
),
|
|
201
|
+
);
|
|
202
|
+
if (
|
|
203
|
+
entry.trailingCommentSuffix === "," &&
|
|
204
|
+
nextContentEntry(entries, i)
|
|
205
|
+
) {
|
|
206
|
+
docs.push(hardline);
|
|
207
|
+
previousKind = "comma";
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
} else {
|
|
211
|
+
docs.push(entryDoc);
|
|
212
|
+
}
|
|
149
213
|
previousKind = isComment(entry.node) ? "comment" : "item";
|
|
150
214
|
}
|
|
151
215
|
|
|
@@ -192,7 +192,9 @@ export function printInfix(node, options, print) {
|
|
|
192
192
|
(entry) => entry.trailingCommentDoc,
|
|
193
193
|
);
|
|
194
194
|
const hasMarkedDocumentationComment = trailingEntries.some((entry) =>
|
|
195
|
-
entry.trailingComments.some(
|
|
195
|
+
entry.trailingComments.some((comment) =>
|
|
196
|
+
hasDocumentationCommentMarker(comment, options),
|
|
197
|
+
),
|
|
196
198
|
);
|
|
197
199
|
const alignTrailingComments =
|
|
198
200
|
(options.wolframDocumentationCommentColumn ?? 0) > 0 ||
|