@simonklee/opentui-tex 0.2.0 → 0.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  # OpenTUI TeX
2
2
 
3
- OpenTUI TeX renders TeX math in an ordinary renderable tree from
4
- [OpenTUI](https://github.com/anomalyco/opentui):
3
+ OpenTUI TeX renders TeX math in a standard
4
+ [OpenTUI](https://github.com/anomalyco/opentui) renderable tree:
5
5
 
6
6
  ```ts
7
7
  import { TexRenderable, UnicodeTexBackend } from "@simonklee/opentui-tex";
@@ -32,36 +32,40 @@ One package supplies two output types:
32
32
  - `@simonklee/opentui-tex/native` renders formulas as images (Kitty, Sixel, or
33
33
  block cells) through a prebuilt shared library.
34
34
 
35
- Both backends run on Bun and Node. Native rendering requires Node 26.4 or
36
- newer and experimental FFI flags. See [Images](#images).
35
+ Both backends run on Bun and Node. On Node, native rendering requires version
36
+ 26.4 or newer and experimental **foreign function interface (FFI)** flags.
37
+ See [Images](#images).
37
38
 
38
39
  ## Install
39
40
 
40
- Starting with the npm release of 0.2.0, install one package:
41
+ For npm releases from 0.2.0 onward, install one package:
41
42
 
42
43
  ```sh
43
44
  npm install @simonklee/opentui-tex
44
45
  ```
45
46
 
46
- You can also use `bun add`. Like `@opentui/core`, the package uses optional
47
- dependencies to select a prebuilt library for the host platform. No local
48
- native build is required. Prebuilt libraries exist for
49
- x64 and arm64 on macOS, Windows, Linux glibc 2.17, and Linux musl.
50
- On Linux, Bun 1.3.14 installs both libc variants; the loader selects one at runtime.
47
+ You can also use `bun add`.
48
+
49
+ Like `@opentui/core`, the package uses optional dependencies to select a
50
+ prebuilt library for the host platform. You do not need a local native build.
51
+ Prebuilt libraries exist for x64 and arm64 on macOS, Windows, Linux glibc 2.17,
52
+ and Linux musl. On Linux, Bun 1.3.14 installs both libc variants. The loader
53
+ selects one at runtime.
51
54
 
52
55
  `@opentui/core` is a required peer dependency, not a bundled copy. Use the same
53
56
  version across your application and its OpenTUI bindings. This release requires
54
- `0.0.0-20260812-1d34234c`; compatibility with other Core versions is not yet
57
+ `0.0.0-20260812-1d34234c`. Compatibility with other Core versions is not yet
55
58
  verified. npm installs required peers automatically.
56
59
 
57
60
  The JavaScript package is MIT-licensed. The optional native binaries are
58
61
  GPL-3.0-only because they link ZigTeX. Each binary package includes its license
59
- notices, and `@simonklee/opentui-tex-native-source` contains the corresponding
60
- source at the same version. Review those licenses before redistributing native
61
- rendering. The source package is not a runtime dependency.
62
+ notices. Before you redistribute native rendering, review those licenses.
63
+
64
+ `@simonklee/opentui-tex-native-source` contains the corresponding source at
65
+ the same version. The source package is not a runtime dependency.
62
66
 
63
- For applications upgrading from the 0.1.0 GitHub tarballs, replace imports from
64
- `@simonklee/opentui-tex-native` with `@simonklee/opentui-tex/native` and remove
67
+ To upgrade from the 0.1.0 GitHub tarballs, replace imports from
68
+ `@simonklee/opentui-tex-native` with `@simonklee/opentui-tex/native`. Then remove
65
69
  the separate native dependency. The existing 0.1.0 release assets are unchanged.
66
70
 
67
71
  ## TexRenderable
@@ -87,18 +91,25 @@ container.add(formula);
87
91
  Options beyond `BoxOptions`:
88
92
 
89
93
  - `formula` (required): TeX source, at most 4,096 UTF-8 bytes.
90
- - `foreground`, `background` (required): six-digit hex colors (`#rrggbb`).
94
+ - `foreground`, `background` (required): six-digit hexadecimal colors (`#rrggbb`).
91
95
  - `backend` (required): the `TexBackend` that renders the formula.
92
96
  - `display`: display style instead of inline style. The default is `false`.
93
97
  - `widthMax`, `heightMax`: output limits in cells. The defaults are 80 and 24.
94
98
  - `fallback`: behavior after a failure. The default is `"message"`.
95
99
  - `streaming`: preview updates for incomplete input. The default is `false`.
100
+ - `strict`: reject unsupported Unicode commands and delimiters instead of showing
101
+ their names as text. This check also applies to previews. The default is `false`.
96
102
  - `imageOptions`: options for the installed `ImageRenderable`.
97
103
  - `onError`: receives backend errors.
98
104
 
99
- When you assign `formula.formula`, `TexRenderable` installs a synchronous
100
- Unicode preview. It then starts a request for the selected backend. A native
101
- result replaces the preview with an image in the same `TexRenderable`.
105
+ Automatic width and height include borders and padding. Explicit dimensions
106
+ set the outer box size. Unicode output clips to the available cells without
107
+ wrapping mathematical rows.
108
+
109
+ When you assign to `formula.formula`, `TexRenderable` installs synchronous Unicode
110
+ output. With the built-in Unicode backend, this is the final result. Other
111
+ backends run next. A native result replaces the preview with an image in the
112
+ same `TexRenderable`.
102
113
 
103
114
  `formula.whenReady()` tracks replacement requests. It resolves after
104
115
  `TexRenderable` installs the latest result. `formula.ready` exposes the
@@ -106,18 +117,21 @@ current request. `setColors()` renders the formula again after a terminal
106
117
  theme change. `TexRenderable` aborts requests for stale or destroyed nodes.
107
118
 
108
119
  With `streaming: true`, only the synchronous Unicode preview changes. The
109
- layout shows incomplete constructs at the end as `□` placeholders.
120
+ layout shows incomplete constructs at the end of the input as `□` placeholders.
121
+
122
+ The `fallback` option controls behavior after a failure:
123
+
124
+ - `"unicode"` keeps the semantic preview.
125
+ - `"retain"` restores the previous successful backend result.
126
+ - `"message"` displays an error. This is the default.
127
+ - `"throw"` rejects readiness.
110
128
 
111
- The `fallback` option controls behavior after a failure. `"unicode"` keeps the
112
- semantic preview. `"retain"` restores the previous successful backend result.
113
- `"message"` displays an error. `"throw"` rejects readiness. The default is
114
- `"message"`.
129
+ Share one backend across multiple `TexRenderable` instances.
115
130
 
116
- Share one backend across multiple `TexRenderable` instances. A `TexBackend`
117
- transfers ownership of each image output to the receiver. The receiver must
118
- dispose the image. `TexRenderable` manages all images that its backend returns.
119
- This includes stale outputs and outputs kept by the `"retain"` fallback. Thus,
120
- most applications do not manage images directly.
131
+ A `TexBackend` transfers ownership of each image output to the receiver. The
132
+ receiver must dispose the image. `TexRenderable` manages all images that its
133
+ backend returns, including stale outputs and outputs that the `"retain"`
134
+ fallback keeps. Thus, most applications do not manage images directly.
121
135
 
122
136
  ## React and Solid
123
137
 
@@ -154,11 +168,35 @@ an `ImageRenderable`.
154
168
  ### Unicode cells
155
169
 
156
170
  `UnicodeTexBackend` parses a bounded subset of TeX math into an abstract syntax
157
- tree (AST). It lays out fractions, roots, scripts, accents, aligned equations,
158
- matrices, and cases as two-dimensional terminal cells. The output remains
159
- selectable terminal text. `string-width` measures the output. The backend is
160
- stateless and synchronous, and `renderSync` is public. It needs no cache or
161
- explicit destruction.
171
+ tree. It arranges fractions, roots, scripts, accents, aligned equations,
172
+ matrices, cases, and annotated braces as two-dimensional terminal cells. Arrays
173
+ support `l`, `c`, `r`, and vertical rules. Continued fractions accept `[l]` and
174
+ `[r]`. Font commands preserve bold and italic attributes or select Unicode
175
+ mathematical alphabets.
176
+
177
+ The output remains selectable terminal text. `string-width` measures the
178
+ output. The backend is stateless and synchronous, and `renderSync` is public.
179
+ It needs no cache or explicit destruction.
180
+
181
+ To distinguish supported math from source that should remain unrendered, use
182
+ `strict: true`:
183
+
184
+ ```ts
185
+ const output = new UnicodeTexBackend().renderSync({
186
+ formula: String.raw`\mathbb{R} + \mathbf{x}`,
187
+ display: true,
188
+ foreground: "#ffffff",
189
+ background: "#000000",
190
+ widthMax: 80,
191
+ heightMax: 24,
192
+ strict: true,
193
+ signal: new AbortController().signal,
194
+ });
195
+ ```
196
+
197
+ The Unicode backend accepts at most 4,096 UTF-8 source bytes and limits each
198
+ layout box to 16,384 cells before clipping. It does not compile LaTeX documents
199
+ or load user-defined TeX packages.
162
200
 
163
201
  ### Images
164
202
 
@@ -172,28 +210,31 @@ import { NativeTexBackend } from "@simonklee/opentui-tex/native";
172
210
  const backend = new NativeTexBackend();
173
211
  ```
174
212
 
175
- On Linux musl, set `OPENTUI_LIBC=musl` before starting the application so both
176
- OpenTUI and TeX select musl libraries. See [Native rendering](docs/native.md)
177
- for library overrides and standalone executables.
213
+ On Linux musl, set `OPENTUI_LIBC=musl` before you start the application.
214
+ This setting makes OpenTUI and TeX select musl libraries. See
215
+ [Native rendering](docs/native.md) for library overrides and standalone
216
+ executables.
178
217
 
179
218
  MicroTeX parses a TeX-math dialect and computes glyph and rule positions.
180
- ZigTeX records SVG paths for the embedded glyph outlines from Latin Modern
181
- Math. NanoSVG rasterizes only the SVG that ZigTeX generates. It does not
182
- rasterize arbitrary external SVG.
219
+ ZigTeX records **Scalable Vector Graphics (SVG)** paths for the embedded glyph
220
+ outlines from Latin Modern Math. NanoSVG rasterizes only the SVG that ZigTeX
221
+ generates. It does not rasterize arbitrary external SVG.
183
222
 
184
223
  MicroTeX uses one process-wide font context. The native library initializes
185
224
  this context once through `texInit`. It keeps the context for the process
186
- lifetime. The renderer supports only the main JavaScript thread. If you
187
- construct `NativeTexRenderer` in a Worker, the constructor fails immediately.
225
+ lifetime.
226
+
227
+ The renderer supports only the main JavaScript thread. If you construct
228
+ `NativeTexRenderer` in a Worker, the constructor fails immediately.
188
229
 
189
230
  Ownership rules for direct use:
190
231
 
191
- - Direct callers of `NativeTexRenderer.renderAsync()` must dispose each
232
+ - If you call `NativeTexRenderer.renderAsync()` directly, you must dispose each
192
233
  returned image. Cached results use independent retained references. When you
193
234
  dispose one result, the other results stay valid.
194
235
  - `NativeImage.takeRaw()` requires exclusive ownership. Before you call it,
195
- dispose all retained references. These references include the renderer cache
196
- and renderable references.
236
+ dispose all retained references. These include references that the renderer
237
+ cache and renderables hold.
197
238
 
198
239
  ### Custom backends
199
240
 
@@ -206,9 +247,14 @@ interface TexBackend {
206
247
  ```
207
248
 
208
249
  The request contains `formula`, `display`, `foreground`, `background`,
209
- `widthMax`, `heightMax`, and an `AbortSignal`. The output is either
250
+ `widthMax`, `heightMax`, an `AbortSignal`, and optional `strict` validation for
251
+ Unicode math. The output is either
210
252
  `{ kind: "image", image }` or `{ kind: "unicode", text, columns, rows }`.
211
253
 
254
+ Unicode output can also include `spans`, an array of `{ text, color?, bold?, italic? }`
255
+ objects. The concatenated span text equals `text`. `TexRenderable` uses these
256
+ spans to preserve styling. Plain-text consumers can continue to read `text`.
257
+
212
258
  ## Node
213
259
 
214
260
  Native rendering requires Node 26.4 or newer. Start Node with these options:
package/dist/backend.d.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  import type { NativeImage } from "@opentui/core";
2
+ import type { MathStyle } from "./math-types.js";
3
+ export type TexTextSpan = MathStyle & {
4
+ text: string;
5
+ };
2
6
  export interface TexRenderRequest {
3
7
  formula: string;
4
8
  display: boolean;
@@ -7,6 +11,7 @@ export interface TexRenderRequest {
7
11
  widthMax: number;
8
12
  heightMax: number;
9
13
  signal: AbortSignal;
14
+ strict?: boolean;
10
15
  }
11
16
  export type TexRenderOutput = {
12
17
  kind: "image";
@@ -16,6 +21,7 @@ export type TexRenderOutput = {
16
21
  text: string;
17
22
  columns: number;
18
23
  rows: number;
24
+ spans?: TexTextSpan[];
19
25
  };
20
26
  export interface TexBackend {
21
27
  /** The receiver owns image outputs and must dispose them. */