@simonklee/opentui-tex 0.3.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,12 +91,14 @@ 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
 
@@ -100,9 +106,9 @@ Automatic width and height include borders and padding. Explicit dimensions
100
106
  set the outer box size. Unicode output clips to the available cells without
101
107
  wrapping mathematical rows.
102
108
 
103
- When you assign `formula.formula`, `TexRenderable` installs synchronous Unicode
109
+ When you assign to `formula.formula`, `TexRenderable` installs synchronous Unicode
104
110
  output. With the built-in Unicode backend, this is the final result. Other
105
- backends run next; a native result replaces the preview with an image in the
111
+ backends run next. A native result replaces the preview with an image in the
106
112
  same `TexRenderable`.
107
113
 
108
114
  `formula.whenReady()` tracks replacement requests. It resolves after
@@ -111,18 +117,21 @@ current request. `setColors()` renders the formula again after a terminal
111
117
  theme change. `TexRenderable` aborts requests for stale or destroyed nodes.
112
118
 
113
119
  With `streaming: true`, only the synchronous Unicode preview changes. The
114
- 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.
115
128
 
116
- The `fallback` option controls behavior after a failure. `"unicode"` keeps the
117
- semantic preview. `"retain"` restores the previous successful backend result.
118
- `"message"` displays an error. `"throw"` rejects readiness. The default is
119
- `"message"`.
129
+ Share one backend across multiple `TexRenderable` instances.
120
130
 
121
- Share one backend across multiple `TexRenderable` instances. A `TexBackend`
122
- transfers ownership of each image output to the receiver. The receiver must
123
- dispose the image. `TexRenderable` manages all images that its backend returns.
124
- This includes stale outputs and outputs kept by the `"retain"` fallback. Thus,
125
- 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.
126
135
 
127
136
  ## React and Solid
128
137
 
@@ -159,11 +168,35 @@ an `ImageRenderable`.
159
168
  ### Unicode cells
160
169
 
161
170
  `UnicodeTexBackend` parses a bounded subset of TeX math into an abstract syntax
162
- tree (AST). It lays out fractions, roots, scripts, accents, aligned equations,
163
- matrices, and cases as two-dimensional terminal cells. The output remains
164
- selectable terminal text. `string-width` measures the output. The backend is
165
- stateless and synchronous, and `renderSync` is public. It needs no cache or
166
- 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.
167
200
 
168
201
  ### Images
169
202
 
@@ -177,28 +210,31 @@ import { NativeTexBackend } from "@simonklee/opentui-tex/native";
177
210
  const backend = new NativeTexBackend();
178
211
  ```
179
212
 
180
- On Linux musl, set `OPENTUI_LIBC=musl` before starting the application so both
181
- OpenTUI and TeX select musl libraries. See [Native rendering](docs/native.md)
182
- 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.
183
217
 
184
218
  MicroTeX parses a TeX-math dialect and computes glyph and rule positions.
185
- ZigTeX records SVG paths for the embedded glyph outlines from Latin Modern
186
- Math. NanoSVG rasterizes only the SVG that ZigTeX generates. It does not
187
- 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.
188
222
 
189
223
  MicroTeX uses one process-wide font context. The native library initializes
190
224
  this context once through `texInit`. It keeps the context for the process
191
- lifetime. The renderer supports only the main JavaScript thread. If you
192
- 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.
193
229
 
194
230
  Ownership rules for direct use:
195
231
 
196
- - Direct callers of `NativeTexRenderer.renderAsync()` must dispose each
232
+ - If you call `NativeTexRenderer.renderAsync()` directly, you must dispose each
197
233
  returned image. Cached results use independent retained references. When you
198
234
  dispose one result, the other results stay valid.
199
235
  - `NativeImage.takeRaw()` requires exclusive ownership. Before you call it,
200
- dispose all retained references. These references include the renderer cache
201
- and renderable references.
236
+ dispose all retained references. These include references that the renderer
237
+ cache and renderables hold.
202
238
 
203
239
  ### Custom backends
204
240
 
@@ -211,9 +247,14 @@ interface TexBackend {
211
247
  ```
212
248
 
213
249
  The request contains `formula`, `display`, `foreground`, `background`,
214
- `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
215
252
  `{ kind: "image", image }` or `{ kind: "unicode", text, columns, rows }`.
216
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
+
217
258
  ## Node
218
259
 
219
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. */