@dogsbay/serialize-core 0.2.0-beta.129 → 0.2.0-beta.130
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/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/reads.d.ts +22 -0
- package/dist/reads.js +78 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* Plus format-agnostic text helpers (`text.ts`) and an unknown-node fallback
|
|
17
17
|
* that reports instead of silently dropping (`unknown.ts`).
|
|
18
18
|
*/
|
|
19
|
-
export { leafInline, leafHtml, hasInline, hasContent, codeText, codeLang, tabTitle, tabValue, cardFields, cardBodySources, headingLevel, headingText, headingFragment, slugifyHeadingText, calloutVariant, calloutTitle, listStart, mediaSrc, renderLeaf, type CardFields, } from "./reads.js";
|
|
19
|
+
export { leafInline, leafHtml, hasInline, hasContent, codeText, codeLang, tabTitle, tabValue, cardFields, cardBodySources, headingLevel, headingText, headingFragment, slugifyHeadingText, calloutVariant, calloutTitle, stepLead, stepTitle, listStart, mediaSrc, renderLeaf, type CardFields, } from "./reads.js";
|
|
20
20
|
export { walkInline, applyTextFlags, inlinePlainText, markdownInlineEmitters, htmlInlineEmitters, escapeHtml, escapeAttr, codeSpan, type InlineContext, type InlineEmitters, type InlineWalkOptions, } from "./inline.js";
|
|
21
21
|
export { ExportLedger, formatLedgerReport, formatCapabilityTable, unsupportedFeatures, validateCapabilities, validateLedgerAgainstCapabilities, type SupportLevel, type CapabilityDeclaration, type LossAction, type ExportLedgerEntry, type LedgerSummaryRow, } from "./capability.js";
|
|
22
22
|
export { MATRIX_ROWS, formatCapabilityMatrix, missingMatrixCells, splitGroupChildren, renderAroundGroup, isDetailsSheet, type MatrixRow, type MatrixGroup, type MatrixColumn } from "./matrix.js";
|
package/dist/index.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* Plus format-agnostic text helpers (`text.ts`) and an unknown-node fallback
|
|
17
17
|
* that reports instead of silently dropping (`unknown.ts`).
|
|
18
18
|
*/
|
|
19
|
-
export { leafInline, leafHtml, hasInline, hasContent, codeText, codeLang, tabTitle, tabValue, cardFields, cardBodySources, headingLevel, headingText, headingFragment, slugifyHeadingText, calloutVariant, calloutTitle, listStart, mediaSrc, renderLeaf, } from "./reads.js";
|
|
19
|
+
export { leafInline, leafHtml, hasInline, hasContent, codeText, codeLang, tabTitle, tabValue, cardFields, cardBodySources, headingLevel, headingText, headingFragment, slugifyHeadingText, calloutVariant, calloutTitle, stepLead, stepTitle, listStart, mediaSrc, renderLeaf, } from "./reads.js";
|
|
20
20
|
export { walkInline, applyTextFlags, inlinePlainText, markdownInlineEmitters, htmlInlineEmitters, escapeHtml, escapeAttr, codeSpan, } from "./inline.js";
|
|
21
21
|
export { ExportLedger, formatLedgerReport, formatCapabilityTable, unsupportedFeatures, validateCapabilities, validateLedgerAgainstCapabilities, } from "./capability.js";
|
|
22
22
|
export { MATRIX_ROWS, formatCapabilityMatrix, missingMatrixCells, splitGroupChildren, renderAroundGroup, isDetailsSheet } from "./matrix.js";
|
package/dist/reads.d.ts
CHANGED
|
@@ -139,6 +139,28 @@ export declare function calloutVariant(node: TreeNode, fallback?: string): strin
|
|
|
139
139
|
* "deliberately untitled" from "absent".
|
|
140
140
|
*/
|
|
141
141
|
export declare function calloutTitle(node: TreeNode): string | undefined;
|
|
142
|
+
/**
|
|
143
|
+
* A step's `title` prop to draw as its lead (Mintlify/MDX `<Step title="…">`), or undefined.
|
|
144
|
+
* The dogsbay-md parser never sets it (a step's title is its own first line); an importer that
|
|
145
|
+
* also writes the title into the content (format-mdx's Steps parser adds `<strong>title</strong>`)
|
|
146
|
+
* is not drawn twice: a title the step's text already starts with is skipped.
|
|
147
|
+
*/
|
|
148
|
+
export declare function stepTitle(node: TreeNode): string | undefined;
|
|
149
|
+
/**
|
|
150
|
+
* A step's title written as its leading bold run on a line of its own, split from the detail:
|
|
151
|
+
* `1. **Stop the writer**` then `Run …` on the next line is ONE paragraph to Markdown, so every
|
|
152
|
+
* renderer drew the title and the detail on one line. The documents skill teaches that form, and
|
|
153
|
+
* it is what Mintlify's `<Step title>` imports as. The line end is what decides it: the
|
|
154
|
+
* dogsbay-md parser marks bold that ends its line (`lineEnd`), and a hard break counts too. So
|
|
155
|
+
* `1. **Click** Save.` and `**Optional:** configure X` stay one line. The bold run is bold text
|
|
156
|
+
* and links whose text is all bold. The title's nodes lose `bold` (the renderer wraps them in
|
|
157
|
+
* its title element) and `lineEnd`; the detail loses a leading break and leading space.
|
|
158
|
+
* Undefined when the step does not start with such a run, or is only the bold text.
|
|
159
|
+
*/
|
|
160
|
+
export declare function stepLead(inline: InlineNode[] | undefined): {
|
|
161
|
+
title: InlineNode[];
|
|
162
|
+
rest: InlineNode[];
|
|
163
|
+
} | undefined;
|
|
142
164
|
/** An ordered list's start number, or undefined when it starts at 1. */
|
|
143
165
|
export declare function listStart(node: TreeNode): number | undefined;
|
|
144
166
|
/** An image/media source, tolerating `props.src` and `props.url`. */
|
package/dist/reads.js
CHANGED
|
@@ -211,6 +211,84 @@ export function calloutTitle(node) {
|
|
|
211
211
|
// title back — so the empty string is preserved and only absence is undefined.
|
|
212
212
|
return typeof title === "string" ? title : undefined;
|
|
213
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* A step's `title` prop to draw as its lead (Mintlify/MDX `<Step title="…">`), or undefined.
|
|
216
|
+
* The dogsbay-md parser never sets it (a step's title is its own first line); an importer that
|
|
217
|
+
* also writes the title into the content (format-mdx's Steps parser adds `<strong>title</strong>`)
|
|
218
|
+
* is not drawn twice: a title the step's text already starts with is skipped.
|
|
219
|
+
*/
|
|
220
|
+
export function stepTitle(node) {
|
|
221
|
+
const title = typeof node.props?.title === "string" ? node.props.title.trim() : "";
|
|
222
|
+
if (!title)
|
|
223
|
+
return undefined;
|
|
224
|
+
const first = node.inline?.length ? node.inline : undefined;
|
|
225
|
+
const firstChild = node.children?.[0];
|
|
226
|
+
const text = (nodes) => (nodes ?? []).map((n) => ("text" in n && typeof n.text === "string" ? n.text : "children" in n && Array.isArray(n.children) ? text(n.children) : "")).join("");
|
|
227
|
+
const html = firstChild && !first ? leafHtml(firstChild) : undefined;
|
|
228
|
+
const lead = (first ? text(first)
|
|
229
|
+
: html !== undefined ? decodeEntities(html.replace(/<[^>]*>/g, ""))
|
|
230
|
+
: firstChild ? text(leafInline(firstChild))
|
|
231
|
+
: "").trim();
|
|
232
|
+
// The whole title, then the end of the lead or a non-word character: "A" is not in "Apple pie"
|
|
233
|
+
return lead.startsWith(title) && !/^[\p{L}\p{N}_]/u.test(lead.slice(title.length)) ? undefined : title;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* A step's title written as its leading bold run on a line of its own, split from the detail:
|
|
237
|
+
* `1. **Stop the writer**` then `Run …` on the next line is ONE paragraph to Markdown, so every
|
|
238
|
+
* renderer drew the title and the detail on one line. The documents skill teaches that form, and
|
|
239
|
+
* it is what Mintlify's `<Step title>` imports as. The line end is what decides it: the
|
|
240
|
+
* dogsbay-md parser marks bold that ends its line (`lineEnd`), and a hard break counts too. So
|
|
241
|
+
* `1. **Click** Save.` and `**Optional:** configure X` stay one line. The bold run is bold text
|
|
242
|
+
* and links whose text is all bold. The title's nodes lose `bold` (the renderer wraps them in
|
|
243
|
+
* its title element) and `lineEnd`; the detail loses a leading break and leading space.
|
|
244
|
+
* Undefined when the step does not start with such a run, or is only the bold text.
|
|
245
|
+
*/
|
|
246
|
+
export function stepLead(inline) {
|
|
247
|
+
if (!inline?.length)
|
|
248
|
+
return undefined;
|
|
249
|
+
const textOf = (n) => ("text" in n && typeof n.text === "string" ? n.text : undefined);
|
|
250
|
+
const flag = (n, k) => n[k] === true;
|
|
251
|
+
const bold = (n) => {
|
|
252
|
+
if (n.type === "link") {
|
|
253
|
+
const texts = n.children.filter((c) => c.type === "text");
|
|
254
|
+
return texts.length > 0 && texts.every((c) => flag(c, "bold"));
|
|
255
|
+
}
|
|
256
|
+
return flag(n, "bold");
|
|
257
|
+
};
|
|
258
|
+
let i = 0;
|
|
259
|
+
while (i < inline.length && textOf(inline[i]) === "" && !bold(inline[i]))
|
|
260
|
+
i++;
|
|
261
|
+
const start = i;
|
|
262
|
+
while (i < inline.length && bold(inline[i]))
|
|
263
|
+
i++;
|
|
264
|
+
if (i === start)
|
|
265
|
+
return undefined;
|
|
266
|
+
let j = i;
|
|
267
|
+
while (j < inline.length && textOf(inline[j]) === "")
|
|
268
|
+
j++;
|
|
269
|
+
const hardBreak = inline[j]?.type === "break";
|
|
270
|
+
if (!flag(inline[i - 1], "lineEnd") && !hardBreak)
|
|
271
|
+
return undefined;
|
|
272
|
+
const plain = (n) => n.type === "link"
|
|
273
|
+
? { ...n, lineEnd: undefined, children: n.children.map((c) => ({ ...c, bold: undefined })) }
|
|
274
|
+
: { ...n, bold: undefined, lineEnd: undefined };
|
|
275
|
+
const title = inline.slice(start, i).map(plain);
|
|
276
|
+
const rest = inline.slice(hardBreak ? j + 1 : i);
|
|
277
|
+
const first = rest[0] && textOf(rest[0]);
|
|
278
|
+
if (first !== undefined)
|
|
279
|
+
rest[0] = { ...rest[0], text: first.replace(/^\s+/, "") };
|
|
280
|
+
if (!rest.some((n) => textOf(n) !== ""))
|
|
281
|
+
return undefined;
|
|
282
|
+
return { title, rest };
|
|
283
|
+
}
|
|
284
|
+
/** The five XML entities and numeric references, for comparing an html lead with a title. */
|
|
285
|
+
function decodeEntities(s) {
|
|
286
|
+
return s
|
|
287
|
+
.replace(/&#(\d+);/g, (_, d) => String.fromCodePoint(Number(d)))
|
|
288
|
+
.replace(/&#x([0-9a-f]+);/gi, (_, h) => String.fromCodePoint(parseInt(h, 16)))
|
|
289
|
+
.replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'|'/g, "'")
|
|
290
|
+
.replace(/&/g, "&");
|
|
291
|
+
}
|
|
214
292
|
/** An ordered list's start number, or undefined when it starts at 1. */
|
|
215
293
|
export function listStart(node) {
|
|
216
294
|
const raw = node.props?.start;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dogsbay/serialize-core",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.130",
|
|
4
4
|
"description": "Shared serializer core — shape-tolerant TreeNode reads, a generic inline walker, fence/indent utilities, and the export capability ledger every format exporter builds on",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@dogsbay/types": "0.2.0-beta.
|
|
25
|
+
"@dogsbay/types": "0.2.0-beta.130"
|
|
26
26
|
},
|
|
27
27
|
"repository": {
|
|
28
28
|
"type": "git",
|