tex2typst 0.3.22 → 0.3.24

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,221 @@
1
+ import { array_includes } from "./generic";
2
+
3
+ export enum TypstTokenType {
4
+ NONE,
5
+ SYMBOL,
6
+ ELEMENT,
7
+ LITERAL,
8
+ TEXT,
9
+ COMMENT,
10
+ SPACE,
11
+ CONTROL,
12
+ NEWLINE
13
+ }
14
+
15
+
16
+ export class TypstToken {
17
+ type: TypstTokenType;
18
+ value: string;
19
+
20
+ constructor(type: TypstTokenType, content: string) {
21
+ this.type = type;
22
+ this.value = content;
23
+ }
24
+
25
+ eq(other: TypstToken): boolean {
26
+ return this.type === other.type && this.value === other.value;
27
+ }
28
+
29
+ isOneOf(tokens: TypstToken[]): boolean {
30
+ return array_includes(tokens, this);
31
+ }
32
+
33
+ public toNode(): TypstNode {
34
+ return new TypstTerminal(this);
35
+ }
36
+
37
+ public toString(): string {
38
+ switch (this.type) {
39
+ case TypstTokenType.TEXT:
40
+ return `"${this.value}"`;
41
+ case TypstTokenType.COMMENT:
42
+ return `//${this.value}`;
43
+ default:
44
+ return this.value;
45
+ }
46
+ }
47
+
48
+ public static readonly NONE = new TypstToken(TypstTokenType.NONE, '#none');
49
+ }
50
+
51
+ export interface TypstSupsubData {
52
+ base: TypstNode;
53
+ sup: TypstNode | null;
54
+ sub: TypstNode | null;
55
+ }
56
+
57
+
58
+ export interface TypstLeftRightData {
59
+ left: TypstToken | null;
60
+ right: TypstToken | null;
61
+ }
62
+
63
+ /**
64
+ * fraction: `1/2`, `(x + y)/2`, `(1+x)/(1-x)`
65
+ * group: `a + 1/3`
66
+ * leftright: `(a + 1/3)`, `[a + 1/3)`, `lr(]sum_(x=1)^n])`
67
+ */
68
+ export type TypstNodeType = 'terminal' | 'group' | 'supsub' | 'funcCall' | 'fraction'| 'leftright' | 'align' | 'matrix' | 'cases';
69
+
70
+ export type TypstNamedParams = { [key: string]: TypstNode; };
71
+
72
+ export abstract class TypstNode {
73
+ readonly type: TypstNodeType;
74
+ head: TypstToken;
75
+ args?: TypstNode[];
76
+ // Some Typst functions accept additional options. e.g. mat() has option "delim", op() has option "limits"
77
+ options?: TypstNamedParams;
78
+
79
+ constructor(type: TypstNodeType, head: TypstToken | null, args?: TypstNode[]) {
80
+ this.type = type;
81
+ this.head = head ? head : TypstToken.NONE;
82
+ this.args = args;
83
+ }
84
+
85
+ // whether the node is over high so that if it's wrapped in braces, \left and \right should be used in its TeX form
86
+ // e.g. 1/2 is over high, "2" is not.
87
+ abstract isOverHigh(): boolean;
88
+
89
+ public setOptions(options: TypstNamedParams) {
90
+ this.options = options;
91
+ }
92
+
93
+ // Note that this is only shallow equality.
94
+ public eq(other: TypstNode): boolean {
95
+ return this.type === other.type && this.head.eq(other.head);
96
+ }
97
+
98
+ public toString(): string {
99
+ throw new Error(`Unimplemented toString() in base class TypstNode`);
100
+ }
101
+ }
102
+
103
+ export class TypstTerminal extends TypstNode {
104
+ constructor(head: TypstToken) {
105
+ super('terminal', head);
106
+ }
107
+
108
+ public isOverHigh(): boolean {
109
+ return false;
110
+ }
111
+
112
+ public toString(): string {
113
+ return this.head.toString();
114
+ }
115
+ }
116
+
117
+ export class TypstGroup extends TypstNode {
118
+ constructor(args: TypstNode[]) {
119
+ super('group', TypstToken.NONE, args);
120
+ }
121
+
122
+ public isOverHigh(): boolean {
123
+ return this.args!.some((n) => n.isOverHigh());
124
+ }
125
+ }
126
+
127
+ export class TypstSupsub extends TypstNode {
128
+ public base: TypstNode;
129
+ public sup: TypstNode | null;
130
+ public sub: TypstNode | null;
131
+
132
+ constructor(data: TypstSupsubData) {
133
+ super('supsub', TypstToken.NONE, []);
134
+ this.base = data.base;
135
+ this.sup = data.sup;
136
+ this.sub = data.sub;
137
+ }
138
+
139
+ public isOverHigh(): boolean {
140
+ return this.base.isOverHigh();
141
+ }
142
+ }
143
+
144
+ export class TypstFuncCall extends TypstNode {
145
+ constructor(head: TypstToken, args: TypstNode[]) {
146
+ super('funcCall', head, args);
147
+ }
148
+
149
+ public isOverHigh(): boolean {
150
+ if (this.head.value === 'frac') {
151
+ return true;
152
+ }
153
+ return this.args!.some((n) => n.isOverHigh());
154
+ }
155
+ }
156
+
157
+ export class TypstFraction extends TypstNode {
158
+ constructor(args: TypstNode[]) {
159
+ super('fraction', TypstToken.NONE, args);
160
+ }
161
+
162
+ public isOverHigh(): boolean {
163
+ return true;
164
+ }
165
+ }
166
+
167
+
168
+ export class TypstLeftright extends TypstNode {
169
+ public left: TypstToken | null;
170
+ public right: TypstToken | null;
171
+
172
+ constructor(head: TypstToken | null, args: TypstNode[], data: TypstLeftRightData) {
173
+ super('leftright', head, args);
174
+ this.left = data.left;
175
+ this.right = data.right;
176
+ }
177
+
178
+ public isOverHigh(): boolean {
179
+ return this.args!.some((n) => n.isOverHigh());
180
+ }
181
+ }
182
+
183
+ export class TypstAlign extends TypstNode {
184
+ public matrix: TypstNode[][];
185
+
186
+ constructor(data: TypstNode[][]) {
187
+ super('align', TypstToken.NONE, []);
188
+ this.matrix = data;
189
+ }
190
+
191
+ public isOverHigh(): boolean {
192
+ return true;
193
+ }
194
+ }
195
+
196
+ export class TypstMatrix extends TypstNode {
197
+ public matrix: TypstNode[][];
198
+
199
+ constructor(data: TypstNode[][]) {
200
+ super('matrix', TypstToken.NONE, []);
201
+ this.matrix = data;
202
+ }
203
+
204
+ public isOverHigh(): boolean {
205
+ return true;
206
+ }
207
+ }
208
+
209
+ export class TypstCases extends TypstNode {
210
+ public matrix: TypstNode[][];
211
+
212
+ constructor(data: TypstNode[][]) {
213
+ super('cases', TypstToken.NONE, []);
214
+ this.matrix = data;
215
+ }
216
+
217
+ public isOverHigh(): boolean {
218
+ return true;
219
+ }
220
+ }
221
+
@@ -1,9 +1,11 @@
1
- import { TexNode, TypstNode, TypstPrimitiveValue, TypstSupsubData, TypstToken, TypstTokenType } from "./types";
1
+ import { TexNode } from "./tex-types";
2
+ import { TypstAlign, TypstCases, TypstFraction, TypstFuncCall, TypstGroup, TypstLeftright, TypstMatrix, TypstNode, TypstSupsub, TypstTerminal } from "./typst-types";
3
+ import { TypstToken } from "./typst-types";
4
+ import { TypstTokenType } from "./typst-types";
2
5
  import { shorthandMap } from "./typst-shorthands";
3
- import { assert } from "./util";
4
6
 
5
7
  function is_delimiter(c: TypstNode): boolean {
6
- return c.type === 'atom' && ['(', ')', '[', ']', '{', '}', '|', '⌊', '⌋', '⌈', '⌉'].includes(c.content);
8
+ return c.head.type === TypstTokenType.ELEMENT && ['(', ')', '[', ']', '{', '}', '|', '⌊', '⌋', '⌈', '⌉'].includes(c.head.value);
7
9
  }
8
10
 
9
11
  const TYPST_LEFT_PARENTHESIS: TypstToken = new TypstToken(TypstTokenType.ELEMENT, '(');
@@ -13,20 +15,6 @@ const TYPST_NEWLINE: TypstToken = new TypstToken(TypstTokenType.SYMBOL, '\n');
13
15
 
14
16
  const SOFT_SPACE = new TypstToken(TypstTokenType.CONTROL, ' ');
15
17
 
16
- function typst_primitive_to_string(value: TypstPrimitiveValue) {
17
- switch (typeof value) {
18
- case 'string':
19
- return `"${value}"`;
20
- case 'number':
21
- return (value as number).toString();
22
- case 'boolean':
23
- return (value as boolean) ? '#true' : '#false';
24
- default:
25
- assert(value instanceof TypstNode, 'Not a valid primitive value');
26
- return (value as TypstNode).content;
27
- }
28
- }
29
-
30
18
  export class TypstWriterError extends Error {
31
19
  node: TexNode | TypstNode | TypstToken;
32
20
 
@@ -106,62 +94,83 @@ export class TypstWriter {
106
94
  }
107
95
 
108
96
  // Serialize a tree of TypstNode into a list of TypstToken
109
- public serialize(node: TypstNode) {
110
- switch (node.type) {
111
- case 'none':
112
- this.queue.push(new TypstToken(TypstTokenType.NONE, '#none'));
113
- break;
114
- case 'atom': {
115
- if (node.content === ',' && this.insideFunctionDepth > 0) {
116
- this.queue.push(new TypstToken(TypstTokenType.SYMBOL, 'comma'));
97
+ public serialize(abstractNode: TypstNode) {
98
+ switch (abstractNode.type) {
99
+ case 'terminal': {
100
+ const node = abstractNode as TypstTerminal;
101
+ if (node.head.type === TypstTokenType.ELEMENT) {
102
+ if (node.head.value === ',' && this.insideFunctionDepth > 0) {
103
+ this.queue.push(new TypstToken(TypstTokenType.SYMBOL, 'comma'));
104
+ } else {
105
+ this.queue.push(node.head);
106
+ }
107
+ break;
108
+ } else if (node.head.type === TypstTokenType.SYMBOL) {
109
+ let symbol_name = node.head.value;
110
+ if(this.preferShorthands) {
111
+ if (shorthandMap.has(symbol_name)) {
112
+ symbol_name = shorthandMap.get(symbol_name)!;
113
+ }
114
+ }
115
+ if (this.inftyToOo && symbol_name === 'infinity') {
116
+ symbol_name = 'oo';
117
+ }
118
+ this.queue.push(new TypstToken(TypstTokenType.SYMBOL, symbol_name));
119
+ break;
120
+ } else if (node.head.type === TypstTokenType.SPACE || node.head.type === TypstTokenType.NEWLINE) {
121
+ for (const c of node.head.value) {
122
+ if (c === ' ') {
123
+ if (this.keepSpaces) {
124
+ this.queue.push(new TypstToken(TypstTokenType.SPACE, c));
125
+ }
126
+ } else if (c === '\n') {
127
+ this.queue.push(new TypstToken(TypstTokenType.SYMBOL, c));
128
+ } else {
129
+ throw new TypstWriterError(`Unexpected whitespace character: ${c}`, node);
130
+ }
131
+ }
132
+ break;
117
133
  } else {
118
- this.queue.push(new TypstToken(TypstTokenType.ELEMENT, node.content));
134
+ this.queue.push(node.head);
135
+ break;
119
136
  }
120
- break;
121
137
  }
122
- case 'symbol': {
123
- let content = node.content;
124
- if(this.preferShorthands) {
125
- if (shorthandMap.has(content)) {
126
- content = shorthandMap.get(content)!;
127
- }
128
- }
129
- if (this.inftyToOo && content === 'infinity') {
130
- content = 'oo';
138
+ case 'group': {
139
+ const node = abstractNode as TypstGroup;
140
+ for (const item of node.args!) {
141
+ this.serialize(item);
131
142
  }
132
- this.queue.push(new TypstToken(TypstTokenType.SYMBOL, content));
133
143
  break;
134
144
  }
135
- case 'text':
136
- this.queue.push(new TypstToken(TypstTokenType.TEXT, node.content));
137
- break;
138
- case 'comment':
139
- this.queue.push(new TypstToken(TypstTokenType.COMMENT, node.content));
140
- break;
141
- case 'whitespace':
142
- for (const c of node.content) {
143
- if (c === ' ') {
144
- if (this.keepSpaces) {
145
- this.queue.push(new TypstToken(TypstTokenType.SPACE, c));
146
- }
147
- } else if (c === '\n') {
148
- this.queue.push(new TypstToken(TypstTokenType.SYMBOL, c));
149
- } else {
150
- throw new TypstWriterError(`Unexpected whitespace character: ${c}`, node);
151
- }
145
+ case 'leftright': {
146
+ const node = abstractNode as TypstLeftright;
147
+ const LR = new TypstToken(TypstTokenType.SYMBOL, 'lr');
148
+ const {left, right} = node;
149
+ if (node.head.eq(LR)) {
150
+ this.queue.push(LR);
151
+ this.queue.push(TYPST_LEFT_PARENTHESIS);
152
+ }
153
+ if (left) {
154
+ this.queue.push(left);
152
155
  }
153
- break;
154
- case 'group':
155
156
  for (const item of node.args!) {
156
157
  this.serialize(item);
157
158
  }
159
+ if (right) {
160
+ this.queue.push(right);
161
+ }
162
+ if (node.head.eq(LR)) {
163
+ this.queue.push(TYPST_RIGHT_PARENTHESIS);
164
+ }
158
165
  break;
166
+ }
159
167
  case 'supsub': {
160
- let { base, sup, sub } = node.data as TypstSupsubData;
168
+ const node = abstractNode as TypstSupsub;
169
+ let { base, sup, sub } = node;
161
170
  this.appendWithBracketsIfNeeded(base);
162
171
 
163
172
  let trailing_space_needed = false;
164
- const has_prime = (sup && sup.type === 'atom' && sup.content === '\'');
173
+ const has_prime = (sup && sup.head.eq(new TypstToken(TypstTokenType.ELEMENT, "'")));
165
174
  if (has_prime) {
166
175
  // Put prime symbol before '_'. Because $y_1'$ is not displayed properly in Typst (so far)
167
176
  // e.g.
@@ -184,11 +193,10 @@ export class TypstWriter {
184
193
  break;
185
194
  }
186
195
  case 'funcCall': {
187
- const func_symbol: TypstToken = new TypstToken(TypstTokenType.SYMBOL, node.content);
196
+ const node = abstractNode as TypstFuncCall;
197
+ const func_symbol: TypstToken = node.head;
188
198
  this.queue.push(func_symbol);
189
- if (node.content !== 'lr') {
190
- this.insideFunctionDepth++;
191
- }
199
+ this.insideFunctionDepth++;
192
200
  this.queue.push(TYPST_LEFT_PARENTHESIS);
193
201
  for (let i = 0; i < node.args!.length; i++) {
194
202
  this.serialize(node.args![i]);
@@ -198,17 +206,15 @@ export class TypstWriter {
198
206
  }
199
207
  if (node.options) {
200
208
  for (const [key, value] of Object.entries(node.options)) {
201
- const value_str = typst_primitive_to_string(value);
202
- this.queue.push(new TypstToken(TypstTokenType.SYMBOL, `, ${key}: ${value_str}`));
209
+ this.queue.push(new TypstToken(TypstTokenType.LITERAL, `, ${key}: ${value.toString()}`));
203
210
  }
204
211
  }
205
212
  this.queue.push(TYPST_RIGHT_PARENTHESIS);
206
- if (node.content !== 'lr') {
207
- this.insideFunctionDepth--;
208
- }
213
+ this.insideFunctionDepth--;
209
214
  break;
210
215
  }
211
216
  case 'fraction': {
217
+ const node = abstractNode as TypstFraction;
212
218
  const [numerator, denominator] = node.args!;
213
219
  const pos = this.queue.length;
214
220
  const no_wrap = this.appendWithBracketsIfNeeded(numerator);
@@ -225,7 +231,8 @@ export class TypstWriter {
225
231
  break;
226
232
  }
227
233
  case 'align': {
228
- const matrix = node.data as TypstNode[][];
234
+ const node = abstractNode as TypstAlign;
235
+ const matrix = node.matrix;
229
236
  matrix.forEach((row, i) => {
230
237
  row.forEach((cell, j) => {
231
238
  if (j > 0) {
@@ -240,14 +247,14 @@ export class TypstWriter {
240
247
  break;
241
248
  }
242
249
  case 'matrix': {
243
- const matrix = node.data as TypstNode[][];
250
+ const node = abstractNode as TypstMatrix;
251
+ const matrix = node.matrix;
244
252
  this.queue.push(new TypstToken(TypstTokenType.SYMBOL, 'mat'));
245
253
  this.insideFunctionDepth++;
246
254
  this.queue.push(TYPST_LEFT_PARENTHESIS);
247
255
  if (node.options) {
248
256
  for (const [key, value] of Object.entries(node.options)) {
249
- const value_str = typst_primitive_to_string(value);
250
- this.queue.push(new TypstToken(TypstTokenType.SYMBOL, `${key}: ${value_str}, `));
257
+ this.queue.push(new TypstToken(TypstTokenType.LITERAL, `${key}: ${value.toString()}, `));
251
258
  }
252
259
  }
253
260
  matrix.forEach((row, i) => {
@@ -276,14 +283,14 @@ export class TypstWriter {
276
283
  break;
277
284
  }
278
285
  case 'cases': {
279
- const cases = node.data as TypstNode[][];
286
+ const node = abstractNode as TypstCases;
287
+ const cases = node.matrix;
280
288
  this.queue.push(new TypstToken(TypstTokenType.SYMBOL, 'cases'));
281
289
  this.insideFunctionDepth++;
282
290
  this.queue.push(TYPST_LEFT_PARENTHESIS);
283
291
  if (node.options) {
284
292
  for (const [key, value] of Object.entries(node.options)) {
285
- const value_str = typst_primitive_to_string(value);
286
- this.queue.push(new TypstToken(TypstTokenType.SYMBOL, `${key}: ${value_str}, `));
293
+ this.queue.push(new TypstToken(TypstTokenType.LITERAL, `${key}: ${value.toString()}, `));
287
294
  }
288
295
  }
289
296
  cases.forEach((row, i) => {
@@ -302,21 +309,13 @@ export class TypstWriter {
302
309
  this.insideFunctionDepth--;
303
310
  break;
304
311
  }
305
- case 'unknown': {
306
- if (this.nonStrict) {
307
- this.queue.push(new TypstToken(TypstTokenType.SYMBOL, node.content));
308
- } else {
309
- throw new TypstWriterError(`Unknown macro: ${node.content}`, node);
310
- }
311
- break;
312
- }
313
312
  default:
314
- throw new TypstWriterError(`Unimplemented node type to append: ${node.type}`, node);
313
+ throw new TypstWriterError(`Unimplemented node type to append: ${abstractNode.type}`, abstractNode);
315
314
  }
316
315
  }
317
316
 
318
317
  private appendWithBracketsIfNeeded(node: TypstNode): boolean {
319
- let need_to_wrap = ['group', 'supsub', 'fraction','empty'].includes(node.type);
318
+ let need_to_wrap = ['group', 'supsub', 'align', 'fraction','empty'].includes(node.type);
320
319
 
321
320
  if (node.type === 'group') {
322
321
  if (node.args!.length === 0) {
package/src/util.ts CHANGED
@@ -7,7 +7,7 @@ export function isdigit(char: string): boolean {
7
7
  return '0123456789'.includes(char);
8
8
  }
9
9
 
10
- export function assert(condition: boolean, message: string = ''): void {
10
+ export function assert(condition: boolean, message: string = 'Assertion failed.'): void {
11
11
  if (!condition) {
12
12
  throw new Error(message);
13
13
  }
package/dist/types.d.ts DELETED
@@ -1,111 +0,0 @@
1
- export declare enum TexTokenType {
2
- ELEMENT = 0,
3
- COMMAND = 1,
4
- TEXT = 2,
5
- COMMENT = 3,
6
- SPACE = 4,
7
- NEWLINE = 5,
8
- CONTROL = 6,
9
- UNKNOWN = 7
10
- }
11
- export declare class TexToken {
12
- type: TexTokenType;
13
- value: string;
14
- constructor(type: TexTokenType, value: string);
15
- eq(token: TexToken): boolean;
16
- toString(): string;
17
- }
18
- export interface TexSupsubData {
19
- base: TexNode;
20
- sup?: TexNode;
21
- sub?: TexNode;
22
- }
23
- export type TexSqrtData = TexNode;
24
- export type TexArrayData = TexNode[][];
25
- /**
26
- * element: 0-9, a-z, A-Z, punctuations such as +-/*,:; etc.
27
- * symbol: LaTeX macro with no parameter. e.g. \sin \cos \int \sum
28
- * unaryFunc: LaTeX macro with 1 parameter. e.g. \sqrt{3} \log{x} \exp{x}
29
- * binaryFunc: LaTeX macro with 2 parameters. e.g. \frac{1}{2}
30
- * text: text enclosed by braces. e.g. \text{hello world}
31
- * empty: special type when something is empty. e.g. the base of _{a} or ^{a}
32
- * whitespace: space, tab, newline
33
- */
34
- type TexNodeType = 'element' | 'text' | 'comment' | 'whitespace' | 'control' | 'ordgroup' | 'supsub' | 'unaryFunc' | 'binaryFunc' | 'leftright' | 'beginend' | 'symbol' | 'empty' | 'unknownMacro';
35
- export declare class TexNode {
36
- type: TexNodeType;
37
- content: string;
38
- args?: TexNode[];
39
- data?: TexSqrtData | TexSupsubData | TexArrayData;
40
- constructor(type: TexNodeType, content: string, args?: TexNode[], data?: TexSqrtData | TexSupsubData | TexArrayData);
41
- eq(other: TexNode): boolean;
42
- toString(): string;
43
- serialize(): TexToken[];
44
- }
45
- export declare enum TypstTokenType {
46
- NONE = 0,
47
- SYMBOL = 1,
48
- ELEMENT = 2,
49
- TEXT = 3,
50
- COMMENT = 4,
51
- SPACE = 5,
52
- CONTROL = 6,
53
- NEWLINE = 7
54
- }
55
- export declare class TypstToken {
56
- type: TypstTokenType;
57
- value: string;
58
- constructor(type: TypstTokenType, content: string);
59
- eq(other: TypstToken): boolean;
60
- isOneOf(tokens: TypstToken[]): boolean;
61
- toNode(): TypstNode;
62
- toString(): string;
63
- }
64
- export interface TypstSupsubData {
65
- base: TypstNode;
66
- sup?: TypstNode;
67
- sub?: TypstNode;
68
- }
69
- export type TypstArrayData = TypstNode[][];
70
- export interface TypstLrData {
71
- leftDelim: string | null;
72
- rightDelim: string | null;
73
- }
74
- type TypstNodeType = 'atom' | 'symbol' | 'text' | 'control' | 'comment' | 'whitespace' | 'none' | 'group' | 'supsub' | 'funcCall' | 'fraction' | 'align' | 'matrix' | 'cases' | 'unknown';
75
- export type TypstPrimitiveValue = string | boolean | TypstNode;
76
- export type TypstNamedParams = {
77
- [key: string]: TypstPrimitiveValue;
78
- };
79
- export declare class TypstNode {
80
- type: TypstNodeType;
81
- content: string;
82
- args?: TypstNode[];
83
- data?: TypstSupsubData | TypstArrayData | TypstLrData;
84
- options?: TypstNamedParams;
85
- constructor(type: TypstNodeType, content: string, args?: TypstNode[], data?: TypstSupsubData | TypstArrayData | TypstLrData);
86
- setOptions(options: TypstNamedParams): void;
87
- eq(other: TypstNode): boolean;
88
- isOverHigh(): boolean;
89
- }
90
- export declare const TYPST_NONE: TypstNode;
91
- export declare const TYPST_TRUE: TypstPrimitiveValue;
92
- export declare const TYPST_FALSE: TypstPrimitiveValue;
93
- /**
94
- * ATTENTION:
95
- * Don't use any options except those explicitly documented in
96
- * https://github.com/qwinsi/tex2typst/blob/main/docs/api-reference.md
97
- * Any undocumented options may be not working at present or break in the future!
98
- */
99
- export interface Tex2TypstOptions {
100
- nonStrict?: boolean; /** default is true */
101
- preferShorthands?: boolean; /** default is true */
102
- keepSpaces?: boolean; /** default is false */
103
- fracToSlash?: boolean; /** default is true */
104
- inftyToOo?: boolean; /** default is false */
105
- optimize?: boolean; /** default is true */
106
- nonAsciiWrapper?: string; /** default is "" */
107
- customTexMacros?: {
108
- [key: string]: string;
109
- };
110
- }
111
- export {};