@dogsbay/minja 0.2.0-beta.100

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 (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +623 -0
  3. package/bin/minja.js +1225 -0
  4. package/dist/browser.d.ts +12 -0
  5. package/dist/browser.d.ts.map +1 -0
  6. package/dist/browser.js +11 -0
  7. package/dist/browser.js.map +1 -0
  8. package/dist/cli.d.ts +5 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +98 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/context.d.ts +47 -0
  13. package/dist/context.d.ts.map +1 -0
  14. package/dist/context.js +112 -0
  15. package/dist/context.js.map +1 -0
  16. package/dist/evaluator.d.ts +20 -0
  17. package/dist/evaluator.d.ts.map +1 -0
  18. package/dist/evaluator.js +213 -0
  19. package/dist/evaluator.js.map +1 -0
  20. package/dist/index.d.ts +20 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +18 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/index.umd.js +1160 -0
  25. package/dist/index.umd.js.map +7 -0
  26. package/dist/index.umd.min.js +12 -0
  27. package/dist/index.umd.min.js.map +7 -0
  28. package/dist/loader-fetch.d.ts +8 -0
  29. package/dist/loader-fetch.d.ts.map +1 -0
  30. package/dist/loader-fetch.js +15 -0
  31. package/dist/loader-fetch.js.map +1 -0
  32. package/dist/loader-memory.d.ts +11 -0
  33. package/dist/loader-memory.d.ts.map +1 -0
  34. package/dist/loader-memory.js +36 -0
  35. package/dist/loader-memory.js.map +1 -0
  36. package/dist/loader.d.ts +73 -0
  37. package/dist/loader.d.ts.map +1 -0
  38. package/dist/loader.js +159 -0
  39. package/dist/loader.js.map +1 -0
  40. package/dist/parser.d.ts +7 -0
  41. package/dist/parser.d.ts.map +1 -0
  42. package/dist/parser.js +609 -0
  43. package/dist/parser.js.map +1 -0
  44. package/dist/renderer.d.ts +13 -0
  45. package/dist/renderer.d.ts.map +1 -0
  46. package/dist/renderer.js +494 -0
  47. package/dist/renderer.js.map +1 -0
  48. package/dist/scan.d.ts +46 -0
  49. package/dist/scan.d.ts.map +1 -0
  50. package/dist/scan.js +46 -0
  51. package/dist/scan.js.map +1 -0
  52. package/dist/types.d.ts +175 -0
  53. package/dist/types.d.ts.map +1 -0
  54. package/dist/types.js +5 -0
  55. package/dist/types.js.map +1 -0
  56. package/package.json +72 -0
@@ -0,0 +1,494 @@
1
+ /**
2
+ * Template renderer
3
+ * Combines parser, evaluator, and loader to render templates
4
+ */
5
+ import { parse } from './parser.js';
6
+ import { Context } from './context.js';
7
+ import { evaluateExpression } from './evaluator.js';
8
+ import { FetchLoader } from './loader-fetch.js';
9
+ /**
10
+ * Transform markdown headings by applying level offset
11
+ * Clamps to valid markdown range (1-6)
12
+ * @param text - Text content to transform
13
+ * @param offset - Level offset to apply
14
+ * @returns Transformed text with adjusted heading levels
15
+ */
16
+ function transformHeadings(text, offset, initialFence = null, fenceOut) {
17
+ if (offset === 0) {
18
+ if (fenceOut)
19
+ fenceOut.fence = initialFence;
20
+ return text;
21
+ }
22
+ // Fence-aware: only shift ATX headings that are NOT inside a fenced code
23
+ // block. A line-anchored regex would otherwise rewrite `# oc get pods`
24
+ // (a shell prompt / comment) inside a ```terminal block to `## …`,
25
+ // mutating code-block content — which the no-code-block-mutation rule
26
+ // forbids. Issue #020 / task #404.
27
+ const lines = text.split('\n');
28
+ // Fence state CARRIES ACROSS text nodes: a directive inside a listing
29
+ // splits the template into several text nodes, and restarting the state
30
+ // per node lost the open fence — `#` comments at column 0 inside the
31
+ // second half were shifted to `###` (issue #043, managing-ce's
32
+ // ClusterRole manifest; the same class as issue #020).
33
+ let fence = initialFence; // active opening fence run (e.g. "```") while inside a code block
34
+ for (let i = 0; i < lines.length; i++) {
35
+ const line = lines[i];
36
+ const fenceMatch = line.match(/^\s*(`{3,}|~{3,})/);
37
+ if (fenceMatch) {
38
+ const run = fenceMatch[1];
39
+ if (fence === null) {
40
+ // Opening fence (an info string may follow on this line).
41
+ fence = run;
42
+ }
43
+ else if (run[0] === fence[0] && run.length >= fence.length && line.trim() === run) {
44
+ // Closing fence: bare marker, same char, length >= opening (CommonMark).
45
+ fence = null;
46
+ }
47
+ continue; // never treat a fence line as a heading
48
+ }
49
+ if (fence !== null) {
50
+ continue; // inside a code block — leave the line verbatim
51
+ }
52
+ const m = line.match(/^(#{1,6})(\s+)/);
53
+ if (m) {
54
+ const newLevel = Math.max(1, Math.min(6, m[1].length + offset));
55
+ lines[i] = '#'.repeat(newLevel) + line.slice(m[1].length);
56
+ }
57
+ }
58
+ if (fenceOut)
59
+ fenceOut.fence = fence;
60
+ return lines.join('\n');
61
+ }
62
+ /**
63
+ * Resolve a relative path against a base path
64
+ * @param path - Relative or absolute path
65
+ * @param basePath - Base path to resolve against
66
+ * @returns Resolved path
67
+ */
68
+ function resolvePath(path, basePath) {
69
+ // If path is absolute, return as-is
70
+ if (path.startsWith('/')) {
71
+ return path;
72
+ }
73
+ // Ensure basePath ends with /
74
+ const base = basePath.endsWith('/') ? basePath : basePath + '/';
75
+ // Combine and normalize
76
+ const combined = base + path;
77
+ // Normalize . and .. segments
78
+ const parts = combined.split('/');
79
+ const resolved = [];
80
+ for (const part of parts) {
81
+ if (part === '.' || part === '') {
82
+ continue;
83
+ }
84
+ else if (part === '..') {
85
+ resolved.pop();
86
+ }
87
+ else {
88
+ resolved.push(part);
89
+ }
90
+ }
91
+ // Preserve leading slash if original had one
92
+ const prefix = combined.startsWith('/') ? '/' : '';
93
+ return prefix + resolved.join('/');
94
+ }
95
+ /**
96
+ * Render a template string
97
+ * @param template - Template string to render
98
+ * @param options - Render options
99
+ * @returns Rendered output
100
+ */
101
+ export async function render(template, options = {}) {
102
+ const { loader = new FetchLoader(), context: initialContext = {}, basePath = '', maxIncludeDepth = 10, timeout = 5000, hyphenToUnderscore = false, undefinedBehavior = 'empty', undefinedConditions = 'preserve', } = options;
103
+ // Create timeout promise
104
+ const timeoutPromise = new Promise((_, reject) => {
105
+ setTimeout(() => reject(new Error('Template rendering timeout')), timeout);
106
+ });
107
+ // Render with timeout
108
+ const renderPromise = renderInternal(template, {
109
+ loader,
110
+ context: Context.from({
111
+ ...initialContext,
112
+ // Built-in variables
113
+ date: new Date().toISOString().split('T')[0],
114
+ timestamp: Date.now(),
115
+ _levelOffset: 0,
116
+ }, { hyphenToUnderscore }),
117
+ includeDepth: 0,
118
+ maxIncludeDepth,
119
+ basePath,
120
+ undefinedBehavior,
121
+ undefinedConditions,
122
+ });
123
+ return await Promise.race([renderPromise, timeoutPromise]);
124
+ }
125
+ /**
126
+ * Internal rendering function with depth tracking
127
+ */
128
+ async function renderInternal(template, options) {
129
+ const { includeDepth, maxIncludeDepth } = options;
130
+ // Check recursion depth
131
+ if (includeDepth > maxIncludeDepth) {
132
+ throw new Error(`Maximum include depth (${maxIncludeDepth}) exceeded`);
133
+ }
134
+ // Parse template
135
+ const parseResult = parse(template);
136
+ if (parseResult.errors.length > 0) {
137
+ const errorMessages = parseResult.errors.map((e) => e.message).join(', ');
138
+ throw new Error(`Parse errors: ${errorMessages}`);
139
+ }
140
+ // Render AST
141
+ return await renderNodes(parseResult.ast, options);
142
+ }
143
+ /**
144
+ * Render an array of AST nodes
145
+ */
146
+ async function renderNodes(nodes, options) {
147
+ const parts = [];
148
+ for (const node of nodes) {
149
+ let rendered = await renderNode(node, options);
150
+ // An {% include %} that sits alone on an INDENTED line splices content
151
+ // into that indentation context (a list item, an open block in a step):
152
+ // re-indent every non-empty spliced line to the directive's own column.
153
+ // Verbatim splicing put included bullets/fences at column 0 inside a
154
+ // level-2 step, shattering the list and orphaning everything after
155
+ // (the ":::important in a code block" class, cnf-image-based-upgrade).
156
+ // Top-level includes have no leading indent and are untouched.
157
+ if (node.type === 'include' && rendered && parts.length > 0) {
158
+ const tail = /(?:^|\n)([ \t]+)$/.exec(parts[parts.length - 1]);
159
+ if (tail) {
160
+ rendered = rendered.replace(/\n(?=[^\n])/g, '\n' + tail[1]);
161
+ }
162
+ }
163
+ parts.push(rendered);
164
+ }
165
+ return parts.join('');
166
+ }
167
+ /**
168
+ * Render a single AST node
169
+ */
170
+ async function renderNode(node, options) {
171
+ const { loader, context, includeDepth, maxIncludeDepth, basePath } = options;
172
+ switch (node.type) {
173
+ case 'text': {
174
+ // Apply leveloffset if active
175
+ const currentOffset = context.get('_levelOffset') || 0;
176
+ if (currentOffset === 0) {
177
+ return node.value;
178
+ }
179
+ const fenceOut = { fence: null };
180
+ const out = transformHeadings(node.value, currentOffset, context.get('_levelOffsetFence') ?? null, fenceOut);
181
+ context.set('_levelOffsetFence', fenceOut.fence);
182
+ return out;
183
+ }
184
+ case 'variable': {
185
+ const value = context.get(node.name);
186
+ if (value === undefined || value === null) {
187
+ // Apply the undefined-variable policy. See RenderOptions.undefinedBehavior.
188
+ switch (options.undefinedBehavior) {
189
+ case 'throw':
190
+ throw new Error(`Undefined variable: ${node.name}`);
191
+ case 'preserve':
192
+ // Round-trip the source form so downstream tooling (or a
193
+ // second-pass minja run with the value supplied) can pick
194
+ // up where we left off.
195
+ return `{{ ${node.name} }}`;
196
+ case 'asciidoc-literal':
197
+ // Terminal build of an AsciiDoc-migrated corpus: every ref
198
+ // came from an `{name}` attribute reference, so an
199
+ // unresolvable one is a literal placeholder — render what
200
+ // asciidoctor renders for an undefined attribute.
201
+ return `{${node.name}}`;
202
+ case 'empty':
203
+ default:
204
+ return '';
205
+ }
206
+ }
207
+ const str = String(value);
208
+ // If the value contains template syntax, re-process it
209
+ if (str.includes('{{') || str.includes('{%')) {
210
+ return await renderInternal(str, options);
211
+ }
212
+ return str;
213
+ }
214
+ case 'set': {
215
+ const value = evaluateExpression(node.value, context);
216
+ context.set(node.name, value);
217
+ return '';
218
+ }
219
+ case 'comment':
220
+ return '';
221
+ case 'if': {
222
+ // In preserve mode, an `if` whose condition references an
223
+ // undefined identifier can't be evaluated — we don't know
224
+ // which branch to take. Preserve the whole `{% if … %}…{% endif %}`
225
+ // verbatim so a second pass (with the value supplied) can
226
+ // resolve it. See plans/format-asciidoc-import.md.
227
+ //
228
+ // Except when `undefinedConditions === 'falsy'`: this is a
229
+ // terminal build with no later pass, so treat the undefined
230
+ // reference as falsy (AsciiDoc `ifdef::attr[]` semantics) and
231
+ // evaluate now rather than leak the directive to readers.
232
+ if ((options.undefinedBehavior === 'preserve' || options.undefinedBehavior === 'asciidoc-literal') && options.undefinedConditions !== 'falsy') {
233
+ const undefinedRefs = findUndefinedRefs(node.condition, context);
234
+ if (undefinedRefs.length > 0) {
235
+ return ifNodeToSource(node);
236
+ }
237
+ if (node.elifBranches) {
238
+ for (const elif of node.elifBranches) {
239
+ if (findUndefinedRefs(elif.condition, context).length > 0) {
240
+ return ifNodeToSource(node);
241
+ }
242
+ }
243
+ }
244
+ }
245
+ const condition = evaluateExpression(node.condition, context);
246
+ if (isTruthy(condition)) {
247
+ return await renderNodes(node.trueBranch, options);
248
+ }
249
+ // Check elif branches
250
+ if (node.elifBranches) {
251
+ for (const elifBranch of node.elifBranches) {
252
+ const elifCondition = evaluateExpression(elifBranch.condition, context);
253
+ if (isTruthy(elifCondition)) {
254
+ return await renderNodes(elifBranch.body, options);
255
+ }
256
+ }
257
+ }
258
+ // Render else branch if present
259
+ if (node.elseBranch) {
260
+ return await renderNodes(node.elseBranch, options);
261
+ }
262
+ return '';
263
+ }
264
+ case 'include': {
265
+ try {
266
+ // Load the included file
267
+ const includedContent = await loader.load(node.path, basePath);
268
+ // Determine new base path for nested includes
269
+ let newBasePath = basePath;
270
+ // If path looks like a URL, extract base
271
+ if (node.path.includes('://')) {
272
+ const url = new URL(node.path);
273
+ newBasePath = url.href.substring(0, url.href.lastIndexOf('/') + 1);
274
+ }
275
+ else if (basePath) {
276
+ // Relative path - resolve against current base
277
+ if (basePath.includes('://')) {
278
+ const url = new URL(node.path, basePath);
279
+ newBasePath = url.href.substring(0, url.href.lastIndexOf('/') + 1);
280
+ }
281
+ else {
282
+ // File path - resolve relative to current base and extract directory
283
+ const resolvedPath = resolvePath(node.path, basePath);
284
+ const lastSlash = resolvedPath.lastIndexOf('/');
285
+ newBasePath = lastSlash >= 0 ? resolvedPath.substring(0, lastSlash + 1) : basePath;
286
+ }
287
+ }
288
+ else if (node.path.includes('/')) {
289
+ // No base path but include has directory - use that as base
290
+ const lastSlash = node.path.lastIndexOf('/');
291
+ newBasePath = node.path.substring(0, lastSlash + 1);
292
+ }
293
+ // Render the included template (recursive)
294
+ return await renderInternal(includedContent, {
295
+ loader,
296
+ context,
297
+ includeDepth: includeDepth + 1,
298
+ maxIncludeDepth,
299
+ basePath: newBasePath,
300
+ undefinedBehavior: options.undefinedBehavior,
301
+ undefinedConditions: options.undefinedConditions,
302
+ });
303
+ }
304
+ catch (error) {
305
+ // A containment refusal is a SECURITY event, not a missing file:
306
+ // neither preserved for a later pass (no later pass may resolve
307
+ // it) nor degraded to a comment — the render fails hard (#027).
308
+ if (error instanceof Error && error.name === 'IncludeContainmentError') {
309
+ throw error;
310
+ }
311
+ // In `preserve` mode, an unresolvable include is preserved
312
+ // as the original directive so a later renderer pass (with
313
+ // the file in place) can resolve it. Matches the semantic
314
+ // of `preserve` for undefined variables. Without this,
315
+ // multi-stage pipelines (e.g. dogsbay's convert + build
316
+ // preprocessor for AsciiDoc imports) lose the directive at
317
+ // stage 1 because targets only exist after stage 2 has
318
+ // converted sibling files.
319
+ if (options.undefinedBehavior === 'preserve' || options.undefinedBehavior === 'asciidoc-literal') {
320
+ return `{% include "${node.path}" %}`;
321
+ }
322
+ const message = error instanceof Error ? error.message : String(error);
323
+ console.error(`Failed to include ${node.path}:`, message);
324
+ return `<!-- Include error: ${node.path} -->`;
325
+ }
326
+ }
327
+ case 'switch': {
328
+ const switchValue = evaluateExpression(node.expression, context);
329
+ // Find matching case
330
+ for (const caseItem of node.cases) {
331
+ const caseValue = evaluateExpression(caseItem.value, context);
332
+ // eslint-disable-next-line eqeqeq
333
+ if (switchValue == caseValue) {
334
+ return await renderNodes(caseItem.body, options);
335
+ }
336
+ }
337
+ // No matching case found
338
+ return '';
339
+ }
340
+ case 'leveloffset': {
341
+ // Calculate new offset (relative or absolute)
342
+ const parentOffset = context.get('_levelOffset') || 0;
343
+ const newOffset = node.isRelative ? parentOffset + node.offset : node.offset;
344
+ // Store current offset to restore later
345
+ const previousOffset = parentOffset;
346
+ // Set new offset in context
347
+ context.set('_levelOffset', newOffset);
348
+ // Fresh scope: a fence left open by unrelated earlier content must
349
+ // not suppress heading shifts here. Save the outer state so a NESTED
350
+ // leveloffset sitting inside an open fence doesn't wipe it — without
351
+ // the restore, the outer fence's real closer was later mis-read as an
352
+ // opener, flipping fence state for the rest of the render.
353
+ const previousFence = context.get('_levelOffsetFence') ?? null;
354
+ context.set('_levelOffsetFence', null);
355
+ try {
356
+ // Render body with offset active
357
+ const result = await renderNodes(node.body, options);
358
+ return result;
359
+ }
360
+ finally {
361
+ // Always restore previous offset + the outer fence state
362
+ context.set('_levelOffset', previousOffset);
363
+ context.set('_levelOffsetFence', previousFence);
364
+ }
365
+ }
366
+ default:
367
+ // TypeScript exhaustiveness check
368
+ const _exhaustive = node;
369
+ return _exhaustive;
370
+ }
371
+ }
372
+ /**
373
+ * Determine if a value is truthy
374
+ */
375
+ function isTruthy(value) {
376
+ if (value === undefined || value === null || value === false) {
377
+ return false;
378
+ }
379
+ if (value === 0 || value === '') {
380
+ return false;
381
+ }
382
+ return true;
383
+ }
384
+ // ============================================================================
385
+ // Preserve-mode helpers — round-trip AST back to Jinja source so an
386
+ // undefined-referencing block can survive into the rendered output for
387
+ // a downstream pass to resolve.
388
+ // ============================================================================
389
+ /**
390
+ * Walk an expression AST, return the names of any `variable` references
391
+ * whose context lookup is undefined. Empty array = all refs are bound.
392
+ */
393
+ function findUndefinedRefs(expr, context) {
394
+ const out = [];
395
+ function walk(e) {
396
+ switch (e.type) {
397
+ case 'variable':
398
+ if (context.get(e.name) === undefined)
399
+ out.push(e.name);
400
+ break;
401
+ case 'binary':
402
+ walk(e.left);
403
+ walk(e.right);
404
+ break;
405
+ case 'unary':
406
+ walk(e.operand);
407
+ break;
408
+ case 'literal':
409
+ break;
410
+ }
411
+ }
412
+ walk(expr);
413
+ return out;
414
+ }
415
+ /**
416
+ * Serialize an Expression back to Jinja source. Used by preserve mode
417
+ * to reconstruct `{% if … %}` headers when the condition can't be
418
+ * evaluated. Operator precedence isn't tracked; the output is
419
+ * conservatively parenthesized for binary/unary so a re-parse round-
420
+ * trips to the same AST shape (modulo redundant parens).
421
+ */
422
+ function expressionToSource(expr) {
423
+ switch (expr.type) {
424
+ case 'literal':
425
+ if (typeof expr.value === 'string')
426
+ return JSON.stringify(expr.value);
427
+ if (expr.value === null)
428
+ return 'null';
429
+ return String(expr.value);
430
+ case 'variable':
431
+ return expr.name;
432
+ case 'unary':
433
+ return `not ${expressionToSource(expr.operand)}`;
434
+ case 'binary':
435
+ return `(${expressionToSource(expr.left)} ${expr.operator} ${expressionToSource(expr.right)})`;
436
+ }
437
+ }
438
+ /**
439
+ * Serialize ASTNode[] back to Jinja source. Mirrors the parser's syntax
440
+ * for every node type so a preserved block can be re-rendered later
441
+ * with the missing values supplied.
442
+ *
443
+ * Throws on shapes we don't support (deep nested includes, switch);
444
+ * preserve mode is opt-in and a hard error here beats silent
445
+ * truncation. The shapes covered are everything md2md emits in the
446
+ * AsciiDoc pipeline.
447
+ */
448
+ function nodesToSource(nodes) {
449
+ return nodes.map(nodeToSource).join('');
450
+ }
451
+ function nodeToSource(node) {
452
+ switch (node.type) {
453
+ case 'text':
454
+ return node.value;
455
+ case 'variable':
456
+ return `{{ ${node.name} }}`;
457
+ case 'set':
458
+ return `{% set ${node.name} = ${expressionToSource(node.value)} %}`;
459
+ case 'comment':
460
+ // Parser strips comment content; emit a placeholder so the block
461
+ // structure round-trips even when the prose inside doesn't.
462
+ return '{# … #}';
463
+ case 'if':
464
+ return ifNodeToSource(node);
465
+ case 'include':
466
+ return `{% include "${node.path}" %}`;
467
+ case 'leveloffset': {
468
+ const sign = node.isRelative && node.offset >= 0 ? '+' : '';
469
+ return `{% leveloffset ${sign}${node.offset} %}${nodesToSource(node.body)}{% endleveloffset %}`;
470
+ }
471
+ case 'switch': {
472
+ // Conservative round-trip; switch isn't on the AsciiDoc hot path
473
+ // but we have an AST shape, so emit it.
474
+ const cases = node.cases
475
+ .map((c) => `{% case ${expressionToSource(c.value)} %}${nodesToSource(c.body)}`)
476
+ .join('');
477
+ return `{% switch ${expressionToSource(node.expression)} %}${cases}{% endswitch %}`;
478
+ }
479
+ }
480
+ }
481
+ function ifNodeToSource(node) {
482
+ const parts = [`{% if ${expressionToSource(node.condition)} %}`, nodesToSource(node.trueBranch)];
483
+ if (node.elifBranches) {
484
+ for (const elif of node.elifBranches) {
485
+ parts.push(`{% elif ${expressionToSource(elif.condition)} %}`, nodesToSource(elif.body));
486
+ }
487
+ }
488
+ if (node.elseBranch) {
489
+ parts.push(`{% else %}`, nodesToSource(node.elseBranch));
490
+ }
491
+ parts.push(`{% endif %}`);
492
+ return parts.join('');
493
+ }
494
+ //# sourceMappingURL=renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
package/dist/scan.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Scanning-grammar mirrors of parser statements, for tools that need to
3
+ * FIND directives in raw text without running the full parser (workspace
4
+ * indexers, linters). Kept next to the parser so grammar changes update
5
+ * both; tests/scan.test.ts asserts parser agreement for every form the
6
+ * scan regex matches.
7
+ */
8
+ /**
9
+ * Fresh regex matching a complete `{% include "path" %}` statement,
10
+ * capturing the path. Factory (not a shared const) because the global
11
+ * flag makes RegExp objects stateful.
12
+ *
13
+ * Grammar notes, matching parser.ts:
14
+ * - `{%-` / `-%}` whitespace-trim markers are accepted.
15
+ * - At least one whitespace character is required after `include`.
16
+ * - The path is quoted with `"` or `'` and contains no quote chars.
17
+ */
18
+ export declare const includeDirectiveRe: () => RegExp;
19
+ /** All `{% include %}` paths in a text, in order. */
20
+ export declare const scanIncludes: (text: string) => string[];
21
+ /**
22
+ * Fresh regex matching a complete `{{ … }}` variable/expression output,
23
+ * capturing the raw inner source (whitespace-trim markers accepted, not
24
+ * captured). Grammar mirror of parser.ts's `{{`→`}}` scan.
25
+ */
26
+ export declare const variableRe: () => RegExp;
27
+ /**
28
+ * Fresh regex matching a complete `{% … %}` statement tag, capturing the
29
+ * keyword and the raw remainder (up to the closing marker). Grammar mirror
30
+ * of parser.ts's `{%`→`%}` scan — the keyword set is NOT validated here;
31
+ * consumers classify (if/elif/else/endif/include/set/…) themselves.
32
+ */
33
+ export declare const directiveTagRe: () => RegExp;
34
+ /**
35
+ * Fresh regex matching a complete `{# … #}` comment. Grammar mirror of
36
+ * parser.ts's `{#`→`#}` scan.
37
+ */
38
+ export declare const commentRe: () => RegExp;
39
+ /**
40
+ * Fresh regex matching a complete `{% raw %}…{% endraw %}` block, capturing
41
+ * the verbatim inner content. Grammar mirror of parser.ts's raw handling.
42
+ * Consumers that classify individual tags (directiveTagRe) should match
43
+ * raw blocks FIRST — the inner content is not directive syntax.
44
+ */
45
+ export declare const rawBlockRe: () => RegExp;
46
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,QAAO,MACS,CAAC;AAEhD,qDAAqD;AACrD,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG,MAAM,EACiB,CAAC;AAEpE;;;;GAIG;AACH,eAAO,MAAM,UAAU,QAAO,MAAmC,CAAC;AAElE;;;;;GAKG;AACH,eAAO,MAAM,cAAc,QAAO,MACkB,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,SAAS,QAAO,MAA2B,CAAC;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,UAAU,QAAO,MAC0B,CAAC"}
package/dist/scan.js ADDED
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Scanning-grammar mirrors of parser statements, for tools that need to
3
+ * FIND directives in raw text without running the full parser (workspace
4
+ * indexers, linters). Kept next to the parser so grammar changes update
5
+ * both; tests/scan.test.ts asserts parser agreement for every form the
6
+ * scan regex matches.
7
+ */
8
+ /**
9
+ * Fresh regex matching a complete `{% include "path" %}` statement,
10
+ * capturing the path. Factory (not a shared const) because the global
11
+ * flag makes RegExp objects stateful.
12
+ *
13
+ * Grammar notes, matching parser.ts:
14
+ * - `{%-` / `-%}` whitespace-trim markers are accepted.
15
+ * - At least one whitespace character is required after `include`.
16
+ * - The path is quoted with `"` or `'` and contains no quote chars.
17
+ */
18
+ export const includeDirectiveRe = () => /\{%-?\s*include\s+["']([^"']+)["']\s*-?%\}/g;
19
+ /** All `{% include %}` paths in a text, in order. */
20
+ export const scanIncludes = (text) => [...text.matchAll(includeDirectiveRe())].map((match) => match[1]);
21
+ /**
22
+ * Fresh regex matching a complete `{{ … }}` variable/expression output,
23
+ * capturing the raw inner source (whitespace-trim markers accepted, not
24
+ * captured). Grammar mirror of parser.ts's `{{`→`}}` scan.
25
+ */
26
+ export const variableRe = () => /\{\{-?([\s\S]*?)-?\}\}/g;
27
+ /**
28
+ * Fresh regex matching a complete `{% … %}` statement tag, capturing the
29
+ * keyword and the raw remainder (up to the closing marker). Grammar mirror
30
+ * of parser.ts's `{%`→`%}` scan — the keyword set is NOT validated here;
31
+ * consumers classify (if/elif/else/endif/include/set/…) themselves.
32
+ */
33
+ export const directiveTagRe = () => /\{%-?\s*([A-Za-z_][A-Za-z0-9_]*)([\s\S]*?)-?%\}/g;
34
+ /**
35
+ * Fresh regex matching a complete `{# … #}` comment. Grammar mirror of
36
+ * parser.ts's `{#`→`#}` scan.
37
+ */
38
+ export const commentRe = () => /\{#[\s\S]*?#\}/g;
39
+ /**
40
+ * Fresh regex matching a complete `{% raw %}…{% endraw %}` block, capturing
41
+ * the verbatim inner content. Grammar mirror of parser.ts's raw handling.
42
+ * Consumers that classify individual tags (directiveTagRe) should match
43
+ * raw blocks FIRST — the inner content is not directive syntax.
44
+ */
45
+ export const rawBlockRe = () => /\{%-?\s*raw\s*-?%\}([\s\S]*?)\{%-?\s*endraw\s*-?%\}/g;
46
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAW,EAAE,CAC7C,6CAA6C,CAAC;AAEhD,qDAAqD;AACrD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAY,EAAY,EAAE,CACrD,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpE;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,GAAW,EAAE,CAAC,yBAAyB,CAAC;AAElE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAW,EAAE,CACzC,kDAAkD,CAAC;AAErD;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,GAAW,EAAE,CAAC,iBAAiB,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,GAAW,EAAE,CACrC,sDAAsD,CAAC"}