@pretextbook/pretext-html 0.16.1 → 0.18.0

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 CHANGED
@@ -1,8 +1,12 @@
1
- export { renderHtml, defaultXslDir, isJspiAvailable, xpathStringLiteral, } from './renderer.js';
2
- export type { RenderOptions, RenderResult } from './renderer.js';
1
+ export { renderHtml, measureDocument, defaultSourceCache, defaultXslDir, isJspiAvailable, xpathStringLiteral, } from './renderer.js';
2
+ export type { DocumentSize, RenderOptions, RenderResult, SourceOptions, } from './renderer.js';
3
+ export type { SubtreeOptions } from './subtree.js';
4
+ export { SourceCache } from './source-cache.js';
5
+ export type { SourceCacheOptions } from './source-cache.js';
6
+ export type { SourceReader } from './xinclude.js';
3
7
  export { findSourceMapEntry } from './sourcemap.js';
4
8
  export type { PtxSourceMap, SourceMapEntry } from './sourcemap.js';
5
- export { forcePortablePublication } from './publication.js';
9
+ export { forcePreviewPublication, forcePortablePublication, } from './publication.js';
6
10
  export type { PublicationOverrides } from './publication.js';
7
11
  export { detectRenderTarget } from './target.js';
8
12
  export type { RenderTarget } from './target.js';
@@ -10,7 +14,9 @@ export { injectRevealBridge, isRevealView, revealBridgeScript, } from './reveal.
10
14
  export type { RevealView, RevealViewOptions } from './reveal.js';
11
15
  export { openBornHiddenKnowls } from './knowls.js';
12
16
  export { buildSkeleton, divisionLevel, replaceDivision } from './skeleton.js';
13
- export type { Skeleton } from './skeleton.js';
17
+ export type { Skeleton, SkeletonOptions } from './skeleton.js';
18
+ export { readPublicationLevels } from './publication.js';
19
+ export type { PublicationLevels } from './publication.js';
14
20
  export { OFF_PAGE_MESSAGE, rewriteXrefLinks } from './xrefs.js';
15
21
  export type { RewriteXrefLinkOptions } from './xrefs.js';
16
22
  export { rewriteAssetUrls } from './assets.js';
package/dist/index.js CHANGED
@@ -1,48 +1,53 @@
1
- import { O as i, P as s, b as t, d as a, a as n, c as o, f as l, e as p, i as c, g as d, o as P, p as E, r as m, h as v, j as A, m as S, s as g, k as B, x as f } from "./cli-DzlCZymu.js";
2
- import { injectRevealBridge as h, isRevealView as w, revealBridgeScript as R } from "./reveal.js";
3
- import { describeAsset as x, missingAssetPlaceholder as L, missingAssetSvg as T, rewriteAssetUrls as b } from "./assets.js";
4
- import { PREVIEW_THEME_MESSAGE as I, injectThemeBridge as M, isPreviewTheme as j, previewThemeMessage as O, themeBridgeScript as V } from "./theme.js";
5
- import { PRINT_PREVIEW_GLOBAL as k, injectPrintPreview as D, listPrintouts as N, printPreviewBridgeScript as W, rootPrintoutId as y } from "./printout.js";
6
- import { LIVE_PATCH_GLOBAL as F, livePatchScript as K, patchDocument as X, typesetPatch as J } from "./live-patch.js";
1
+ import { O as i, P as s, S as t, b as a, d as o, a as n, c, e as l, f as p, g as P, h as d, i as E, j as m, m as v, o as S, p as u, r as A, k as f, l as g, n as h, q as B, s as w, t as _, x as R } from "./cli-CKAOX3L6.js";
2
+ import { injectRevealBridge as b, isRevealView as x, revealBridgeScript as T } from "./reveal.js";
3
+ import { describeAsset as I, missingAssetPlaceholder as M, missingAssetSvg as j, rewriteAssetUrls as O } from "./assets.js";
4
+ import { PREVIEW_THEME_MESSAGE as C, injectThemeBridge as D, isPreviewTheme as H, previewThemeMessage as k, themeBridgeScript as N } from "./theme.js";
5
+ import { PRINT_PREVIEW_GLOBAL as y, injectPrintPreview as F, listPrintouts as K, printPreviewBridgeScript as X, rootPrintoutId as q } from "./printout.js";
6
+ import { LIVE_PATCH_GLOBAL as U, livePatchScript as Y, patchDocument as z, typesetPatch as Q } from "./live-patch.js";
7
7
  export {
8
- F as LIVE_PATCH_GLOBAL,
8
+ U as LIVE_PATCH_GLOBAL,
9
9
  i as OFF_PAGE_MESSAGE,
10
10
  s as PREVIEW_BANNER_STORAGE_KEY,
11
- I as PREVIEW_THEME_MESSAGE,
12
- k as PRINT_PREVIEW_GLOBAL,
13
- t as buildSkeleton,
14
- a as defaultXslDir,
15
- x as describeAsset,
16
- n as detectRenderTarget,
17
- o as divisionLevel,
18
- l as findSourceMapEntry,
19
- p as forcePortablePublication,
20
- c as injectPreviewBanner,
21
- D as injectPrintPreview,
22
- h as injectRevealBridge,
23
- M as injectThemeBridge,
24
- d as isJspiAvailable,
25
- j as isPreviewTheme,
26
- w as isRevealView,
27
- N as listPrintouts,
28
- K as livePatchScript,
29
- L as missingAssetPlaceholder,
30
- T as missingAssetSvg,
31
- P as openBornHiddenKnowls,
32
- X as patchDocument,
33
- E as previewBannerScript,
34
- O as previewThemeMessage,
35
- W as printPreviewBridgeScript,
36
- m as renderHtml,
37
- v as replaceDivision,
38
- R as revealBridgeScript,
39
- b as rewriteAssetUrls,
40
- A as rewriteXrefLinks,
41
- y as rootPrintoutId,
42
- S as runCli,
43
- g as setAssetsBase,
44
- B as setMountReader,
45
- V as themeBridgeScript,
46
- J as typesetPatch,
47
- f as xpathStringLiteral
11
+ C as PREVIEW_THEME_MESSAGE,
12
+ y as PRINT_PREVIEW_GLOBAL,
13
+ t as SourceCache,
14
+ a as buildSkeleton,
15
+ o as defaultSourceCache,
16
+ n as defaultXslDir,
17
+ I as describeAsset,
18
+ c as detectRenderTarget,
19
+ l as divisionLevel,
20
+ p as findSourceMapEntry,
21
+ P as forcePortablePublication,
22
+ d as forcePreviewPublication,
23
+ E as injectPreviewBanner,
24
+ F as injectPrintPreview,
25
+ b as injectRevealBridge,
26
+ D as injectThemeBridge,
27
+ m as isJspiAvailable,
28
+ H as isPreviewTheme,
29
+ x as isRevealView,
30
+ K as listPrintouts,
31
+ Y as livePatchScript,
32
+ v as measureDocument,
33
+ M as missingAssetPlaceholder,
34
+ j as missingAssetSvg,
35
+ S as openBornHiddenKnowls,
36
+ z as patchDocument,
37
+ u as previewBannerScript,
38
+ k as previewThemeMessage,
39
+ X as printPreviewBridgeScript,
40
+ A as readPublicationLevels,
41
+ f as renderHtml,
42
+ g as replaceDivision,
43
+ T as revealBridgeScript,
44
+ O as rewriteAssetUrls,
45
+ h as rewriteXrefLinks,
46
+ q as rootPrintoutId,
47
+ B as runCli,
48
+ w as setAssetsBase,
49
+ _ as setMountReader,
50
+ N as themeBridgeScript,
51
+ Q as typesetPatch,
52
+ R as xpathStringLiteral
48
53
  };
@@ -1,3 +1,4 @@
1
+ import { Root } from 'xast';
1
2
  import { RenderTarget } from './target.js';
2
3
  /** Optional adjustments layered onto the publication file for a render. */
3
4
  export interface PublicationOverrides {
@@ -19,39 +20,92 @@ export interface PublicationOverrides {
19
20
  target?: RenderTarget;
20
21
  }
21
22
  /**
22
- * Return publication-file XML with `<html><platform portable="yes"/></html>`
23
- * forced, preserving everything else from `publicationXml` when given.
23
+ * Return publication-file XML with the preview's settings forced (see
24
+ * {@link PREVIEW_SETTINGS}), preserving everything else from `publicationXml`
25
+ * when given.
24
26
  *
25
- * Portable mode is forced for slideshows too, even though the reveal.js
26
- * conversion never chunks: it is what sets `$cdn-prefix`, and so what puts the
27
- * PreTeXt-side css and js (sagecell, syntax highlighting, the slide styling)
28
- * on the CDN rather than at a relative path that does not exist.
27
+ * The CDN host is forced for slideshows too: it is what sets `$cdn-prefix`, and
28
+ * so what puts the PreTeXt-side css and js (sagecell, syntax highlighting, the
29
+ * slide styling) on the CDN rather than at a relative path that does not
30
+ * exist.
29
31
  */
30
- export declare function forcePortablePublication(publicationXml?: string, overrides?: PublicationOverrides): string;
32
+ export declare function forcePreviewPublication(publicationXml?: string, overrides?: PublicationOverrides): string;
31
33
  /**
32
- * Where a project's images live, as declared by
33
- * `<source><directories external generated/></source>`.
34
+ * The previous name of {@link forcePreviewPublication}, from when the preview
35
+ * forced PreTeXt's portable HTML mode.
36
+ *
37
+ * @deprecated Use {@link forcePreviewPublication}. The preview no longer uses
38
+ * portable mode, so the name no longer describes what this does.
39
+ */
40
+ export declare const forcePortablePublication: typeof forcePreviewPublication;
41
+ /**
42
+ * Where a project's images live. PreTeXt emits every asset URL under one of
43
+ * two fixed prefixes, `external/` and `generated/`, and these are the
44
+ * directories those prefixes stand for.
34
45
  *
35
46
  * Both paths are relative to the directory of the *main* source file — the one
36
47
  * holding `<pretext>` — not to whichever file is being rendered. See
37
48
  * RenderOptions.mainSourcePath.
38
49
  */
39
50
  export interface AssetDirectories {
40
- /** e.g. "../assets/" — trailing slash, relative to the main source dir. */
51
+ /**
52
+ * e.g. "../assets/" — trailing slash, relative to the main source dir.
53
+ * Undefined when nothing declares one, which upstream reads as "this
54
+ * project has no external assets".
55
+ */
41
56
  external?: string;
42
- /** e.g. "../generated-assets/" — likewise. */
43
- generated?: string;
44
57
  /**
45
- * True when the publication declares both attributes ("managed
46
- * directories"). Only then does PreTeXt emit asset URLs under the fixed
47
- * `external/` and `generated/` prefixes that {@link rewriteAssetUrls} keys
48
- * on; legacy projects emit bare or `images/`-prefixed paths that cannot be
49
- * told apart from anything else, so the preview leaves them alone.
58
+ * e.g. "../generated-assets/" — likewise. Always set: the directory is
59
+ * machine-owned, so an undeclared one defaults to "generated/" beside the
60
+ * source.
61
+ */
62
+ generated: string;
63
+ }
64
+ /** The depths a publication file sets numbering and the contents list to. */
65
+ export interface PublicationLevels {
66
+ /** `common/tableofcontents/@level`. */
67
+ tocLevel?: number;
68
+ /**
69
+ * The deepest of `numbering/{blocks,projects,equations,footnotes,figures,
70
+ * ...}/@level` — the families share one default, but a publisher may set
71
+ * them apart, and a preview must keep what the deepest of them counts.
50
72
  */
51
- managed: boolean;
73
+ numberingLevel?: number;
74
+ /** `numbering/divisions/@level`, which caps every other numbering level. */
75
+ maxNumberingLevel?: number;
52
76
  }
53
77
  /**
54
- * Read the asset directories from a publication file, falling back to the
55
- * defaults baked into MINIMAL_PUBLICATION when none is supplied.
78
+ * Read the numbering and table-of-contents depths from a publication file —
79
+ * the ones that decide how much of a document a division preview has to keep
80
+ * (see skeleton.ts). Absent entries are left undefined for the skeleton to
81
+ * default by the document's structure, exactly as publisher-variables.xsl
82
+ * does. Falls back to MINIMAL_PUBLICATION when none is supplied.
83
+ */
84
+ export declare function readPublicationLevels(publicationXml?: string): PublicationLevels;
85
+ /**
86
+ * Read the asset directories the way PreTeXt resolves them (as of 2026-08,
87
+ * when managed directories became the only scheme):
88
+ *
89
+ * - **external** is a property of the source. The document's
90
+ * `<docinfo><directories external="..."/>` wins; the publication file's
91
+ * `source/directories/@external` is the deprecated fallback; with neither,
92
+ * the project has no external assets.
93
+ * - **generated** is a publication setting, `source/directories/@generated`,
94
+ * and defaults to "generated/" beside the source.
95
+ *
96
+ * `docinfoExternal` is the raw `@external` from the document's docinfo, which
97
+ * the caller reads from the source (see {@link docinfoExternalDirectory}). The
98
+ * publication file falls back to MINIMAL_PUBLICATION when none is supplied.
99
+ */
100
+ export declare function readAssetDirectories(publicationXml?: string, docinfoExternal?: string): AssetDirectories;
101
+ /**
102
+ * The raw `directories/@external` of a document's `<docinfo>`, or undefined
103
+ * when it declares none. `root` is a parsed document (whose `<pretext>` holds
104
+ * the docinfo), or a `<docinfo>` on its own — parsed, or as the XML string a
105
+ * fragment preview is given. Only the docinfo's direct `<directories>` child
106
+ * counts, as upstream's `$version-root/docinfo/directories` does.
107
+ *
108
+ * A string that does not parse declares nothing here; the transform reports
109
+ * the malformed docinfo itself.
56
110
  */
57
- export declare function readAssetDirectories(publicationXml?: string): AssetDirectories;
111
+ export declare function docinfoExternalDirectory(root: Root | string): string | undefined;
@@ -4,9 +4,64 @@ import { RevealView } from './reveal.js';
4
4
  import { PtxSourceMap } from './sourcemap.js';
5
5
  import { RenderTarget } from './target.js';
6
6
  import { PreviewTheme } from './theme.js';
7
- export interface RenderOptions {
7
+ import { SourceReader } from './xinclude.js';
8
+ import { SourceCache } from './source-cache.js';
9
+ import { SubtreeOptions } from './subtree.js';
10
+ /**
11
+ * How a document is read: the options every entry point that reads source
12
+ * shares — {@link renderHtml} and {@link measureDocument}.
13
+ */
14
+ export interface SourceOptions {
8
15
  /** Path to the root PreTeXt source file (typically source/main.ptx). */
9
16
  sourcePath: string;
17
+ /**
18
+ * Source text to transform instead of reading `sourcePath` from disk.
19
+ * `sourcePath` is still used to resolve relative xi:includes. Lets callers
20
+ * render unsaved editor content.
21
+ */
22
+ sourceContent?: string;
23
+ /**
24
+ * Directory served to the transform for xi:includes and relative
25
+ * references. Defaults to the directory containing `sourcePath`. Set it to
26
+ * the project root when the publication file or includes live outside the
27
+ * source directory. Files outside this directory are not readable by the
28
+ * transform.
29
+ */
30
+ projectDir?: string;
31
+ /**
32
+ * Supply the files the document refers to — xi:include targets, the
33
+ * context document, the publication file, the docinfo source — from
34
+ * somewhere other than the platform: an in-memory project in a browser,
35
+ * an editor's unsaved buffers. Called with each file's absolute, normalized
36
+ * path; `undefined` falls through to the platform's own read (disk under
37
+ * Node, an absolute URL in the browser), so the reader can overlay just a
38
+ * few files or stand in for a filesystem entirely. See {@link SourceReader}.
39
+ *
40
+ * This is what lets the browser build resolve `xi:include`s at all, and
41
+ * what the per-file parse cache (`cache`) keys on: hand it the same string
42
+ * for an unchanged file and that file is not parsed again.
43
+ */
44
+ readSource?: SourceReader;
45
+ /**
46
+ * The same as `readSource`, as a map from absolute path to content, for
47
+ * hosts whose project simply is such a map. Consulted before `readSource`.
48
+ */
49
+ files?: Record<string, string>;
50
+ /**
51
+ * Reuse the parse of every file whose content has not changed since the
52
+ * last render (see source-cache.ts). On by default, with one cache shared
53
+ * by every render in the process; pass a {@link SourceCache} to scope it
54
+ * (one per project, say, so `invalidate()` has a clear meaning), or
55
+ * `false` to parse everything afresh each time.
56
+ *
57
+ * What it buys: a fragment preview placed in its document
58
+ * (`contextSourcePath`) and a division preview of a complete document
59
+ * (`subtree`) both parse the *whole* document to prune it to a skeleton;
60
+ * with the cache, a keystroke re-parses only the file being edited.
61
+ */
62
+ cache?: SourceCache | false;
63
+ }
64
+ export interface RenderOptions extends SourceOptions {
10
65
  /**
11
66
  * Path to the project's *main* source file — the one holding `<pretext>`.
12
67
  * Defaults to `sourcePath`, which is correct whenever a complete document is
@@ -21,22 +76,31 @@ export interface RenderOptions {
21
76
  */
22
77
  mainSourcePath?: string;
23
78
  /**
24
- * Source text to transform instead of reading `sourcePath` from disk.
25
- * `sourcePath` is still used to resolve relative xi:includes. Lets callers
26
- * render unsaved editor content.
27
- */
28
- sourceContent?: string;
29
- /**
30
- * Directory served to the transform for xi:includes and relative
31
- * references. Defaults to the directory containing `sourcePath`. Set it to
32
- * the project root when the publication file or includes live outside the
33
- * source directory. Files outside this directory are not readable by the
34
- * transform.
79
+ * Preview one division of the document instead of all of it — the one
80
+ * around the author's cursor (`line`, and `file` when that is not the file
81
+ * being rendered) or the one carrying an `id` — numbered and
82
+ * cross-referenced exactly as the whole document would be, by the same
83
+ * skeleton pruning a fragment placed in its document gets (see
84
+ * skeleton.ts). The cost of a render then tracks the division, not the
85
+ * document, which is what makes previewing a large single-file book as
86
+ * you type feasible at all.
87
+ *
88
+ * `level` chooses the page by PreTeXt's chunk-level rules, and
89
+ * `wholeDocumentUpTo` keeps small documents previewing whole; see
90
+ * {@link SubtreeOptions}. With `fragment` and a context document, the
91
+ * selection is made within the placed fragment (so a cursor line narrows
92
+ * the preview to the subsection it is in); without `subtree` the fragment's
93
+ * own root is the division, as before.
94
+ *
95
+ * Ignored when no division can be selected — the document then renders
96
+ * whole, and {@link RenderResult.subtree} is absent.
35
97
  */
36
- projectDir?: string;
98
+ subtree?: SubtreeOptions;
37
99
  /**
38
- * Path to a publication file. Its settings are respected except
39
- * `<html><platform portable="yes"/></html>`, which the preview forces.
100
+ * Path to a publication file. Its settings are respected except the few a
101
+ * one-page, in-memory build cannot honour, which the preview forces: css/js
102
+ * from the CDN, chunk level 0, cross-references as links rather than knowls,
103
+ * and portable mode off. See publication.ts.
40
104
  */
41
105
  publicationPath?: string;
42
106
  /**
@@ -49,7 +113,7 @@ export interface RenderOptions {
49
113
  * ignored, and with no publication file at all it themes the synthesized
50
114
  * minimal one.
51
115
  *
52
- * Portable builds load `theme-<name>.min.css` from the CDN, so an
116
+ * Previews load `theme-<name>.min.css` from the CDN, so an
53
117
  * unrecognised name renders an unstyled page. The themes the vendored
54
118
  * stylesheets know are default-modern (PreTeXt's own default), denver,
55
119
  * tacoma, salem, greeley and boulder; `custom` additionally needs a locally
@@ -246,9 +310,52 @@ export interface RenderOptions {
246
310
  */
247
311
  printPreview?: string;
248
312
  }
313
+ /** How big a document is, as {@link measureDocument} reports it. */
314
+ export interface DocumentSize {
315
+ /** Length of the xi:include-merged source, in UTF-16 code units. */
316
+ bytes: number;
317
+ /**
318
+ * Number of elements in the merged source. The better predictor of render
319
+ * time: PreTeXt's assembly walks the tree in a dozen passes, so cost tracks
320
+ * nodes rather than text. For scale, a small article is a few hundred, a
321
+ * long chapter a few thousand, a whole book tens of thousands.
322
+ */
323
+ elements: number;
324
+ /**
325
+ * Every file the document spans — the source first, then each xi:included
326
+ * file in the order first reached. What to watch for changes.
327
+ */
328
+ files: string[];
329
+ }
249
330
  export interface RenderResult {
250
331
  /** Complete standalone HTML page (CDN-hosted css/js/MathJax). */
251
332
  html: string;
333
+ /**
334
+ * The size of the document the render assembled — the whole context
335
+ * document for a fragment placed in it, the whole document for a `subtree`
336
+ * preview — before any pruning. What to compare against a threshold when
337
+ * deciding how much of a document to preview next time.
338
+ */
339
+ size: DocumentSize;
340
+ /**
341
+ * Present when one division was emitted rather than the whole document:
342
+ * `id` is its `xml:id`, which is also its HTML id on the page; `level` its
343
+ * numbering level; `collapsed` whether the divisions nested inside it were
344
+ * reduced to headings (see {@link SubtreeOptions.level}).
345
+ */
346
+ subtree?: {
347
+ id: string;
348
+ level: number;
349
+ collapsed: boolean;
350
+ /**
351
+ * When `collapsed`, the ids of the divisions the summary page lists, in
352
+ * document order — each the `xml:id` (authored or injected) its link
353
+ * names in `data-ptx-division`, and its id in the source map. A host
354
+ * following the cursor re-renders when it enters one of these. Empty
355
+ * for a division shown whole.
356
+ */
357
+ children: string[];
358
+ };
252
359
  /**
253
360
  * The conversion that actually ran — as asked for, or as detected. Lets an
254
361
  * embedder tell a deck from a document without re-inspecting the source,
@@ -273,15 +380,20 @@ export interface RenderResult {
273
380
  rootPrintout?: string;
274
381
  /**
275
382
  * Absolute directories that the `external/` and `generated/` URL prefixes in
276
- * `html` refer to, resolved from the publication file against the main
277
- * source file's directory. Feed these to `rewriteAssetUrls` to point the
278
- * page at assets the host can actually serve (see assets.ts).
383
+ * `html` refer to, resolved against the main source file's directory the way
384
+ * PreTeXt resolves them (see readAssetDirectories). Feed these to
385
+ * `rewriteAssetUrls` to point the page at assets the host can actually
386
+ * serve (see assets.ts). That covers latex-image and PreFigure diagrams
387
+ * too, which the page links like any other image.
279
388
  *
280
- * Absent for legacy projects that declare neither directory: those emit bare
281
- * or `images/`-prefixed URLs that cannot be identified reliably.
389
+ * `generated` is always known, since an undeclared one defaults to
390
+ * `generated/` beside the source. `external` is absent when neither the
391
+ * docinfo nor the publication file declares it: the project then has no
392
+ * external assets, and any `external/` URL in the page is a dangling
393
+ * reference.
282
394
  */
283
- assetDirs?: {
284
- external: string;
395
+ assetDirs: {
396
+ external?: string;
285
397
  generated: string;
286
398
  };
287
399
  }
@@ -293,6 +405,22 @@ export declare function defaultXslDir(): string;
293
405
  export declare function isJspiAvailable(): boolean;
294
406
  /** Quote a string as an XPath 1.0 string literal. */
295
407
  export declare function xpathStringLiteral(value: string): string;
408
+ /**
409
+ * The parse cache renders use when {@link SourceOptions.cache} is not given.
410
+ * Exposed so a host can drop it (`invalidate()`) or read its hit counts.
411
+ */
412
+ export declare function defaultSourceCache(): SourceCache;
413
+ /**
414
+ * Measure a document without rendering it: resolve its xi:includes and count.
415
+ * Cheap — with the parse cache warm, a copy of the tree and a walk — so a
416
+ * host can decide before each render whether to preview the whole document
417
+ * or one division of it (see {@link SubtreeOptions.wholeDocumentUpTo}), and
418
+ * learn which files to watch.
419
+ *
420
+ * Measures the document at `sourcePath` as given: to size the book a
421
+ * fragment belongs to, pass the main file.
422
+ */
423
+ export declare function measureDocument(options: SourceOptions): Promise<DocumentSize>;
296
424
  /**
297
425
  * Render a PreTeXt document to a single standalone HTML page.
298
426
  *
@@ -1,4 +1,9 @@
1
1
  import { Element, Root } from 'xast';
2
+ /**
3
+ * True for a division upstream will accept as a `subtree` root — the
4
+ * `&STRUCTURAL;` set, which is also what the skeleton keeps shells of.
5
+ */
6
+ export declare function isStructural(element: Element): boolean;
2
7
  /** A pruned document, ready to render as a fragment preview. */
3
8
  export interface Skeleton {
4
9
  /** The pruned document, serialized. */
@@ -7,16 +12,72 @@ export interface Skeleton {
7
12
  divisionId: string;
8
13
  /** That division's numbering level; pass as the `subtree-level` param. */
9
14
  level: number;
15
+ /**
16
+ * Whether the division's own child divisions were reduced to title shells
17
+ * (see {@link SkeletonOptions.collapseChildren}).
18
+ */
19
+ collapsed: boolean;
20
+ }
21
+ export interface SkeletonOptions {
22
+ /**
23
+ * Keep the previewed division's own content but reduce the divisions
24
+ * nested inside it to shells — a heading each, no prose — the way a
25
+ * chunked build's page for an intermediate division shows its introduction
26
+ * and then only a summary of what is below. What makes previewing a
27
+ * chapter's introduction cheap when the chapter itself is long.
28
+ *
29
+ * Cross-references from the kept content into a collapsed child still
30
+ * resolve: the child holding the target is stripped of text rather than
31
+ * emptied, exactly like any other target division.
32
+ */
33
+ collapseChildren?: boolean;
34
+ /**
35
+ * How deep the table of contents lists divisions (`tableofcontents/@level`
36
+ * in the publication file). Shells of divisions are kept down to this
37
+ * level everywhere in the document, so the preview's contents list is the
38
+ * built book's; deeper divisions survive only where numbering needs them.
39
+ * Defaults to PreTeXt's own default for the document's structure.
40
+ */
41
+ tocLevel?: number;
42
+ /**
43
+ * The level within which blocks — theorems, examples, figures, equations
44
+ * and the rest — are numbered (the `numbering/*​/@level` family in the
45
+ * publication file; the deepest of them, if they differ). Divisions deeper
46
+ * than this that precede the previewed division within its scope are kept
47
+ * with their text stripped, so the blocks in them are counted. Defaults to
48
+ * PreTeXt's own default for the document's structure.
49
+ */
50
+ numberingLevel?: number;
51
+ /**
52
+ * The deepest level anything is numbered to (`numbering/divisions/@level`),
53
+ * which caps `numberingLevel` and its default.
54
+ */
55
+ maxNumberingLevel?: number;
10
56
  }
57
+ /** Depth-first search for the element carrying `@xml:id` equal to `id`. */
58
+ export declare function findById(node: Root | Element, id: string): Element | undefined;
11
59
  /**
12
- * A division's numbering level, mirroring `mode="level"` in
13
- * pretext-numbers.xsl. `ancestors` runs from the document element down to (and
14
- * including) the division itself.
15
- *
16
- * `hasParts` is upstream's `$b-has-parts` (`boolean($root/book/part)`), which
17
- * pushes a book's chapters down a level.
60
+ * The chain of elements from the document root down to `target`, inclusive.
61
+ * Returns undefined when `target` is not in the tree.
62
+ */
63
+ export declare function pathTo(node: Root | Element, target: Element): Element[] | undefined;
64
+ /**
65
+ * A division's numbering level. `ancestors` runs from the document element
66
+ * down to (and including) the division itself.
18
67
  */
19
68
  export declare function divisionLevel(ancestors: Element[], hasParts: boolean): number;
69
+ /**
70
+ * PreTeXt's default table-of-contents depth for a document, by its structure
71
+ * — the `common/tableofcontents/pi:pub-attribute[@name='level']` default in
72
+ * publisher-variables.xsl.
73
+ */
74
+ export declare function defaultTocLevel(documentElement: Element | undefined): number;
75
+ /**
76
+ * PreTeXt's default numbering level for blocks, projects, equations, figures
77
+ * and footnotes, by the document's structure — `$default-numbering-level` in
78
+ * publisher-variables.xsl.
79
+ */
80
+ export declare function defaultNumberingLevel(documentElement: Element | undefined): number;
20
81
  /**
21
82
  * Swap the division carrying `id` for `replacement`, in place. Returns false
22
83
  * when the tree holds no such division.
@@ -38,4 +99,4 @@ export declare function replaceDivision(tree: Root, id: string, replacement: Ele
38
99
  * whose `@xml:id` is not yet in the main document, say — which the caller
39
100
  * should treat as "fall back to the standalone fragment wrapper".
40
101
  */
41
- export declare function buildSkeleton(tree: Root, divisionId: string): Skeleton | undefined;
102
+ export declare function buildSkeleton(tree: Root, divisionId: string, options?: SkeletonOptions): Skeleton | undefined;
@@ -0,0 +1,36 @@
1
+ import { Root, RootContent } from 'xast';
2
+ export interface SourceCacheOptions {
3
+ /**
4
+ * How many files to keep. The least recently used entry is evicted when a
5
+ * new file would exceed it. Defaults to 1024 — enough for any project with
6
+ * one file per division, which is the layout that produces the most files.
7
+ */
8
+ maxEntries?: number;
9
+ }
10
+ export declare class SourceCache {
11
+ private readonly entries;
12
+ private readonly maxEntries;
13
+ /** Cumulative hit/miss counts, for diagnostics and tests. */
14
+ hits: number;
15
+ misses: number;
16
+ constructor(options?: SourceCacheOptions);
17
+ /**
18
+ * The parse of `content`, as a fresh tree the caller may mutate freely.
19
+ * `key` names the file — a path — so that a changed file replaces its own
20
+ * entry instead of accumulating one per version.
21
+ *
22
+ * Throws what `fromXml` throws for malformed content; nothing is cached
23
+ * then.
24
+ */
25
+ parse(key: string, content: string): Root;
26
+ /** Number of files currently held. */
27
+ get size(): number;
28
+ /** Drop one file (when the host knows it is gone), or everything. */
29
+ invalidate(key?: string): void;
30
+ }
31
+ /**
32
+ * Deep-copy an xast tree. Positions are shared (nothing ever mutates them);
33
+ * attributes, children and `data` are copied, since the renderer mutates all
34
+ * three (tagging included roots, injecting an `xml:id`, splicing and pruning).
35
+ */
36
+ export declare function cloneTree<T extends Root | RootContent>(node: T): T;
@@ -1,4 +1,4 @@
1
- import { Root } from 'xast';
1
+ import { Element, Root } from 'xast';
2
2
  /** One element of the rendered document, in document order. */
3
3
  export interface SourceMapEntry {
4
4
  /** The element's @unique-id — its HTML id when the page emits one. */
@@ -32,6 +32,16 @@ export declare function computeSourceMap(tree: Root, rootFile: string, options?:
32
32
  parentId?: string;
33
33
  position?: number;
34
34
  }): PtxSourceMap;
35
+ /**
36
+ * The @unique-id pretext-assembly.xsl will stamp on `target` — authored or
37
+ * positional — or undefined when `target` is not in `tree` (or is foreign
38
+ * vocabulary, which is never stamped). Same walk and same seating as
39
+ * {@link computeSourceMap}.
40
+ */
41
+ export declare function stampedIdOf(tree: Root, target: Element, options?: {
42
+ parentId?: string;
43
+ position?: number;
44
+ }): string | undefined;
35
45
  /**
36
46
  * The entry to sync to for a cursor at `line`, given the entries of ONE file
37
47
  * in document order (start lines are non-decreasing within a file): the last