tex2typst 0.3.0 → 0.3.2

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,51 @@
1
+ const shorthandMap = new Map<string, string>([
2
+ ['arrow.l.r.double.long', '<==>'],
3
+ ['arrow.l.r.long', '<-->'],
4
+ ['arrow.r.bar', '|->'],
5
+ ['arrow.r.double.bar', '|=>'],
6
+ ['arrow.r.double.long', '==>'],
7
+ ['arrow.r.long', '-->'],
8
+ ['arrow.r.long.squiggly', '~~>'],
9
+ ['arrow.r.tail', '>->'],
10
+ ['arrow.r.twohead', '->>'],
11
+ ['arrow.l.double.long', '<=='],
12
+ ['arrow.l.long', '<--'],
13
+ ['arrow.l.long.squiggly', '<~~'],
14
+ ['arrow.l.tail', '<-<'],
15
+ ['arrow.l.twohead', '<<-'],
16
+ ['arrow.l.r', '<->'],
17
+ ['arrow.l.r.double', '<=>'],
18
+ ['colon.double.eq', '::='],
19
+ ['dots.h', '...'],
20
+ ['gt.triple', '>>>'],
21
+ ['lt.triple', '<<<'],
22
+ ['arrow.r', '->'],
23
+ ['arrow.r.double', '=>'],
24
+ ['arrow.r.squiggly', '~>'],
25
+ ['arrow.l', '<-'],
26
+ ['arrow.l.squiggly', '<~'],
27
+ ['bar.v.double', '||'],
28
+ ['bracket.l.double', '[|'],
29
+ ['bracket.r.double', '|]'],
30
+ ['colon.eq', ':='],
31
+ ['eq.colon', '=:'],
32
+ ['eq.not', '!='],
33
+ ['gt.double', '>>'],
34
+ ['gt.eq', '>='],
35
+ ['lt.double', '<<'],
36
+ ['lt.eq', '<='],
37
+ ['ast.op', '*'],
38
+ ['minus', '-'],
39
+ ['tilde.op', '~'],
40
+ ]);
41
+
42
+
43
+ const reverseShorthandMap = new Map<string, string>();
44
+ for (const [key, value] of shorthandMap.entries()) {
45
+ // filter out single character values ('-', '~', '*')
46
+ if(value.length > 1) {
47
+ reverseShorthandMap.set(value, key);
48
+ }
49
+ }
50
+
51
+ export { shorthandMap, reverseShorthandMap };
@@ -1,29 +1,33 @@
1
- import { TexNode, TypstNode, TypstSupsubData, TypstToken, TypstTokenType } from "./types";
2
-
3
-
4
- // symbols that are supported by Typst but not by KaTeX
5
- export const TYPST_INTRINSIC_SYMBOLS = [
6
- 'dim',
7
- 'id',
8
- 'im',
9
- 'mod',
10
- 'Pr',
11
- 'sech',
12
- 'csch',
13
- // 'sgn
14
- ];
15
-
1
+ import { TexNode, TypstNode, TypstPrimitiveValue, TypstSupsubData, TypstToken, TypstTokenType } from "./types";
2
+ import { shorthandMap } from "./typst-shorthands";
16
3
 
17
4
  function is_delimiter(c: TypstNode): boolean {
18
5
  return c.type === 'atom' && ['(', ')', '[', ']', '{', '}', '|', '⌊', '⌋', '⌈', '⌉'].includes(c.content);
19
6
  }
20
7
 
21
-
22
8
  const TYPST_LEFT_PARENTHESIS: TypstToken = new TypstToken(TypstTokenType.ELEMENT, '(');
23
9
  const TYPST_RIGHT_PARENTHESIS: TypstToken = new TypstToken(TypstTokenType.ELEMENT, ')');
24
10
  const TYPST_COMMA: TypstToken = new TypstToken(TypstTokenType.ELEMENT, ',');
25
11
  const TYPST_NEWLINE: TypstToken = new TypstToken(TypstTokenType.SYMBOL, '\n');
26
12
 
13
+ function typst_primitive_to_string(value: TypstPrimitiveValue) {
14
+ switch (typeof value) {
15
+ case 'string':
16
+ return `"${value}"`;
17
+ case 'number':
18
+ return (value as number).toString();
19
+ case 'boolean':
20
+ return (value as boolean) ? '#true' : '#false';
21
+ default:
22
+ if (value === null) {
23
+ return '#none';
24
+ } else if (value instanceof TypstToken) {
25
+ return value.toString();
26
+ }
27
+ throw new TypstWriterError(`Invalid primitive value: ${value}`, value);
28
+ }
29
+ }
30
+
27
31
  export class TypstWriterError extends Error {
28
32
  node: TexNode | TypstNode | TypstToken;
29
33
 
@@ -34,20 +38,29 @@ export class TypstWriterError extends Error {
34
38
  }
35
39
  }
36
40
 
41
+ export interface TypstWriterOptions {
42
+ nonStrict: boolean;
43
+ preferShorthands: boolean;
44
+ keepSpaces: boolean;
45
+ inftyToOo: boolean;
46
+ }
47
+
37
48
  export class TypstWriter {
38
49
  private nonStrict: boolean;
39
- private preferTypstIntrinsic: boolean;
50
+ private preferShorthands: boolean;
40
51
  private keepSpaces: boolean;
52
+ private inftyToOo: boolean;
41
53
 
42
54
  protected buffer: string = "";
43
55
  protected queue: TypstToken[] = [];
44
56
 
45
57
  private insideFunctionDepth = 0;
46
58
 
47
- constructor(nonStrict: boolean, preferTypstIntrinsic: boolean, keepSpaces: boolean) {
48
- this.nonStrict = nonStrict;
49
- this.preferTypstIntrinsic = preferTypstIntrinsic;
50
- this.keepSpaces = keepSpaces;
59
+ constructor(opt: TypstWriterOptions) {
60
+ this.nonStrict = opt.nonStrict;
61
+ this.preferShorthands = opt.preferShorthands;
62
+ this.keepSpaces = opt.keepSpaces;
63
+ this.inftyToOo = opt.inftyToOo;
51
64
  }
52
65
 
53
66
 
@@ -58,6 +71,8 @@ export class TypstWriter {
58
71
  return;
59
72
  }
60
73
 
74
+ // TODO: "C \frac{xy}{z}" should translate to "C (x y)/z" instead of "C(x y)/z"
75
+
61
76
  let no_need_space = false;
62
77
  // putting the first token in clause
63
78
  no_need_space ||= /[\(\[\|]$/.test(this.buffer) && /^\w/.test(str);
@@ -105,9 +120,19 @@ export class TypstWriter {
105
120
  }
106
121
  break;
107
122
  }
108
- case 'symbol':
109
- this.queue.push(new TypstToken(TypstTokenType.SYMBOL, node.content));
123
+ case 'symbol': {
124
+ let content = node.content;
125
+ if(this.preferShorthands) {
126
+ if (shorthandMap.has(content)) {
127
+ content = shorthandMap.get(content)!;
128
+ }
129
+ }
130
+ if (this.inftyToOo && content === 'infinity') {
131
+ content = 'oo';
132
+ }
133
+ this.queue.push(new TypstToken(TypstTokenType.SYMBOL, content));
110
134
  break;
135
+ }
111
136
  case 'text':
112
137
  this.queue.push(new TypstToken(TypstTokenType.TEXT, node.content));
113
138
  break;
@@ -172,7 +197,8 @@ export class TypstWriter {
172
197
  }
173
198
  if (node.options) {
174
199
  for (const [key, value] of Object.entries(node.options)) {
175
- this.queue.push(new TypstToken(TypstTokenType.SYMBOL, `, ${key}: ${value}`));
200
+ const value_str = typst_primitive_to_string(value);
201
+ this.queue.push(new TypstToken(TypstTokenType.SYMBOL, `, ${key}: ${value_str}`));
176
202
  }
177
203
  }
178
204
  this.queue.push(TYPST_RIGHT_PARENTHESIS);
@@ -220,7 +246,8 @@ export class TypstWriter {
220
246
  this.queue.push(TYPST_LEFT_PARENTHESIS);
221
247
  if (node.options) {
222
248
  for (const [key, value] of Object.entries(node.options)) {
223
- this.queue.push(new TypstToken(TypstTokenType.SYMBOL, `${key}: ${value}, `));
249
+ const value_str = typst_primitive_to_string(value);
250
+ this.queue.push(new TypstToken(TypstTokenType.SYMBOL, `${key}: ${value_str}, `));
224
251
  }
225
252
  }
226
253
  matrix.forEach((row, i) => {
@@ -0,0 +1,33 @@
1
+ import urllib.request
2
+ import html
3
+ from bs4 import BeautifulSoup
4
+
5
+
6
+ if __name__ == '__main__':
7
+ shorthand_map = []
8
+
9
+
10
+ url = "https://typst.app/docs/reference/symbols/"
11
+ with urllib.request.urlopen(url) as response:
12
+ html_text = response.read().decode('utf-8')
13
+
14
+ soup = BeautifulSoup(html_text, 'html.parser')
15
+
16
+ # <ul class="symbol-grid">
17
+ ul_list = soup.find_all('ul', class_='symbol-grid')
18
+ # ul_shorthands_markup = ul_list[0]
19
+ ul_shorthands_math = ul_list[1]
20
+
21
+ li_list = ul_shorthands_math.find_all('li')
22
+ for li in li_list:
23
+ # e.g. <li id="symbol-arrow.r" data-math-shorthand="-&gt;"><button>...</button></li>
24
+ # ==> typst = "arrow.r"
25
+ # ==> shorthand = "->"
26
+ typst = li['id'][7:]
27
+ shorthand = html.unescape(li['data-math-shorthand'])
28
+ shorthand_map.append((typst, shorthand))
29
+
30
+ # Sort by length of shorthand, order from longest to shortest
31
+ shorthand_map.sort(key=lambda x: len(x[1]), reverse=True)
32
+ for typst, shorthand in shorthand_map:
33
+ print(f"['{typst}', '{shorthand}'],")
@@ -1,12 +1,13 @@
1
- import requests
1
+ import urllib.request
2
2
  from bs4 import BeautifulSoup
3
3
 
4
-
5
4
  if __name__ == '__main__':
6
5
  symbol_map = {}
7
6
 
8
7
  url = "https://typst.app/docs/reference/symbols/sym/"
9
- html_text = requests.get(url).text
8
+ with urllib.request.urlopen(url) as response:
9
+ html_text = response.read().decode('utf-8')
10
+
10
11
  soup = BeautifulSoup(html_text, 'html.parser')
11
12
  # <ul class="symbol-grid">
12
13
  ul = soup.find('ul', class_='symbol-grid')