@dogsbay/minja 0.2.0-beta.48
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/LICENSE +21 -0
- package/README.md +603 -0
- package/bin/minja.js +1062 -0
- package/dist/browser.d.ts +11 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +10 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +97 -0
- package/dist/cli.js.map +1 -0
- package/dist/context.d.ts +47 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +112 -0
- package/dist/context.js.map +1 -0
- package/dist/evaluator.d.ts +20 -0
- package/dist/evaluator.d.ts.map +1 -0
- package/dist/evaluator.js +207 -0
- package/dist/evaluator.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.js +1026 -0
- package/dist/index.umd.js.map +7 -0
- package/dist/index.umd.min.js +9 -0
- package/dist/index.umd.min.js.map +7 -0
- package/dist/loader-fetch.d.ts +8 -0
- package/dist/loader-fetch.d.ts.map +1 -0
- package/dist/loader-fetch.js +15 -0
- package/dist/loader-fetch.js.map +1 -0
- package/dist/loader-memory.d.ts +11 -0
- package/dist/loader-memory.d.ts.map +1 -0
- package/dist/loader-memory.js +36 -0
- package/dist/loader-memory.js.map +1 -0
- package/dist/loader.d.ts +54 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +91 -0
- package/dist/loader.js.map +1 -0
- package/dist/parser.d.ts +12 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +501 -0
- package/dist/parser.js.map +1 -0
- package/dist/renderer.d.ts +13 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +415 -0
- package/dist/renderer.js.map +1 -0
- package/dist/types.d.ts +150 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,603 @@
|
|
|
1
|
+
# minja
|
|
2
|
+
|
|
3
|
+
**Minimal, secure Jinja2/Nunjucks subset for documentation preprocessing**
|
|
4
|
+
|
|
5
|
+
Minja is a template engine designed specifically for documentation and content preprocessing, using standard Jinja2/Nunjucks syntax with **zero arbitrary code execution risk**.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Security First**: No `eval()`, no `new Function()`, no arbitrary code execution
|
|
10
|
+
- **Standard Jinja2 Syntax**: Fully compatible with Jinja2/Nunjucks conditionals
|
|
11
|
+
- **Variable Substitution**: Simple `{{ variable }}` syntax
|
|
12
|
+
- **Conditionals**: `{% if %}`, `{% elif %}`, `{% else %}` with safe expression evaluation
|
|
13
|
+
- **Switch Statements**: `{% switch %}` / `{% case %}` for multiple conditions
|
|
14
|
+
- **Nested Includes**: Recursive `{% include "file.md" %}` support
|
|
15
|
+
- **Leveloffset**: `{% leveloffset +1 %}` for shifting heading levels in included content
|
|
16
|
+
- **Variable Scoping**: Global and local variables with dot notation
|
|
17
|
+
- **Modern**: TypeScript, ES modules, works in browsers and Node.js
|
|
18
|
+
- **Small**: ~10KB minified + gzipped
|
|
19
|
+
- **Zero Dependencies**: No runtime dependencies
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install minja
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Or install globally to use the CLI:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install -g minja
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { render } from 'minja'
|
|
37
|
+
|
|
38
|
+
const template = `
|
|
39
|
+
{% set product = "MyApp" %}
|
|
40
|
+
{% set version = "1.0" %}
|
|
41
|
+
|
|
42
|
+
# {{ product }} Documentation
|
|
43
|
+
|
|
44
|
+
Version: {{ version }}
|
|
45
|
+
|
|
46
|
+
{% if version >= "1.0" %}
|
|
47
|
+
This is a stable release.
|
|
48
|
+
{% endif %}
|
|
49
|
+
|
|
50
|
+
{% include "common/footer.md" %}
|
|
51
|
+
`
|
|
52
|
+
|
|
53
|
+
const output = await render(template, {
|
|
54
|
+
context: {
|
|
55
|
+
author: 'John Doe'
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
console.log(output)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## CLI Usage
|
|
63
|
+
|
|
64
|
+
Minja includes a command-line interface for rendering templates from files or stdin.
|
|
65
|
+
|
|
66
|
+
### Basic Usage
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Render a template file
|
|
70
|
+
minja template.md
|
|
71
|
+
|
|
72
|
+
# Render with context from JSON file
|
|
73
|
+
minja template.md --context vars.json
|
|
74
|
+
|
|
75
|
+
# Render with context from YAML file
|
|
76
|
+
minja template.md --context vars.yaml
|
|
77
|
+
|
|
78
|
+
# Render with inline variables
|
|
79
|
+
minja template.md --vars '{"title":"My Doc","version":"1.0"}'
|
|
80
|
+
|
|
81
|
+
# Save output to file
|
|
82
|
+
minja template.md --context vars.json --output result.html
|
|
83
|
+
|
|
84
|
+
# Read from stdin
|
|
85
|
+
cat template.md | minja --vars '{"name":"World"}'
|
|
86
|
+
echo "# {{ title }}" | minja --vars '{"title":"Test"}'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### CLI Options
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
Usage: minja [options] [template]
|
|
93
|
+
|
|
94
|
+
Arguments:
|
|
95
|
+
template Template file to render (or read from stdin)
|
|
96
|
+
|
|
97
|
+
Options:
|
|
98
|
+
-V, --version output the version number
|
|
99
|
+
-c, --context <file> Context file (JSON or YAML)
|
|
100
|
+
-o, --output <file> Output file (default: stdout)
|
|
101
|
+
-d, --max-depth <number> Maximum include depth (default: 10)
|
|
102
|
+
-t, --timeout <ms> Rendering timeout in milliseconds (default: 5000)
|
|
103
|
+
-v, --vars <json> Inline context variables as JSON
|
|
104
|
+
-h, --help display help for command
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Examples
|
|
108
|
+
|
|
109
|
+
**Simple template rendering:**
|
|
110
|
+
```bash
|
|
111
|
+
minja hello.md --vars '{"name":"World"}'
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**With context file:**
|
|
115
|
+
```bash
|
|
116
|
+
# vars.json
|
|
117
|
+
{
|
|
118
|
+
"product": "MyApp",
|
|
119
|
+
"version": "2.0"
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
# Render
|
|
123
|
+
minja README.md --context vars.json
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Using includes:**
|
|
127
|
+
```bash
|
|
128
|
+
# document.md includes common/vars.md
|
|
129
|
+
minja document.md --output docs/index.html
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Pipeline usage:**
|
|
133
|
+
```bash
|
|
134
|
+
# Generate docs from multiple sources
|
|
135
|
+
cat header.md content.md footer.md | minja --context config.yaml > output.html
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Syntax
|
|
139
|
+
|
|
140
|
+
### Variable Substitution
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
{{ variable }}
|
|
144
|
+
{{ object.property }}
|
|
145
|
+
{{ nested.property.value }}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Variable Definition
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
{% set variable = "value" %}
|
|
152
|
+
{% set count = 42 %}
|
|
153
|
+
{% set enabled = true %}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Conditionals
|
|
157
|
+
|
|
158
|
+
Basic if statement:
|
|
159
|
+
```
|
|
160
|
+
{% if condition %}
|
|
161
|
+
Content when true
|
|
162
|
+
{% endif %}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
If-else statement:
|
|
166
|
+
```
|
|
167
|
+
{% if condition %}
|
|
168
|
+
Content when true
|
|
169
|
+
{% else %}
|
|
170
|
+
Content when false
|
|
171
|
+
{% endif %}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
If-elif-else statement:
|
|
175
|
+
```
|
|
176
|
+
{% if platform == "aws" %}
|
|
177
|
+
Amazon Web Services
|
|
178
|
+
{% elif platform == "azure" %}
|
|
179
|
+
Microsoft Azure
|
|
180
|
+
{% elif platform == "gcp" %}
|
|
181
|
+
Google Cloud Platform
|
|
182
|
+
{% else %}
|
|
183
|
+
Unknown platform
|
|
184
|
+
{% endif %}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Ifdef/Ifndef (AsciiDoc-style)
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
{% ifdef variable %}
|
|
191
|
+
Content when variable is defined
|
|
192
|
+
{% endifdef %}
|
|
193
|
+
|
|
194
|
+
{% ifndef variable %}
|
|
195
|
+
Content when variable is not defined
|
|
196
|
+
{% endifndef %}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Ifeval (Conditional Expressions)
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
{% ifeval [version >= "1.0"] %}
|
|
203
|
+
Stable release content
|
|
204
|
+
{% endifeval %}
|
|
205
|
+
|
|
206
|
+
{% ifeval [platform == "linux"] %}
|
|
207
|
+
Linux-specific content
|
|
208
|
+
{% endifeval %}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Switch Statements
|
|
212
|
+
|
|
213
|
+
Switch-case for multiple conditions:
|
|
214
|
+
```
|
|
215
|
+
{% switch platform %}
|
|
216
|
+
{% case "aws" %}
|
|
217
|
+
Amazon Web Services (AWS)
|
|
218
|
+
{% case "azure" %}
|
|
219
|
+
Microsoft Azure
|
|
220
|
+
{% case "gcp" %}
|
|
221
|
+
Google Cloud Platform (GCP)
|
|
222
|
+
{% endswitch %}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Switch statements support:
|
|
226
|
+
- String and numeric case values
|
|
227
|
+
- Expression-based switch values
|
|
228
|
+
- Multiple case blocks
|
|
229
|
+
- Falls through on first match only (no default case)
|
|
230
|
+
|
|
231
|
+
### Leveloffset (Heading Level Control)
|
|
232
|
+
|
|
233
|
+
Shift markdown heading levels in included content:
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
{% leveloffset +1 %}
|
|
237
|
+
{% include "chapter.md" %}
|
|
238
|
+
{% endleveloffset %}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Offset types:**
|
|
242
|
+
- **Absolute**: `{% leveloffset 2 %}` - Sets offset to exact value
|
|
243
|
+
- **Relative**: `{% leveloffset +1 %}` or `{% leveloffset -1 %}` - Adds/subtracts from current
|
|
244
|
+
- **Reset**: `{% leveloffset 0 %}` - No offset
|
|
245
|
+
|
|
246
|
+
**Example:**
|
|
247
|
+
|
|
248
|
+
`chapter.md`:
|
|
249
|
+
```markdown
|
|
250
|
+
# Chapter Title
|
|
251
|
+
## Section
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
With `{% leveloffset +1 %}`:
|
|
255
|
+
```markdown
|
|
256
|
+
## Chapter Title
|
|
257
|
+
### Section
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
This is perfect for modular documentation where you include the same content at different hierarchical levels. Inspired by AsciiDoc's `leveloffset` attribute.
|
|
261
|
+
|
|
262
|
+
See [Leveloffset documentation](docs/syntax-reference.md#leveloffset-heading-level-control) for detailed usage and examples.
|
|
263
|
+
|
|
264
|
+
### Includes
|
|
265
|
+
|
|
266
|
+
```
|
|
267
|
+
{% include "path/to/file.md" %}
|
|
268
|
+
{% include "common/header.md" %}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Includes support:
|
|
272
|
+
- Relative paths
|
|
273
|
+
- Nested includes (with depth limit)
|
|
274
|
+
- URL-based loading (in browsers)
|
|
275
|
+
- Filesystem loading (in Node.js)
|
|
276
|
+
|
|
277
|
+
### Comments
|
|
278
|
+
|
|
279
|
+
```
|
|
280
|
+
{# This is a comment and won't appear in output #}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Comments on their own line are automatically stripped along with surrounding whitespace.
|
|
284
|
+
|
|
285
|
+
### Whitespace Control
|
|
286
|
+
|
|
287
|
+
Minja supports Nunjucks/Jinja2 whitespace control syntax to manage spacing and newlines in your output.
|
|
288
|
+
|
|
289
|
+
#### Basic Syntax
|
|
290
|
+
|
|
291
|
+
- `{%-` - Left strip: removes whitespace before the tag
|
|
292
|
+
- `-%}` - Right strip: removes whitespace after the tag
|
|
293
|
+
- `{%- -%}` - Both: removes whitespace on both sides
|
|
294
|
+
|
|
295
|
+
#### Examples
|
|
296
|
+
|
|
297
|
+
**Without whitespace control:**
|
|
298
|
+
```markdown
|
|
299
|
+
{% set product = "MyApp" %}
|
|
300
|
+
{% set version = "1.0" %}
|
|
301
|
+
# {{ product }}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Output (note the blank lines from set statements):
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
# MyApp
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
**With whitespace control:**
|
|
312
|
+
```markdown
|
|
313
|
+
{%- set product = "MyApp" -%}
|
|
314
|
+
{%- set version = "1.0" -%}
|
|
315
|
+
# {{ product }}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Output (clean, no blank lines):
|
|
319
|
+
```
|
|
320
|
+
# MyApp
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
**Mixed control:**
|
|
324
|
+
```markdown
|
|
325
|
+
Line 1
|
|
326
|
+
{%- set var = "value" %}
|
|
327
|
+
Line 2
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Output (left strip removes newline before set):
|
|
331
|
+
```
|
|
332
|
+
Line 1
|
|
333
|
+
Line 2
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
#### Best Practices
|
|
337
|
+
|
|
338
|
+
For attribute files with many set statements, use `{%- set -%}` to avoid blank lines:
|
|
339
|
+
|
|
340
|
+
`common-attributes.md`:
|
|
341
|
+
```markdown
|
|
342
|
+
{%- set product_name = "MyProduct" -%}
|
|
343
|
+
{%- set product_version = "1.0" -%}
|
|
344
|
+
{%- set company = "ACME Corp" -%}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
This prevents each set statement from adding blank lines to your output.
|
|
348
|
+
|
|
349
|
+
## API
|
|
350
|
+
|
|
351
|
+
### `render(template, options)`
|
|
352
|
+
|
|
353
|
+
Render a template string.
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
async function render(
|
|
357
|
+
template: string,
|
|
358
|
+
options?: RenderOptions
|
|
359
|
+
): Promise<string>
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
**Options:**
|
|
363
|
+
|
|
364
|
+
- `loader?: Loader` - File loader for includes (default: `FetchLoader`)
|
|
365
|
+
- `context?: Record<string, unknown>` - Initial variables
|
|
366
|
+
- `maxIncludeDepth?: number` - Maximum include recursion depth (default: 10)
|
|
367
|
+
- `timeout?: number` - Rendering timeout in ms (default: 5000)
|
|
368
|
+
|
|
369
|
+
**Example:**
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
import { render, FileSystemLoader } from 'minja'
|
|
373
|
+
|
|
374
|
+
const output = await render(template, {
|
|
375
|
+
loader: new FileSystemLoader('/path/to/docs'),
|
|
376
|
+
context: {
|
|
377
|
+
product: 'MyApp',
|
|
378
|
+
version: '2.0'
|
|
379
|
+
},
|
|
380
|
+
maxIncludeDepth: 5,
|
|
381
|
+
timeout: 10000
|
|
382
|
+
})
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Loaders
|
|
386
|
+
|
|
387
|
+
#### `FetchLoader`
|
|
388
|
+
|
|
389
|
+
For browsers and service workers (uses Fetch API).
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
import { render, FetchLoader } from 'minja'
|
|
393
|
+
|
|
394
|
+
const output = await render(template, {
|
|
395
|
+
loader: new FetchLoader()
|
|
396
|
+
})
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
#### `FileSystemLoader`
|
|
400
|
+
|
|
401
|
+
For Node.js (uses `fs.readFile`).
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
import { render, FileSystemLoader } from 'minja'
|
|
405
|
+
|
|
406
|
+
const loader = new FileSystemLoader('/base/path')
|
|
407
|
+
const output = await render(template, { loader })
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
#### `MemoryLoader`
|
|
411
|
+
|
|
412
|
+
For testing (stores files in memory).
|
|
413
|
+
|
|
414
|
+
```typescript
|
|
415
|
+
import { render, MemoryLoader } from 'minja'
|
|
416
|
+
|
|
417
|
+
const loader = new MemoryLoader({
|
|
418
|
+
'header.md': '# {{ title }}',
|
|
419
|
+
'footer.md': '© 2026'
|
|
420
|
+
})
|
|
421
|
+
|
|
422
|
+
const output = await render('{% include "header.md" %}', { loader })
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
## Security Model
|
|
426
|
+
|
|
427
|
+
Minja is designed to be **secure by default**:
|
|
428
|
+
|
|
429
|
+
### What's Allowed
|
|
430
|
+
|
|
431
|
+
- Variable substitution
|
|
432
|
+
- Safe comparisons (`==`, `!=`, `<`, `>`, `<=`, `>=`)
|
|
433
|
+
- Logical operators (`and`, `or`, `not`)
|
|
434
|
+
- Simple literals (strings, numbers, booleans, null)
|
|
435
|
+
- Dot notation for object properties
|
|
436
|
+
|
|
437
|
+
### What's Blocked
|
|
438
|
+
|
|
439
|
+
- ❌ Arbitrary code execution
|
|
440
|
+
- ❌ Function calls (except whitelisted built-ins)
|
|
441
|
+
- ❌ Access to `eval`, `Function`, `require`, `import`
|
|
442
|
+
- ❌ Access to `window`, `process`, `globalThis`
|
|
443
|
+
- ❌ Prototype pollution
|
|
444
|
+
- ❌ Property assignment beyond template variables
|
|
445
|
+
|
|
446
|
+
### Resource Limits
|
|
447
|
+
|
|
448
|
+
- Maximum include depth (default: 10)
|
|
449
|
+
- Rendering timeout (default: 5000ms)
|
|
450
|
+
- Expression complexity limits
|
|
451
|
+
|
|
452
|
+
## Use Cases
|
|
453
|
+
|
|
454
|
+
Minja is perfect for:
|
|
455
|
+
|
|
456
|
+
- **Documentation preprocessing**: AsciiDoc-style attribute substitution
|
|
457
|
+
- **Static site generation**: Conditional content based on variables
|
|
458
|
+
- **Multi-variant docs**: Platform-specific or version-specific content
|
|
459
|
+
- **Email templates**: Safe user-data substitution
|
|
460
|
+
- **Configuration files**: Template-driven config generation
|
|
461
|
+
|
|
462
|
+
## Comparison with Nunjucks/Jinja2
|
|
463
|
+
|
|
464
|
+
| Feature | minja | Nunjucks |
|
|
465
|
+
|---------|-------|----------|
|
|
466
|
+
| Variable substitution | ✅ | ✅ |
|
|
467
|
+
| Conditionals (if/elif/else) | ✅ | ✅ |
|
|
468
|
+
| Switch statements | ✅ | ❌ |
|
|
469
|
+
| Includes | ✅ | ✅ |
|
|
470
|
+
| Security | ✅ No code execution | ❌ Arbitrary code |
|
|
471
|
+
| AsciiDoc-style | ✅ ifdef/ifndef/ifeval | ❌ |
|
|
472
|
+
| Loops | ❌ | ✅ |
|
|
473
|
+
| Filters | ❌ | ✅ |
|
|
474
|
+
| Macros | ❌ | ✅ |
|
|
475
|
+
| Extends/Blocks | ❌ | ✅ |
|
|
476
|
+
| Bundle size | ~10KB | ~50KB+ |
|
|
477
|
+
|
|
478
|
+
## Examples
|
|
479
|
+
|
|
480
|
+
### Platform-Specific Documentation
|
|
481
|
+
|
|
482
|
+
Using ifeval:
|
|
483
|
+
```markdown
|
|
484
|
+
{% set platform = "linux" %}
|
|
485
|
+
|
|
486
|
+
# Installation Guide
|
|
487
|
+
|
|
488
|
+
{% ifeval [platform == "linux"] %}
|
|
489
|
+
Install using your package manager:
|
|
490
|
+
```bash
|
|
491
|
+
sudo apt install myapp
|
|
492
|
+
```
|
|
493
|
+
{% endifeval %}
|
|
494
|
+
|
|
495
|
+
{% ifeval [platform == "macos"] %}
|
|
496
|
+
Install using Homebrew:
|
|
497
|
+
```bash
|
|
498
|
+
brew install myapp
|
|
499
|
+
```
|
|
500
|
+
{% endifeval %}
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
Using switch statements:
|
|
504
|
+
```markdown
|
|
505
|
+
{% set platform = "linux" %}
|
|
506
|
+
|
|
507
|
+
# Installation Guide
|
|
508
|
+
|
|
509
|
+
{% switch platform %}
|
|
510
|
+
{% case "linux" %}
|
|
511
|
+
Install using your package manager:
|
|
512
|
+
```bash
|
|
513
|
+
sudo apt install myapp
|
|
514
|
+
```
|
|
515
|
+
{% case "macos" %}
|
|
516
|
+
Install using Homebrew:
|
|
517
|
+
```bash
|
|
518
|
+
brew install myapp
|
|
519
|
+
```
|
|
520
|
+
{% case "windows" %}
|
|
521
|
+
Download the installer from our website.
|
|
522
|
+
{% endswitch %}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### Version-Specific Content
|
|
526
|
+
|
|
527
|
+
```markdown
|
|
528
|
+
{% set version = "2.0" %}
|
|
529
|
+
|
|
530
|
+
# Features
|
|
531
|
+
|
|
532
|
+
{% ifeval [version >= "2.0"] %}
|
|
533
|
+
## New in 2.0
|
|
534
|
+
- Feature A
|
|
535
|
+
- Feature B
|
|
536
|
+
{% endifeval %}
|
|
537
|
+
|
|
538
|
+
{% ifeval [version >= "1.0"] %}
|
|
539
|
+
## Available since 1.0
|
|
540
|
+
- Feature X
|
|
541
|
+
- Feature Y
|
|
542
|
+
{% endifeval %}
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### Common Attributes Pattern (AsciiDoc-style)
|
|
546
|
+
|
|
547
|
+
`common-attributes.md`:
|
|
548
|
+
```
|
|
549
|
+
{%- set product_name = "MyProduct" -%}
|
|
550
|
+
{%- set product_version = "1.0" -%}
|
|
551
|
+
{%- set company = "ACME Corp" -%}
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
`document.md`:
|
|
555
|
+
```
|
|
556
|
+
{% include "common-attributes.md" %}
|
|
557
|
+
|
|
558
|
+
# {{ product_name }} Guide
|
|
559
|
+
|
|
560
|
+
Version {{ product_version }}
|
|
561
|
+
|
|
562
|
+
Welcome to {{ product_name }} by {{ company }}.
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
**Note:** Use `{%- set -%}` in attribute files to prevent blank lines in the output.
|
|
566
|
+
|
|
567
|
+
## Documentation
|
|
568
|
+
|
|
569
|
+
For complete documentation, see the [docs/](docs/) directory:
|
|
570
|
+
|
|
571
|
+
- **[Getting Started](docs/getting-started.md)** - Installation and your first template
|
|
572
|
+
- **[Syntax Reference](docs/syntax-reference.md)** - Complete syntax documentation
|
|
573
|
+
- **[AsciiDoc Migration](docs/asciidoc-migration.md)** - Converting from AsciiDoc to Minja
|
|
574
|
+
- **[CLI Usage](docs/cli-usage.md)** - Command-line interface guide
|
|
575
|
+
- **[Examples](docs/examples.md)** - Common patterns and use cases
|
|
576
|
+
- **[API Reference](docs/api-reference.md)** - Programmatic API documentation
|
|
577
|
+
- **[FAQ](docs/faq.md)** - Frequently asked questions
|
|
578
|
+
|
|
579
|
+
## Development
|
|
580
|
+
|
|
581
|
+
```bash
|
|
582
|
+
# Install dependencies
|
|
583
|
+
npm install
|
|
584
|
+
|
|
585
|
+
# Build
|
|
586
|
+
npm run build
|
|
587
|
+
|
|
588
|
+
# Test
|
|
589
|
+
npm test
|
|
590
|
+
|
|
591
|
+
# Test with coverage
|
|
592
|
+
npm run test:coverage
|
|
593
|
+
|
|
594
|
+
# Lint
|
|
595
|
+
npm run lint
|
|
596
|
+
|
|
597
|
+
# Format
|
|
598
|
+
npm run format
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
## License
|
|
602
|
+
|
|
603
|
+
MIT
|