@vectojs/markdown 0.14.0 → 0.16.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.
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Color, typography and spacing tokens for `@vectojs/markdown`.
3
+ *
4
+ * Split out of `Markdown.ts` so `CodeBlock` and the inline renderer can take a
5
+ * theme without importing the whole component, which would make the module
6
+ * graph cyclic. See `forge/decisions/file-decomposition-2026-08.md`.
7
+ */
8
+ /**
9
+ * Color, typography and spacing theme for Markdown rendering.
10
+ *
11
+ * The shape is deliberately **flat**, not a nested token tree. Every key is
12
+ * optional and merged over {@link DEFAULT_THEME} by a single spread, so adding a
13
+ * key is backward compatible and a caller may override exactly one value
14
+ * without restating a group. A nested `{ colors: {...}, spacing: {...} }` shape
15
+ * would need a deep merge and would break every existing caller.
16
+ *
17
+ * Sizes and spacing are **numbers in px**, not CSS strings, because the values
18
+ * are consumed by canvas layout arithmetic rather than by a stylesheet.
19
+ */
20
+ export interface MarkdownTheme {
21
+ /** Body text color. */
22
+ textColor?: string;
23
+ /** Heading text color. */
24
+ headingColor?: string;
25
+ /** Code text color (inline + block). */
26
+ codeColor?: string;
27
+ /** Code block background color. */
28
+ codeBgColor?: string;
29
+ /** Blockquote border/accent color. */
30
+ quoteBorderColor?: string;
31
+ /**
32
+ * Blockquote text color. Defaults to {@link MarkdownTheme.textColor} so
33
+ * blockquote body text matches surrounding prose unless overridden.
34
+ */
35
+ quoteTextColor?: string;
36
+ /** Horizontal-rule color. */
37
+ hrColor?: string;
38
+ /** Table background color. */
39
+ tableBgColor?: string;
40
+ /** Table header background color. */
41
+ tableHeaderBgColor?: string;
42
+ /** Link text color. */
43
+ linkColor?: string;
44
+ /**
45
+ * Color of a footnote reference marker and of the label on its definition.
46
+ *
47
+ * Defaults to {@link MarkdownTheme.linkColor} so a marker reads as a
48
+ * cross-reference in whatever palette the caller supplied, rather than being
49
+ * pinned to the stock accent. Derived in {@link resolveTheme}, so overriding
50
+ * only `linkColor` recolours footnote markers too.
51
+ *
52
+ * A marker is deliberately **not** a link: it carries no `href`, so it is
53
+ * neither underlined nor routed to `onLinkClick`. There is no destination to
54
+ * give it — the definition is a sibling block in the same document, not a URL —
55
+ * and synthesising one (`'#fn-1'`) would hand a consumer's click handler a
56
+ * string it would try to open as a page.
57
+ */
58
+ footnoteColor?: string;
59
+ /**
60
+ * Color for TeX source shown verbatim when a formula could not be typeset.
61
+ * Deliberately distinct from body text so an untypeset formula is visible as
62
+ * a failure rather than reading as prose.
63
+ */
64
+ mathFallbackColor?: string;
65
+ /** Code-block keyword color. */
66
+ syntaxKeywordColor?: string;
67
+ /** Code-block string-literal color. */
68
+ syntaxStringColor?: string;
69
+ /** Code-block comment color. */
70
+ syntaxCommentColor?: string;
71
+ /** Code-block numeric-literal color. */
72
+ syntaxNumberColor?: string;
73
+ /** Body font. */
74
+ bodyFont?: string;
75
+ /** Monospace font for code. */
76
+ codeFont?: string;
77
+ /** Base font size in px. */
78
+ fontSize?: number;
79
+ /**
80
+ * Font sizes in px for heading depths 1-6. A shorter array is padded by
81
+ * repeating its last entry; depths past the end clamp to the last entry.
82
+ */
83
+ headingSizes?: readonly number[];
84
+ /** Code-block font size in px. */
85
+ codeFontSize?: number;
86
+ /**
87
+ * Table cell font size in px.
88
+ *
89
+ * Left `undefined` by default and **derived** as `fontSize - 2` (clamped to
90
+ * at least 1) rather than defaulted to a literal, because that is how it was
91
+ * hardcoded before it became a key: a caller who raises only `fontSize` must
92
+ * keep getting a proportionally larger table, which a fixed default would
93
+ * silently break.
94
+ */
95
+ tableFontSize?: number;
96
+ /**
97
+ * Size of a footnote reference marker, as a multiple of the size of the run it
98
+ * sits in.
99
+ *
100
+ * Relative rather than absolute so a marker in a heading scales with the
101
+ * heading, exactly as inline math and inline images do. Smaller than the
102
+ * surrounding prose is the whole visual signal that `[1]` is a reference and
103
+ * not literal text, since {@link TextStyle} has no baseline shift and a raised
104
+ * superscript is therefore not expressible — see `markdown-footnote.ts`.
105
+ */
106
+ footnoteMarkerScale?: number;
107
+ /** Code-block line height in px. */
108
+ codeLineHeight?: number;
109
+ /**
110
+ * Line height in px for body text drawn through the plain-`Text` fallback
111
+ * path (an unrecognised block token that still carries `text`).
112
+ */
113
+ bodyLineHeight?: number;
114
+ /** Vertical gap in px between top-level blocks. */
115
+ blockGap?: number;
116
+ /** Inner padding in px of a code block. */
117
+ codePadding?: number;
118
+ /** Corner radius in px of a code block. */
119
+ codeRadius?: number;
120
+ /** Vertical gap in px between list items. */
121
+ listGap?: number;
122
+ /** Vertical gap in px between blocks inside one multi-block list item. */
123
+ listItemGap?: number;
124
+ /** Left indent in px of a blockquote's contents. */
125
+ quoteIndent?: number;
126
+ /** Width in px of a blockquote's accent border. */
127
+ quoteBorderWidth?: number;
128
+ /** Vertical gap in px between blocks inside a blockquote. */
129
+ quoteInnerGap?: number;
130
+ /** Corner radius in px of an image. */
131
+ imageRadius?: number;
132
+ /**
133
+ * Height of an image that renders *inline*, as a multiple of the run's font
134
+ * size.
135
+ *
136
+ * Applies only where an image shares a line with text — a heading or a table
137
+ * cell. An image that is its own block (the ordinary `![alt](url)` paragraph)
138
+ * still renders at its natural size capped to the available width, and ignores
139
+ * this.
140
+ *
141
+ * A cap rather than the natural size, because an inline object's box is fixed
142
+ * when the span is collected while the natural size is known only after the
143
+ * decode, and because a 512px logo written into an `h1` would otherwise tower
144
+ * over its own heading. The width follows the natural aspect ratio, so a wide
145
+ * badge stays wide. `1.15` keeps a square icon a little shorter than the line it
146
+ * sits on, which is where a cap-height glyph puts its own ink.
147
+ */
148
+ inlineImageScale?: number;
149
+ }
150
+ /**
151
+ * Resolved defaults. Every key of {@link MarkdownTheme} has an entry here, so a
152
+ * resolved theme is `Required<MarkdownTheme>` and no consumer needs a fallback.
153
+ *
154
+ * Two entries are placeholders that {@link resolveTheme} overwrites when the
155
+ * caller did not set them: `quoteTextColor` (follows `textColor`) and
156
+ * `tableFontSize` (derived from `fontSize`). They still carry a literal so this
157
+ * object satisfies `Required<MarkdownTheme>`; read {@link resolveTheme} for the
158
+ * value a caller actually gets.
159
+ */
160
+ export declare const DEFAULT_THEME: Required<MarkdownTheme>;
161
+ /**
162
+ * Merge a caller's partial theme over {@link DEFAULT_THEME}.
163
+ *
164
+ * `tableFontSize` is **derived** from the resolved `fontSize` when the caller
165
+ * did not set it explicitly, so raising only `fontSize` still scales tables.
166
+ * A plain spread cannot express that: `DEFAULT_THEME` has to satisfy
167
+ * `Required<MarkdownTheme>`, so its literal would always win over the
168
+ * derivation.
169
+ */
170
+ export declare function resolveTheme(theme?: MarkdownTheme): Required<MarkdownTheme>;
171
+ /**
172
+ * Font size in px for a 1-based heading depth, clamping past the end of
173
+ * `headingSizes` and tolerating a short or empty array.
174
+ *
175
+ * Extracted so the heading renderer and any caller inspecting the scale agree;
176
+ * an inline `sizes[Math.min(depth - 1, 5)]` silently yields `undefined` for a
177
+ * theme that supplied fewer than six sizes.
178
+ */
179
+ export declare function headingSize(theme: Required<MarkdownTheme>, depth: number): number;
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "@vectojs/markdown",
3
- "version": "0.14.0",
3
+ "version": "0.16.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "description": "Canvas-native Markdown (and TeX math) rendering for VectoJS: a Markdown entity plus CodeBlock, built on @vectojs/ui components with marked + MathJax.",
7
+ "description": "Canvas-native Markdown (and TeX math) rendering for VectoJS: a Markdown entity plus CodeBlock, built on @vectojs/ui components with marked + @vectojs/tex.",
8
8
  "keywords": [
9
9
  "markdown",
10
10
  "marked",
11
- "mathjax",
11
+ "tex",
12
+ "latex",
12
13
  "canvas",
13
14
  "vectojs",
14
15
  "typescript"
@@ -38,13 +39,13 @@
38
39
  "dist"
39
40
  ],
40
41
  "scripts": {
41
- "build": "(cd ../ui && bun run build) && node scripts/build-worker.js && tsup src/index.ts --format cjs,esm --clean && tsc -p tsconfig.build.json",
42
+ "build": "(cd ../ui && bun run build) && (cd ../tex && bun run build) && node scripts/build-worker.js && tsup src/index.ts --format cjs,esm --clean && tsc -p tsconfig.build.json",
42
43
  "test": "vitest run",
43
- "test:e2e": "bun e2e/blockquote-layout.e2e.ts && bun e2e/stream-controller.e2e.ts && bun e2e/lazy-math.e2e.ts && bun e2e/paragraph-image-repaint.e2e.ts && bun e2e/selection-fidelity.e2e.ts && bun e2e/code-atlas-dpr.e2e.ts && bun e2e/set-max-width.e2e.ts && bun e2e/block-affordances.e2e.ts"
44
+ "test:e2e": "bun e2e/blockquote-layout.e2e.ts && bun e2e/stream-controller.e2e.ts && bun e2e/lazy-math.e2e.ts && bun e2e/paragraph-image-repaint.e2e.ts && bun e2e/inline-image.e2e.ts && bun e2e/selection-fidelity.e2e.ts && bun e2e/code-atlas-dpr.e2e.ts && bun e2e/set-max-width.e2e.ts && bun e2e/block-affordances.e2e.ts"
44
45
  },
45
46
  "dependencies": {
46
- "marked": "^18.0.7",
47
- "mathjax-full": "^3.2.2"
47
+ "@vectojs/tex": "^0.1.0",
48
+ "marked": "^18.0.7"
48
49
  },
49
50
  "peerDependencies": {
50
51
  "@vectojs/core": ">=1.25.0 <2.0.0",