From c2bb83367d817a91987ed1b2318b22d1de805ff2 Mon Sep 17 00:00:00 2001 From: qwinsi <70425035+qwinsi@users.noreply.github.com> Date: Tue, 10 Sep 2024 23:24:57 +0800 Subject: [PATCH] fix 2 wrong cases --- src/writer.ts | 47 +++++++++++++++++++++++++++++------------------ test/math.yml | 8 +++++++- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/writer.ts b/src/writer.ts index 57ef2ff..67f32f8 100644 --- a/src/writer.ts +++ b/src/writer.ts @@ -14,6 +14,11 @@ const TYPST_INTRINSIC_SYMBOLS = [ // 'sgn ]; + +function is_delimiter(c: TypstNode): boolean { + return c.type === 'atom' && ['(', ')', '[', ']', '{', '}', '|', '⌊', '⌋', '⌈', '⌉'].includes(c.content); +} + export class TypstWriterError extends Error { node: TexNode | TypstNode; @@ -60,7 +65,7 @@ export class TypstWriter { // buffer is empty no_need_space ||= this.buffer === ""; // other cases - no_need_space ||= /[\s"_^{\(]$/.test(this.buffer); + no_need_space ||= /[\s_^{\(]$/.test(this.buffer); if(!no_need_space) { this.buffer += ' '; } @@ -77,14 +82,15 @@ export class TypstWriter { switch (node.type) { case 'empty': break; - case 'symbol': { - let content = node.content!; + case 'atom': { if (node.content === ',' && this.insideFunctionDepth > 0) { - content = 'comma'; + this.queue.push({ type: 'symbol', content: 'comma' }); + } else { + this.queue.push({ type: 'atom', content: node.content }); } - this.queue.push({ type: 'symbol', content: content }); break; } + case 'symbol': case 'text': case 'comment': case 'newline': @@ -100,7 +106,7 @@ export class TypstWriter { this.appendWithBracketsIfNeeded(base); let trailing_space_needed = false; - const has_prime = (sup && sup.type === 'symbol' && sup.content === '\''); + const has_prime = (sup && sup.type === 'atom' && sup.content === '\''); if (has_prime) { // Put prime symbol before '_'. Because $y_1'$ is not displayed properly in Typst (so far) // e.g. @@ -206,21 +212,25 @@ export class TypstWriter { } private appendWithBracketsIfNeeded(node: TypstNode): boolean { - const is_single = !['group', 'supsub', 'empty'].includes(node.type); - if (is_single) { + let need_to_wrap = ['group', 'supsub', 'empty'].includes(node.type); + + if (node.type === 'group') { + const first = node.args![0]; + const last = node.args![node.args!.length - 1]; + if (is_delimiter(first) && is_delimiter(last)) { + need_to_wrap = false; + } + } + + if (need_to_wrap) { + this.queue.push({ type: 'atom', content: '(' }); this.append(node); + this.queue.push({ type: 'atom', content: ')' }); } else { - this.queue.push({ - type: 'atom', - content: '(' - }); this.append(node); - this.queue.push({ - type: 'atom', - content: ')' - }); } - return is_single; + + return !need_to_wrap; } protected flushQueue() { @@ -288,6 +298,7 @@ export function convertTree(node: TexNode): TypstNode { args: node.args!.map(convertTree), }; case 'element': + return { type: 'atom', content: convertToken(node.content) }; case 'symbol': return { type: 'symbol', content: convertToken(node.content) }; case 'text': @@ -382,7 +393,7 @@ export function convertTree(node: TexNode): TypstNode { }; } // \mathbb{R} -> RR - if (node.content === '\\mathbb' && arg0.type === 'symbol' && /^[A-Z]$/.test(arg0.content)) { + if (node.content === '\\mathbb' && arg0.type === 'atom' && /^[A-Z]$/.test(arg0.content)) { return { type: 'symbol', content: arg0.content + arg0.content, diff --git a/test/math.yml b/test/math.yml index f58ffc0..a6a829d 100644 --- a/test/math.yml +++ b/test/math.yml @@ -302,4 +302,10 @@ cases: typst: a thin b - title: space before or after script tex: \lim _{x \to 0} \sum_{i=1} ^ n - typst: lim_(x arrow.r 0) sum_(i = 1)^n \ No newline at end of file + typst: lim_(x arrow.r 0) sum_(i = 1)^n + - title: spaces around text + tex: i_D = \mu_n C_\text{ox} \frac{W}{L} \left[ (v_\text{GS} - V_t)v_\text{DS} - \frac{1}{2} v_\text{DS}^2 \right] + typst: i_D = mu_n C_"ox" frac(W, L) [(v_"GS" - V_t) v_"DS" - frac(1, 2) v_"DS"^2 ] + - title: base is group wrapped in brackets + tex: e = \lim_{{n \to \infty}} \left(1 + \frac{1}{n}\right)^n + typst: e = lim_(n arrow.r infinity)(1 + frac(1, n))^n \ No newline at end of file