@herb-tools/printer 0.6.0

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.
@@ -0,0 +1,325 @@
1
+ import { Visitor, isToken, isParseResult } from "@herb-tools/core";
2
+ import { PrintContext } from "./print-context.js";
3
+ /**
4
+ * Default print options used when none are provided
5
+ */
6
+ export const DEFAULT_PRINT_OPTIONS = {
7
+ ignoreErrors: false
8
+ };
9
+ export class Printer extends Visitor {
10
+ context = new PrintContext();
11
+ /**
12
+ * Static method to print a node without creating an instance
13
+ *
14
+ * @param input - The AST Node, Token, or ParseResult to print
15
+ * @param options - Print options to control behavior
16
+ * @returns The printed string representation of the input
17
+ * @throws {Error} When node has parse errors and ignoreErrors is false
18
+ */
19
+ static print(input, options = DEFAULT_PRINT_OPTIONS) {
20
+ const printer = new this();
21
+ return printer.print(input, options);
22
+ }
23
+ /**
24
+ * Print a node, token, or parse result to a string
25
+ *
26
+ * @param input - The AST Node, Token, or ParseResult to print
27
+ * @param options - Print options to control behavior
28
+ * @returns The printed string representation of the input
29
+ * @throws {Error} When node has parse errors and ignoreErrors is false
30
+ */
31
+ print(input, options = DEFAULT_PRINT_OPTIONS) {
32
+ if (isToken(input)) {
33
+ return input.value;
34
+ }
35
+ const node = isParseResult(input) ? input.value : input;
36
+ if (options.ignoreErrors === false && node.recursiveErrors().length > 0) {
37
+ throw new Error(`Cannot print the node (${node.type}) since it or any of its children has parse errors. Either pass in a valid Node or call \`print()\` using \`print(node, { ignoreErrors: true })\``);
38
+ }
39
+ this.context.reset();
40
+ this.visit(node);
41
+ return this.context.getOutput();
42
+ }
43
+ visitDocumentNode(node) {
44
+ this.visitChildNodes(node);
45
+ }
46
+ visitLiteralNode(node) {
47
+ this.context.write(node.content);
48
+ }
49
+ visitHTMLTextNode(node) {
50
+ this.write(node.content);
51
+ }
52
+ visitWhitespaceNode(node) {
53
+ if (node.value) {
54
+ this.write(node.value.value);
55
+ }
56
+ }
57
+ visitHTMLOpenTagNode(node) {
58
+ if (node.tag_opening) {
59
+ this.context.write(node.tag_opening.value);
60
+ }
61
+ if (node.tag_name) {
62
+ this.context.write(node.tag_name.value);
63
+ }
64
+ this.visitChildNodes(node);
65
+ if (node.tag_closing) {
66
+ this.context.write(node.tag_closing.value);
67
+ }
68
+ }
69
+ visitHTMLCloseTagNode(node) {
70
+ if (node.tag_opening) {
71
+ this.context.write(node.tag_opening.value);
72
+ }
73
+ if (node.tag_name) {
74
+ this.context.write(node.tag_name.value);
75
+ }
76
+ if (node.tag_closing) {
77
+ this.context.write(node.tag_closing.value);
78
+ }
79
+ }
80
+ visitHTMLElementNode(node) {
81
+ const tagName = node.tag_name?.value;
82
+ if (tagName) {
83
+ this.context.enterTag(tagName);
84
+ }
85
+ if (node.open_tag) {
86
+ this.visit(node.open_tag);
87
+ }
88
+ if (node.body) {
89
+ node.body.forEach(child => this.visit(child));
90
+ }
91
+ if (node.close_tag) {
92
+ this.visit(node.close_tag);
93
+ }
94
+ if (tagName) {
95
+ this.context.exitTag();
96
+ }
97
+ }
98
+ visitHTMLAttributeNode(node) {
99
+ if (node.name) {
100
+ this.visit(node.name);
101
+ }
102
+ if (node.equals) {
103
+ this.context.write(node.equals.value);
104
+ }
105
+ if (node.equals && node.value) {
106
+ this.visit(node.value);
107
+ }
108
+ }
109
+ visitHTMLAttributeNameNode(node) {
110
+ this.visitChildNodes(node);
111
+ }
112
+ visitHTMLAttributeValueNode(node) {
113
+ if (node.quoted && node.open_quote) {
114
+ this.context.write(node.open_quote.value);
115
+ }
116
+ this.visitChildNodes(node);
117
+ if (node.quoted && node.close_quote) {
118
+ this.context.write(node.close_quote.value);
119
+ }
120
+ }
121
+ visitHTMLCommentNode(node) {
122
+ if (node.comment_start) {
123
+ this.context.write(node.comment_start.value);
124
+ }
125
+ this.visitChildNodes(node);
126
+ if (node.comment_end) {
127
+ this.context.write(node.comment_end.value);
128
+ }
129
+ }
130
+ visitHTMLDoctypeNode(node) {
131
+ if (node.tag_opening) {
132
+ this.context.write(node.tag_opening.value);
133
+ }
134
+ this.visitChildNodes(node);
135
+ if (node.tag_closing) {
136
+ this.context.write(node.tag_closing.value);
137
+ }
138
+ }
139
+ visitXMLDeclarationNode(node) {
140
+ if (node.tag_opening) {
141
+ this.context.write(node.tag_opening.value);
142
+ }
143
+ this.visitChildNodes(node);
144
+ if (node.tag_closing) {
145
+ this.context.write(node.tag_closing.value);
146
+ }
147
+ }
148
+ visitCDATANode(node) {
149
+ if (node.tag_opening) {
150
+ this.context.write(node.tag_opening.value);
151
+ }
152
+ this.visitChildNodes(node);
153
+ if (node.tag_closing) {
154
+ this.context.write(node.tag_closing.value);
155
+ }
156
+ }
157
+ visitERBContentNode(node) {
158
+ this.printERBNode(node);
159
+ }
160
+ visitERBIfNode(node) {
161
+ this.printERBNode(node);
162
+ if (node.statements) {
163
+ node.statements.forEach(statement => this.visit(statement));
164
+ }
165
+ if (node.subsequent) {
166
+ this.visit(node.subsequent);
167
+ }
168
+ if (node.end_node) {
169
+ this.visit(node.end_node);
170
+ }
171
+ }
172
+ visitERBElseNode(node) {
173
+ this.printERBNode(node);
174
+ if (node.statements) {
175
+ node.statements.forEach(statement => this.visit(statement));
176
+ }
177
+ }
178
+ visitERBEndNode(node) {
179
+ this.printERBNode(node);
180
+ }
181
+ visitERBBlockNode(node) {
182
+ this.printERBNode(node);
183
+ if (node.body) {
184
+ node.body.forEach(child => this.visit(child));
185
+ }
186
+ if (node.end_node) {
187
+ this.visit(node.end_node);
188
+ }
189
+ }
190
+ visitERBCaseNode(node) {
191
+ this.printERBNode(node);
192
+ if (node.children) {
193
+ node.children.forEach(child => this.visit(child));
194
+ }
195
+ if (node.conditions) {
196
+ node.conditions.forEach(condition => this.visit(condition));
197
+ }
198
+ if (node.else_clause) {
199
+ this.visit(node.else_clause);
200
+ }
201
+ if (node.end_node) {
202
+ this.visit(node.end_node);
203
+ }
204
+ }
205
+ visitERBWhenNode(node) {
206
+ this.printERBNode(node);
207
+ if (node.statements) {
208
+ node.statements.forEach(statement => this.visit(statement));
209
+ }
210
+ }
211
+ visitERBWhileNode(node) {
212
+ this.printERBNode(node);
213
+ if (node.statements) {
214
+ node.statements.forEach(statement => this.visit(statement));
215
+ }
216
+ if (node.end_node) {
217
+ this.visit(node.end_node);
218
+ }
219
+ }
220
+ visitERBUntilNode(node) {
221
+ this.printERBNode(node);
222
+ if (node.statements) {
223
+ node.statements.forEach(statement => this.visit(statement));
224
+ }
225
+ if (node.end_node) {
226
+ this.visit(node.end_node);
227
+ }
228
+ }
229
+ visitERBForNode(node) {
230
+ this.printERBNode(node);
231
+ if (node.statements) {
232
+ node.statements.forEach(statement => this.visit(statement));
233
+ }
234
+ if (node.end_node) {
235
+ this.visit(node.end_node);
236
+ }
237
+ }
238
+ visitERBBeginNode(node) {
239
+ this.printERBNode(node);
240
+ if (node.statements) {
241
+ node.statements.forEach(statement => this.visit(statement));
242
+ }
243
+ if (node.rescue_clause) {
244
+ this.visit(node.rescue_clause);
245
+ }
246
+ if (node.else_clause) {
247
+ this.visit(node.else_clause);
248
+ }
249
+ if (node.ensure_clause) {
250
+ this.visit(node.ensure_clause);
251
+ }
252
+ if (node.end_node) {
253
+ this.visit(node.end_node);
254
+ }
255
+ }
256
+ visitERBRescueNode(node) {
257
+ this.printERBNode(node);
258
+ if (node.statements) {
259
+ node.statements.forEach(statement => this.visit(statement));
260
+ }
261
+ if (node.subsequent) {
262
+ this.visit(node.subsequent);
263
+ }
264
+ }
265
+ visitERBEnsureNode(node) {
266
+ this.printERBNode(node);
267
+ if (node.statements) {
268
+ node.statements.forEach(statement => this.visit(statement));
269
+ }
270
+ }
271
+ visitERBUnlessNode(node) {
272
+ this.printERBNode(node);
273
+ if (node.statements) {
274
+ node.statements.forEach(statement => this.visit(statement));
275
+ }
276
+ if (node.else_clause) {
277
+ this.visit(node.else_clause);
278
+ }
279
+ if (node.end_node) {
280
+ this.visit(node.end_node);
281
+ }
282
+ }
283
+ visitERBYieldNode(node) {
284
+ this.printERBNode(node);
285
+ }
286
+ visitERBInNode(node) {
287
+ this.printERBNode(node);
288
+ if (node.statements) {
289
+ node.statements.forEach(statement => this.visit(statement));
290
+ }
291
+ }
292
+ visitERBCaseMatchNode(node) {
293
+ this.printERBNode(node);
294
+ if (node.children) {
295
+ node.children.forEach(child => this.visit(child));
296
+ }
297
+ if (node.conditions) {
298
+ node.conditions.forEach(condition => this.visit(condition));
299
+ }
300
+ if (node.else_clause) {
301
+ this.visit(node.else_clause);
302
+ }
303
+ if (node.end_node) {
304
+ this.visit(node.end_node);
305
+ }
306
+ }
307
+ /**
308
+ * Print ERB node tags and content
309
+ */
310
+ printERBNode(node) {
311
+ if (node.tag_opening) {
312
+ this.context.write(node.tag_opening.value);
313
+ }
314
+ if (node.content) {
315
+ this.context.write(node.content.value);
316
+ }
317
+ if (node.tag_closing) {
318
+ this.context.write(node.tag_closing.value);
319
+ }
320
+ }
321
+ write(content) {
322
+ this.context.write(content);
323
+ }
324
+ }
325
+ //# sourceMappingURL=printer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"printer.js","sourceRoot":"","sources":["../src/printer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"root":["../src/cli.ts","../src/herb-print.ts","../src/identity-printer.ts","../src/index.ts","../src/print-context.ts","../src/printer.ts"],"version":"5.9.2"}
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ export declare class CLI {
3
+ private parseArgs;
4
+ private showHelp;
5
+ run(): Promise<void>;
6
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,12 @@
1
+ import { Printer } from "./printer.js";
2
+ /**
3
+ * IdentityPrinter - Provides lossless reconstruction of the original source
4
+ *
5
+ * This printer aims to reconstruct the original input as faithfully as possible,
6
+ * preserving all whitespace, formatting, and structure. It's useful for:
7
+ * - Testing parser accuracy (input should equal output)
8
+ * - Baseline printing before applying transformations
9
+ * - Verifying AST round-trip fidelity
10
+ */
11
+ export declare class IdentityPrinter extends Printer {
12
+ }
@@ -0,0 +1,4 @@
1
+ export { IdentityPrinter } from "./identity-printer.js";
2
+ export { PrintContext } from "./print-context.js";
3
+ export { Printer, DEFAULT_PRINT_OPTIONS } from "./printer.js";
4
+ export type { PrintOptions } from "./printer.js";
@@ -0,0 +1,54 @@
1
+ export declare class PrintContext {
2
+ private output;
3
+ private indentLevel;
4
+ private currentColumn;
5
+ private preserveStack;
6
+ /**
7
+ * Write text to the output
8
+ */
9
+ write(text: string): void;
10
+ /**
11
+ * Write text and update column tracking for newlines
12
+ */
13
+ writeWithColumnTracking(text: string): void;
14
+ /**
15
+ * Increase indentation level
16
+ */
17
+ indent(): void;
18
+ /**
19
+ * Decrease indentation level
20
+ */
21
+ dedent(): void;
22
+ /**
23
+ * Enter a tag that may preserve whitespace
24
+ */
25
+ enterTag(tagName: string): void;
26
+ /**
27
+ * Exit the current tag
28
+ */
29
+ exitTag(): void;
30
+ /**
31
+ * Check if we're at the start of a line
32
+ */
33
+ isAtStartOfLine(): boolean;
34
+ /**
35
+ * Get current indentation level
36
+ */
37
+ getCurrentIndentLevel(): number;
38
+ /**
39
+ * Get current column position
40
+ */
41
+ getCurrentColumn(): number;
42
+ /**
43
+ * Get the current tag stack (for debugging)
44
+ */
45
+ getTagStack(): string[];
46
+ /**
47
+ * Get the complete output string
48
+ */
49
+ getOutput(): string;
50
+ /**
51
+ * Reset the context for reuse
52
+ */
53
+ reset(): void;
54
+ }
@@ -0,0 +1,75 @@
1
+ import { Node, Visitor, Token, ParseResult } from "@herb-tools/core";
2
+ import { PrintContext } from "./print-context.js";
3
+ import type * as Nodes from "@herb-tools/core";
4
+ /**
5
+ * Options for controlling the printing behavior
6
+ */
7
+ export type PrintOptions = {
8
+ /**
9
+ * When true, allows printing nodes that have parse errors.
10
+ * When false (default), throws an error if attempting to print nodes with errors.
11
+ * @default false
12
+ */
13
+ ignoreErrors: boolean;
14
+ };
15
+ /**
16
+ * Default print options used when none are provided
17
+ */
18
+ export declare const DEFAULT_PRINT_OPTIONS: PrintOptions;
19
+ export declare abstract class Printer extends Visitor {
20
+ protected context: PrintContext;
21
+ /**
22
+ * Static method to print a node without creating an instance
23
+ *
24
+ * @param input - The AST Node, Token, or ParseResult to print
25
+ * @param options - Print options to control behavior
26
+ * @returns The printed string representation of the input
27
+ * @throws {Error} When node has parse errors and ignoreErrors is false
28
+ */
29
+ static print(input: Token | Node | ParseResult, options?: PrintOptions): string;
30
+ /**
31
+ * Print a node, token, or parse result to a string
32
+ *
33
+ * @param input - The AST Node, Token, or ParseResult to print
34
+ * @param options - Print options to control behavior
35
+ * @returns The printed string representation of the input
36
+ * @throws {Error} When node has parse errors and ignoreErrors is false
37
+ */
38
+ print(input: Token | Node | ParseResult, options?: PrintOptions): string;
39
+ visitDocumentNode(node: Nodes.DocumentNode): void;
40
+ visitLiteralNode(node: Nodes.LiteralNode): void;
41
+ visitHTMLTextNode(node: Nodes.HTMLTextNode): void;
42
+ visitWhitespaceNode(node: Nodes.WhitespaceNode): void;
43
+ visitHTMLOpenTagNode(node: Nodes.HTMLOpenTagNode): void;
44
+ visitHTMLCloseTagNode(node: Nodes.HTMLCloseTagNode): void;
45
+ visitHTMLElementNode(node: Nodes.HTMLElementNode): void;
46
+ visitHTMLAttributeNode(node: Nodes.HTMLAttributeNode): void;
47
+ visitHTMLAttributeNameNode(node: Nodes.HTMLAttributeNameNode): void;
48
+ visitHTMLAttributeValueNode(node: Nodes.HTMLAttributeValueNode): void;
49
+ visitHTMLCommentNode(node: Nodes.HTMLCommentNode): void;
50
+ visitHTMLDoctypeNode(node: Nodes.HTMLDoctypeNode): void;
51
+ visitXMLDeclarationNode(node: Nodes.XMLDeclarationNode): void;
52
+ visitCDATANode(node: Nodes.CDATANode): void;
53
+ visitERBContentNode(node: Nodes.ERBContentNode): void;
54
+ visitERBIfNode(node: Nodes.ERBIfNode): void;
55
+ visitERBElseNode(node: Nodes.ERBElseNode): void;
56
+ visitERBEndNode(node: Nodes.ERBEndNode): void;
57
+ visitERBBlockNode(node: Nodes.ERBBlockNode): void;
58
+ visitERBCaseNode(node: Nodes.ERBCaseNode): void;
59
+ visitERBWhenNode(node: Nodes.ERBWhenNode): void;
60
+ visitERBWhileNode(node: Nodes.ERBWhileNode): void;
61
+ visitERBUntilNode(node: Nodes.ERBUntilNode): void;
62
+ visitERBForNode(node: Nodes.ERBForNode): void;
63
+ visitERBBeginNode(node: Nodes.ERBBeginNode): void;
64
+ visitERBRescueNode(node: Nodes.ERBRescueNode): void;
65
+ visitERBEnsureNode(node: Nodes.ERBEnsureNode): void;
66
+ visitERBUnlessNode(node: Nodes.ERBUnlessNode): void;
67
+ visitERBYieldNode(node: Nodes.ERBYieldNode): void;
68
+ visitERBInNode(node: Nodes.ERBInNode): void;
69
+ visitERBCaseMatchNode(node: Nodes.ERBCaseMatchNode): void;
70
+ /**
71
+ * Print ERB node tags and content
72
+ */
73
+ protected printERBNode(node: Nodes.ERBNode): void;
74
+ protected write(content: string): void;
75
+ }
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@herb-tools/printer",
3
+ "version": "0.6.0",
4
+ "description": "AST printer infrastructure and lossless reconstruction tool for HTML+ERB templates",
5
+ "license": "MIT",
6
+ "homepage": "https://herb-tools.dev",
7
+ "bugs": "https://github.com/marcoroth/herb/issues/new?title=Package%20%60@herb-tools/printer%60:%20",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/marcoroth/herb.git",
11
+ "directory": "javascript/packages/printer"
12
+ },
13
+ "bin": {
14
+ "herb-print": "./bin/herb-print"
15
+ },
16
+ "main": "./dist/index.cjs",
17
+ "module": "./dist/index.js",
18
+ "types": "./dist/types/index.d.ts",
19
+ "exports": {
20
+ "./package.json": "./package.json",
21
+ ".": {
22
+ "types": "./dist/types/index.d.ts",
23
+ "import": "./dist/index.js",
24
+ "require": "./dist/index.cjs",
25
+ "default": "./dist/index.js"
26
+ }
27
+ },
28
+ "scripts": {
29
+ "clean": "rimraf dist",
30
+ "prebuild": "yarn run clean",
31
+ "build": "yarn generate:node-tests && tsc -b && rollup -c rollup.config.mjs",
32
+ "watch": "tsc -b -w",
33
+ "test": "vitest run",
34
+ "test:watch": "vitest --watch",
35
+ "test:nodes": "vitest run test/nodes",
36
+ "generate:node-tests": "node scripts/generate-node-tests.mjs",
37
+ "prepublishOnly": "yarn clean && yarn build && yarn test"
38
+ },
39
+ "dependencies": {
40
+ "@herb-tools/core": "0.6.0",
41
+ "glob": "^10.3.10"
42
+ },
43
+ "files": [
44
+ "package.json",
45
+ "README.md",
46
+ "src/",
47
+ "bin/",
48
+ "dist/"
49
+ ]
50
+ }