@dogsbay/minja 0.2.0-beta.92 → 0.2.0-beta.98
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -0
- package/bin/minja.js +179 -19
- package/dist/browser.d.ts +1 -0
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +1 -0
- package/dist/browser.js.map +1 -1
- package/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +148 -17
- package/dist/index.umd.js.map +4 -4
- package/dist/index.umd.min.js +7 -4
- package/dist/index.umd.min.js.map +4 -4
- package/dist/loader.d.ts +20 -1
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +69 -1
- package/dist/loader.js.map +1 -1
- package/dist/parser.d.ts +0 -5
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +112 -4
- package/dist/parser.js.map +1 -1
- package/dist/renderer.d.ts.map +1 -1
- package/dist/renderer.js +84 -12
- package/dist/renderer.js.map +1 -1
- package/dist/scan.d.ts +46 -0
- package/dist/scan.d.ts.map +1 -0
- package/dist/scan.js +46 -0
- package/dist/scan.js.map +1 -0
- package/dist/types.d.ts +12 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +17 -7
package/dist/index.umd.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* minja v0.2.0-beta.
|
|
2
|
+
* minja v0.2.0-beta.98
|
|
3
3
|
* Minimal, secure Jinja2/Nunjucks subset for documentation preprocessing
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
@@ -29,10 +29,16 @@ var minja = (() => {
|
|
|
29
29
|
Context: () => Context,
|
|
30
30
|
FetchLoader: () => FetchLoader,
|
|
31
31
|
MemoryLoader: () => MemoryLoader,
|
|
32
|
+
commentRe: () => commentRe,
|
|
33
|
+
directiveTagRe: () => directiveTagRe,
|
|
32
34
|
evaluateExpression: () => evaluateExpression,
|
|
35
|
+
includeDirectiveRe: () => includeDirectiveRe,
|
|
33
36
|
parse: () => parse,
|
|
34
37
|
parseExpression: () => parseExpression,
|
|
35
|
-
|
|
38
|
+
rawBlockRe: () => rawBlockRe,
|
|
39
|
+
render: () => render,
|
|
40
|
+
scanIncludes: () => scanIncludes,
|
|
41
|
+
variableRe: () => variableRe
|
|
36
42
|
});
|
|
37
43
|
|
|
38
44
|
// src/evaluator.ts
|
|
@@ -195,6 +201,24 @@ var minja = (() => {
|
|
|
195
201
|
}
|
|
196
202
|
|
|
197
203
|
// src/parser.ts
|
|
204
|
+
var KNOWN_TAG_KEYWORDS = /* @__PURE__ */ new Set([
|
|
205
|
+
"set",
|
|
206
|
+
"if",
|
|
207
|
+
"include",
|
|
208
|
+
"switch",
|
|
209
|
+
"leveloffset",
|
|
210
|
+
"raw",
|
|
211
|
+
"endif",
|
|
212
|
+
"elif",
|
|
213
|
+
"else",
|
|
214
|
+
"endswitch",
|
|
215
|
+
"case",
|
|
216
|
+
"endleveloffset",
|
|
217
|
+
"endraw"
|
|
218
|
+
]);
|
|
219
|
+
function stripBodyForEndTag(body, endTag) {
|
|
220
|
+
return endTag.startsWith("{%-") ? body.replace(/[ \t]*\n[ \t\n]*$/, "") : body;
|
|
221
|
+
}
|
|
198
222
|
function parse(template) {
|
|
199
223
|
const errors = [];
|
|
200
224
|
const ast = [];
|
|
@@ -277,12 +301,57 @@ var minja = (() => {
|
|
|
277
301
|
}
|
|
278
302
|
}
|
|
279
303
|
} else if (nearest.type === "tag") {
|
|
304
|
+
const tagStart2 = position;
|
|
280
305
|
advance(2);
|
|
281
306
|
const endPos = findNext("%}", position);
|
|
282
307
|
if (endPos === -1) {
|
|
283
308
|
errors.push(createError("Unclosed statement tag"));
|
|
284
309
|
break;
|
|
285
310
|
}
|
|
311
|
+
const peeked = template.substring(position, endPos).trim();
|
|
312
|
+
const peekKeyword = peeked.replace(/^-\s*/, "").replace(/\s*-$/, "").split(/\s+/)[0] ?? "";
|
|
313
|
+
if (peekKeyword === "raw") {
|
|
314
|
+
const openerLeftStrip = peeked.startsWith("-");
|
|
315
|
+
const openerRightStrip = peeked.endsWith("-");
|
|
316
|
+
if (openerLeftStrip && ast.length > 0 && ast[ast.length - 1].type === "text") {
|
|
317
|
+
const lastNode = ast[ast.length - 1];
|
|
318
|
+
lastNode.value = lastNode.value.replace(/[ \t]*\n[ \t\n]*$/, "");
|
|
319
|
+
}
|
|
320
|
+
extractTo(endPos);
|
|
321
|
+
advance(2);
|
|
322
|
+
if (openerRightStrip) {
|
|
323
|
+
while (position < template.length && /[ \t\n]/.test(template[position])) {
|
|
324
|
+
advance(1);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
const endrawMatch = /\{%-?\s*endraw\s*-?%\}/.exec(template.substring(position));
|
|
328
|
+
if (!endrawMatch) {
|
|
329
|
+
errors.push(createError("Unclosed raw block"));
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
332
|
+
const endrawAbs = position + endrawMatch.index;
|
|
333
|
+
let content = extractTo(endrawAbs);
|
|
334
|
+
const endrawTag = endrawMatch[0];
|
|
335
|
+
if (endrawTag.startsWith("{%-")) {
|
|
336
|
+
content = content.replace(/[ \t]*\n[ \t\n]*$/, "");
|
|
337
|
+
}
|
|
338
|
+
advance(endrawTag.length);
|
|
339
|
+
if (endrawTag.endsWith("-%}")) {
|
|
340
|
+
while (position < template.length && /[ \t\n]/.test(template[position])) {
|
|
341
|
+
advance(1);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
if (content) {
|
|
345
|
+
ast.push({ type: "text", value: content });
|
|
346
|
+
}
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
if (!KNOWN_TAG_KEYWORDS.has(peekKeyword)) {
|
|
350
|
+
extractTo(endPos);
|
|
351
|
+
advance(2);
|
|
352
|
+
ast.push({ type: "text", value: template.substring(tagStart2, endPos + 2) });
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
286
355
|
let statement = extractTo(endPos).trim();
|
|
287
356
|
const hasLeftStrip = statement.startsWith("-");
|
|
288
357
|
const hasRightStrip = statement.endsWith("-");
|
|
@@ -416,12 +485,13 @@ var minja = (() => {
|
|
|
416
485
|
}
|
|
417
486
|
return { ast, errors };
|
|
418
487
|
function findEndTag(tagName) {
|
|
419
|
-
const pattern = new RegExp(`{
|
|
488
|
+
const pattern = new RegExp(`{%-?\\s*${tagName}\\s*-?%}`);
|
|
420
489
|
const match = pattern.exec(template.substring(position));
|
|
421
490
|
if (match) {
|
|
422
491
|
return {
|
|
423
492
|
start: position + match.index,
|
|
424
|
-
length: match[0].length
|
|
493
|
+
length: match[0].length,
|
|
494
|
+
tag: match[0]
|
|
425
495
|
};
|
|
426
496
|
}
|
|
427
497
|
return null;
|
|
@@ -453,8 +523,12 @@ var minja = (() => {
|
|
|
453
523
|
searchPos = nearest.pos + nearest.match[0].length;
|
|
454
524
|
} else if (nearest.type === "endif") {
|
|
455
525
|
if (depth === 0) {
|
|
456
|
-
const bodyTemplate = extractTo(nearest.pos);
|
|
526
|
+
const bodyTemplate = stripBodyForEndTag(extractTo(nearest.pos), nearest.match[0]);
|
|
457
527
|
advance(nearest.match[0].length);
|
|
528
|
+
if (nearest.match[0].endsWith("-%}")) {
|
|
529
|
+
while (position < template.length && /[ \t\n]/.test(template[position]))
|
|
530
|
+
advance(1);
|
|
531
|
+
}
|
|
458
532
|
const bodyResult = parse(bodyTemplate);
|
|
459
533
|
parseErrors.push(...bodyResult.errors);
|
|
460
534
|
return {
|
|
@@ -468,7 +542,7 @@ var minja = (() => {
|
|
|
468
542
|
searchPos = nearest.pos + nearest.match[0].length;
|
|
469
543
|
}
|
|
470
544
|
} else if (depth === 0 && (nearest.type === "elif" || nearest.type === "else")) {
|
|
471
|
-
const bodyTemplate = extractTo(nearest.pos);
|
|
545
|
+
const bodyTemplate = stripBodyForEndTag(extractTo(nearest.pos), nearest.match[0]);
|
|
472
546
|
const bodyResult = parse(bodyTemplate);
|
|
473
547
|
if (elifBranches.length === 0 && elseBranch.length === 0) {
|
|
474
548
|
parseErrors.push(...bodyResult.errors);
|
|
@@ -505,7 +579,10 @@ var minja = (() => {
|
|
|
505
579
|
if (!endifMatch2) {
|
|
506
580
|
parseErrors.push(createError("Missing endif after else"));
|
|
507
581
|
} else {
|
|
508
|
-
const elseBodyTemplate =
|
|
582
|
+
const elseBodyTemplate = stripBodyForEndTag(
|
|
583
|
+
extractTo(endifMatch2.start),
|
|
584
|
+
endifMatch2.tag
|
|
585
|
+
);
|
|
509
586
|
advance(endifMatch2.length);
|
|
510
587
|
const elseBodyResult = parse(elseBodyTemplate);
|
|
511
588
|
parseErrors.push(...elseBodyResult.errors);
|
|
@@ -691,15 +768,38 @@ var minja = (() => {
|
|
|
691
768
|
};
|
|
692
769
|
|
|
693
770
|
// src/renderer.ts
|
|
694
|
-
function transformHeadings(text, offset) {
|
|
771
|
+
function transformHeadings(text, offset, initialFence = null, fenceOut) {
|
|
695
772
|
if (offset === 0) {
|
|
773
|
+
if (fenceOut)
|
|
774
|
+
fenceOut.fence = initialFence;
|
|
696
775
|
return text;
|
|
697
776
|
}
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
777
|
+
const lines = text.split("\n");
|
|
778
|
+
let fence = initialFence;
|
|
779
|
+
for (let i = 0; i < lines.length; i++) {
|
|
780
|
+
const line = lines[i];
|
|
781
|
+
const fenceMatch = line.match(/^\s*(`{3,}|~{3,})/);
|
|
782
|
+
if (fenceMatch) {
|
|
783
|
+
const run = fenceMatch[1];
|
|
784
|
+
if (fence === null) {
|
|
785
|
+
fence = run;
|
|
786
|
+
} else if (run[0] === fence[0] && run.length >= fence.length && line.trim() === run) {
|
|
787
|
+
fence = null;
|
|
788
|
+
}
|
|
789
|
+
continue;
|
|
790
|
+
}
|
|
791
|
+
if (fence !== null) {
|
|
792
|
+
continue;
|
|
793
|
+
}
|
|
794
|
+
const m = line.match(/^(#{1,6})(\s+)/);
|
|
795
|
+
if (m) {
|
|
796
|
+
const newLevel = Math.max(1, Math.min(6, m[1].length + offset));
|
|
797
|
+
lines[i] = "#".repeat(newLevel) + line.slice(m[1].length);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
if (fenceOut)
|
|
801
|
+
fenceOut.fence = fence;
|
|
802
|
+
return lines.join("\n");
|
|
703
803
|
}
|
|
704
804
|
function resolvePath(path, basePath) {
|
|
705
805
|
if (path.startsWith("/")) {
|
|
@@ -770,7 +870,14 @@ var minja = (() => {
|
|
|
770
870
|
async function renderNodes(nodes, options) {
|
|
771
871
|
const parts = [];
|
|
772
872
|
for (const node of nodes) {
|
|
773
|
-
|
|
873
|
+
let rendered = await renderNode(node, options);
|
|
874
|
+
if (node.type === "include" && rendered && parts.length > 0) {
|
|
875
|
+
const tail = /(?:^|\n)([ \t]+)$/.exec(parts[parts.length - 1]);
|
|
876
|
+
if (tail) {
|
|
877
|
+
rendered = rendered.replace(/\n(?=[^\n])/g, "\n" + tail[1]);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
parts.push(rendered);
|
|
774
881
|
}
|
|
775
882
|
return parts.join("");
|
|
776
883
|
}
|
|
@@ -782,7 +889,15 @@ var minja = (() => {
|
|
|
782
889
|
if (currentOffset === 0) {
|
|
783
890
|
return node.value;
|
|
784
891
|
}
|
|
785
|
-
|
|
892
|
+
const fenceOut = { fence: null };
|
|
893
|
+
const out = transformHeadings(
|
|
894
|
+
node.value,
|
|
895
|
+
currentOffset,
|
|
896
|
+
context.get("_levelOffsetFence") ?? null,
|
|
897
|
+
fenceOut
|
|
898
|
+
);
|
|
899
|
+
context.set("_levelOffsetFence", fenceOut.fence);
|
|
900
|
+
return out;
|
|
786
901
|
}
|
|
787
902
|
case "variable": {
|
|
788
903
|
const value = context.get(node.name);
|
|
@@ -792,6 +907,8 @@ var minja = (() => {
|
|
|
792
907
|
throw new Error(`Undefined variable: ${node.name}`);
|
|
793
908
|
case "preserve":
|
|
794
909
|
return `{{ ${node.name} }}`;
|
|
910
|
+
case "asciidoc-literal":
|
|
911
|
+
return `{${node.name}}`;
|
|
795
912
|
case "empty":
|
|
796
913
|
default:
|
|
797
914
|
return "";
|
|
@@ -811,7 +928,7 @@ var minja = (() => {
|
|
|
811
928
|
case "comment":
|
|
812
929
|
return "";
|
|
813
930
|
case "if": {
|
|
814
|
-
if (options.undefinedBehavior === "preserve" && options.undefinedConditions !== "falsy") {
|
|
931
|
+
if ((options.undefinedBehavior === "preserve" || options.undefinedBehavior === "asciidoc-literal") && options.undefinedConditions !== "falsy") {
|
|
815
932
|
const undefinedRefs = findUndefinedRefs(node.condition, context);
|
|
816
933
|
if (undefinedRefs.length > 0) {
|
|
817
934
|
return ifNodeToSource(node);
|
|
@@ -871,7 +988,10 @@ var minja = (() => {
|
|
|
871
988
|
undefinedConditions: options.undefinedConditions
|
|
872
989
|
});
|
|
873
990
|
} catch (error) {
|
|
874
|
-
if (
|
|
991
|
+
if (error instanceof Error && error.name === "IncludeContainmentError") {
|
|
992
|
+
throw error;
|
|
993
|
+
}
|
|
994
|
+
if (options.undefinedBehavior === "preserve" || options.undefinedBehavior === "asciidoc-literal") {
|
|
875
995
|
return `{% include "${node.path}" %}`;
|
|
876
996
|
}
|
|
877
997
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -894,11 +1014,14 @@ var minja = (() => {
|
|
|
894
1014
|
const newOffset = node.isRelative ? parentOffset + node.offset : node.offset;
|
|
895
1015
|
const previousOffset = parentOffset;
|
|
896
1016
|
context.set("_levelOffset", newOffset);
|
|
1017
|
+
const previousFence = context.get("_levelOffsetFence") ?? null;
|
|
1018
|
+
context.set("_levelOffsetFence", null);
|
|
897
1019
|
try {
|
|
898
1020
|
const result = await renderNodes(node.body, options);
|
|
899
1021
|
return result;
|
|
900
1022
|
} finally {
|
|
901
1023
|
context.set("_levelOffset", previousOffset);
|
|
1024
|
+
context.set("_levelOffsetFence", previousFence);
|
|
902
1025
|
}
|
|
903
1026
|
}
|
|
904
1027
|
default:
|
|
@@ -1024,6 +1147,14 @@ var minja = (() => {
|
|
|
1024
1147
|
return content;
|
|
1025
1148
|
}
|
|
1026
1149
|
};
|
|
1150
|
+
|
|
1151
|
+
// src/scan.ts
|
|
1152
|
+
var includeDirectiveRe = () => /\{%-?\s*include\s+["']([^"']+)["']\s*-?%\}/g;
|
|
1153
|
+
var scanIncludes = (text) => [...text.matchAll(includeDirectiveRe())].map((match) => match[1]);
|
|
1154
|
+
var variableRe = () => /\{\{-?([\s\S]*?)-?\}\}/g;
|
|
1155
|
+
var directiveTagRe = () => /\{%-?\s*([A-Za-z_][A-Za-z0-9_]*)([\s\S]*?)-?%\}/g;
|
|
1156
|
+
var commentRe = () => /\{#[\s\S]*?#\}/g;
|
|
1157
|
+
var rawBlockRe = () => /\{%-?\s*raw\s*-?%\}([\s\S]*?)\{%-?\s*endraw\s*-?%\}/g;
|
|
1027
1158
|
return __toCommonJS(browser_exports);
|
|
1028
1159
|
})();
|
|
1029
1160
|
//# sourceMappingURL=index.umd.js.map
|