sommark 5.0.5 → 5.1.0
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/async-hooks.js +19 -0
- package/core/evaluator.js +83 -13
- package/core/helpers/config-loader.js +29 -9
- package/core/helpers/lib.js +1 -1
- package/core/helpers/preprocessor.js +19 -0
- package/core/modules.js +35 -18
- package/core/parser.js +6 -3
- package/core/transpiler.js +30 -10
- package/core/validator.js +17 -4
- package/dist/sommark.browser.js +414 -196
- package/dist/sommark.browser.lite.js +331 -182
- package/dist/sommark.parser.js +6 -3
- package/esbuild.js +64 -0
- package/index.browser.js +4 -1
- package/index.js +32 -1
- package/index.shared.js +10 -1
- package/mappers/languages/markdown.js +99 -81
- package/mappers/languages/xml.js +76 -61
- package/mappers/shared/index.js +10 -1
- package/package.json +9 -2
- package/rollup.js +79 -0
- package/vite.js +20 -0
|
@@ -1474,6 +1474,7 @@ function makeBlockNode() {
|
|
|
1474
1474
|
structure: "Block",
|
|
1475
1475
|
id: "",
|
|
1476
1476
|
props: {},
|
|
1477
|
+
directives: {},
|
|
1477
1478
|
body: [],
|
|
1478
1479
|
depth: 0,
|
|
1479
1480
|
range: {
|
|
@@ -1959,9 +1960,11 @@ function parseBlock(tokens, i, filename = null, placeholders = {}, variables = {
|
|
|
1959
1960
|
i = valueIndex;
|
|
1960
1961
|
|
|
1961
1962
|
// Store Argument
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1963
|
+
if (k && k.startsWith("smark-")) {
|
|
1964
|
+
blockNode.directives[k.slice(6)] = v; // strip "smark-" prefix
|
|
1965
|
+
} else {
|
|
1966
|
+
blockNode.props[String(argIndex++)] = v;
|
|
1967
|
+
if (k) blockNode.props[k] = v;
|
|
1965
1968
|
}
|
|
1966
1969
|
k = "";
|
|
1967
1970
|
v = "";
|
|
@@ -8798,8 +8801,27 @@ async function preprocessRuntimeLogic(code, filename = null, security = {}, inst
|
|
|
8798
8801
|
if (filename && filename !== "anonymous") {
|
|
8799
8802
|
baseDir = posix.dirname(posix.resolve(filename));
|
|
8800
8803
|
}
|
|
8804
|
+
|
|
8805
|
+
// Block absolute paths — path.resolve would ignore baseDir entirely
|
|
8806
|
+
if (posix.isAbsolute(argValue)) {
|
|
8807
|
+
transpilerError([
|
|
8808
|
+
`<$red:Security Error:$> Absolute import paths are not allowed: <$magenta:${argValue}$>{line}`,
|
|
8809
|
+
`<$yellow:Use a path relative to the template file, e.g.$> <$green:SomMark.import("./data.json")$> <$yellow:or$> <$green:SomMark.import("../shared/data.json")$><$yellow:.$>{line}`,
|
|
8810
|
+
`<$yellow:Base directory:$> <$blue:${baseDir}$>{line}`
|
|
8811
|
+
]);
|
|
8812
|
+
}
|
|
8813
|
+
|
|
8801
8814
|
const resolvedPath = posix.resolve(baseDir, argValue);
|
|
8802
8815
|
|
|
8816
|
+
// Block path traversal — resolved path must stay inside baseDir
|
|
8817
|
+
const safeBases = baseDir.endsWith(posix.sep) ? baseDir : baseDir + posix.sep;
|
|
8818
|
+
if (!resolvedPath.startsWith(safeBases) && resolvedPath !== baseDir) {
|
|
8819
|
+
transpilerError([
|
|
8820
|
+
`<$red:Security Error:$> Import path escapes the project directory: <$magenta:${argValue}$>{line}`,
|
|
8821
|
+
`<$yellow:Resolved Path:$> <$blue:${resolvedPath}$>{line}`
|
|
8822
|
+
]);
|
|
8823
|
+
}
|
|
8824
|
+
|
|
8803
8825
|
const fsImpl = instance?.fs || await getNodeFs();
|
|
8804
8826
|
|
|
8805
8827
|
// File presence validation
|
|
@@ -8912,6 +8934,7 @@ const randomBytesHex = (size) => {
|
|
|
8912
8934
|
|
|
8913
8935
|
const BODY_PLACEHOLDER = `SOMMARKBODYPLACEHOLDER${randomBytesHex(8)}SOMMARK`;
|
|
8914
8936
|
|
|
8937
|
+
|
|
8915
8938
|
/**
|
|
8916
8939
|
* Extracts all plain text from a node and its children.
|
|
8917
8940
|
*
|
|
@@ -9010,6 +9033,17 @@ async function generateOutput(ast, i, format, mapper_file, security = {}, parent
|
|
|
9010
9033
|
|
|
9011
9034
|
if (node.type === FOR_EACH) {
|
|
9012
9035
|
const transpiledArgs = await transpileArgs(node.props);
|
|
9036
|
+
|
|
9037
|
+
if (!node.props || (node.props[0] === undefined && node.props["items"] === undefined)) {
|
|
9038
|
+
const line = node.range?.start?.line + 1 || 1;
|
|
9039
|
+
transpilerError([
|
|
9040
|
+
`<$red:Missing Prop Error in [for-each]:$>{line}`,
|
|
9041
|
+
`[for-each] requires an array as its first prop, e.g. [for-each = \${ array }\$]{line}`,
|
|
9042
|
+
`at line <$yellow:${line}$>{line}`
|
|
9043
|
+
]);
|
|
9044
|
+
return "";
|
|
9045
|
+
}
|
|
9046
|
+
|
|
9013
9047
|
const items = mapper_file ? mapper_file.safeArg({ props: transpiledArgs, index: 0, key: "items", fallBack: [] }) : [];
|
|
9014
9048
|
|
|
9015
9049
|
if (!Array.isArray(items)) {
|
|
@@ -9023,11 +9057,11 @@ async function generateOutput(ast, i, format, mapper_file, security = {}, parent
|
|
|
9023
9057
|
}
|
|
9024
9058
|
|
|
9025
9059
|
const asVar = transpiledArgs.as || "value";
|
|
9026
|
-
if (asVar === "i") {
|
|
9060
|
+
if (asVar === "i" || asVar === "length") {
|
|
9027
9061
|
const line = node.range?.start?.line + 1 || 1;
|
|
9028
9062
|
transpilerError([
|
|
9029
9063
|
`<$red:Reserved Variable Error in [for-each]:$>{line}`,
|
|
9030
|
-
`'
|
|
9064
|
+
`'${asVar}' is a reserved variable name.{N}Use a different name for the 'as' prop, e.g. as: "item"{line}`,
|
|
9031
9065
|
`at line <$yellow:${line}$>{line}`
|
|
9032
9066
|
]);
|
|
9033
9067
|
return "";
|
|
@@ -9057,22 +9091,28 @@ async function generateOutput(ast, i, format, mapper_file, security = {}, parent
|
|
|
9057
9091
|
}
|
|
9058
9092
|
}
|
|
9059
9093
|
|
|
9060
|
-
|
|
9094
|
+
const rawJoin = transpiledArgs.join ?? null;
|
|
9095
|
+
const join = rawJoin !== null ? rawJoin.replace(/\\n/g, "\n").replace(/\\t/g, "\t").replace(/\\r/g, "\r") : null;
|
|
9096
|
+
const parts = [];
|
|
9061
9097
|
let idx = 0;
|
|
9098
|
+
const length = items.length;
|
|
9062
9099
|
for (const item of items) {
|
|
9063
9100
|
Evaluator.pushScope();
|
|
9064
9101
|
Evaluator.inject({
|
|
9065
9102
|
[asVar]: item,
|
|
9066
|
-
i: idx
|
|
9103
|
+
i: idx++,
|
|
9104
|
+
length
|
|
9067
9105
|
});
|
|
9068
9106
|
|
|
9107
|
+
let iterOutput = "";
|
|
9069
9108
|
for (let j = 0; j < cleanedBody.length; j++) {
|
|
9070
|
-
|
|
9109
|
+
iterOutput += await generateOutput(cleanedBody, j, format, mapper_file, security, parentId, generateRuntimeOutput, hideRuntimeOutput, instance, idState, extraCtx);
|
|
9071
9110
|
}
|
|
9072
9111
|
|
|
9073
9112
|
await Evaluator.popScope();
|
|
9113
|
+
parts.push(iterOutput);
|
|
9074
9114
|
}
|
|
9075
|
-
return
|
|
9115
|
+
return join !== null ? parts.join(join) : parts.join("");
|
|
9076
9116
|
}
|
|
9077
9117
|
|
|
9078
9118
|
let secretId = null;
|
|
@@ -9100,13 +9140,12 @@ async function generateOutput(ast, i, format, mapper_file, security = {}, parent
|
|
|
9100
9140
|
}
|
|
9101
9141
|
|
|
9102
9142
|
// smark-raw block — body collected verbatim by lexer, bypasses normal body processing pipeline
|
|
9103
|
-
if (node.type === BLOCK && (node.
|
|
9143
|
+
if (node.type === BLOCK && (node.directives?.raw === "true" || node.directives?.raw === true)) {
|
|
9104
9144
|
if (generateRuntimeOutput) return "";
|
|
9105
9145
|
const rawContent = node.body?.map(n => String(n.text || "")).join("") || "";
|
|
9106
|
-
const
|
|
9107
|
-
const transpiledArgs = await transpileArgs(cleanArgs);
|
|
9146
|
+
const transpiledArgs = await transpileArgs(node.props);
|
|
9108
9147
|
if (Evaluator.active?.hasDynamicTag?.(node.id)) {
|
|
9109
|
-
return await Evaluator.active.executeDynamicTag(node.id, { props: transpiledArgs, content: rawContent, textContent: rawContent });
|
|
9148
|
+
return await Evaluator.active.executeDynamicTag(node.id, { props: transpiledArgs, directives: node.directives, content: rawContent, textContent: rawContent });
|
|
9110
9149
|
}
|
|
9111
9150
|
let rawTarget = mapper_file ? matchedValue(mapper_file.outputs, node.id) : null;
|
|
9112
9151
|
if (!rawTarget && mapper_file) rawTarget = mapper_file.getUnknownTag(node);
|
|
@@ -9114,6 +9153,7 @@ async function generateOutput(ast, i, format, mapper_file, security = {}, parent
|
|
|
9114
9153
|
const isManualMode = !!rawTarget.options?.handleAst;
|
|
9115
9154
|
return await rawTarget.render.call(mapper_file, {
|
|
9116
9155
|
props: transpiledArgs,
|
|
9156
|
+
directives: node.directives,
|
|
9117
9157
|
content: rawContent,
|
|
9118
9158
|
textContent: rawContent,
|
|
9119
9159
|
ast: isManualMode ? node : undefined,
|
|
@@ -9225,6 +9265,7 @@ async function generateOutput(ast, i, format, mapper_file, security = {}, parent
|
|
|
9225
9265
|
|
|
9226
9266
|
return await target.render.call(mapper_file, {
|
|
9227
9267
|
props: transpiledArgs,
|
|
9268
|
+
directives: node.directives,
|
|
9228
9269
|
content: "",
|
|
9229
9270
|
textContent: richText || textContent,
|
|
9230
9271
|
ast: cleanAst,
|
|
@@ -9243,6 +9284,7 @@ async function generateOutput(ast, i, format, mapper_file, security = {}, parent
|
|
|
9243
9284
|
}
|
|
9244
9285
|
result += await target.render.call(mapper_file, {
|
|
9245
9286
|
props: transpiledArgs,
|
|
9287
|
+
directives: node.directives,
|
|
9246
9288
|
content,
|
|
9247
9289
|
textContent,
|
|
9248
9290
|
ast: new Proxy({}, {
|
|
@@ -10666,11 +10708,20 @@ class Mapper {
|
|
|
10666
10708
|
|
|
10667
10709
|
/**
|
|
10668
10710
|
* Registers universal utility blocks shared across all SomMark mappers.
|
|
10669
|
-
* These blocks are considered "Format Agnostic."
|
|
10670
10711
|
*
|
|
10671
10712
|
* @param {Mapper} mapper - The mapper instance to register tags on.
|
|
10672
10713
|
*/
|
|
10673
10714
|
function registerSharedOutputs(mapper) {
|
|
10715
|
+
mapper.register(
|
|
10716
|
+
["raw", "Raw"],
|
|
10717
|
+
({ content }) => {
|
|
10718
|
+
return content;
|
|
10719
|
+
},
|
|
10720
|
+
{
|
|
10721
|
+
escape: false, rules: {
|
|
10722
|
+
required_directives: ["raw"]
|
|
10723
|
+
} }
|
|
10724
|
+
);
|
|
10674
10725
|
}
|
|
10675
10726
|
|
|
10676
10727
|
const SVG_ELEMENTS = new Set([
|
|
@@ -10823,6 +10874,7 @@ HTML.register(
|
|
|
10823
10874
|
return "";
|
|
10824
10875
|
},
|
|
10825
10876
|
);
|
|
10877
|
+
registerSharedOutputs(HTML);
|
|
10826
10878
|
|
|
10827
10879
|
/**
|
|
10828
10880
|
* The Markdown Mapper used for generating Markdown text.
|
|
@@ -10849,42 +10901,37 @@ const MARKDOWN = Mapper.define({
|
|
|
10849
10901
|
},
|
|
10850
10902
|
|
|
10851
10903
|
/**
|
|
10852
|
-
* Provides a fallback for unknown tags by
|
|
10853
|
-
|
|
10904
|
+
* Provides a fallback for unknown tags by rendering them as HTML elements.
|
|
10905
|
+
* Passes child nodes to the transpiler, which handles all node types (such as ForEach).
|
|
10906
|
+
**/
|
|
10854
10907
|
getUnknownTag(node) {
|
|
10855
|
-
const id = node.id
|
|
10856
|
-
|
|
10908
|
+
const id = node.id;
|
|
10857
10909
|
return {
|
|
10858
|
-
|
|
10910
|
+
options: { trimAndWrapBlocks: true },
|
|
10911
|
+
render: ({ props, content, isSelfClosing }) => {
|
|
10859
10912
|
const element = this.tag(id).smartAttributes(props, this.customProps, this.options);
|
|
10860
10913
|
if (isSelfClosing || VOID_ELEMENTS.has(id)) return element.selfClose();
|
|
10861
|
-
|
|
10862
|
-
|
|
10863
|
-
for (const child of (ast.body || [])) {
|
|
10864
|
-
if (child.type === TEXT$1) rawContent += this.text(child.text);
|
|
10865
|
-
else if (child.type === BLOCK) rawContent += await renderChild(child);
|
|
10866
|
-
}
|
|
10867
|
-
rawContent = rawContent.trim();
|
|
10868
|
-
|
|
10869
|
-
const meaningful = (ast.body || []).filter(c => c.type !== TEXT$1 || c.text.trim());
|
|
10870
|
-
const finalContent = meaningful.length <= 1 ? rawContent : `\n${rawContent}\n`;
|
|
10871
|
-
return element.body(finalContent);
|
|
10872
|
-
},
|
|
10873
|
-
options: { handleAst: true }
|
|
10914
|
+
return element.body(content);
|
|
10915
|
+
}
|
|
10874
10916
|
};
|
|
10875
10917
|
}
|
|
10876
10918
|
});
|
|
10877
10919
|
|
|
10878
10920
|
MARKDOWN.inherit(HTML);
|
|
10879
10921
|
const { md, safeArg } = MARKDOWN;
|
|
10922
|
+
registerSharedOutputs(MARKDOWN);
|
|
10880
10923
|
|
|
10881
10924
|
/**
|
|
10882
10925
|
* Quote - Renders blockquote content or GFM alerts.
|
|
10883
10926
|
*/
|
|
10884
|
-
MARKDOWN.register(
|
|
10885
|
-
|
|
10886
|
-
|
|
10887
|
-
|
|
10927
|
+
MARKDOWN.register(
|
|
10928
|
+
"quote",
|
|
10929
|
+
({ props, content }) => {
|
|
10930
|
+
const type = safeArg({ props, index: 0, key: "type", fallBack: "" });
|
|
10931
|
+
return md.quote(content, type);
|
|
10932
|
+
},
|
|
10933
|
+
{ resolve: true }
|
|
10934
|
+
);
|
|
10888
10935
|
|
|
10889
10936
|
/**
|
|
10890
10937
|
* Headings - Renders H1-H6 block headings.
|
|
@@ -10964,12 +11011,12 @@ MARKDOWN.register(
|
|
|
10964
11011
|
"link",
|
|
10965
11012
|
({ props, content, isSelfClosing }) => {
|
|
10966
11013
|
if (isSelfClosing) {
|
|
10967
|
-
const text
|
|
10968
|
-
const src
|
|
11014
|
+
const text = safeArg({ props, index: 0, key: "text", fallBack: "" });
|
|
11015
|
+
const src = safeArg({ props, index: 1, key: "src", fallBack: "" });
|
|
10969
11016
|
const title = safeArg({ props, index: 2, key: "title", fallBack: "" });
|
|
10970
11017
|
return md.url("link", text, src, title);
|
|
10971
11018
|
}
|
|
10972
|
-
const src
|
|
11019
|
+
const src = safeArg({ props, index: 0, key: "src", fallBack: "" });
|
|
10973
11020
|
const title = safeArg({ props, index: 1, key: "title", fallBack: "" });
|
|
10974
11021
|
return md.url("link", content, src, title);
|
|
10975
11022
|
},
|
|
@@ -11007,10 +11054,14 @@ MARKDOWN.register(
|
|
|
11007
11054
|
* Escape - Escapes special Markdown characters.
|
|
11008
11055
|
* Self-closing: [escape = "text" !] or [escape = text: "text" !]
|
|
11009
11056
|
*/
|
|
11010
|
-
MARKDOWN.register(
|
|
11011
|
-
|
|
11012
|
-
|
|
11013
|
-
|
|
11057
|
+
MARKDOWN.register(
|
|
11058
|
+
["escape", "e"],
|
|
11059
|
+
function ({ props, content, isSelfClosing }) {
|
|
11060
|
+
const text = isSelfClosing ? safeArg({ props, index: 0, key: "text", fallBack: "" }) : content;
|
|
11061
|
+
return this.md.escape(text);
|
|
11062
|
+
},
|
|
11063
|
+
{ resolve: true }
|
|
11064
|
+
);
|
|
11014
11065
|
|
|
11015
11066
|
const ROW_SEP = "\x1E";
|
|
11016
11067
|
const CELL_SEP = "\x1F";
|
|
@@ -11026,12 +11077,16 @@ MARKDOWN.register(
|
|
|
11026
11077
|
const headers = [];
|
|
11027
11078
|
const rows = [];
|
|
11028
11079
|
|
|
11029
|
-
const extractRows = async
|
|
11080
|
+
const extractRows = async sectionNode => {
|
|
11030
11081
|
const sectionRows = [];
|
|
11031
|
-
for (const child of
|
|
11082
|
+
for (const child of sectionNode.body || []) {
|
|
11032
11083
|
if (child.type === BLOCK && child.id?.toLowerCase() === "row") {
|
|
11033
11084
|
const rendered = await renderChild(child, { inTable: true });
|
|
11034
|
-
const cells =
|
|
11085
|
+
const cells =
|
|
11086
|
+
rendered
|
|
11087
|
+
.split(ROW_SEP)[0]
|
|
11088
|
+
?.split(CELL_SEP)
|
|
11089
|
+
.filter(c => c !== "") ?? [];
|
|
11035
11090
|
if (cells.length > 0) sectionRows.push(cells);
|
|
11036
11091
|
} else if (child.type === FOR_EACH) {
|
|
11037
11092
|
const rendered = await renderChild(child, { inTable: true });
|
|
@@ -11065,25 +11120,29 @@ MARKDOWN.register(
|
|
|
11065
11120
|
*/
|
|
11066
11121
|
MARKDOWN.register(["header", "body"], ({ content }) => content);
|
|
11067
11122
|
|
|
11068
|
-
MARKDOWN.register(
|
|
11069
|
-
|
|
11070
|
-
|
|
11071
|
-
|
|
11072
|
-
|
|
11073
|
-
|
|
11123
|
+
MARKDOWN.register(
|
|
11124
|
+
"row",
|
|
11125
|
+
async function ({ ast, renderChild, inTable }) {
|
|
11126
|
+
if (!inTable) {
|
|
11127
|
+
let result = "";
|
|
11128
|
+
for (const child of ast.body) {
|
|
11129
|
+
if (child.type === TEXT$1) result += this.text(child.text);
|
|
11130
|
+
else if (child.type === BLOCK) result += await renderChild(child);
|
|
11131
|
+
}
|
|
11132
|
+
return result;
|
|
11074
11133
|
}
|
|
11075
|
-
|
|
11076
|
-
|
|
11077
|
-
|
|
11078
|
-
|
|
11079
|
-
|
|
11080
|
-
|
|
11081
|
-
|
|
11082
|
-
cells += await renderChild(child, { inTable: true });
|
|
11134
|
+
let cells = "";
|
|
11135
|
+
for (const child of ast.body) {
|
|
11136
|
+
if (child.type !== BLOCK) continue;
|
|
11137
|
+
const id = child.id?.toLowerCase();
|
|
11138
|
+
if (id === "cell" || id === "th" || id === "td") {
|
|
11139
|
+
cells += await renderChild(child, { inTable: true });
|
|
11140
|
+
}
|
|
11083
11141
|
}
|
|
11084
|
-
|
|
11085
|
-
|
|
11086
|
-
|
|
11142
|
+
return cells + ROW_SEP;
|
|
11143
|
+
},
|
|
11144
|
+
{ handleAst: true }
|
|
11145
|
+
);
|
|
11087
11146
|
|
|
11088
11147
|
MARKDOWN.register(["cell", "th", "td"], ({ content, inTable }) => {
|
|
11089
11148
|
return inTable ? content.trim() + CELL_SEP : content;
|
|
@@ -11093,34 +11152,42 @@ MARKDOWN.register(["cell", "th", "td"], ({ content, inTable }) => {
|
|
|
11093
11152
|
* Lists - Authoritative Native AST List resolution.
|
|
11094
11153
|
* Supports Ordered (Number) and Unordered (Dotlex) lists with deep nesting.
|
|
11095
11154
|
*/
|
|
11096
|
-
MARKDOWN.register(
|
|
11097
|
-
|
|
11098
|
-
|
|
11099
|
-
|
|
11100
|
-
|
|
11155
|
+
MARKDOWN.register(
|
|
11156
|
+
["list", "List"],
|
|
11157
|
+
async function ({ ast, props, renderChild }) {
|
|
11158
|
+
const indicator = safeArg({ props, index: 0, fallBack: "dot" });
|
|
11159
|
+
const isOrdered = indicator === "number" || indicator === "ol";
|
|
11160
|
+
const marker = isOrdered ? "" : indicator === "dot" ? "-" : indicator;
|
|
11161
|
+
const items = [];
|
|
11101
11162
|
|
|
11102
|
-
|
|
11103
|
-
|
|
11104
|
-
|
|
11105
|
-
|
|
11106
|
-
|
|
11163
|
+
for (const node of ast.body) {
|
|
11164
|
+
if (node.type !== BLOCK) continue;
|
|
11165
|
+
const id = node.id?.toLowerCase();
|
|
11166
|
+
if (id === "item") {
|
|
11167
|
+
items.push((await renderChild(node)).trim());
|
|
11168
|
+
}
|
|
11107
11169
|
}
|
|
11108
|
-
}
|
|
11109
11170
|
|
|
11110
|
-
|
|
11111
|
-
},
|
|
11171
|
+
return isOrdered ? md.orderedList(items, 0) : md.unorderedList(items, 0, marker);
|
|
11172
|
+
},
|
|
11173
|
+
{ handleAst: true, trimAndWrapBlocks: false }
|
|
11174
|
+
);
|
|
11112
11175
|
|
|
11113
11176
|
/**
|
|
11114
11177
|
* List Helpers - Internal tags for list structural organization.
|
|
11115
11178
|
*/
|
|
11116
|
-
MARKDOWN.register(
|
|
11117
|
-
|
|
11118
|
-
|
|
11119
|
-
|
|
11120
|
-
|
|
11121
|
-
|
|
11122
|
-
|
|
11123
|
-
}
|
|
11179
|
+
MARKDOWN.register(
|
|
11180
|
+
["item", "Item"],
|
|
11181
|
+
async function ({ ast, renderChild }) {
|
|
11182
|
+
let result = "";
|
|
11183
|
+
for (const child of ast.body) {
|
|
11184
|
+
if (child.type === TEXT$1) result += this.text(child.text);
|
|
11185
|
+
else if (child.type === BLOCK) result += await renderChild(child);
|
|
11186
|
+
}
|
|
11187
|
+
return result.trim();
|
|
11188
|
+
},
|
|
11189
|
+
{ handleAst: true, trimAndWrapBlocks: false }
|
|
11190
|
+
);
|
|
11124
11191
|
|
|
11125
11192
|
/**
|
|
11126
11193
|
* Todo - Renders task list items with status markers.
|
|
@@ -11130,19 +11197,23 @@ MARKDOWN.register(["item", "Item"], async function ({ ast, renderChild }) {
|
|
|
11130
11197
|
* [todo = "Add feature", "x" !] positional self-closing (task, status)
|
|
11131
11198
|
* [todo = "x"]Add feature[end] status in prop, task in body
|
|
11132
11199
|
*/
|
|
11133
|
-
MARKDOWN.register(
|
|
11134
|
-
|
|
11200
|
+
MARKDOWN.register(
|
|
11201
|
+
"todo",
|
|
11202
|
+
({ props, content, isSelfClosing }) => {
|
|
11203
|
+
let status, task;
|
|
11135
11204
|
|
|
11136
|
-
|
|
11137
|
-
|
|
11138
|
-
|
|
11139
|
-
|
|
11140
|
-
|
|
11141
|
-
|
|
11142
|
-
|
|
11205
|
+
if (isSelfClosing) {
|
|
11206
|
+
task = safeArg({ props, index: 0, key: "task", fallBack: "" });
|
|
11207
|
+
status = safeArg({ props, index: 1, key: "status", fallBack: "" });
|
|
11208
|
+
} else {
|
|
11209
|
+
status = safeArg({ props, index: 0, fallBack: "" });
|
|
11210
|
+
task = content;
|
|
11211
|
+
}
|
|
11143
11212
|
|
|
11144
|
-
|
|
11145
|
-
},
|
|
11213
|
+
return md.todo(status, task);
|
|
11214
|
+
},
|
|
11215
|
+
{ trimAndWrapBlocks: false }
|
|
11216
|
+
);
|
|
11146
11217
|
|
|
11147
11218
|
/**
|
|
11148
11219
|
* The MDX Mapper used for generating Markdown with JSX.
|
|
@@ -11352,100 +11423,115 @@ Jsonc.register(["Array", "array"], async function ({ props, ast, depth = 0, inAr
|
|
|
11352
11423
|
/**
|
|
11353
11424
|
* Renders a standard XML tag based on the provided identifier and arguments.
|
|
11354
11425
|
* Ensures strict attribute quoting and handles self-closing tags for empty bodies.
|
|
11355
|
-
*
|
|
11426
|
+
*
|
|
11356
11427
|
* @param {string} id - The XML tag identifier (case-sensitive).
|
|
11357
11428
|
* @param {Object} props - Key-value pairs to be rendered as XML attributes.
|
|
11358
11429
|
* @param {string} content - The rendered inner content of the tag.
|
|
11359
11430
|
* @returns {string} The fully rendered XML tag string.
|
|
11360
11431
|
*/
|
|
11361
11432
|
const renderXmlTag = function (id, props, content, isSelfClosing) {
|
|
11362
|
-
|
|
11363
|
-
|
|
11364
|
-
|
|
11365
|
-
// Filter out positional indices (numeric keys) for XML attributes
|
|
11366
|
-
const namedArgs = {};
|
|
11367
|
-
Object.keys(props).forEach(key => {
|
|
11368
|
-
if (isNaN(parseInt(key))) {
|
|
11369
|
-
namedArgs[key] = props[key];
|
|
11370
|
-
}
|
|
11371
|
-
});
|
|
11433
|
+
// XML is case-sensitive, so we use the exact id provided
|
|
11434
|
+
const element = this.tag(id);
|
|
11372
11435
|
|
|
11373
|
-
|
|
11374
|
-
|
|
11436
|
+
// Filter out positional indices (numeric keys) for XML attributes
|
|
11437
|
+
const namedArgs = {};
|
|
11438
|
+
Object.keys(props).forEach(key => {
|
|
11439
|
+
if (isNaN(parseInt(key))) {
|
|
11440
|
+
namedArgs[key] = props[key];
|
|
11441
|
+
}
|
|
11442
|
+
});
|
|
11375
11443
|
|
|
11376
|
-
|
|
11444
|
+
// In XML, attributes must always have values (strict = true)
|
|
11445
|
+
element.attributes(namedArgs, true);
|
|
11377
11446
|
|
|
11378
|
-
|
|
11379
|
-
return element.selfClose();
|
|
11380
|
-
}
|
|
11447
|
+
const hasBody = typeof content === "string" && content.trim().length > 0;
|
|
11381
11448
|
|
|
11382
|
-
|
|
11449
|
+
if (isSelfClosing || !hasBody) {
|
|
11450
|
+
return element.selfClose();
|
|
11451
|
+
}
|
|
11452
|
+
|
|
11453
|
+
return element.body(content);
|
|
11383
11454
|
};
|
|
11384
11455
|
|
|
11385
11456
|
/**
|
|
11386
11457
|
* The XML Mapper used for creating XML pages.
|
|
11387
11458
|
*/
|
|
11388
11459
|
const XML = Mapper.define({
|
|
11389
|
-
|
|
11390
|
-
|
|
11391
|
-
|
|
11392
|
-
|
|
11393
|
-
|
|
11394
|
-
|
|
11395
|
-
|
|
11396
|
-
|
|
11397
|
-
|
|
11398
|
-
|
|
11399
|
-
|
|
11400
|
-
|
|
11401
|
-
|
|
11402
|
-
|
|
11403
|
-
|
|
11404
|
-
|
|
11405
|
-
|
|
11406
|
-
|
|
11407
|
-
|
|
11408
|
-
|
|
11409
|
-
|
|
11460
|
+
/**
|
|
11461
|
+
* Renders a comment in XML format.
|
|
11462
|
+
* @param {string} text - The comment content.
|
|
11463
|
+
* @returns {string}
|
|
11464
|
+
*/
|
|
11465
|
+
comment(text) {
|
|
11466
|
+
return `<!-- ${text} -->`;
|
|
11467
|
+
},
|
|
11468
|
+
|
|
11469
|
+
/**
|
|
11470
|
+
* Resolves unknown tags by preserving their original case and applying XML rules.
|
|
11471
|
+
* @param {Object} node - The AST node representing the unknown tag.
|
|
11472
|
+
* @returns {Object} Renderer definition for the tag.
|
|
11473
|
+
*/
|
|
11474
|
+
getUnknownTag(node) {
|
|
11475
|
+
const id = node.id;
|
|
11476
|
+
return {
|
|
11477
|
+
render: ({ props, content, isSelfClosing }) => renderXmlTag.call(this, id, props, content, isSelfClosing),
|
|
11478
|
+
options: {}
|
|
11479
|
+
};
|
|
11480
|
+
},
|
|
11481
|
+
options: {
|
|
11482
|
+
trimAndWrapBlocks: true
|
|
11483
|
+
}
|
|
11410
11484
|
});
|
|
11411
11485
|
|
|
11412
11486
|
/**
|
|
11413
11487
|
* Registers the XML declaration as a self-closing block.
|
|
11414
11488
|
* Usage: [xml = version: "1.0", encoding: "UTF-8"]
|
|
11415
11489
|
*/
|
|
11416
|
-
XML.register(
|
|
11417
|
-
|
|
11418
|
-
|
|
11419
|
-
|
|
11420
|
-
|
|
11490
|
+
XML.register(
|
|
11491
|
+
"xml",
|
|
11492
|
+
({ props }) => {
|
|
11493
|
+
const version = props.version || "1.0";
|
|
11494
|
+
const encoding = props.encoding || "UTF-8";
|
|
11495
|
+
return `<?xml version="${version}" encoding="${encoding}"?>`;
|
|
11496
|
+
},
|
|
11497
|
+
{ rules: { is_empty_body: true } }
|
|
11498
|
+
);
|
|
11421
11499
|
|
|
11422
11500
|
/**
|
|
11423
11501
|
* Registers the DOCTYPE declaration.
|
|
11424
11502
|
* Usage: [doctype = root: "note", system: "note.dtd"]
|
|
11425
11503
|
*/
|
|
11426
|
-
XML.register(
|
|
11427
|
-
|
|
11428
|
-
|
|
11429
|
-
|
|
11504
|
+
XML.register(
|
|
11505
|
+
["DOCTYPE", "doctype"],
|
|
11506
|
+
({ props }) => {
|
|
11507
|
+
const root = props.root || "root";
|
|
11508
|
+
const system = props.system;
|
|
11509
|
+
const pub = props.public || props.fpi;
|
|
11430
11510
|
|
|
11431
|
-
|
|
11432
|
-
|
|
11433
|
-
|
|
11434
|
-
|
|
11435
|
-
|
|
11436
|
-
|
|
11437
|
-
},
|
|
11511
|
+
if (pub && system) {
|
|
11512
|
+
return `<!DOCTYPE ${root} PUBLIC "${pub}" "${system}">`;
|
|
11513
|
+
} else if (system) {
|
|
11514
|
+
return `<!DOCTYPE ${root} SYSTEM "${system}">`;
|
|
11515
|
+
}
|
|
11516
|
+
return `<!DOCTYPE ${root}>`;
|
|
11517
|
+
},
|
|
11518
|
+
{ rules: { is_empty_body: true } }
|
|
11519
|
+
);
|
|
11438
11520
|
|
|
11439
11521
|
/**
|
|
11440
11522
|
* Registers the XML stylesheet processing instruction.
|
|
11441
11523
|
* Usage: [xml-stylesheet = href: "style.xsl"]
|
|
11442
11524
|
*/
|
|
11443
|
-
XML.register(
|
|
11444
|
-
|
|
11445
|
-
|
|
11446
|
-
|
|
11447
|
-
|
|
11448
|
-
|
|
11525
|
+
XML.register(
|
|
11526
|
+
"xml-stylesheet",
|
|
11527
|
+
({ props }) => {
|
|
11528
|
+
const type = props.type || "text/xsl";
|
|
11529
|
+
const href = props.href;
|
|
11530
|
+
if (!href) return "";
|
|
11531
|
+
return `<?xml-stylesheet type="${type}" href="${href}"?>`;
|
|
11532
|
+
},
|
|
11533
|
+
{ rules: { is_empty_body: true } }
|
|
11534
|
+
);
|
|
11449
11535
|
|
|
11450
11536
|
/**
|
|
11451
11537
|
* Registers CDATA sections.
|
|
@@ -11453,10 +11539,12 @@ XML.register("xml-stylesheet", ({ props }) => {
|
|
|
11453
11539
|
* Self-closing: [cdata = "raw content" !] or [cdata = text: "raw content" !]
|
|
11454
11540
|
*/
|
|
11455
11541
|
XML.register("cdata", ({ props, content, isSelfClosing }) => {
|
|
11456
|
-
|
|
11457
|
-
|
|
11542
|
+
const text = isSelfClosing ? (props[0] ?? props.text ?? "") : content;
|
|
11543
|
+
return `<![CDATA[${text}]]>`;
|
|
11458
11544
|
});
|
|
11459
11545
|
|
|
11546
|
+
registerSharedOutputs(XML);
|
|
11547
|
+
|
|
11460
11548
|
const csvEscape = (value) => {
|
|
11461
11549
|
const str = String(value ?? "").trim();
|
|
11462
11550
|
if (str.includes(",") || str.includes('"') || str.includes("\n") || str.includes("\r")) {
|
|
@@ -11513,6 +11601,8 @@ CSV.register(["col", "cell", "td"], ({ textContent }) => {
|
|
|
11513
11601
|
return csvEscape(textContent);
|
|
11514
11602
|
}, { handleAst: true, trimAndWrapBlocks: false });
|
|
11515
11603
|
|
|
11604
|
+
registerSharedOutputs(CSV);
|
|
11605
|
+
|
|
11516
11606
|
const isValidInt$1 = (v) => v !== "" && !isNaN(Number(v)) && !v.includes(".");
|
|
11517
11607
|
const isValidFloat$1 = (v) => v !== "" && !isNaN(Number(v)) && v.includes(".");
|
|
11518
11608
|
const isValidNumber$1 = (v) => v !== "" && !isNaN(Number(v));
|
|
@@ -11736,6 +11826,8 @@ TOML.register("array", async ({ props, ast, renderChild }) => {
|
|
|
11736
11826
|
return `${tomlKey(key)} = [${vals.join(", ")}]\n`;
|
|
11737
11827
|
}, { handleAst: true });
|
|
11738
11828
|
|
|
11829
|
+
registerSharedOutputs(TOML);
|
|
11830
|
+
|
|
11739
11831
|
const isValidInt = (v) => v !== "" && !isNaN(Number(v)) && !v.includes(".");
|
|
11740
11832
|
const isValidFloat = (v) => v !== "" && !isNaN(Number(v)) && v.includes(".");
|
|
11741
11833
|
const isValidNumber = (v) => v !== "" && !isNaN(Number(v));
|
|
@@ -12051,6 +12143,8 @@ YAML.register("doc-start", () => "---\n", { rules: { is_empty_body: true } });
|
|
|
12051
12143
|
*/
|
|
12052
12144
|
YAML.register("doc-end", () => "...\n", { rules: { is_empty_body: true } });
|
|
12053
12145
|
|
|
12146
|
+
registerSharedOutputs(YAML);
|
|
12147
|
+
|
|
12054
12148
|
/**
|
|
12055
12149
|
* The Text Mapper used for plain-text extraction.
|
|
12056
12150
|
*/
|
|
@@ -12327,34 +12421,48 @@ async function resolveModules(ast, context) {
|
|
|
12327
12421
|
const baseDir = context.instance.baseDir || ((filename === "anonymous") ? absFilename : posix.dirname(absFilename));
|
|
12328
12422
|
|
|
12329
12423
|
// 1. Helper: Trim AST to remove file-boundary whitespace and "ghost" newlines
|
|
12330
|
-
const trimAst = (nodes) => {
|
|
12424
|
+
const trimAst = (nodes, trimBoundaries = true) => {
|
|
12331
12425
|
if (!nodes) return [];
|
|
12332
12426
|
|
|
12333
|
-
// 1. Filter out
|
|
12334
|
-
// (Comments, Imports,
|
|
12427
|
+
// 1. Filter out whitespace-only text nodes adjacent (directly or through other whitespace)
|
|
12428
|
+
// to non-rendering nodes (Comments, Imports, USE_MODULE).
|
|
12335
12429
|
const nonRenderingTypes = [COMMENT, IMPORT, USE_MODULE];
|
|
12336
12430
|
let res = nodes.filter((node, idx) => {
|
|
12337
12431
|
if (node.type !== TEXT$1 || node.text.trim() !== "") return true;
|
|
12338
12432
|
|
|
12339
|
-
|
|
12340
|
-
|
|
12341
|
-
|
|
12342
|
-
(
|
|
12343
|
-
|
|
12433
|
+
// Walk backwards through consecutive whitespace nodes to find prev non-whitespace
|
|
12434
|
+
let prevIsNonRendering = false;
|
|
12435
|
+
for (let j = idx - 1; j >= 0; j--) {
|
|
12436
|
+
if (nodes[j].type === TEXT$1 && nodes[j].text.trim() === "") continue;
|
|
12437
|
+
prevIsNonRendering = nonRenderingTypes.includes(nodes[j].type);
|
|
12438
|
+
break;
|
|
12439
|
+
}
|
|
12440
|
+
|
|
12441
|
+
// Walk forwards through consecutive whitespace nodes to find next non-whitespace
|
|
12442
|
+
let nextIsNonRendering = false;
|
|
12443
|
+
for (let j = idx + 1; j < nodes.length; j++) {
|
|
12444
|
+
if (nodes[j].type === TEXT$1 && nodes[j].text.trim() === "") continue;
|
|
12445
|
+
nextIsNonRendering = nonRenderingTypes.includes(nodes[j].type);
|
|
12446
|
+
break;
|
|
12447
|
+
}
|
|
12344
12448
|
|
|
12345
|
-
return !
|
|
12449
|
+
return !(prevIsNonRendering || nextIsNonRendering);
|
|
12346
12450
|
});
|
|
12347
12451
|
|
|
12348
|
-
|
|
12349
|
-
|
|
12350
|
-
res
|
|
12351
|
-
|
|
12352
|
-
|
|
12353
|
-
res
|
|
12452
|
+
if (trimBoundaries) {
|
|
12453
|
+
// 2. Final pass: trim leading/trailing newlines from the remaining boundary text nodes
|
|
12454
|
+
if (res.length > 0 && res[0].type === TEXT$1) {
|
|
12455
|
+
res[0].text = res[0].text.replace(/^[\r\n]+/, "");
|
|
12456
|
+
}
|
|
12457
|
+
if (res.length > 0 && res[res.length - 1].type === TEXT$1) {
|
|
12458
|
+
res[res.length - 1].text = res[res.length - 1].text.replace(/[\r\n]+\s*$/, "");
|
|
12459
|
+
}
|
|
12460
|
+
|
|
12461
|
+
// 3. Remove any nodes that became purely empty after trimming
|
|
12462
|
+
res = res.filter(node => node.type !== TEXT$1 || node.text !== "");
|
|
12354
12463
|
}
|
|
12355
12464
|
|
|
12356
|
-
|
|
12357
|
-
return res.filter(node => node.type !== TEXT$1 || node.text !== "");
|
|
12465
|
+
return res;
|
|
12358
12466
|
};
|
|
12359
12467
|
|
|
12360
12468
|
// 2. Helper: Inject Slots with Indentation Propagation
|
|
@@ -12425,6 +12533,10 @@ async function resolveModules(ast, context) {
|
|
|
12425
12533
|
// 1b. Resolve relative to current base (FS)
|
|
12426
12534
|
const absolutePath = resolveModulePath(resolvedPath, currentBaseDir);
|
|
12427
12535
|
|
|
12536
|
+
if (!context.instance.fs) {
|
|
12537
|
+
runtimeError([`<$red:Module Error:$> Cannot import <$magenta:${filePath}$> — no filesystem is available.{N}In browser mode, pass a URL-based <$cyan:baseDir$> or a <$cyan:files$> map to enable module loading.`]);
|
|
12538
|
+
}
|
|
12539
|
+
|
|
12428
12540
|
// Local Path Resolution with Auto-Extension
|
|
12429
12541
|
let localPath = absolutePath;
|
|
12430
12542
|
if (!await context.instance.fs.exists(localPath) && !localPath.endsWith(".smark")) {
|
|
@@ -12576,7 +12688,6 @@ async function resolveModules(ast, context) {
|
|
|
12576
12688
|
Object.entries(node.props).filter(([key]) => {
|
|
12577
12689
|
if (key === "__consumed__") return false;
|
|
12578
12690
|
if (consumed.has(key)) return false; // THE FIX: Filter if hit by v{}
|
|
12579
|
-
if (key === "smark-raw") return false; // directive — must not leak onto root element
|
|
12580
12691
|
return true;
|
|
12581
12692
|
})
|
|
12582
12693
|
);
|
|
@@ -12691,10 +12802,7 @@ const runValidations = (node, target, instance) => {
|
|
|
12691
12802
|
const isStructural = node.type === "Block";
|
|
12692
12803
|
if (isStructural && rules.required_args && Array.isArray(rules.required_args)) {
|
|
12693
12804
|
const missingArgs = rules.required_args.filter(arg => {
|
|
12694
|
-
|
|
12695
|
-
if (typeof arg === "number") {
|
|
12696
|
-
return node.props[arg] === undefined;
|
|
12697
|
-
}
|
|
12805
|
+
if (typeof arg === "number") return node.props[arg] === undefined;
|
|
12698
12806
|
return node.props[arg] === undefined;
|
|
12699
12807
|
});
|
|
12700
12808
|
|
|
@@ -12709,6 +12817,22 @@ const runValidations = (node, target, instance) => {
|
|
|
12709
12817
|
);
|
|
12710
12818
|
}
|
|
12711
12819
|
}
|
|
12820
|
+
|
|
12821
|
+
// -- Directives Validation (Required Directives) ----------------------- //
|
|
12822
|
+
if (isStructural && rules.required_directives && Array.isArray(rules.required_directives)) {
|
|
12823
|
+
const missingDirectives = rules.required_directives.filter(key => node.directives?.[key] === undefined);
|
|
12824
|
+
|
|
12825
|
+
if (missingDirectives.length > 0) {
|
|
12826
|
+
transpilerError(
|
|
12827
|
+
[
|
|
12828
|
+
"{N}",
|
|
12829
|
+
`<$yellow:Identifier$> <$blue:'${id}'$> <$yellow:is missing required directive props:$> <$red:${missingDirectives.map(k => `smark-${k}`).join(", ")}$>{N}`,
|
|
12830
|
+
`<$blue:Please ensure these directive props are provided in the template usage.$>`
|
|
12831
|
+
],
|
|
12832
|
+
context
|
|
12833
|
+
);
|
|
12834
|
+
}
|
|
12835
|
+
}
|
|
12712
12836
|
};
|
|
12713
12837
|
|
|
12714
12838
|
/**
|
|
@@ -12880,6 +13004,14 @@ function setDefaultFs(fs) {
|
|
|
12880
13004
|
Evaluator.setDefaultFs(fs);
|
|
12881
13005
|
}
|
|
12882
13006
|
|
|
13007
|
+
function setDefaultEnv(env) {
|
|
13008
|
+
Evaluator.setDefaultEnv(env);
|
|
13009
|
+
}
|
|
13010
|
+
|
|
13011
|
+
function setDefaultAsyncLocalStorage(cls) {
|
|
13012
|
+
Evaluator.setDefaultAsyncLocalStorage(cls);
|
|
13013
|
+
}
|
|
13014
|
+
|
|
12883
13015
|
function setDefaultResolvePath(fn) {
|
|
12884
13016
|
defaultResolvePath = fn;
|
|
12885
13017
|
}
|
|
@@ -12951,7 +13083,8 @@ class SomMark {
|
|
|
12951
13083
|
allowFetch: security?.allowFetch !== false,
|
|
12952
13084
|
allowHttp: security?.allowHttp === true,
|
|
12953
13085
|
allowedOrigins: Array.isArray(security?.allowedOrigins) ? security.allowedOrigins.map(o => o.toLowerCase()) : null,
|
|
12954
|
-
allowedExtensions: Array.isArray(security?.allowedExtensions) ? security.allowedExtensions.map(e => e.toLowerCase()) : null
|
|
13086
|
+
allowedExtensions: Array.isArray(security?.allowedExtensions) ? security.allowedExtensions.map(e => e.toLowerCase()) : null,
|
|
13087
|
+
env: Array.isArray(security?.env) ? security.env : []
|
|
12955
13088
|
};
|
|
12956
13089
|
this.warnings = [];
|
|
12957
13090
|
this._prepared = false;
|
|
@@ -13262,8 +13395,24 @@ async function findAndLoadConfig(targetPath) {
|
|
|
13262
13395
|
return await defaultFindAndLoadConfig(targetPath);
|
|
13263
13396
|
}
|
|
13264
13397
|
|
|
13398
|
+
class AsyncLocalStorage {
|
|
13399
|
+
#store = undefined;
|
|
13400
|
+
run(store, fn) {
|
|
13401
|
+
const prev = this.#store;
|
|
13402
|
+
this.#store = store;
|
|
13403
|
+
try { return fn(); }
|
|
13404
|
+
finally { this.#store = prev; }
|
|
13405
|
+
}
|
|
13406
|
+
getStore() { return this.#store; }
|
|
13407
|
+
exit(fn) { return fn(); }
|
|
13408
|
+
enterWith(store) { this.#store = store; }
|
|
13409
|
+
disable() {}
|
|
13410
|
+
}
|
|
13411
|
+
|
|
13265
13412
|
setDefaultFs(null);
|
|
13266
13413
|
setDefaultCwd("/");
|
|
13414
|
+
setDefaultEnv(null);
|
|
13415
|
+
setDefaultAsyncLocalStorage(AsyncLocalStorage);
|
|
13267
13416
|
|
|
13268
13417
|
/**
|
|
13269
13418
|
* Resolves a relative path into a full URL using the current document location.
|
|
@@ -13345,4 +13494,4 @@ function renderCompiledHTML(container, html) {
|
|
|
13345
13494
|
}
|
|
13346
13495
|
}
|
|
13347
13496
|
|
|
13348
|
-
export { CSV, Evaluator, formats as FORMATS, HTML, Json, Jsonc, MARKDOWN, MDX, Mapper, TOKEN_TYPES, TOML, XML, YAML, SomMark as default, enableColor, findAndLoadConfig, labels, lex, lexSync, parse, parseSync, preprocessRuntimeLogic, registerSharedOutputs, renderCompiledHTML, resolveBaseDir, safeArg$1 as safeArg, setDefaultCwd, setDefaultFindAndLoadConfig, setDefaultFs, setDefaultResolvePath, transpile };
|
|
13497
|
+
export { CSV, Evaluator, formats as FORMATS, HTML, Json, Jsonc, MARKDOWN, MDX, Mapper, TOKEN_TYPES, TOML, XML, YAML, SomMark as default, enableColor, findAndLoadConfig, labels, lex, lexSync, parse, parseSync, preprocessRuntimeLogic, registerSharedOutputs, renderCompiledHTML, resolveBaseDir, safeArg$1 as safeArg, setDefaultAsyncLocalStorage, setDefaultCwd, setDefaultEnv, setDefaultFindAndLoadConfig, setDefaultFs, setDefaultResolvePath, transpile };
|