@dogsbay/render-html 0.2.0-beta.124 → 0.2.0-beta.125
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 +9 -0
- package/css/docs.css +5 -4
- package/dist/render.d.ts +7 -0
- package/dist/render.js +18 -4
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -27,6 +27,15 @@ const html = renderBlocks(dogsbayMdToTree(markdown).tree, ctx);
|
|
|
27
27
|
The output uses Tailwind utility classes and the theme tokens. Styling it needs the Dogsbay
|
|
28
28
|
theme CSS, compiled for the classes the page uses.
|
|
29
29
|
|
|
30
|
+
## Source lines (scroll sync)
|
|
31
|
+
|
|
32
|
+
Parse with `sourceLines: true` (`dogsbayMdToTree` in format-dogsbay-md, or
|
|
33
|
+
`ditaTopicToTree` in format-dita) and each block carries its 1-based source line
|
|
34
|
+
on `meta.line`. Render with `createRenderContext({ dataLines: true })` and
|
|
35
|
+
it is written as `data-line="N"` on each block's first element and on list
|
|
36
|
+
items, so an editor can map a click in the preview to the source and scroll the
|
|
37
|
+
preview to the cursor. Off by default; only a positive integer is ever written.
|
|
38
|
+
|
|
30
39
|
## API reference pages
|
|
31
40
|
|
|
32
41
|
Autodoc symbols (`api-class`, `api-member`, `api-doc`, `api-params`,
|
package/css/docs.css
CHANGED
|
@@ -35,10 +35,11 @@
|
|
|
35
35
|
.docs-prose {
|
|
36
36
|
line-height: 1.7;
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
&
|
|
40
|
-
&
|
|
41
|
-
&
|
|
38
|
+
/* A heading that is part of a component (a card title: h3.not-prose) keeps the component look */
|
|
39
|
+
& h1:not(.dba-api *):not(.not-prose) { font-family: var(--font-heading); font-size: 2rem; font-weight: 700; margin-top: 0; margin-bottom: 1rem; line-height: 1.2; letter-spacing: -0.025em; }
|
|
40
|
+
& h2:not(.dba-api *):not(.not-prose) { font-family: var(--font-heading); font-size: 1.5rem; font-weight: 600; margin-top: 2.5rem; margin-bottom: 0.75rem; line-height: 1.3; border-bottom: 1px solid var(--border); padding-bottom: 0.5rem; letter-spacing: -0.015em; }
|
|
41
|
+
& h3:not(.dba-api *):not(.not-prose) { font-family: var(--font-heading); font-size: 1.25rem; font-weight: 600; margin-top: 2rem; margin-bottom: 0.5rem; line-height: 1.4; }
|
|
42
|
+
& h4:not(.dba-api *):not(.not-prose) { font-family: var(--font-heading); font-size: 1.1rem; font-weight: 600; margin-top: 1.5rem; margin-bottom: 0.5rem; }
|
|
42
43
|
|
|
43
44
|
& p:not(.dba-api *) { margin-top: 0.75rem; margin-bottom: 0.75rem; }
|
|
44
45
|
|
package/dist/render.d.ts
CHANGED
|
@@ -73,6 +73,13 @@ export interface RenderContext {
|
|
|
73
73
|
lastHeadingLevel?: number;
|
|
74
74
|
/** While rendering an autodoc symbol's body: that symbol's heading level. */
|
|
75
75
|
apiParentLevel?: number;
|
|
76
|
+
/**
|
|
77
|
+
* Write each block's source line (`meta.line`, from the parsers'
|
|
78
|
+
* `sourceLines` option) as `data-line` on its first element, and on list
|
|
79
|
+
* items, so a host can map the page back to the source (an editor's scroll
|
|
80
|
+
* sync). Off by default; only a positive integer is ever written.
|
|
81
|
+
*/
|
|
82
|
+
dataLines?: boolean;
|
|
76
83
|
}
|
|
77
84
|
export { FOREIGN_END, FOREIGN_START };
|
|
78
85
|
export { scriptUrl };
|
package/dist/render.js
CHANGED
|
@@ -276,9 +276,22 @@ export function renderBlocks(nodes, ctx) {
|
|
|
276
276
|
plannedHeadingIds.set(ctx, planHeadingIds(nodes, new Set()));
|
|
277
277
|
let out = "";
|
|
278
278
|
for (const n of nodes)
|
|
279
|
-
out += block(n, ctx);
|
|
279
|
+
out += ctx.dataLines ? withDataLine(block(n, ctx), n) : block(n, ctx);
|
|
280
280
|
return out;
|
|
281
281
|
}
|
|
282
|
+
/** A node's source line, when it is a positive integer (ctx.dataLines). */
|
|
283
|
+
const sourceLine = (n) => {
|
|
284
|
+
const line = n.meta?.line;
|
|
285
|
+
return typeof line === "number" && Number.isInteger(line) && line > 0 ? line : undefined;
|
|
286
|
+
};
|
|
287
|
+
/** `data-line` on the first element of a block's HTML (none when it starts with text or a comment). */
|
|
288
|
+
function withDataLine(html, n) {
|
|
289
|
+
const line = sourceLine(n);
|
|
290
|
+
if (line === undefined)
|
|
291
|
+
return html;
|
|
292
|
+
// The source's line wins over a `data-line` already in raw HTML (it would send scroll sync elsewhere)
|
|
293
|
+
return html.replace(/^(\s*<[A-Za-z][\w:-]*)(?=[\s/>])([^>]*?)(?:\sdata-line=(?:"[^"]*"|'[^']*'|[^\s>]*))?/, `$1 data-line="${line}"$2`);
|
|
294
|
+
}
|
|
282
295
|
const str = (v) => (v == null || v === "" ? undefined : String(v));
|
|
283
296
|
/** A list item or step: the item's own inline run followed by its block children. */
|
|
284
297
|
function itemBody(n, ctx) {
|
|
@@ -292,7 +305,8 @@ function listItem(n, ctx) {
|
|
|
292
305
|
const lead = n.inline && n.inline.length ? renderInline(n.inline, ctx) : "";
|
|
293
306
|
const rest = renderBlocks(n.children, ctx);
|
|
294
307
|
const body = rest && lead ? `<p>${task}${lead}</p>${rest}` : task + lead + rest;
|
|
295
|
-
|
|
308
|
+
const line = ctx.dataLines ? sourceLine(n) : undefined;
|
|
309
|
+
return `<li${attrs(passthrough(p))}${line ? ` data-line="${line}"` : ""}>${body}</li>`;
|
|
296
310
|
}
|
|
297
311
|
function block(n, ctx) {
|
|
298
312
|
const p = (n.props ?? {});
|
|
@@ -910,7 +924,7 @@ function card(n, ctx) {
|
|
|
910
924
|
// An image path is shown as an image, as the Astro pipeline's cardIconHtml does.
|
|
911
925
|
const iconHtml = !ic ? "" : /\.(svg|png|jpe?g|webp|avif)$/i.test(ic) ? `<img src="${esc(assetUrl(ic, ctx))}" alt="" class="size-5 mb-2" loading="lazy">` : namedIcon(ic, "mb-2 size-5 text-muted-foreground", ctx);
|
|
912
926
|
const inner = insideLink(!!href, ctx, () => iconHtml +
|
|
913
|
-
(title ? `<h3 class="m-0 border-0 p-0 text-base font-semibold">${renderInline(parseInline(title), ctx)}</h3>` : "") +
|
|
927
|
+
(title ? `<h3 class="not-prose m-0 border-0 p-0 text-base font-semibold">${renderInline(parseInline(title), ctx)}</h3>` : "") +
|
|
914
928
|
(desc ? `<p class="m-0 mt-1 text-sm text-muted-foreground [text-decoration:none]">${renderInline(parseInline(desc), ctx)}</p>` : "") +
|
|
915
929
|
// Body blocks in the same description wrapper as the Astro pipeline's card (a <div>: they carry their own <p>).
|
|
916
930
|
(n.children?.length ? `<div class="text-sm text-muted-foreground mt-1 [text-decoration:none]">${renderBlocks(n.children, ctx)}</div>` : ""));
|
|
@@ -918,7 +932,7 @@ function card(n, ctx) {
|
|
|
918
932
|
const toned = lookup(CARD_TONE_CLASSES, str(p.tone));
|
|
919
933
|
const cls = `rounded-lg border ${toned ?? "bg-card"} p-4 text-card-foreground shadow-sm${href ? ` transition-colors ${toned ? "hover:shadow-md" : "hover:border-foreground/20"}` : ""}`;
|
|
920
934
|
return href
|
|
921
|
-
? `<div${attrs(passthrough(p, cls))}><div class="p-0"><a href="${esc(linkUrl(href, ctx))}" class="block text-foreground [text-decoration:none]">${inner}</a></div></div>`
|
|
935
|
+
? `<div${attrs(passthrough(p, cls))}><div class="p-0"><a href="${esc(linkUrl(href, ctx))}" class="not-prose block text-foreground [text-decoration:none]">${inner}</a></div></div>`
|
|
922
936
|
: `<div${attrs(passthrough(p, cls))}><div class="p-0">${inner}</div></div>`;
|
|
923
937
|
}
|
|
924
938
|
function linkCard(n, ctx) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dogsbay/render-html",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.125",
|
|
4
4
|
"description": "Dogsbay MD TreeNode → HTML with the Astro components' markup and classes. No highlighter, math or CSS compiler unless you pass one; Worker- and browser-safe",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"htmlparser2": "^10.1.0",
|
|
32
32
|
"markdown-it": "^14.3.0",
|
|
33
|
-
"@dogsbay/format-dogsbay-md": "0.2.0-beta.
|
|
34
|
-
"@dogsbay/serialize-core": "0.2.0-beta.
|
|
35
|
-
"@dogsbay/types": "0.2.0-beta.
|
|
33
|
+
"@dogsbay/format-dogsbay-md": "0.2.0-beta.125",
|
|
34
|
+
"@dogsbay/serialize-core": "0.2.0-beta.125",
|
|
35
|
+
"@dogsbay/types": "0.2.0-beta.125"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"katex": "^0.16.0"
|