@dogsbay/minja 0.2.0-beta.93 → 0.2.0-beta.99
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 +156 -15
- 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 +125 -13
- package/dist/index.umd.js.map +4 -4
- package/dist/index.umd.min.js +7 -6
- 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 +53 -7
- 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.99
|
|
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,12 +768,14 @@ 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
777
|
const lines = text.split("\n");
|
|
699
|
-
let fence =
|
|
778
|
+
let fence = initialFence;
|
|
700
779
|
for (let i = 0; i < lines.length; i++) {
|
|
701
780
|
const line = lines[i];
|
|
702
781
|
const fenceMatch = line.match(/^\s*(`{3,}|~{3,})/);
|
|
@@ -718,6 +797,8 @@ var minja = (() => {
|
|
|
718
797
|
lines[i] = "#".repeat(newLevel) + line.slice(m[1].length);
|
|
719
798
|
}
|
|
720
799
|
}
|
|
800
|
+
if (fenceOut)
|
|
801
|
+
fenceOut.fence = fence;
|
|
721
802
|
return lines.join("\n");
|
|
722
803
|
}
|
|
723
804
|
function resolvePath(path, basePath) {
|
|
@@ -789,7 +870,14 @@ var minja = (() => {
|
|
|
789
870
|
async function renderNodes(nodes, options) {
|
|
790
871
|
const parts = [];
|
|
791
872
|
for (const node of nodes) {
|
|
792
|
-
|
|
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);
|
|
793
881
|
}
|
|
794
882
|
return parts.join("");
|
|
795
883
|
}
|
|
@@ -801,7 +889,15 @@ var minja = (() => {
|
|
|
801
889
|
if (currentOffset === 0) {
|
|
802
890
|
return node.value;
|
|
803
891
|
}
|
|
804
|
-
|
|
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;
|
|
805
901
|
}
|
|
806
902
|
case "variable": {
|
|
807
903
|
const value = context.get(node.name);
|
|
@@ -811,6 +907,8 @@ var minja = (() => {
|
|
|
811
907
|
throw new Error(`Undefined variable: ${node.name}`);
|
|
812
908
|
case "preserve":
|
|
813
909
|
return `{{ ${node.name} }}`;
|
|
910
|
+
case "asciidoc-literal":
|
|
911
|
+
return `{${node.name}}`;
|
|
814
912
|
case "empty":
|
|
815
913
|
default:
|
|
816
914
|
return "";
|
|
@@ -830,7 +928,7 @@ var minja = (() => {
|
|
|
830
928
|
case "comment":
|
|
831
929
|
return "";
|
|
832
930
|
case "if": {
|
|
833
|
-
if (options.undefinedBehavior === "preserve" && options.undefinedConditions !== "falsy") {
|
|
931
|
+
if ((options.undefinedBehavior === "preserve" || options.undefinedBehavior === "asciidoc-literal") && options.undefinedConditions !== "falsy") {
|
|
834
932
|
const undefinedRefs = findUndefinedRefs(node.condition, context);
|
|
835
933
|
if (undefinedRefs.length > 0) {
|
|
836
934
|
return ifNodeToSource(node);
|
|
@@ -890,7 +988,10 @@ var minja = (() => {
|
|
|
890
988
|
undefinedConditions: options.undefinedConditions
|
|
891
989
|
});
|
|
892
990
|
} catch (error) {
|
|
893
|
-
if (
|
|
991
|
+
if (error instanceof Error && error.name === "IncludeContainmentError") {
|
|
992
|
+
throw error;
|
|
993
|
+
}
|
|
994
|
+
if (options.undefinedBehavior === "preserve" || options.undefinedBehavior === "asciidoc-literal") {
|
|
894
995
|
return `{% include "${node.path}" %}`;
|
|
895
996
|
}
|
|
896
997
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -913,11 +1014,14 @@ var minja = (() => {
|
|
|
913
1014
|
const newOffset = node.isRelative ? parentOffset + node.offset : node.offset;
|
|
914
1015
|
const previousOffset = parentOffset;
|
|
915
1016
|
context.set("_levelOffset", newOffset);
|
|
1017
|
+
const previousFence = context.get("_levelOffsetFence") ?? null;
|
|
1018
|
+
context.set("_levelOffsetFence", null);
|
|
916
1019
|
try {
|
|
917
1020
|
const result = await renderNodes(node.body, options);
|
|
918
1021
|
return result;
|
|
919
1022
|
} finally {
|
|
920
1023
|
context.set("_levelOffset", previousOffset);
|
|
1024
|
+
context.set("_levelOffsetFence", previousFence);
|
|
921
1025
|
}
|
|
922
1026
|
}
|
|
923
1027
|
default:
|
|
@@ -1043,6 +1147,14 @@ var minja = (() => {
|
|
|
1043
1147
|
return content;
|
|
1044
1148
|
}
|
|
1045
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;
|
|
1046
1158
|
return __toCommonJS(browser_exports);
|
|
1047
1159
|
})();
|
|
1048
1160
|
//# sourceMappingURL=index.umd.js.map
|