@dogsbay/serialize-core 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/dist/capability.d.ts +142 -0
- package/dist/capability.d.ts.map +1 -0
- package/dist/capability.js +189 -0
- package/dist/capability.js.map +1 -0
- package/dist/includes.d.ts +68 -0
- package/dist/includes.d.ts.map +1 -0
- package/dist/includes.js +94 -0
- package/dist/includes.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/inline.d.ts +141 -0
- package/dist/inline.d.ts.map +1 -0
- package/dist/inline.js +183 -0
- package/dist/inline.js.map +1 -0
- package/dist/plugins.d.ts +99 -0
- package/dist/plugins.d.ts.map +1 -0
- package/dist/plugins.js +119 -0
- package/dist/plugins.js.map +1 -0
- package/dist/reads.d.ts +165 -0
- package/dist/reads.d.ts.map +1 -0
- package/dist/reads.js +268 -0
- package/dist/reads.js.map +1 -0
- package/dist/text.d.ts +55 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +191 -0
- package/dist/text.js.map +1 -0
- package/dist/unknown.d.ts +39 -0
- package/dist/unknown.d.ts.map +1 -0
- package/dist/unknown.js +34 -0
- package/dist/unknown.js.map +1 -0
- package/package.json +42 -0
package/dist/reads.d.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shape-tolerant TreeNode reads — the single place that knows WHERE a value
|
|
3
|
+
* lives on a node.
|
|
4
|
+
*
|
|
5
|
+
* Different importers produce different TreeNode shapes for the same content:
|
|
6
|
+
* text arrives as flat `node.inline` (the dogsbay-md parser) or wrapped as
|
|
7
|
+
* `node.children[{ type: "prose", inline }]` (the Starlight importer); code
|
|
8
|
+
* text as `props.code` or `node.html`; language as `props.lang` or
|
|
9
|
+
* `props.language`; a tab title as `props.title`, `props.label`, or
|
|
10
|
+
* `props.value`.
|
|
11
|
+
*
|
|
12
|
+
* Every serializer used to re-derive these independently, and every serializer
|
|
13
|
+
* that got one wrong emitted SILENTLY EMPTY output — the entire
|
|
14
|
+
* "format-obsidian serializer field-drift" bug class
|
|
15
|
+
* (plans/format-obsidian-serializer-realign.md), where six separate reads had
|
|
16
|
+
* drifted from what the parser actually emits.
|
|
17
|
+
*
|
|
18
|
+
* These functions are deliberately DATA-ONLY: they return values and nodes,
|
|
19
|
+
* never rendered text, so every format can render them its own way while
|
|
20
|
+
* agreeing on where to look. Extracted from the canonical reads in
|
|
21
|
+
* `format-astro/src/serialize.ts`; the operator asymmetries below are
|
|
22
|
+
* behavioural and deliberate — read the comments before "simplifying" them.
|
|
23
|
+
*/
|
|
24
|
+
import type { TreeNode, InlineNode } from "@dogsbay/types";
|
|
25
|
+
/**
|
|
26
|
+
* A node's inline content, handling BOTH shapes:
|
|
27
|
+
* flat `node.inline`, or a single wrapped `prose` child carrying `inline`.
|
|
28
|
+
*
|
|
29
|
+
* Mirrors `paragraphToAstro`'s dual-shape read. Note it does NOT fall back to
|
|
30
|
+
* arbitrary children — only the single-`prose`-child wrapper, matching the
|
|
31
|
+
* importer shape it exists for.
|
|
32
|
+
*/
|
|
33
|
+
export declare function leafInline(node: TreeNode): InlineNode[] | undefined;
|
|
34
|
+
/** True when the node carries inline content in either shape. */
|
|
35
|
+
export declare function hasInline(node: TreeNode): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* A node's pre-rendered HTML content, handling both the flat and the
|
|
38
|
+
* wrapped-`prose` shapes.
|
|
39
|
+
*
|
|
40
|
+
* THIRD shape, and the one that bites: several importers (MDX, Starlight,
|
|
41
|
+
* MkDocs) emit `prose` nodes carrying `html` with NO `inline` array at all.
|
|
42
|
+
* A serializer that reads only `inline`/`children` renders those nodes as
|
|
43
|
+
* EMPTY — silently dropping every paragraph and list-item body on a real
|
|
44
|
+
* page. (Found by dogfooding this very package on a real Mintlify → Docusaurus
|
|
45
|
+
* conversion: two paragraphs vanished and every bullet came out bare.)
|
|
46
|
+
*/
|
|
47
|
+
export declare function leafHtml(node: TreeNode): string | undefined;
|
|
48
|
+
/** True when the node has content in ANY of the three shapes. */
|
|
49
|
+
export declare function hasContent(node: TreeNode): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* A code node's text.
|
|
52
|
+
*
|
|
53
|
+
* Uses `??` (NOT `||`) deliberately: an explicitly empty `props.code` (`""`)
|
|
54
|
+
* is a real, intentional empty code block and must win over `node.html`.
|
|
55
|
+
* Switching this to `||` silently changes behaviour for empty code blocks.
|
|
56
|
+
*/
|
|
57
|
+
export declare function codeText(node: TreeNode): string;
|
|
58
|
+
/**
|
|
59
|
+
* A code node's language.
|
|
60
|
+
*
|
|
61
|
+
* Uses `||` (NOT `??`) deliberately: an empty-string language is meaningless
|
|
62
|
+
* and must fall through to the next candidate, then to `fallback`.
|
|
63
|
+
*/
|
|
64
|
+
export declare function codeLang(node: TreeNode, fallback?: string): string;
|
|
65
|
+
/**
|
|
66
|
+
* A tab's display title.
|
|
67
|
+
*
|
|
68
|
+
* Cascade order is `title || label || value`, then an index-based default —
|
|
69
|
+
* which is why the index must be passed rather than this being a plain
|
|
70
|
+
* property pick. (The dogsbay-md parser emits `label`; MDX importers emit
|
|
71
|
+
* `title`; reading only one of them renders every tab as the literal fallback.)
|
|
72
|
+
*/
|
|
73
|
+
export declare function tabTitle(tab: TreeNode, index?: number): string;
|
|
74
|
+
/** A tab's stable value/key, falling back to its title. */
|
|
75
|
+
export declare function tabValue(tab: TreeNode, index?: number): string;
|
|
76
|
+
/** The non-content fields of a card / link-card. */
|
|
77
|
+
export interface CardFields {
|
|
78
|
+
title: string;
|
|
79
|
+
href: string;
|
|
80
|
+
icon?: string;
|
|
81
|
+
/** Only the `props.description` fallback — NOT the node's body content. */
|
|
82
|
+
description?: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* A card's scalar fields.
|
|
86
|
+
*
|
|
87
|
+
* Body content is deliberately NOT resolved here: cards use
|
|
88
|
+
* children-before-inline precedence (the opposite of {@link leafInline}'s
|
|
89
|
+
* inline-first order) and each format escapes the `props.description`
|
|
90
|
+
* fallback differently. Resolve the body with {@link cardBodySources}.
|
|
91
|
+
*/
|
|
92
|
+
export declare function cardFields(node: TreeNode): CardFields;
|
|
93
|
+
/**
|
|
94
|
+
* The ordered candidate sources for a card's body, most-preferred first:
|
|
95
|
+
* children → inline → `props.description`.
|
|
96
|
+
*
|
|
97
|
+
* Returned as a discriminated list (rather than a rendered string) because the
|
|
98
|
+
* last source needs format-specific escaping while the first two are rendered
|
|
99
|
+
* through the format's normal paths.
|
|
100
|
+
*/
|
|
101
|
+
export declare function cardBodySources(node: TreeNode): Array<{
|
|
102
|
+
kind: "children";
|
|
103
|
+
children: TreeNode[];
|
|
104
|
+
} | {
|
|
105
|
+
kind: "inline";
|
|
106
|
+
inline: InlineNode[];
|
|
107
|
+
} | {
|
|
108
|
+
kind: "text";
|
|
109
|
+
text: string;
|
|
110
|
+
}>;
|
|
111
|
+
/** A heading's level, defaulting to 1. */
|
|
112
|
+
export declare function headingLevel(node: TreeNode): number;
|
|
113
|
+
/**
|
|
114
|
+
* THE Dogsbay heading slug rule — lowercase, drop non-word chars (keeping
|
|
115
|
+
* `_` and `-`), spaces → `-`. This is what the site build assigns as anchor
|
|
116
|
+
* ids (`format-dogsbay-md/src/headings.ts` re-exports it), what
|
|
117
|
+
* `format-dogsbay-md`'s TOC emits, and what every exporter that writes a
|
|
118
|
+
* heading link must use — one rule, so a link and its target cannot
|
|
119
|
+
* disagree. Dedupe (`-1`, `-2`) is the CALLER's job over its own heading
|
|
120
|
+
* set; an explicit `{#id}` replaces the text slug (see `headingFragment`).
|
|
121
|
+
*/
|
|
122
|
+
export declare function slugifyHeadingText(text: string): string;
|
|
123
|
+
/** The plain text of a heading across the three TreeNode shapes. */
|
|
124
|
+
export declare function headingText(node: TreeNode): string;
|
|
125
|
+
/**
|
|
126
|
+
* The fragment a link to this heading uses on a Dogsbay site: the explicit
|
|
127
|
+
* `props.slug` (backfilled by the parser's `extractHeadings`, or an author's
|
|
128
|
+
* `{#id}`), else the slug of the text.
|
|
129
|
+
*/
|
|
130
|
+
export declare function headingFragment(node: TreeNode): string;
|
|
131
|
+
/**
|
|
132
|
+
* A callout/details variant (`note`, `warning`, …), lower-cased, default
|
|
133
|
+
* `note`. Importers spell this `variant` or `type` depending on source syntax.
|
|
134
|
+
*/
|
|
135
|
+
export declare function calloutVariant(node: TreeNode, fallback?: string): string;
|
|
136
|
+
/**
|
|
137
|
+
* An explicit callout title, or undefined when the format should derive one
|
|
138
|
+
* from the variant. `null` is preserved by callers that distinguish
|
|
139
|
+
* "deliberately untitled" from "absent".
|
|
140
|
+
*/
|
|
141
|
+
export declare function calloutTitle(node: TreeNode): string | undefined;
|
|
142
|
+
/** An ordered list's start number, or undefined when it starts at 1. */
|
|
143
|
+
export declare function listStart(node: TreeNode): number | undefined;
|
|
144
|
+
/** An image/media source, tolerating `props.src` and `props.url`. */
|
|
145
|
+
export declare function mediaSrc(node: TreeNode): string;
|
|
146
|
+
/**
|
|
147
|
+
* Render a "leaf" node's content (list-item, table cell, step, dt, dd) in the
|
|
148
|
+
* canonical order: inline content first, then block children.
|
|
149
|
+
*
|
|
150
|
+
* This is the ordering `format-astro`'s `leafContent` established and the one
|
|
151
|
+
* the obsidian field-drift fix adopted. Formats supply their own renderers;
|
|
152
|
+
* only the ORDER and the empty-part filtering are shared.
|
|
153
|
+
*/
|
|
154
|
+
export declare function renderLeaf(node: TreeNode, renderers: {
|
|
155
|
+
inline: (nodes: InlineNode[]) => string;
|
|
156
|
+
children: (nodes: TreeNode[]) => string;
|
|
157
|
+
/**
|
|
158
|
+
* Render pre-rendered HTML content. Supply this or nodes carrying only
|
|
159
|
+
* `html` (the MDX/Starlight/MkDocs `prose` shape) render as EMPTY —
|
|
160
|
+
* see {@link leafHtml}.
|
|
161
|
+
*/
|
|
162
|
+
html?: (html: string) => string;
|
|
163
|
+
join?: string;
|
|
164
|
+
}): string;
|
|
165
|
+
//# sourceMappingURL=reads.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reads.d.ts","sourceRoot":"","sources":["../src/reads.ts"],"names":[],"mappings":"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"}
|
package/dist/reads.js
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A node's inline content, handling BOTH shapes:
|
|
3
|
+
* flat `node.inline`, or a single wrapped `prose` child carrying `inline`.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors `paragraphToAstro`'s dual-shape read. Note it does NOT fall back to
|
|
6
|
+
* arbitrary children — only the single-`prose`-child wrapper, matching the
|
|
7
|
+
* importer shape it exists for.
|
|
8
|
+
*/
|
|
9
|
+
export function leafInline(node) {
|
|
10
|
+
if (node.inline)
|
|
11
|
+
return node.inline;
|
|
12
|
+
if (node.children?.length === 1 &&
|
|
13
|
+
node.children[0].type === "prose" &&
|
|
14
|
+
node.children[0].inline) {
|
|
15
|
+
return node.children[0].inline;
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
/** True when the node carries inline content in either shape. */
|
|
20
|
+
export function hasInline(node) {
|
|
21
|
+
const inline = leafInline(node);
|
|
22
|
+
return Boolean(inline && inline.length > 0);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A node's pre-rendered HTML content, handling both the flat and the
|
|
26
|
+
* wrapped-`prose` shapes.
|
|
27
|
+
*
|
|
28
|
+
* THIRD shape, and the one that bites: several importers (MDX, Starlight,
|
|
29
|
+
* MkDocs) emit `prose` nodes carrying `html` with NO `inline` array at all.
|
|
30
|
+
* A serializer that reads only `inline`/`children` renders those nodes as
|
|
31
|
+
* EMPTY — silently dropping every paragraph and list-item body on a real
|
|
32
|
+
* page. (Found by dogfooding this very package on a real Mintlify → Docusaurus
|
|
33
|
+
* conversion: two paragraphs vanished and every bullet came out bare.)
|
|
34
|
+
*/
|
|
35
|
+
export function leafHtml(node) {
|
|
36
|
+
// Symmetry matters: inline wins over html in BOTH shapes. Returning
|
|
37
|
+
// `node.html` while `node.inline` also exists gave callers writing the
|
|
38
|
+
// natural `leafHtml(n) ?? render(leafInline(n))` opposite precedence on flat
|
|
39
|
+
// vs wrapped nodes.
|
|
40
|
+
if (node.inline && node.inline.length > 0)
|
|
41
|
+
return undefined;
|
|
42
|
+
if (node.html)
|
|
43
|
+
return node.html;
|
|
44
|
+
if (node.children?.length === 1 &&
|
|
45
|
+
node.children[0].type === "prose" &&
|
|
46
|
+
!node.children[0].inline &&
|
|
47
|
+
node.children[0].html) {
|
|
48
|
+
return node.children[0].html;
|
|
49
|
+
}
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
/** True when the node has content in ANY of the three shapes. */
|
|
53
|
+
export function hasContent(node) {
|
|
54
|
+
return (hasInline(node) ||
|
|
55
|
+
Boolean(leafHtml(node)) ||
|
|
56
|
+
Boolean(node.children && node.children.length > 0));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A code node's text.
|
|
60
|
+
*
|
|
61
|
+
* Uses `??` (NOT `||`) deliberately: an explicitly empty `props.code` (`""`)
|
|
62
|
+
* is a real, intentional empty code block and must win over `node.html`.
|
|
63
|
+
* Switching this to `||` silently changes behaviour for empty code blocks.
|
|
64
|
+
*/
|
|
65
|
+
export function codeText(node) {
|
|
66
|
+
return (node.props?.code ?? node.html ?? "");
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* A code node's language.
|
|
70
|
+
*
|
|
71
|
+
* Uses `||` (NOT `??`) deliberately: an empty-string language is meaningless
|
|
72
|
+
* and must fall through to the next candidate, then to `fallback`.
|
|
73
|
+
*/
|
|
74
|
+
export function codeLang(node, fallback = "") {
|
|
75
|
+
return ((node.props?.lang || node.props?.language || fallback));
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* A tab's display title.
|
|
79
|
+
*
|
|
80
|
+
* Cascade order is `title || label || value`, then an index-based default —
|
|
81
|
+
* which is why the index must be passed rather than this being a plain
|
|
82
|
+
* property pick. (The dogsbay-md parser emits `label`; MDX importers emit
|
|
83
|
+
* `title`; reading only one of them renders every tab as the literal fallback.)
|
|
84
|
+
*/
|
|
85
|
+
export function tabTitle(tab, index = 0) {
|
|
86
|
+
return (tab.props?.title ||
|
|
87
|
+
tab.props?.label ||
|
|
88
|
+
tab.props?.value ||
|
|
89
|
+
`Tab ${index + 1}`);
|
|
90
|
+
}
|
|
91
|
+
/** A tab's stable value/key, falling back to its title. */
|
|
92
|
+
export function tabValue(tab, index = 0) {
|
|
93
|
+
return tab.props?.value || tabTitle(tab, index);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* A card's scalar fields.
|
|
97
|
+
*
|
|
98
|
+
* Body content is deliberately NOT resolved here: cards use
|
|
99
|
+
* children-before-inline precedence (the opposite of {@link leafInline}'s
|
|
100
|
+
* inline-first order) and each format escapes the `props.description`
|
|
101
|
+
* fallback differently. Resolve the body with {@link cardBodySources}.
|
|
102
|
+
*/
|
|
103
|
+
export function cardFields(node) {
|
|
104
|
+
return {
|
|
105
|
+
title: node.props?.title ?? "",
|
|
106
|
+
href: node.props?.href ?? "",
|
|
107
|
+
icon: node.props?.icon,
|
|
108
|
+
description: node.props?.description,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The ordered candidate sources for a card's body, most-preferred first:
|
|
113
|
+
* children → inline → `props.description`.
|
|
114
|
+
*
|
|
115
|
+
* Returned as a discriminated list (rather than a rendered string) because the
|
|
116
|
+
* last source needs format-specific escaping while the first two are rendered
|
|
117
|
+
* through the format's normal paths.
|
|
118
|
+
*/
|
|
119
|
+
export function cardBodySources(node) {
|
|
120
|
+
const out = [];
|
|
121
|
+
if (node.children && node.children.length > 0) {
|
|
122
|
+
out.push({ kind: "children", children: node.children });
|
|
123
|
+
}
|
|
124
|
+
if (node.inline && node.inline.length > 0) {
|
|
125
|
+
out.push({ kind: "inline", inline: node.inline });
|
|
126
|
+
}
|
|
127
|
+
const description = node.props?.description;
|
|
128
|
+
if (description)
|
|
129
|
+
out.push({ kind: "text", text: description });
|
|
130
|
+
return out;
|
|
131
|
+
}
|
|
132
|
+
/** A heading's level, defaulting to 1. */
|
|
133
|
+
export function headingLevel(node) {
|
|
134
|
+
return node.props?.level ?? 1;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* THE Dogsbay heading slug rule — lowercase, drop non-word chars (keeping
|
|
138
|
+
* `_` and `-`), spaces → `-`. This is what the site build assigns as anchor
|
|
139
|
+
* ids (`format-dogsbay-md/src/headings.ts` re-exports it), what
|
|
140
|
+
* `format-dogsbay-md`'s TOC emits, and what every exporter that writes a
|
|
141
|
+
* heading link must use — one rule, so a link and its target cannot
|
|
142
|
+
* disagree. Dedupe (`-1`, `-2`) is the CALLER's job over its own heading
|
|
143
|
+
* set; an explicit `{#id}` replaces the text slug (see `headingFragment`).
|
|
144
|
+
*/
|
|
145
|
+
export function slugifyHeadingText(text) {
|
|
146
|
+
return text
|
|
147
|
+
.toLowerCase()
|
|
148
|
+
.replace(/[^\w\s-]/g, "")
|
|
149
|
+
.trim()
|
|
150
|
+
.replace(/\s+/g, "-");
|
|
151
|
+
}
|
|
152
|
+
/** The plain text of a heading across the three TreeNode shapes. */
|
|
153
|
+
export function headingText(node) {
|
|
154
|
+
const fromInline = (nodes) => {
|
|
155
|
+
let out = "";
|
|
156
|
+
for (const n of nodes) {
|
|
157
|
+
if (!n || typeof n !== "object")
|
|
158
|
+
continue;
|
|
159
|
+
const x = n;
|
|
160
|
+
if (typeof x.text === "string")
|
|
161
|
+
out += x.text;
|
|
162
|
+
else if (typeof x.alt === "string")
|
|
163
|
+
out += x.alt;
|
|
164
|
+
if (Array.isArray(x.children))
|
|
165
|
+
out += fromInline(x.children);
|
|
166
|
+
}
|
|
167
|
+
return out;
|
|
168
|
+
};
|
|
169
|
+
if (Array.isArray(node.inline) && node.inline.length)
|
|
170
|
+
return fromInline(node.inline);
|
|
171
|
+
if (typeof node.props?.text === "string" && node.props.text)
|
|
172
|
+
return node.props.text;
|
|
173
|
+
// the wrapped shape: children:[{type:"prose", inline}] (fluidtopics/html importers)
|
|
174
|
+
if (Array.isArray(node.children) && node.children.length) {
|
|
175
|
+
const inner = node.children.map((c) => headingText(c)).join("");
|
|
176
|
+
if (inner)
|
|
177
|
+
return inner;
|
|
178
|
+
}
|
|
179
|
+
if (typeof node.html === "string")
|
|
180
|
+
return node.html.replace(/<[^>]+>/g, "");
|
|
181
|
+
return "";
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* The fragment a link to this heading uses on a Dogsbay site: the explicit
|
|
185
|
+
* `props.slug` (backfilled by the parser's `extractHeadings`, or an author's
|
|
186
|
+
* `{#id}`), else the slug of the text.
|
|
187
|
+
*/
|
|
188
|
+
export function headingFragment(node) {
|
|
189
|
+
const explicit = node.props?.slug;
|
|
190
|
+
if (typeof explicit === "string" && explicit)
|
|
191
|
+
return explicit;
|
|
192
|
+
return slugifyHeadingText(headingText(node));
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* A callout/details variant (`note`, `warning`, …), lower-cased, default
|
|
196
|
+
* `note`. Importers spell this `variant` or `type` depending on source syntax.
|
|
197
|
+
*/
|
|
198
|
+
export function calloutVariant(node, fallback = "note") {
|
|
199
|
+
const raw = node.props?.variant || node.props?.type || fallback;
|
|
200
|
+
return raw.toLowerCase();
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* An explicit callout title, or undefined when the format should derive one
|
|
204
|
+
* from the variant. `null` is preserved by callers that distinguish
|
|
205
|
+
* "deliberately untitled" from "absent".
|
|
206
|
+
*/
|
|
207
|
+
export function calloutTitle(node) {
|
|
208
|
+
const title = node.props?.title;
|
|
209
|
+
// An explicit `title=""` is the author suppressing the auto-title. Mapping it
|
|
210
|
+
// to undefined means "derive one from the variant" and the exporter puts the
|
|
211
|
+
// title back — so the empty string is preserved and only absence is undefined.
|
|
212
|
+
return typeof title === "string" ? title : undefined;
|
|
213
|
+
}
|
|
214
|
+
/** An ordered list's start number, or undefined when it starts at 1. */
|
|
215
|
+
export function listStart(node) {
|
|
216
|
+
const raw = node.props?.start;
|
|
217
|
+
if (raw == null)
|
|
218
|
+
return undefined;
|
|
219
|
+
const n = typeof raw === "number" ? raw : parseInt(String(raw), 10);
|
|
220
|
+
return Number.isNaN(n) ? undefined : n;
|
|
221
|
+
}
|
|
222
|
+
/** An image/media source, tolerating `props.src` and `props.url`. */
|
|
223
|
+
export function mediaSrc(node) {
|
|
224
|
+
return (node.props?.src || node.props?.url || "");
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Render a "leaf" node's content (list-item, table cell, step, dt, dd) in the
|
|
228
|
+
* canonical order: inline content first, then block children.
|
|
229
|
+
*
|
|
230
|
+
* This is the ordering `format-astro`'s `leafContent` established and the one
|
|
231
|
+
* the obsidian field-drift fix adopted. Formats supply their own renderers;
|
|
232
|
+
* only the ORDER and the empty-part filtering are shared.
|
|
233
|
+
*/
|
|
234
|
+
export function renderLeaf(node, renderers) {
|
|
235
|
+
const parts = [];
|
|
236
|
+
// Go through the TOLERANT reads, not the raw fields. Reading `node.inline` /
|
|
237
|
+
// `node.html` directly meant the wrapped `children:[{prose, html}]` shape
|
|
238
|
+
// never reached the html renderer and rendered EMPTY — the exact field-drift
|
|
239
|
+
// failure this package exists to prevent.
|
|
240
|
+
const inline = leafInline(node);
|
|
241
|
+
const html = leafHtml(node);
|
|
242
|
+
// Provenance is established by IDENTITY against the wrapper child, not by
|
|
243
|
+
// re-deriving it from `node.inline === undefined`. That inference was wrong
|
|
244
|
+
// for a falsy-but-present field: `{ html: "", children:[{prose, html:"H"}] }`
|
|
245
|
+
// read the wrapper, concluded the value was flat, and then descended into
|
|
246
|
+
// children — emitting the same paragraph twice.
|
|
247
|
+
const wrapper = node.children?.length === 1 && node.children[0].type === "prose"
|
|
248
|
+
? node.children[0]
|
|
249
|
+
: undefined;
|
|
250
|
+
let consumedWrapper = false;
|
|
251
|
+
if (inline && inline.length > 0) {
|
|
252
|
+
parts.push(renderers.inline(inline));
|
|
253
|
+
consumedWrapper = wrapper !== undefined && inline === wrapper.inline;
|
|
254
|
+
}
|
|
255
|
+
else if (html && renderers.html) {
|
|
256
|
+
parts.push(renderers.html(html));
|
|
257
|
+
consumedWrapper = wrapper !== undefined && html === wrapper.html;
|
|
258
|
+
}
|
|
259
|
+
// When the content came from the single wrapped `prose` child, that child is
|
|
260
|
+
// already rendered — descending into children would duplicate it.
|
|
261
|
+
if (!consumedWrapper && node.children && node.children.length > 0) {
|
|
262
|
+
const rendered = renderers.children(node.children);
|
|
263
|
+
if (rendered)
|
|
264
|
+
parts.push(rendered);
|
|
265
|
+
}
|
|
266
|
+
return parts.filter(Boolean).join(renderers.join ?? "\n");
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=reads.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reads.js","sourceRoot":"","sources":["../src/reads.ts"],"names":[],"mappings":"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"}
|
package/dist/text.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format-agnostic text utilities.
|
|
3
|
+
*
|
|
4
|
+
* These are byte-identical (or strictly stronger) versions of helpers
|
|
5
|
+
* currently duplicated across serializers: `indent` exists three times
|
|
6
|
+
* (format-dogsbay-md, format-obsidian, format-astro's `indentStr`), and
|
|
7
|
+
* format-obsidian's `chooseFence` is a weaker `pickCodeFence` (hardcoded
|
|
8
|
+
* backtick, `match` instead of `matchAll`).
|
|
9
|
+
*
|
|
10
|
+
* Only genuinely universal helpers live here. Per-dialect escaping
|
|
11
|
+
* (CommonMark text escaping, Astro brace-neutralising, dogsbay-md attribute
|
|
12
|
+
* syntax) stays in its own package — those profiles are not interchangeable.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Choose a fence long enough to wrap `content` without being terminated early.
|
|
16
|
+
*
|
|
17
|
+
* Scans for the longest run of the fence character and returns one longer,
|
|
18
|
+
* with a minimum of three.
|
|
19
|
+
*/
|
|
20
|
+
export declare function pickCodeFence(content: string, fenceChar?: "`" | "~"): string;
|
|
21
|
+
/**
|
|
22
|
+
* Choose a `:::` directive fence long enough to wrap `content`.
|
|
23
|
+
* Used by markdown dialects with container directives (Docusaurus
|
|
24
|
+
* admonitions, MyST, dogsbay-md).
|
|
25
|
+
*/
|
|
26
|
+
export declare function pickDirectiveFence(content: string): string;
|
|
27
|
+
/** Indent every non-empty line by `spaces`. Empty lines stay empty. */
|
|
28
|
+
export declare function indent(content: string, spaces: number): string;
|
|
29
|
+
/** Prefix every line, using a trimmed prefix for empty lines (blockquotes). */
|
|
30
|
+
export declare function prefixLines(content: string, prefix: string): string;
|
|
31
|
+
/** Collapse 3+ blank lines to 2 and strip trailing whitespace on each line. */
|
|
32
|
+
export declare function normalizeTrailingWhitespace(content: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Strip HTML tags, keeping text content — the lossy fallback markdown targets
|
|
35
|
+
* use for HTML they cannot represent. Callers should record the degradation.
|
|
36
|
+
*/
|
|
37
|
+
export declare function stripHtml(html: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Convert common INLINE HTML back to markdown.
|
|
40
|
+
*
|
|
41
|
+
* Importers frequently hand serializers pre-rendered HTML for prose
|
|
42
|
+
* (`<code>x</code>`, `<strong>y</strong>`). Passing it through works in
|
|
43
|
+
* MDX-ish targets but produces source no human wants to maintain — and the
|
|
44
|
+
* point of a migration is clean, editable markdown.
|
|
45
|
+
*
|
|
46
|
+
* Deliberately conservative: only unambiguous inline tags, non-greedy, and
|
|
47
|
+
* block-level markup is left completely alone (a regex cannot restructure
|
|
48
|
+
* tables or lists safely). Anything not listed here survives as raw HTML.
|
|
49
|
+
*/
|
|
50
|
+
export declare function inlineHtmlToMarkdown(html: string): string;
|
|
51
|
+
/** Serialize a value as YAML frontmatter scalar, quoting when required. */
|
|
52
|
+
export declare function yamlScalar(value: string): string;
|
|
53
|
+
/** Build a YAML frontmatter block from ordered entries. Empty → "". */
|
|
54
|
+
export declare function frontmatterBlock(entries: Array<[string, string | number | boolean | undefined]>): string;
|
|
55
|
+
//# sourceMappingURL=text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../src/text.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,GAAE,GAAG,GAAG,GAAS,GAAG,MAAM,CAOjF;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED,uEAAuE;AACvE,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAM9D;AAED,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKnE;AAED,+EAA+E;AAC/E,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMnE;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkC9C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAwBzD;AAkBD,2EAA2E;AAC3E,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CA8BhD;AAED,uEAAuE;AACvE,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC,GAC9D,MAAM,CAQR"}
|