@jxsuite/parser 0.28.2 → 0.28.3
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/dist/content.js +32 -16
- package/dist/csv.js +15 -11
- package/dist/markdown.js +516 -336
- package/dist/serialize.js +379 -254
- package/package.json +3 -3
- package/src/content.ts +41 -20
- package/src/csv.ts +18 -10
- package/src/html-to-jx.ts +23 -9
- package/src/markdown.ts +19 -10
- package/src/md.ts +57 -34
- package/src/serialize.ts +401 -246
- package/src/transpile.ts +114 -53
- package/src/types.ts +1 -3
package/src/transpile.ts
CHANGED
|
@@ -19,7 +19,8 @@ import remarkGfm from "remark-gfm";
|
|
|
19
19
|
import remarkDirective from "remark-directive";
|
|
20
20
|
import { htmlToJx } from "./html-to-jx.ts";
|
|
21
21
|
import type { MdastNode } from "./types.ts";
|
|
22
|
-
import type { JxDocument, JxElement } from "@jxsuite/schema/types";
|
|
22
|
+
import type { JsonValue, JxAttributeValue, JxDocument, JxElement } from "@jxsuite/schema/types";
|
|
23
|
+
|
|
23
24
|
export { htmlToJx };
|
|
24
25
|
|
|
25
26
|
// ─── Dot-path expansion ─────────────────────────────────────────────────────
|
|
@@ -43,8 +44,12 @@ const JX_ANNOTATION_KEYS = new Set(["title", "description"]);
|
|
|
43
44
|
* @returns {string}
|
|
44
45
|
*/
|
|
45
46
|
export function jxKey(key: string) {
|
|
46
|
-
if (JX_DOLLAR_KEYS.has(key))
|
|
47
|
-
|
|
47
|
+
if (JX_DOLLAR_KEYS.has(key)) {
|
|
48
|
+
return `$${key}`;
|
|
49
|
+
}
|
|
50
|
+
if (key.startsWith("--") && JX_ANNOTATION_KEYS.has(key.slice(2))) {
|
|
51
|
+
return `$${key.slice(2)}`;
|
|
52
|
+
}
|
|
48
53
|
return key;
|
|
49
54
|
}
|
|
50
55
|
|
|
@@ -89,7 +94,7 @@ export function expandDotPaths(attrs: Record<string, string>) {
|
|
|
89
94
|
}
|
|
90
95
|
target = target[seg] as Record<string, unknown>;
|
|
91
96
|
}
|
|
92
|
-
target[jxKey(segments
|
|
97
|
+
target[jxKey(segments.at(-1) as string)] = value;
|
|
93
98
|
}
|
|
94
99
|
|
|
95
100
|
return result;
|
|
@@ -214,7 +219,9 @@ export function collapseStylePaths(styleObj: Record<string, unknown>) {
|
|
|
214
219
|
*/
|
|
215
220
|
export function isJxMarkdown(source: string) {
|
|
216
221
|
const fmMatch = source.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
217
|
-
if (!fmMatch)
|
|
222
|
+
if (!fmMatch) {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
218
225
|
return /^tagName:\s*.+-.+/m.test(fmMatch[1]);
|
|
219
226
|
}
|
|
220
227
|
|
|
@@ -290,7 +297,7 @@ function routeAttributes(attrs: Record<string, string>) {
|
|
|
290
297
|
}
|
|
291
298
|
}
|
|
292
299
|
|
|
293
|
-
return {
|
|
300
|
+
return { attributes, props };
|
|
294
301
|
}
|
|
295
302
|
|
|
296
303
|
/**
|
|
@@ -299,23 +306,23 @@ function routeAttributes(attrs: Record<string, string>) {
|
|
|
299
306
|
* @type {Record<string, (n: MdastNode) => string>}
|
|
300
307
|
*/
|
|
301
308
|
const JX_TAG_MAP: Record<string, (n: MdastNode) => string> = {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
strong: () => "strong",
|
|
309
|
+
blockquote: () => "blockquote",
|
|
310
|
+
break: () => "br",
|
|
311
|
+
code: () => "pre",
|
|
306
312
|
delete: () => "del",
|
|
313
|
+
emphasis: () => "em",
|
|
314
|
+
heading: (n: MdastNode) => `h${n.depth}`,
|
|
315
|
+
image: () => "img",
|
|
307
316
|
inlineCode: () => "code",
|
|
308
317
|
link: () => "a",
|
|
309
|
-
image: () => "img",
|
|
310
|
-
blockquote: () => "blockquote",
|
|
311
318
|
list: (n: MdastNode) => (n.ordered ? "ol" : "ul"),
|
|
312
319
|
listItem: () => "li",
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
break: () => "br",
|
|
320
|
+
paragraph: () => "p",
|
|
321
|
+
strong: () => "strong",
|
|
316
322
|
table: () => "table",
|
|
317
|
-
tableRow: () => "tr",
|
|
318
323
|
tableCell: (n: MdastNode) => (n.isHeader ? "th" : "td"),
|
|
324
|
+
tableRow: () => "tr",
|
|
325
|
+
thematicBreak: () => "hr",
|
|
319
326
|
};
|
|
320
327
|
|
|
321
328
|
/**
|
|
@@ -325,9 +332,13 @@ const JX_TAG_MAP: Record<string, (n: MdastNode) => string> = {
|
|
|
325
332
|
* @returns {JxElement | string | (JxElement | string)[] | null} Jx element or null
|
|
326
333
|
*/
|
|
327
334
|
export function mdastNodeToJx(node: MdastNode) {
|
|
328
|
-
if (!node || typeof node !== "object")
|
|
335
|
+
if (!node || typeof node !== "object") {
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
329
338
|
|
|
330
|
-
if (node.type === "yaml" || node.type === "toml")
|
|
339
|
+
if (node.type === "yaml" || node.type === "toml") {
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
331
342
|
|
|
332
343
|
if (
|
|
333
344
|
node.type === "containerDirective" ||
|
|
@@ -342,12 +353,16 @@ export function mdastNodeToJx(node: MdastNode) {
|
|
|
342
353
|
}
|
|
343
354
|
|
|
344
355
|
if (node.type === "html") {
|
|
345
|
-
if (node.value)
|
|
356
|
+
if (node.value) {
|
|
357
|
+
return htmlToJx(node.value);
|
|
358
|
+
}
|
|
346
359
|
return null;
|
|
347
360
|
}
|
|
348
361
|
|
|
349
362
|
const tagFn = JX_TAG_MAP[node.type];
|
|
350
|
-
if (!tagFn)
|
|
363
|
+
if (!tagFn) {
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
351
366
|
|
|
352
367
|
const tag = tagFn(node);
|
|
353
368
|
const el: JxElement = { tagName: tag };
|
|
@@ -364,36 +379,52 @@ export function mdastNodeToJx(node: MdastNode) {
|
|
|
364
379
|
case "tableCell": {
|
|
365
380
|
const children = convertChildren(node.children ?? []);
|
|
366
381
|
if (children.length === 1 && typeof children[0] === "string") {
|
|
367
|
-
el.textContent = children
|
|
382
|
+
[el.textContent] = children;
|
|
368
383
|
} else if (children.length > 0) {
|
|
369
384
|
el.children = children;
|
|
370
385
|
}
|
|
371
386
|
break;
|
|
372
387
|
}
|
|
373
388
|
|
|
374
|
-
case "inlineCode":
|
|
389
|
+
case "inlineCode": {
|
|
375
390
|
el.textContent = node.value ?? null;
|
|
376
391
|
break;
|
|
392
|
+
}
|
|
377
393
|
|
|
378
|
-
case "link":
|
|
379
|
-
|
|
380
|
-
|
|
394
|
+
case "link": {
|
|
395
|
+
{
|
|
396
|
+
const linkAttrs: Record<string, JxAttributeValue> = {
|
|
397
|
+
href: node.url ?? "",
|
|
398
|
+
};
|
|
399
|
+
if (node.title) {
|
|
400
|
+
linkAttrs.title = node.title;
|
|
401
|
+
}
|
|
402
|
+
el.attributes = linkAttrs;
|
|
403
|
+
}
|
|
381
404
|
{
|
|
382
405
|
const children = convertChildren(node.children ?? []);
|
|
383
406
|
if (children.length === 1 && typeof children[0] === "string") {
|
|
384
|
-
el.textContent = children
|
|
407
|
+
[el.textContent] = children;
|
|
385
408
|
} else if (children.length > 0) {
|
|
386
409
|
el.children = children;
|
|
387
410
|
}
|
|
388
411
|
}
|
|
389
412
|
break;
|
|
413
|
+
}
|
|
390
414
|
|
|
391
|
-
case "image":
|
|
392
|
-
|
|
393
|
-
|
|
415
|
+
case "image": {
|
|
416
|
+
const imageAttrs: Record<string, JxAttributeValue> = {
|
|
417
|
+
alt: node.alt ?? "",
|
|
418
|
+
src: node.url ?? "",
|
|
419
|
+
};
|
|
420
|
+
if (node.title) {
|
|
421
|
+
imageAttrs.title = node.title;
|
|
422
|
+
}
|
|
423
|
+
el.attributes = imageAttrs;
|
|
394
424
|
break;
|
|
425
|
+
}
|
|
395
426
|
|
|
396
|
-
case "list":
|
|
427
|
+
case "list": {
|
|
397
428
|
if (node.children && node.children.length > 0) {
|
|
398
429
|
el.children = convertChildren(node.children);
|
|
399
430
|
}
|
|
@@ -401,8 +432,9 @@ export function mdastNodeToJx(node: MdastNode) {
|
|
|
401
432
|
el.attributes = { start: String(node.start) };
|
|
402
433
|
}
|
|
403
434
|
break;
|
|
435
|
+
}
|
|
404
436
|
|
|
405
|
-
case "code":
|
|
437
|
+
case "code": {
|
|
406
438
|
el.children = [
|
|
407
439
|
{
|
|
408
440
|
tagName: "code",
|
|
@@ -411,18 +443,23 @@ export function mdastNodeToJx(node: MdastNode) {
|
|
|
411
443
|
},
|
|
412
444
|
];
|
|
413
445
|
break;
|
|
446
|
+
}
|
|
414
447
|
|
|
415
448
|
case "thematicBreak":
|
|
416
|
-
case "break":
|
|
449
|
+
case "break": {
|
|
417
450
|
break;
|
|
451
|
+
}
|
|
418
452
|
|
|
419
453
|
case "table": {
|
|
420
454
|
const rows = convertChildren(node.children ?? []);
|
|
421
|
-
const thead = rows.length > 0 ? {
|
|
422
|
-
const tbody = rows.length > 1 ? {
|
|
455
|
+
const thead = rows.length > 0 ? { children: [rows[0]], tagName: "thead" } : null;
|
|
456
|
+
const tbody = rows.length > 1 ? { children: rows.slice(1), tagName: "tbody" } : null;
|
|
423
457
|
el.children = [thead, tbody].filter(Boolean) as JxElement[];
|
|
424
458
|
break;
|
|
425
459
|
}
|
|
460
|
+
default: {
|
|
461
|
+
break;
|
|
462
|
+
}
|
|
426
463
|
}
|
|
427
464
|
|
|
428
465
|
return el;
|
|
@@ -455,10 +492,12 @@ function directiveToJx(node: MdastNode) {
|
|
|
455
492
|
) {
|
|
456
493
|
el[key] = value;
|
|
457
494
|
} else if (key === "props") {
|
|
458
|
-
el.$props = value as Record<string,
|
|
495
|
+
el.$props = value as Record<string, JsonValue>;
|
|
459
496
|
} else {
|
|
460
|
-
if (!el.attributes)
|
|
461
|
-
|
|
497
|
+
if (!el.attributes) {
|
|
498
|
+
el.attributes = {};
|
|
499
|
+
}
|
|
500
|
+
el.attributes[key] = value as JxAttributeValue;
|
|
462
501
|
}
|
|
463
502
|
}
|
|
464
503
|
} else {
|
|
@@ -483,8 +522,10 @@ function directiveToJx(node: MdastNode) {
|
|
|
483
522
|
) {
|
|
484
523
|
el[key] = value;
|
|
485
524
|
} else {
|
|
486
|
-
if (!el.attributes)
|
|
487
|
-
|
|
525
|
+
if (!el.attributes) {
|
|
526
|
+
el.attributes = {};
|
|
527
|
+
}
|
|
528
|
+
el.attributes[key] = value as JxAttributeValue;
|
|
488
529
|
}
|
|
489
530
|
}
|
|
490
531
|
}
|
|
@@ -497,7 +538,7 @@ function directiveToJx(node: MdastNode) {
|
|
|
497
538
|
if (node.children && node.children.length > 0) {
|
|
498
539
|
const children = convertChildren(node.children ?? []);
|
|
499
540
|
if (children.length === 1 && typeof children[0] === "string") {
|
|
500
|
-
el.textContent = children
|
|
541
|
+
[el.textContent] = children;
|
|
501
542
|
} else if (children.length > 0) {
|
|
502
543
|
el.children = children;
|
|
503
544
|
}
|
|
@@ -518,24 +559,34 @@ function directiveToJx(node: MdastNode) {
|
|
|
518
559
|
// Unwrap: promote paragraph's inline children directly
|
|
519
560
|
for (const inline of child.children ?? []) {
|
|
520
561
|
const converted = mdastNodeToJx(inline);
|
|
521
|
-
if (converted == null)
|
|
522
|
-
|
|
523
|
-
|
|
562
|
+
if (converted == null) {
|
|
563
|
+
continue;
|
|
564
|
+
}
|
|
565
|
+
if (Array.isArray(converted)) {
|
|
566
|
+
jxChildren.push(...converted);
|
|
567
|
+
} else {
|
|
568
|
+
jxChildren.push(converted);
|
|
569
|
+
}
|
|
524
570
|
}
|
|
525
571
|
} else {
|
|
526
572
|
const converted = mdastNodeToJx(child);
|
|
527
|
-
if (converted == null)
|
|
528
|
-
|
|
529
|
-
|
|
573
|
+
if (converted == null) {
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
if (Array.isArray(converted)) {
|
|
577
|
+
jxChildren.push(...converted);
|
|
578
|
+
} else {
|
|
579
|
+
jxChildren.push(converted);
|
|
580
|
+
}
|
|
530
581
|
}
|
|
531
582
|
}
|
|
532
583
|
|
|
533
584
|
// Don't overwrite children if already set as an object by dot-path attributes
|
|
534
585
|
// (e.g. children.prototype="Array" children.items.ref="...")
|
|
535
586
|
if (el.children && typeof el.children === "object" && !Array.isArray(el.children)) {
|
|
536
|
-
//
|
|
587
|
+
// Children was set to a descriptor object by dot-path expansion — keep it
|
|
537
588
|
} else if (jxChildren.length === 1 && typeof jxChildren[0] === "string") {
|
|
538
|
-
el.textContent = jxChildren
|
|
589
|
+
[el.textContent] = jxChildren;
|
|
539
590
|
} else if (jxChildren.length > 0) {
|
|
540
591
|
el.children = jxChildren;
|
|
541
592
|
}
|
|
@@ -551,8 +602,13 @@ function directiveToJx(node: MdastNode) {
|
|
|
551
602
|
* @returns {(JxElement | string)[]}
|
|
552
603
|
*/
|
|
553
604
|
export function convertChildren(children: MdastNode[]) {
|
|
554
|
-
if (!children)
|
|
555
|
-
|
|
605
|
+
if (!children) {
|
|
606
|
+
return [];
|
|
607
|
+
}
|
|
608
|
+
return children.flatMap((n) => mdastNodeToJx(n)).filter((c) => c != null) as (
|
|
609
|
+
| JxElement
|
|
610
|
+
| string
|
|
611
|
+
)[];
|
|
556
612
|
}
|
|
557
613
|
|
|
558
614
|
/**
|
|
@@ -592,9 +648,14 @@ export function transpileJxMarkdown(source: string) {
|
|
|
592
648
|
|
|
593
649
|
for (const node of bodyNodes) {
|
|
594
650
|
const converted = mdastNodeToJx(node);
|
|
595
|
-
if (converted == null)
|
|
596
|
-
|
|
597
|
-
|
|
651
|
+
if (converted == null) {
|
|
652
|
+
continue;
|
|
653
|
+
}
|
|
654
|
+
if (Array.isArray(converted)) {
|
|
655
|
+
children.push(...converted);
|
|
656
|
+
} else {
|
|
657
|
+
children.push(converted);
|
|
658
|
+
}
|
|
598
659
|
}
|
|
599
660
|
|
|
600
661
|
if (children.length > 0) {
|
package/src/types.ts
CHANGED
|
@@ -18,9 +18,7 @@ export interface TocEntry {
|
|
|
18
18
|
id: string;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
export
|
|
22
|
-
[key: string]: unknown;
|
|
23
|
-
}
|
|
21
|
+
export type ContentEntry = MarkdownFileResult & Record<string, unknown>;
|
|
24
22
|
|
|
25
23
|
export interface ContentLoaderEntry {
|
|
26
24
|
id: string;
|