sommark 4.5.3 → 5.0.1
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 +315 -179
- package/cli/cli.mjs +1 -1
- package/cli/commands/color.js +36 -14
- package/cli/commands/help.js +3 -0
- package/cli/commands/init.js +1 -3
- package/cli/constants.js +5 -2
- package/constants/html_props.js +0 -5
- package/core/errors.js +5 -4
- package/core/evaluator.js +1 -2
- package/core/formats.js +7 -1
- package/core/helpers/config-loader.js +2 -4
- package/core/helpers/lib.js +1 -1
- package/core/labels.js +2 -15
- package/core/lexer.js +197 -313
- package/core/modules.js +13 -13
- package/core/parser.js +226 -535
- package/core/tokenTypes.js +6 -15
- package/core/transpiler.js +129 -110
- package/core/validator.js +6 -26
- package/dist/sommark.browser.js +1781 -2172
- package/dist/sommark.browser.lite.js +1779 -2169
- package/dist/sommark.lexer.js +392 -544
- package/dist/sommark.parser.js +604 -1200
- package/formatter/mark.js +34 -0
- package/formatter/tag.js +7 -33
- package/helpers/utils.js +15 -16
- package/index.js +9 -1
- package/index.shared.js +26 -16
- package/mappers/languages/csv.js +62 -0
- package/mappers/languages/html.js +12 -66
- package/mappers/languages/json.js +74 -156
- package/mappers/languages/jsonc.js +21 -63
- package/mappers/languages/markdown.js +159 -276
- package/mappers/languages/mdx.js +7 -62
- package/mappers/languages/text.js +2 -19
- package/mappers/languages/toml.js +231 -0
- package/mappers/languages/xml.js +25 -25
- package/mappers/languages/yaml.js +323 -0
- package/mappers/mapper.js +1 -22
- package/mappers/shared/index.js +3 -16
- package/package.json +5 -2
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import Mapper from "../mapper.js";
|
|
2
|
+
import { safeArg } from "../../helpers/utils.js";
|
|
3
|
+
import { registerSharedOutputs } from "../shared/index.js";
|
|
4
|
+
import { transpilerError } from "../../core/errors.js";
|
|
5
|
+
|
|
6
|
+
const isValidInt = (v) => v !== "" && !isNaN(Number(v)) && !v.includes(".");
|
|
7
|
+
const isValidFloat = (v) => v !== "" && !isNaN(Number(v)) && v.includes(".");
|
|
8
|
+
const isValidNumber = (v) => v !== "" && !isNaN(Number(v));
|
|
9
|
+
|
|
10
|
+
const ITEM_SEP = "\x1F";
|
|
11
|
+
|
|
12
|
+
const getIndent = (depth) => " ".repeat(depth);
|
|
13
|
+
|
|
14
|
+
// Escape a string value for use inside YAML double-quoted scalars
|
|
15
|
+
const yamlEscape = (str) =>
|
|
16
|
+
String(str ?? "")
|
|
17
|
+
.replace(/\\/g, "\\\\")
|
|
18
|
+
.replace(/"/g, '\\"')
|
|
19
|
+
.replace(/\n/g, "\\n")
|
|
20
|
+
.replace(/\r/g, "\\r")
|
|
21
|
+
.replace(/\t/g, "\\t");
|
|
22
|
+
|
|
23
|
+
// Always double-quote string values — [str] is explicitly typed, no ambiguity needed
|
|
24
|
+
const yamlStr = (val) => `"${yamlEscape(val)}"`;
|
|
25
|
+
|
|
26
|
+
// Bare keys: [A-Za-z0-9_-] are safe without quoting
|
|
27
|
+
const yamlKey = (key) => {
|
|
28
|
+
const s = String(key ?? "");
|
|
29
|
+
return /^[A-Za-z0-9_\-]+$/.test(s) ? s : `"${yamlEscape(s)}"`;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const YAML = Mapper.define({
|
|
33
|
+
comment(text) {
|
|
34
|
+
return `# ${text}`;
|
|
35
|
+
},
|
|
36
|
+
text(text) {
|
|
37
|
+
return text.trim() === "" ? "" : text;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* [str] / [string] — string scalar
|
|
43
|
+
*
|
|
44
|
+
* Key-value: [str = "name", "SomMark" !] → name: "SomMark"
|
|
45
|
+
* Body form: [str = "desc"]Long text[end] → desc: "Long text"
|
|
46
|
+
* In sequence: [str = "rust" !] → - "rust"
|
|
47
|
+
* In map-item: [str = "host", "localhost" !] → host: "localhost" (no indent, feeds [map-item])
|
|
48
|
+
*/
|
|
49
|
+
YAML.register(["str", "string"], ({ props, textContent, depth = 0, inSeq = false, inMapItem = false }) => {
|
|
50
|
+
if (inSeq) {
|
|
51
|
+
const val = safeArg({ props, index: 0, key: "value", fallBack: textContent.trim() });
|
|
52
|
+
return `${getIndent(depth)}- ${yamlStr(val)}\n`;
|
|
53
|
+
}
|
|
54
|
+
const key = safeArg({ props, index: 0, key: "key", fallBack: "" });
|
|
55
|
+
const val = safeArg({ props, index: 1, key: "value", fallBack: textContent.trim() });
|
|
56
|
+
if (inMapItem) return `${yamlKey(key)}: ${yamlStr(val)}${ITEM_SEP}`;
|
|
57
|
+
return `${getIndent(depth)}${yamlKey(key)}: ${yamlStr(val)}\n`;
|
|
58
|
+
}, { handleAst: true });
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* [int] / [integer] — integer scalar
|
|
62
|
+
*
|
|
63
|
+
* Key-value: [int = "port", "5432" !] → port: 5432
|
|
64
|
+
* In sequence: [int = "8001" !] → - 8001
|
|
65
|
+
*/
|
|
66
|
+
YAML.register(["int", "integer"], ({ props, textContent, depth = 0, inSeq = false, inMapItem = false }) => {
|
|
67
|
+
const val = String(safeArg({ props, index: inSeq ? 0 : 1, key: "value", fallBack: textContent.trim() })).trim();
|
|
68
|
+
if (!isValidInt(val))
|
|
69
|
+
transpilerError(`<$yellow:[int]$> expects a whole number but got <$yellow:'${val}'$>.{N}Use <$cyan:[float]$> for decimal numbers or <$cyan:[number]$> for either.`);
|
|
70
|
+
if (inSeq) return `${getIndent(depth)}- ${val}\n`;
|
|
71
|
+
const key = safeArg({ props, index: 0, key: "key", fallBack: "" });
|
|
72
|
+
if (inMapItem) return `${yamlKey(key)}: ${val}${ITEM_SEP}`;
|
|
73
|
+
return `${getIndent(depth)}${yamlKey(key)}: ${val}\n`;
|
|
74
|
+
}, { handleAst: true });
|
|
75
|
+
|
|
76
|
+
YAML.register("float", ({ props, textContent, depth = 0, inSeq = false, inMapItem = false }) => {
|
|
77
|
+
const val = String(safeArg({ props, index: inSeq ? 0 : 1, key: "value", fallBack: textContent.trim() })).trim();
|
|
78
|
+
if (!isValidFloat(val))
|
|
79
|
+
transpilerError(`<$yellow:[float]$> expects a decimal number but got <$yellow:'${val}'$>.{N}Use <$cyan:[int]$> for whole numbers or <$cyan:[number]$> for either.`);
|
|
80
|
+
if (inSeq) return `${getIndent(depth)}- ${val}\n`;
|
|
81
|
+
const key = safeArg({ props, index: 0, key: "key", fallBack: "" });
|
|
82
|
+
if (inMapItem) return `${yamlKey(key)}: ${val}${ITEM_SEP}`;
|
|
83
|
+
return `${getIndent(depth)}${yamlKey(key)}: ${val}\n`;
|
|
84
|
+
}, { handleAst: true });
|
|
85
|
+
|
|
86
|
+
YAML.register("number", ({ props, textContent, depth = 0, inSeq = false, inMapItem = false }) => {
|
|
87
|
+
const val = String(safeArg({ props, index: inSeq ? 0 : 1, key: "value", fallBack: textContent.trim() })).trim();
|
|
88
|
+
if (!isValidNumber(val))
|
|
89
|
+
transpilerError(`<$yellow:[number]$> expects a numeric value but got <$yellow:'${val}'$>.`);
|
|
90
|
+
if (inSeq) return `${getIndent(depth)}- ${val}\n`;
|
|
91
|
+
const key = safeArg({ props, index: 0, key: "key", fallBack: "" });
|
|
92
|
+
if (inMapItem) return `${yamlKey(key)}: ${val}${ITEM_SEP}`;
|
|
93
|
+
return `${getIndent(depth)}${yamlKey(key)}: ${val}\n`;
|
|
94
|
+
}, { handleAst: true });
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* [bool] / [boolean] — boolean scalar
|
|
98
|
+
*
|
|
99
|
+
* Key-value: [bool = "debug", "false" !] → debug: false
|
|
100
|
+
* In sequence: [bool = "true" !] → - true
|
|
101
|
+
*/
|
|
102
|
+
YAML.register(["bool", "boolean"], ({ props, textContent, depth = 0, inSeq = false, inMapItem = false }) => {
|
|
103
|
+
const raw = String(
|
|
104
|
+
inSeq
|
|
105
|
+
? safeArg({ props, index: 0, key: "value", fallBack: textContent.trim() })
|
|
106
|
+
: safeArg({ props, index: 1, key: "value", fallBack: textContent.trim() })
|
|
107
|
+
).trim().toLowerCase();
|
|
108
|
+
const val = (raw === "true" || raw === "1" || raw === "yes") ? "true" : "false";
|
|
109
|
+
if (inSeq) return `${getIndent(depth)}- ${val}\n`;
|
|
110
|
+
const key = safeArg({ props, index: 0, key: "key", fallBack: "" });
|
|
111
|
+
if (inMapItem) return `${yamlKey(key)}: ${val}${ITEM_SEP}`;
|
|
112
|
+
return `${getIndent(depth)}${yamlKey(key)}: ${val}\n`;
|
|
113
|
+
}, { handleAst: true });
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* [null] — null scalar
|
|
117
|
+
*
|
|
118
|
+
* Key-value: [null = "missing" !] → missing: null
|
|
119
|
+
* In sequence: [null !] → - null
|
|
120
|
+
*/
|
|
121
|
+
YAML.register("null", ({ props, depth = 0, inSeq = false, inMapItem = false }) => {
|
|
122
|
+
if (inSeq) return `${getIndent(depth)}- null\n`;
|
|
123
|
+
const key = safeArg({ props, index: 0, key: "key", fallBack: "" });
|
|
124
|
+
if (inMapItem) return `${yamlKey(key)}: null${ITEM_SEP}`;
|
|
125
|
+
return `${getIndent(depth)}${yamlKey(key)}: null\n`;
|
|
126
|
+
}, { handleAst: true });
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* [mapping] / [map] — block mapping (YAML object)
|
|
130
|
+
*
|
|
131
|
+
* [mapping = "database"]
|
|
132
|
+
* [str = "host", "localhost" !]
|
|
133
|
+
* [int = "port", "5432" !]
|
|
134
|
+
* [end]
|
|
135
|
+
*
|
|
136
|
+
* →
|
|
137
|
+
*
|
|
138
|
+
* database:
|
|
139
|
+
* host: "localhost"
|
|
140
|
+
* port: 5432
|
|
141
|
+
*
|
|
142
|
+
* Omit the key for a root mapping.
|
|
143
|
+
* Supports [for-each] inside — each iteration's lines are pre-indented and concatenate correctly.
|
|
144
|
+
*/
|
|
145
|
+
YAML.register(["mapping", "map"], async ({ props, ast, depth = 0, renderChild }) => {
|
|
146
|
+
const key = safeArg({ props, index: 0, key: "key", fallBack: "" });
|
|
147
|
+
const childDepth = key ? depth + 1 : depth;
|
|
148
|
+
let body = "";
|
|
149
|
+
for (const child of ast.body) {
|
|
150
|
+
body += await renderChild(child, { depth: childDepth });
|
|
151
|
+
}
|
|
152
|
+
if (!key) return body;
|
|
153
|
+
return `${getIndent(depth)}${yamlKey(key)}:\n${body}`;
|
|
154
|
+
}, { handleAst: true });
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* [seq] / [sequence] / [list] — block sequence (YAML array of scalars)
|
|
158
|
+
*
|
|
159
|
+
* Scalar items use [str], [int], [bool], [float], [null].
|
|
160
|
+
* Mapping items use [map-item].
|
|
161
|
+
*
|
|
162
|
+
* [seq = "tags"]
|
|
163
|
+
* [str = "rust" !]
|
|
164
|
+
* [str = "cli" !]
|
|
165
|
+
* [end]
|
|
166
|
+
*
|
|
167
|
+
* →
|
|
168
|
+
*
|
|
169
|
+
* tags:
|
|
170
|
+
* - "rust"
|
|
171
|
+
* - "cli"
|
|
172
|
+
*
|
|
173
|
+
* Supports [for-each] inside naturally.
|
|
174
|
+
*/
|
|
175
|
+
YAML.register(["seq", "sequence", "list"], async ({ props, ast, depth = 0, renderChild }) => {
|
|
176
|
+
const key = safeArg({ props, index: 0, key: "key", fallBack: "" });
|
|
177
|
+
let body = "";
|
|
178
|
+
for (const child of ast.body) {
|
|
179
|
+
body += await renderChild(child, { depth: depth + 1, inSeq: true });
|
|
180
|
+
}
|
|
181
|
+
if (!key) return body;
|
|
182
|
+
return `${getIndent(depth)}${yamlKey(key)}:\n${body}`;
|
|
183
|
+
}, { handleAst: true });
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* [map-item] — mapping as a sequence item (used inside [seq])
|
|
187
|
+
*
|
|
188
|
+
* Each child scalar renders a bare "key: value" pair (no indent).
|
|
189
|
+
* [map-item] assembles them with the correct "- " prefix on the first pair
|
|
190
|
+
* and aligned indentation for the rest.
|
|
191
|
+
*
|
|
192
|
+
* [seq = "servers"]
|
|
193
|
+
* [map-item]
|
|
194
|
+
* [str = "host", "10.0.0.1" !]
|
|
195
|
+
* [int = "port", "8001" !]
|
|
196
|
+
* [end]
|
|
197
|
+
* [end]
|
|
198
|
+
*
|
|
199
|
+
* →
|
|
200
|
+
*
|
|
201
|
+
* servers:
|
|
202
|
+
* - host: "10.0.0.1"
|
|
203
|
+
* port: 8001
|
|
204
|
+
*/
|
|
205
|
+
YAML.register("map-item", async ({ props, ast, depth = 0, renderChild }) => {
|
|
206
|
+
let combined = "";
|
|
207
|
+
for (const child of ast.body) {
|
|
208
|
+
combined += await renderChild(child, { depth: 0, inMapItem: true });
|
|
209
|
+
}
|
|
210
|
+
const pairs = combined.split(ITEM_SEP).map(v => v.trim()).filter(v => v !== "");
|
|
211
|
+
if (pairs.length === 0) return "";
|
|
212
|
+
const seqIndent = getIndent(depth);
|
|
213
|
+
const bodyIndent = getIndent(depth) + " ";
|
|
214
|
+
const [first, ...rest] = pairs;
|
|
215
|
+
const restLines = rest.length > 0 ? `\n${rest.map(p => `${bodyIndent}${p}`).join("\n")}` : "";
|
|
216
|
+
return `${seqIndent}- ${first}${restLines}\n`;
|
|
217
|
+
}, { handleAst: true });
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* [literal] / [lit] — literal block scalar (|)
|
|
221
|
+
* Preserves newlines exactly as written.
|
|
222
|
+
*
|
|
223
|
+
* [literal = "script"]
|
|
224
|
+
* echo "hello"
|
|
225
|
+
* echo "world"
|
|
226
|
+
* [end]
|
|
227
|
+
*
|
|
228
|
+
* →
|
|
229
|
+
*
|
|
230
|
+
* script: |
|
|
231
|
+
* echo "hello"
|
|
232
|
+
* echo "world"
|
|
233
|
+
*/
|
|
234
|
+
YAML.register(["literal", "lit"], ({ props, textContent, depth = 0, inMapItem = false }) => {
|
|
235
|
+
const key = safeArg({ props, index: 0, key: "key", fallBack: "" });
|
|
236
|
+
const childIndent = getIndent(depth + 1);
|
|
237
|
+
const lines = textContent
|
|
238
|
+
.split("\n")
|
|
239
|
+
.map(l => l.trim())
|
|
240
|
+
.filter((l, i, a) => !(i === 0 && l === "") && !(i === a.length - 1 && l === ""))
|
|
241
|
+
.map(l => l === "" ? "" : `${childIndent}${l}`)
|
|
242
|
+
.join("\n");
|
|
243
|
+
if (inMapItem) return `${yamlKey(key)}: |\n${lines}\n${ITEM_SEP}`;
|
|
244
|
+
return `${getIndent(depth)}${yamlKey(key)}: |\n${lines}\n`;
|
|
245
|
+
}, { handleAst: true });
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* [folded] / [fold] — folded block scalar (>)
|
|
249
|
+
* Newlines become spaces; blank lines become paragraph breaks.
|
|
250
|
+
*
|
|
251
|
+
* [folded = "description"]
|
|
252
|
+
* This is a long
|
|
253
|
+
* description.
|
|
254
|
+
* [end]
|
|
255
|
+
*
|
|
256
|
+
* →
|
|
257
|
+
*
|
|
258
|
+
* description: >
|
|
259
|
+
* This is a long
|
|
260
|
+
* description.
|
|
261
|
+
*/
|
|
262
|
+
YAML.register(["folded", "fold"], ({ props, textContent, depth = 0, inMapItem = false }) => {
|
|
263
|
+
const key = safeArg({ props, index: 0, key: "key", fallBack: "" });
|
|
264
|
+
const childIndent = getIndent(depth + 1);
|
|
265
|
+
const lines = textContent
|
|
266
|
+
.split("\n")
|
|
267
|
+
.map(l => l.trim())
|
|
268
|
+
.filter((l, i, a) => !(i === 0 && l === "") && !(i === a.length - 1 && l === ""))
|
|
269
|
+
.map(l => l === "" ? "" : `${childIndent}${l}`)
|
|
270
|
+
.join("\n");
|
|
271
|
+
if (inMapItem) return `${yamlKey(key)}: >\n${lines}\n${ITEM_SEP}`;
|
|
272
|
+
return `${getIndent(depth)}${yamlKey(key)}: >\n${lines}\n`;
|
|
273
|
+
}, { handleAst: true });
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Unknown tag — tag name becomes the YAML key, first positional arg is the value.
|
|
277
|
+
* Type is inferred: number → raw, true/false → boolean, everything else → quoted string.
|
|
278
|
+
*
|
|
279
|
+
* [greeting = "Hello" !] → greeting: "Hello"
|
|
280
|
+
* [price = 99.99 !] → price: 99.99
|
|
281
|
+
* [active = true !] → active: true
|
|
282
|
+
* [label]My text[end] → label: "My text"
|
|
283
|
+
*/
|
|
284
|
+
YAML.getUnknownTag = function (node) {
|
|
285
|
+
const key = node.id;
|
|
286
|
+
return {
|
|
287
|
+
render({ props, textContent, depth = 0, inSeq = false, inMapItem = false }) {
|
|
288
|
+
const raw = String(
|
|
289
|
+
safeArg({ props, index: 0, key: "value", fallBack: textContent.trim() })
|
|
290
|
+
).trim();
|
|
291
|
+
|
|
292
|
+
let val;
|
|
293
|
+
if (raw === "true" || raw === "false") {
|
|
294
|
+
val = raw;
|
|
295
|
+
} else if (raw !== "" && !isNaN(Number(raw))) {
|
|
296
|
+
val = raw;
|
|
297
|
+
} else {
|
|
298
|
+
val = yamlStr(raw);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (inSeq) return `${getIndent(depth)}- ${val}\n`;
|
|
302
|
+
if (inMapItem) return `${yamlKey(key)}: ${val}${ITEM_SEP}`;
|
|
303
|
+
return `${getIndent(depth)}${yamlKey(key)}: ${val}\n`;
|
|
304
|
+
},
|
|
305
|
+
options: { handleAst: true }
|
|
306
|
+
};
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* [doc-start] — YAML document start marker (---)
|
|
311
|
+
* [doc-start !] → ---
|
|
312
|
+
*/
|
|
313
|
+
YAML.register("doc-start", () => "---\n", { rules: { is_empty_body: true } });
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* [doc-end] — YAML document end marker (...)
|
|
317
|
+
* [doc-end !] → ...
|
|
318
|
+
*/
|
|
319
|
+
YAML.register("doc-end", () => "...\n", { rules: { is_empty_body: true } });
|
|
320
|
+
|
|
321
|
+
registerSharedOutputs(YAML);
|
|
322
|
+
|
|
323
|
+
export default YAML;
|
package/mappers/mapper.js
CHANGED
|
@@ -33,10 +33,9 @@ class Mapper {
|
|
|
33
33
|
*
|
|
34
34
|
* @param {string|Array<string>} id - The name of the tag (like 'Person' or ['p', 'para']).
|
|
35
35
|
* @param {Function} renderOutput - The function that formats this tag. It receives:
|
|
36
|
-
* - `
|
|
36
|
+
* - `props`: Tag attributes.
|
|
37
37
|
* - `content`: Formatted inner content.
|
|
38
38
|
* - `textContent`: Raw inner text.
|
|
39
|
-
* - `nodeType`: Type of node (Block, Inline, etc.).
|
|
40
39
|
* - `isSelfClosing`: (Blocks only) True if marked with !.
|
|
41
40
|
* - `ast`: The full AST node.
|
|
42
41
|
* @param {Object} [options={ escape: true }] - Settings for this tag.
|
|
@@ -155,26 +154,6 @@ class Mapper {
|
|
|
155
154
|
return text;
|
|
156
155
|
}
|
|
157
156
|
|
|
158
|
-
/**
|
|
159
|
-
* Formats the content of an inline statement.
|
|
160
|
-
* @param {string} text - The raw inline content.
|
|
161
|
-
* @param {Object} options - The target output options.
|
|
162
|
-
* @returns {string} - The formatted inline string.
|
|
163
|
-
*/
|
|
164
|
-
inlineText(text, options) {
|
|
165
|
-
return text;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Formats the raw body of an At-Block.
|
|
170
|
-
* @param {string} text - The raw atblock body.
|
|
171
|
-
* @param {Object} options - The target output options.
|
|
172
|
-
* @returns {string} - The formatted atblock string.
|
|
173
|
-
*/
|
|
174
|
-
atBlockBody(text, options) {
|
|
175
|
-
return text;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
157
|
/**
|
|
179
158
|
* Formats runtime logic blocks natively.
|
|
180
159
|
* By default, this returns an empty string to discard logic for formats like JSON/MDX.
|
package/mappers/shared/index.js
CHANGED
|
@@ -1,21 +1,8 @@
|
|
|
1
|
-
import { runtimeError } from "../../core/errors.js";
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
|
-
* Registers universal utility
|
|
5
|
-
* These
|
|
6
|
-
*
|
|
2
|
+
* Registers universal utility blocks shared across all SomMark mappers.
|
|
3
|
+
* These blocks are considered "Format Agnostic."
|
|
4
|
+
*
|
|
7
5
|
* @param {Mapper} mapper - The mapper instance to register tags on.
|
|
8
6
|
*/
|
|
9
7
|
export function registerSharedOutputs(mapper) {
|
|
10
|
-
// 1. 'raw' - AtBlock that return the raw, unparsed content.
|
|
11
|
-
mapper.register("raw", ({ content, nodeType }) => {
|
|
12
|
-
if (nodeType === "Block") {
|
|
13
|
-
return String(content);
|
|
14
|
-
}
|
|
15
|
-
return content;
|
|
16
|
-
}, {
|
|
17
|
-
type: "AtBlock",
|
|
18
|
-
escape: false
|
|
19
|
-
});
|
|
20
|
-
|
|
21
8
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sommark",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "SomMark is a
|
|
3
|
+
"version": "5.0.1",
|
|
4
|
+
"description": "SomMark is a template language that compiles to multiple output formats — HTML, JSON, YAML, TOML, CSV, Markdown, XML, and more.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
7
7
|
"index.js",
|
|
@@ -74,11 +74,14 @@
|
|
|
74
74
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
75
75
|
"fast-xml-parser": "^5.5.11",
|
|
76
76
|
"isomorphic-dompurify": "^3.14.0",
|
|
77
|
+
"js-yaml": "^5.0.0",
|
|
77
78
|
"jsdom": "^29.0.2",
|
|
79
|
+
"papaparse": "^5.5.4",
|
|
78
80
|
"remark": "^15.0.1",
|
|
79
81
|
"remark-gfm": "^4.0.1",
|
|
80
82
|
"remark-parse": "^11.0.0",
|
|
81
83
|
"rollup": "^4.61.1",
|
|
84
|
+
"smol-toml": "^1.7.0",
|
|
82
85
|
"vitest": "^4.0.16"
|
|
83
86
|
},
|
|
84
87
|
"dependencies": {
|