@macroforge/mcp-server 0.1.33 → 0.1.35

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 (50) hide show
  1. package/README.md +68 -0
  2. package/dist/index.d.ts +32 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +46 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/tools/docs-loader.d.ts +133 -5
  7. package/dist/tools/docs-loader.d.ts.map +1 -1
  8. package/dist/tools/docs-loader.js +131 -15
  9. package/dist/tools/docs-loader.js.map +1 -1
  10. package/dist/tools/index.d.ts +48 -1
  11. package/dist/tools/index.d.ts.map +1 -1
  12. package/dist/tools/index.js +163 -14
  13. package/dist/tools/index.js.map +1 -1
  14. package/docs/api/api-overview.md +24 -46
  15. package/docs/api/expand-sync.md +24 -51
  16. package/docs/api/native-plugin.md +24 -56
  17. package/docs/api/position-mapper.md +34 -76
  18. package/docs/api/transform-sync.md +27 -59
  19. package/docs/builtin-macros/clone.md +45 -104
  20. package/docs/builtin-macros/debug.md +33 -104
  21. package/docs/builtin-macros/default.md +78 -114
  22. package/docs/builtin-macros/deserialize.md +93 -273
  23. package/docs/builtin-macros/hash.md +58 -100
  24. package/docs/builtin-macros/macros-overview.md +42 -103
  25. package/docs/builtin-macros/ord.md +65 -133
  26. package/docs/builtin-macros/partial-eq.md +53 -179
  27. package/docs/builtin-macros/partial-ord.md +67 -159
  28. package/docs/builtin-macros/serialize.md +64 -194
  29. package/docs/concepts/architecture.md +40 -99
  30. package/docs/concepts/derive-system.md +129 -125
  31. package/docs/concepts/how-macros-work.md +52 -84
  32. package/docs/custom-macros/custom-overview.md +17 -39
  33. package/docs/custom-macros/rust-setup.md +22 -55
  34. package/docs/custom-macros/ts-macro-derive.md +43 -107
  35. package/docs/custom-macros/ts-quote.md +177 -507
  36. package/docs/getting-started/first-macro.md +108 -33
  37. package/docs/getting-started/installation.md +32 -73
  38. package/docs/integration/cli.md +70 -156
  39. package/docs/integration/configuration.md +32 -75
  40. package/docs/integration/integration-overview.md +16 -55
  41. package/docs/integration/mcp-server.md +30 -69
  42. package/docs/integration/svelte-preprocessor.md +60 -83
  43. package/docs/integration/typescript-plugin.md +32 -74
  44. package/docs/integration/vite-plugin.md +30 -79
  45. package/docs/language-servers/ls-overview.md +22 -46
  46. package/docs/language-servers/svelte.md +30 -69
  47. package/docs/language-servers/zed.md +34 -72
  48. package/docs/roadmap/roadmap.md +54 -130
  49. package/docs/sections.json +3 -262
  50. package/package.json +2 -2
@@ -1,156 +1,36 @@
1
1
  # Template Syntax
2
-
3
- *The `macroforge_ts_quote` crate provides template-based code generation for TypeScript. The `ts_template!` macro uses Rust-inspired syntax for control flow and interpolation, making it easy to generate complex TypeScript code.*
4
-
5
- ## Available Macros
6
-
7
- | `ts_template!`
8
- | Any TypeScript code
9
- | General code generation
10
-
11
-
12
-
13
- | `body!`
14
- | Class body members
15
- | Methods and properties
16
-
17
- ## Quick Reference
18
-
19
- | `@{expr}`
20
- | Interpolate a Rust expression (adds space after)
21
-
22
-
23
-
24
- | `{| content |}`
25
- | Ident block: concatenates without spaces (e.g., <code
26
- >&#123;|get@&#123;name&#125;|&#125;</code
27
- >
28
- `getUser`)</td
29
- >
30
-
31
-
32
-
33
- <td>`&#123;> "comment" <&#125;`
34
- | Block comment: outputs `/* comment */` (string preserves
35
- whitespace)</td
36
- >
37
-
38
-
39
-
40
- <td>`&#123;>> "doc" <<&#125;`
41
- | Doc comment: outputs `/** doc */` (string preserves whitespace)</td
42
- >
43
-
44
-
45
-
46
- <td>`@@&#123;`
47
- | Escape for literal `@&#123;` (e.g.,
48
- `"@@&#123;foo&#125;"`
49
- → `@&#123;foo&#125;`)</td
50
- >
51
-
52
-
53
-
54
- <td>`"text @&#123;expr&#125;"`
55
- | String interpolation (auto-detected)
56
-
57
-
58
-
59
- | `"'^template $&#123;js&#125;^'"`
60
- | JS backtick template literal (outputs <code
61
- >`template $&#123;js&#125;`</code
62
- >)</td
63
- >
64
-
65
-
66
-
67
- <td>`&#123;#if cond&#125;...&#123;/if&#125;`
68
- | Conditional block
69
-
70
-
71
-
72
- | <code
73
- >&#123;#if cond&#125;...&#123;:else&#125;...&#123;/if&#125;</code
74
- ></td
75
- >
76
- <td>Conditional with else
77
-
78
-
79
-
80
- | <code
81
- >&#123;#if a&#125;...&#123;:else if
82
- b&#125;...&#123;:else&#125;...&#123;/if&#125;</code
83
- ></td
84
- >
85
- <td>Full if/else-if/else chain
86
-
87
-
88
-
89
- | <code
90
- >&#123;#if let pattern = expr&#125;...&#123;/if&#125;</code
91
- ></td
92
- >
93
- <td>Pattern matching if-let
94
-
95
-
96
-
97
- | <code
98
- >&#123;#match expr&#125;&#123;:case
99
- pattern&#125;...&#123;/match&#125;</code
100
- ></td
101
- >
102
- <td>Match expression with case arms
103
-
104
-
105
-
106
- | <code>&#123;#for item in list&#125;...&#123;/for&#125;</code
107
- ></td
108
- >
109
- <td>Iterate over a collection
110
-
111
-
112
-
113
- | `&#123;#while cond&#125;...&#123;/while&#125;`
114
- | While loop
115
-
116
-
117
-
118
- | <code
119
- >&#123;#while let pattern = expr&#125;...&#123;/while&#125;</code
120
- ></td
121
- >
122
- <td>While-let pattern matching loop
123
-
124
-
125
-
126
- | `&#123;$let name = expr&#125;`
127
- | Define a local constant
128
-
129
-
130
-
131
- | `&#123;$let mut name = expr&#125;`
132
- | Define a mutable local variable
133
-
134
-
135
-
136
- | `&#123;$do expr&#125;`
137
- | Execute a side-effectful expression
138
-
139
-
140
-
141
- | `&#123;$typescript stream&#125;`
142
- <td
143
- >Inject a TsStream, preserving its source and runtime_patches
144
- (imports)</td
145
- >
146
-
147
- **Note:** A single `@` not followed by `&#123;` passes through unchanged (e.g., `email@domain.com` works as expected).
148
-
149
- ## Interpolation: `@&#123;expr&#125;`
150
-
151
- Insert Rust expressions into the generated TypeScript:
152
-
153
- ```rust
2
+ *The `macroforge_ts_quote` crate provides template-based code generation for TypeScript. The `ts_template!` macro uses Rust-inspired syntax for control flow and interpolation, making it easy to generate complex TypeScript code.*
3
+ ## Available Macros
4
+ | Macro | Output | Use Case |
5
+ | --- | --- | --- |
6
+ | `ts_template!` | Any TypeScript code | General code generation |
7
+ | `body!` | Class body members | Methods and properties |
8
+ ## Quick Reference
9
+ | Syntax | Description |
10
+ | --- | --- |
11
+ | `@{expr}` | Interpolate a Rust expression (adds space after) |
12
+ | `{| content |}` | Ident block: concatenates without spaces (e.g., `{|get@{name}|}` → `getUser`) |
13
+ | `{> "comment" <}` | Block comment: outputs `/* comment */` (string preserves whitespace) |
14
+ | `{>> "doc" <<}` | Doc comment: outputs `/** doc */` (string preserves whitespace) |
15
+ | `@@{` | Escape for literal `@{` (e.g., `"@@{foo}"` → `@{foo}`) |
16
+ | `"text @{expr}"` | String interpolation (auto-detected) |
17
+ | `"'^template ${js}^'"` | JS backtick template literal (outputs ``template ${js}``) |
18
+ | `{#if cond}...{/if}` | Conditional block |
19
+ | `{#if cond}...{:else}...{/if}` | Conditional with else |
20
+ | {#if a}...{:else if b}...{:else}...{/if} | Full if/else-if/else chain |
21
+ | `{#if let pattern = expr}...{/if}` | Pattern matching if-let |
22
+ | {#match expr}{:case pattern}...{/match} | Match expression with case arms |
23
+ | `{#for item in list}...{/for}` | Iterate over a collection |
24
+ | `{#while cond}...{/while}` | While loop |
25
+ | `{#while let pattern = expr}...{/while}` | While-let pattern matching loop |
26
+ | `{$let name = expr}` | Define a local constant |
27
+ | `{$let mut name = expr}` | Define a mutable local variable |
28
+ | `{$do expr}` | Execute a side-effectful expression |
29
+ | `{$typescript stream}` | Inject a TsStream, preserving its source and runtime_patches (imports) |
30
+ **Note:** A single `@` not followed by `{` passes through unchanged (e.g., `email@domain.com` works as expected).
31
+ ## Interpolation: `@{expr}`
32
+ Insert Rust expressions into the generated TypeScript:
33
+ ```
154
34
  let class_name = "User";
155
35
  let method = "toString";
156
36
 
@@ -159,23 +39,14 @@ let code = ts_template! {
159
39
  return "User instance";
160
40
  };
161
41
  };
162
- ```
163
-
164
- **Generates:**
165
-
166
- ```typescript
42
+ ``` **Generates:**
43
+ ```
167
44
  User.prototype.toString = function () {
168
45
  return "User instance";
169
46
  };
170
- ```
171
-
172
- <h2 id="ident-blocks">
173
- Identifier Concatenation: `&#123;| content |&#125;`
174
- </h2>
175
-
176
- When you need to build identifiers dynamically (like `getUser`, `setName`), use the ident block syntax. Everything inside `&#123;| |&#125;` is concatenated without spaces:
177
-
178
- ```rust
47
+ ``` ## Identifier Concatenation: `{| content |}`
48
+ When you need to build identifiers dynamically (like `getUser`, `setName`), use the ident block syntax. Everything inside `{| |}` is concatenated without spaces:
49
+ ```
179
50
  let field_name = "User";
180
51
 
181
52
  let code = ts_template! {
@@ -183,19 +54,13 @@ let code = ts_template! {
183
54
  return this.@{field_name.to_lowercase()};
184
55
  }
185
56
  };
186
- ```
187
-
188
- **Generates:**
189
-
190
- ```typescript
57
+ ``` **Generates:**
58
+ ```
191
59
  function getUser() {
192
60
  return this.user;
193
61
  }
194
- ```
195
-
196
- Without ident blocks, `@&#123;&#125;` always adds a space after for readability. Use `&#123;| |&#125;` when you explicitly want concatenation:
197
-
198
- ```rust
62
+ ``` Without ident blocks, `@{}` always adds a space after for readability. Use `{| |}` when you explicitly want concatenation:
63
+ ```
199
64
  let name = "Status";
200
65
 
201
66
  // With space (default behavior)
@@ -203,47 +68,28 @@ ts_template! { namespace @{name} } // → "namespace Status"
203
68
 
204
69
  // Without space (ident block)
205
70
  ts_template! { {|namespace@{name}|} } // → "namespaceStatus"
206
- ```
207
-
208
- Multiple interpolations can be combined:
209
-
210
- ```rust
71
+ ``` Multiple interpolations can be combined:
72
+ ```
211
73
  let entity = "user";
212
74
  let action = "create";
213
75
 
214
76
  ts_template! { {|@{entity}_@{action}|} } // → "user_create"
215
- ```
216
-
217
- <h2 id="comments">
218
- Comments: `&#123;> "..." <&#125;` and
219
- `&#123;>> "..." <<&#125;`
220
- </h2>
221
-
222
- Since Rust's tokenizer strips whitespace before macros see them, use string literals to preserve exact spacing in comments:
223
-
224
- ### Block Comments
225
-
226
- Use `&#123;> "comment" <&#125;` for block comments:
227
-
228
- ```rust
77
+ ``` ## Comments: `{> "..." <}` and `{>> "..." <<}`
78
+ Since Rust's tokenizer strips whitespace before macros see them, use string literals to preserve exact spacing in comments:
79
+ ### Block Comments
80
+ Use `{> "comment" <}` for block comments:
81
+ ```
229
82
  let code = ts_template! {
230
83
  {> "This is a block comment" <}
231
84
  const x = 42;
232
85
  };
233
- ```
234
-
235
- **Generates:**
236
-
237
- ```typescript
86
+ ``` **Generates:**
87
+ ```
238
88
  /* This is a block comment */
239
89
  const x = 42;
240
- ```
241
-
242
- ### Doc Comments (JSDoc)
243
-
244
- Use `&#123;>> "doc" <<&#125;` for JSDoc comments:
245
-
246
- ```rust
90
+ ``` ### Doc Comments (JSDoc)
91
+ Use `{>> "doc" <<}` for JSDoc comments:
92
+ ```
247
93
  let code = ts_template! {
248
94
  {>> "@param {string} name - The user's name" <<}
249
95
  {>> "@returns {string} A greeting message" <<}
@@ -251,23 +97,16 @@ let code = ts_template! {
251
97
  return "Hello, " + name;
252
98
  }
253
99
  };
254
- ```
255
-
256
- **Generates:**
257
-
258
- ```typescript
100
+ ``` **Generates:**
101
+ ```
259
102
  /** @param {string} name - The user's name */
260
103
  /** @returns {string} A greeting message */
261
104
  function greet(name: string): string {
262
105
  return "Hello, " + name;
263
106
  }
264
- ```
265
-
266
- ### Comments with Interpolation
267
-
268
- Use `format!()` or similar to build dynamic comment strings:
269
-
270
- ```rust
107
+ ``` ### Comments with Interpolation
108
+ Use `format!()` or similar to build dynamic comment strings:
109
+ ```
271
110
  let param_name = "userId";
272
111
  let param_type = "number";
273
112
  let comment = format!("@param {{{}}} {} - The user ID", param_type, param_name);
@@ -276,22 +115,13 @@ let code = ts_template! {
276
115
  {>> @{comment} <<}
277
116
  function getUser(userId: number) {}
278
117
  };
279
- ```
280
-
281
- **Generates:**
282
-
283
- ```typescript
118
+ ``` **Generates:**
119
+ ```
284
120
  /** @param {number} userId - The user ID */
285
121
  function getUser(userId: number) {}
286
- ```
287
-
288
- <h2 id="string-interpolation">
289
- String Interpolation: `"text @&#123;expr&#125;"`
290
- </h2>
291
-
292
- Interpolation works automatically inside string literals - no <code >format!()</code > needed:
293
-
294
- ```rust
122
+ ``` ## String Interpolation: `"text @{expr}"`
123
+ Interpolation works automatically inside string literals - no `format!()` needed:
124
+ ```
295
125
  let name = "World";
296
126
  let count = 42;
297
127
 
@@ -299,64 +129,41 @@ let code = ts_template! {
299
129
  console.log("Hello @{name}!");
300
130
  console.log("Count: @{count}, doubled: @{count * 2}");
301
131
  };
302
- ```
303
-
304
- **Generates:**
305
-
306
- ```typescript
132
+ ``` **Generates:**
133
+ ```
307
134
  console.log("Hello World!");
308
135
  console.log("Count: 42, doubled: 84");
309
- ```
310
-
311
- This also works with method calls and complex expressions:
312
-
313
- ```rust
136
+ ``` This also works with method calls and complex expressions:
137
+ ```
314
138
  let field = "username";
315
139
 
316
140
  let code = ts_template! {
317
141
  throw new Error("Invalid @{field.to_uppercase()}");
318
142
  };
319
- ```
320
-
321
- <h2 id="backtick-templates">
322
- Backtick Template Literals: `"'^...^'"`
323
- </h2>
324
-
325
- For JavaScript template literals (backtick strings), use the <code >'^...^'</code > syntax. This outputs actual backticks and passes through `${"${}"}` for JS interpolation:
326
-
327
- ```rust
143
+ ``` ## Backtick Template Literals: `"'^...^'"`
144
+ For JavaScript template literals (backtick strings), use the `'^...^'` syntax. This outputs actual backticks and passes through `$${}` for JS interpolation:
145
+ ```
328
146
  let tag_name = "div";
329
147
 
330
148
  let code = ts_template! {
331
- const html = "'^<@{tag_name}>\${content}</@{tag_name}>^'";
149
+ const html = "'^<@{tag_name}>${content}</@{tag_name}>^'";
332
150
  };
333
- ```
334
-
335
- **Generates:**
336
-
337
- <CodeBlock code={"const html = `${content}`;"} lang="typescript" />
338
-
339
- You can mix Rust `@&#123;&#125;` interpolation (evaluated at macro expansion time) with JS `${"${}"}` interpolation (evaluated at runtime):
340
-
341
- ```rust
151
+ ``` **Generates:**
152
+ ```
153
+ const html = `${content}`;
154
+ ``` You can mix Rust `@{}` interpolation (evaluated at macro expansion time) with JS `$${}` interpolation (evaluated at runtime):
155
+ ```
342
156
  let class_name = "User";
343
157
 
344
158
  let code = ts_template! {
345
- "'^Hello \${this.name}, you are a @{class_name}^'"
159
+ "'^Hello ${this.name}, you are a @{class_name}^'"
346
160
  };
347
- ```
348
-
349
- **Generates:**
350
-
351
- <CodeBlock code={"`Hello ${this.name}, you are a User`"} lang="typescript" />
352
-
353
- <h2 id="conditionals">
354
- Conditionals: `&#123;#if&#125;...&#123;/if&#125;`
355
- </h2>
356
-
357
- Basic conditional:
358
-
359
- ```rust
161
+ ``` **Generates:**
162
+ ```
163
+ `Hello ${this.name}, you are a User`
164
+ ``` ## Conditionals: `{#if}...{/if}`
165
+ Basic conditional:
166
+ ```
360
167
  let needs_validation = true;
361
168
 
362
169
  let code = ts_template! {
@@ -367,11 +174,8 @@ let code = ts_template! {
367
174
  return this.doSave();
368
175
  }
369
176
  };
370
- ```
371
-
372
- ### If-Else
373
-
374
- ```rust
177
+ ``` ### If-Else
178
+ ```
375
179
  let has_default = true;
376
180
 
377
181
  let code = ts_template! {
@@ -381,11 +185,8 @@ let code = ts_template! {
381
185
  throw new Error("No default");
382
186
  {/if}
383
187
  };
384
- ```
385
-
386
- ### If-Else-If Chains
387
-
388
- ```rust
188
+ ``` ### If-Else-If Chains
189
+ ```
389
190
  let level = 2;
390
191
 
391
192
  let code = ts_template! {
@@ -397,15 +198,9 @@ let code = ts_template! {
397
198
  console.log("Other level");
398
199
  {/if}
399
200
  };
400
- ```
401
-
402
- <h2 id="pattern-matching">
403
- Pattern Matching: `&#123;#if let&#125;`
404
- </h2>
405
-
406
- Use `if let` for pattern matching on `Option`, `Result`, or other Rust enums:
407
-
408
- ```rust
201
+ ``` ## Pattern Matching: `{#if let}`
202
+ Use `if let` for pattern matching on `Option`, `Result`, or other Rust enums:
203
+ ```
409
204
  let maybe_name: Option<&str> = Some("Alice");
410
205
 
411
206
  let code = ts_template! {
@@ -415,17 +210,11 @@ let code = ts_template! {
415
210
  console.log("Hello, anonymous!");
416
211
  {/if}
417
212
  };
418
- ```
419
-
420
- **Generates:**
421
-
422
- ```typescript
213
+ ``` **Generates:**
214
+ ```
423
215
  console.log("Hello, Alice!");
424
- ```
425
-
426
- This is useful when working with optional values from your IR:
427
-
428
- ```rust
216
+ ``` This is useful when working with optional values from your IR:
217
+ ```
429
218
  let code = ts_template! {
430
219
  {#if let Some(default_val) = field.default_value}
431
220
  this.@{field.name} = @{default_val};
@@ -433,15 +222,9 @@ let code = ts_template! {
433
222
  this.@{field.name} = undefined;
434
223
  {/if}
435
224
  };
436
- ```
437
-
438
- <h2 id="match-expressions">
439
- Match Expressions: `&#123;#match&#125;`
440
- </h2>
441
-
442
- Use `match` for exhaustive pattern matching:
443
-
444
- ```rust
225
+ ``` ## Match Expressions: `{#match}`
226
+ Use `match` for exhaustive pattern matching:
227
+ ```
445
228
  enum Visibility { Public, Private, Protected }
446
229
  let visibility = Visibility::Public;
447
230
 
@@ -456,17 +239,11 @@ let code = ts_template! {
456
239
  {/match}
457
240
  field: string;
458
241
  };
459
- ```
460
-
461
- **Generates:**
462
-
463
- ```typescript
242
+ ``` **Generates:**
243
+ ```
464
244
  public field: string;
465
- ```
466
-
467
- ### Match with Value Extraction
468
-
469
- ```rust
245
+ ``` ### Match with Value Extraction
246
+ ```
470
247
  let result: Result<i32, &str> = Ok(42);
471
248
 
472
249
  let code = ts_template! {
@@ -477,11 +254,8 @@ let code = ts_template! {
477
254
  throw new Error("@{msg}")
478
255
  {/match};
479
256
  };
480
- ```
481
-
482
- ### Match with Wildcard
483
-
484
- ```rust
257
+ ``` ### Match with Wildcard
258
+ ```
485
259
  let count = 5;
486
260
 
487
261
  let code = ts_template! {
@@ -494,11 +268,8 @@ let code = ts_template! {
494
268
  console.log("many");
495
269
  {/match}
496
270
  };
497
- ```
498
-
499
- ## Iteration: `&#123;#for&#125;`
500
-
501
- ```rust
271
+ ``` ## Iteration: `{#for}`
272
+ ```
502
273
  let fields = vec!["name", "email", "age"];
503
274
 
504
275
  let code = ts_template! {
@@ -510,11 +281,8 @@ let code = ts_template! {
510
281
  return result;
511
282
  }
512
283
  };
513
- ```
514
-
515
- **Generates:**
516
-
517
- ```typescript
284
+ ``` **Generates:**
285
+ ```
518
286
  function toJSON() {
519
287
  const result = {};
520
288
  result.name = this.name;
@@ -522,11 +290,8 @@ function toJSON() {
522
290
  result.age = this.age;
523
291
  return result;
524
292
  }
525
- ```
526
-
527
- ### Tuple Destructuring in Loops
528
-
529
- ```rust
293
+ ``` ### Tuple Destructuring in Loops
294
+ ```
530
295
  let items = vec![("user", "User"), ("post", "Post")];
531
296
 
532
297
  let code = ts_template! {
@@ -534,11 +299,8 @@ let code = ts_template! {
534
299
  const @{key} = new @{class_name}();
535
300
  {/for}
536
301
  };
537
- ```
538
-
539
- ### Nested Iterations
540
-
541
- ```rust
302
+ ``` ### Nested Iterations
303
+ ```
542
304
  let classes = vec![
543
305
  ("User", vec!["name", "email"]),
544
306
  ("Post", vec!["title", "content"]),
@@ -555,13 +317,9 @@ ts_template! {
555
317
  };
556
318
  {/for}
557
319
  }
558
- ```
559
-
560
- ## While Loops: `&#123;#while&#125;`
561
-
562
- Use `while` for loops that need to continue until a condition is false:
563
-
564
- ```rust
320
+ ``` ## While Loops: `{#while}`
321
+ Use `while` for loops that need to continue until a condition is false:
322
+ ```
565
323
  let items = get_items();
566
324
  let mut idx = 0;
567
325
 
@@ -572,13 +330,9 @@ let code = ts_template! {
572
330
  {$do i += 1}
573
331
  {/while}
574
332
  };
575
- ```
576
-
577
- ### While-Let Pattern Matching
578
-
579
- Use `while let` for iterating with pattern matching, similar to `if let`:
580
-
581
- ```rust
333
+ ``` ### While-Let Pattern Matching
334
+ Use `while let` for iterating with pattern matching, similar to `if let`:
335
+ ```
582
336
  let mut items = vec!["a", "b", "c"].into_iter();
583
337
 
584
338
  let code = ts_template! {
@@ -586,31 +340,21 @@ let code = ts_template! {
586
340
  console.log("@{item}");
587
341
  {/while}
588
342
  };
589
- ```
590
-
591
- **Generates:**
592
-
593
- ```typescript
343
+ ``` **Generates:**
344
+ ```
594
345
  console.log("a");
595
346
  console.log("b");
596
347
  console.log("c");
597
- ```
598
-
599
- This is especially useful when working with iterators or consuming optional values:
600
-
601
- ```rust
348
+ ``` This is especially useful when working with iterators or consuming optional values:
349
+ ```
602
350
  let code = ts_template! {
603
351
  {#while let Some(next_field) = remaining_fields.pop()}
604
352
  result.@{next_field.name} = this.@{next_field.name};
605
353
  {/while}
606
354
  };
607
- ```
608
-
609
- ## Local Constants: `&#123;$let&#125;`
610
-
611
- Define local variables within the template scope:
612
-
613
- ```rust
355
+ ``` ## Local Constants: `{$let}`
356
+ Define local variables within the template scope:
357
+ ```
614
358
  let items = vec![("user", "User"), ("post", "Post")];
615
359
 
616
360
  let code = ts_template! {
@@ -620,17 +364,10 @@ let code = ts_template! {
620
364
  const @{key} = new @{class_name}();
621
365
  {/for}
622
366
  };
623
- ```
624
-
625
- This is useful for computing derived values inside loops without cluttering the Rust code.
626
-
627
- <h2 id="mutable-variables">
628
- Mutable Variables: `&#123;$let mut&#125;`
629
- </h2>
630
-
631
- When you need to modify a variable within the template (e.g., in a <code >while</code > loop), use `&#123;$let mut&#125;`:
632
-
633
- ```rust
367
+ ``` This is useful for computing derived values inside loops without cluttering the Rust code.
368
+ ## Mutable Variables: `{$let mut}`
369
+ When you need to modify a variable within the template (e.g., in a `while` loop), use `{$let mut}`:
370
+ ```
634
371
  let code = ts_template! {
635
372
  {$let mut count = 0}
636
373
  {#for item in items}
@@ -639,13 +376,9 @@ let code = ts_template! {
639
376
  {/for}
640
377
  console.log("Total: @{count}");
641
378
  };
642
- ```
643
-
644
- ## Side Effects: `&#123;$do&#125;`
645
-
646
- Execute an expression for its side effects without producing output. This is commonly used with mutable variables:
647
-
648
- ```rust
379
+ ``` ## Side Effects: `{$do}`
380
+ Execute an expression for its side effects without producing output. This is commonly used with mutable variables:
381
+ ```
649
382
  let code = ts_template! {
650
383
  {$let mut results: Vec<String> = Vec::new()}
651
384
  {#for field in fields}
@@ -653,25 +386,14 @@ let code = ts_template! {
653
386
  {/for}
654
387
  return [@{results.join(", ")}];
655
388
  };
656
- ```
657
-
658
- Common uses for `&#123;$do&#125;`:
659
-
660
- - Incrementing counters: `&#123;$do i += 1&#125;`
661
-
662
- - Building collections: `&#123;$do vec.push(item)&#125;`
663
-
664
- - Setting flags: `&#123;$do found = true&#125;`
665
-
666
- - Any mutating operation
667
-
668
- <h2 id="typescript-injection">
669
- TsStream Injection: `&#123;$typescript&#125;`
670
- </h2>
671
-
672
- Inject another TsStream into your template, preserving both its source code and runtime patches (like imports added via `add_import()`):
673
-
674
- ```rust
389
+ ``` Common uses for `{$do}`:
390
+ - Incrementing counters: `{$do i += 1}`
391
+ - Building collections: `{$do vec.push(item)}`
392
+ - Setting flags: `{$do found = true}`
393
+ - Any mutating operation
394
+ ## TsStream Injection: `{$typescript}`
395
+ Inject another TsStream into your template, preserving both its source code and runtime patches (like imports added via `add_import()`):
396
+ ```
675
397
  // Create a helper method with its own import
676
398
  let mut helper = body! {
677
399
  validateEmail(email: string): boolean {
@@ -689,11 +411,8 @@ let result = body! {
689
411
  }
690
412
  };
691
413
  // result now includes helper's source AND its Result import
692
- ```
693
-
694
- This is essential for composing multiple macro outputs while preserving imports and patches:
695
-
696
- ```rust
414
+ ``` This is essential for composing multiple macro outputs while preserving imports and patches:
415
+ ```
697
416
  let extra_methods = if include_validation {
698
417
  Some(body! {
699
418
  validate(): boolean { return true; }
@@ -709,33 +428,21 @@ body! {
709
428
  {$typescript methods}
710
429
  {/if}
711
430
  }
712
- ```
713
-
714
- ## Escape Syntax
715
-
716
- If you need a literal `@&#123;` in your output (not interpolation), use `@@&#123;`:
717
-
718
- ```rust
431
+ ``` ## Escape Syntax
432
+ If you need a literal `@{` in your output (not interpolation), use `@@{`:
433
+ ```
719
434
  ts_template! {
720
435
  // This outputs a literal @{foo}
721
436
  const example = "Use @@{foo} for templates";
722
437
  }
723
- ```
724
-
725
- **Generates:**
726
-
727
- ```typescript
438
+ ``` **Generates:**
439
+ ```
728
440
  // This outputs a literal @{foo}
729
441
  const example = "Use @{foo} for templates";
730
- ```
731
-
732
- ## Complete Example: JSON Derive Macro
733
-
734
- Here's a comparison showing how `ts_template!` simplifies code generation:
735
-
736
- ### Before (Manual AST Building)
737
-
738
- ```rust
442
+ ``` ## Complete Example: JSON Derive Macro
443
+ Here's a comparison showing how `ts_template!` simplifies code generation:
444
+ ### Before (Manual AST Building)
445
+ ```
739
446
  pub fn derive_json_macro(input: TsStream) -> MacroResult {
740
447
  let input = parse_ts_macro_input!(input as DeriveInput);
741
448
 
@@ -764,11 +471,8 @@ pub fn derive_json_macro(input: TsStream) -> MacroResult {
764
471
  }
765
472
  }
766
473
  }
767
- ```
768
-
769
- ### After (With ts_template!)
770
-
771
- ```rust
474
+ ``` ### After (With ts_template!)
475
+ ```
772
476
  pub fn derive_json_macro(input: TsStream) -> MacroResult {
773
477
  let input = parse_ts_macro_input!(input as DeriveInput);
774
478
 
@@ -791,40 +495,24 @@ pub fn derive_json_macro(input: TsStream) -> MacroResult {
791
495
  }
792
496
  }
793
497
  }
794
- ```
795
-
796
- ## How It Works
797
-
798
- 1. **Compile-Time:** The template is parsed during macro expansion
799
-
800
- 2. **String Building:** Generates Rust code that builds a TypeScript string at runtime
801
-
802
- 3. **SWC Parsing:** The generated string is parsed with SWC to produce a typed AST
803
-
804
- 4. **Result:** Returns `Stmt` that can be used in `MacroResult` patches
805
-
806
- ## Return Type
807
-
808
- `ts_template!` returns a `Result<Stmt, TsSynError>` by default. The macro automatically unwraps and provides helpful error messages showing the generated TypeScript code if parsing fails:
809
-
810
- ```text
498
+ ``` ## How It Works
499
+ 1. **Compile-Time:** The template is parsed during macro expansion
500
+ 2. **String Building:** Generates Rust code that builds a TypeScript string at runtime
501
+ 3. **SWC Parsing:** The generated string is parsed with SWC to produce a typed AST
502
+ 4. **Result:** Returns `Stmt` that can be used in `MacroResult` patches
503
+ ## Return Type
504
+ `ts_template!` returns a `Result<Stmt, TsSynError>` by default. The macro automatically unwraps and provides helpful error messages showing the generated TypeScript code if parsing fails:
505
+ ```
811
506
  Failed to parse generated TypeScript:
812
507
  User.prototype.toJSON = function( {
813
508
  return {};
814
509
  }
815
- ```
816
-
817
- This shows you exactly what was generated, making debugging easy!
818
-
819
- ## Nesting and Regular TypeScript
820
-
821
- You can mix template syntax with regular TypeScript. Braces <code >&#123;&#125;</code > are recognized as either:
822
-
823
- - **Template tags** if they start with `#`, `$`, `:`, or `/`
824
-
825
- - **Regular TypeScript blocks** otherwise
826
-
827
- ```rust
510
+ ``` This shows you exactly what was generated, making debugging easy!
511
+ ## Nesting and Regular TypeScript
512
+ You can mix template syntax with regular TypeScript. Braces `{}` are recognized as either:
513
+ - **Template tags** if they start with `#`, `$`, `:`, or `/`
514
+ - **Regular TypeScript blocks** otherwise
515
+ ```
828
516
  ts_template! {
829
517
  const config = {
830
518
  {#if use_strict}
@@ -835,32 +523,14 @@ ts_template! {
835
523
  timeout: 5000
836
524
  };
837
525
  }
838
- ```
839
-
840
- ## Comparison with Alternatives
841
-
842
- | `ts_quote!`
843
- | Compile-time validation, type-safe
844
- | Can't handle Vec<Stmt>, verbose
845
-
846
-
847
-
848
- | `parse_ts_str()`
849
- | Maximum flexibility
850
- | Runtime parsing, less readable
851
-
852
-
853
-
854
- | `ts_template!`
855
- | Readable, handles loops/conditions
856
- | Small runtime parsing overhead
857
-
858
- ## Best Practices
859
-
860
- 1. Use `ts_template!` for complex code generation with loops/conditions
861
-
862
- 2. Use `ts_quote!` for simple, static statements
863
-
864
- 3. Keep templates readable - extract complex logic into variables
865
-
866
- 4. Don't nest templates too deeply - split into helper functions
526
+ ``` ## Comparison with Alternatives
527
+ | Approach | Pros | Cons |
528
+ | --- | --- | --- |
529
+ | `ts_quote!` | Compile-time validation, type-safe | Can't handle Vec<Stmt>, verbose |
530
+ | `parse_ts_str()` | Maximum flexibility | Runtime parsing, less readable |
531
+ | `ts_template!` | Readable, handles loops/conditions | Small runtime parsing overhead |
532
+ ## Best Practices
533
+ 1. Use `ts_template!` for complex code generation with loops/conditions
534
+ 2. Use `ts_quote!` for simple, static statements
535
+ 3. Keep templates readable - extract complex logic into variables
536
+ 4. Don't nest templates too deeply - split into helper functions