Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🧮 Updates to check, bar, bf, widetilde, aligned #17

Merged
merged 1 commit into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ export function parseLatex(value: string) {
ddot: { signature: 'm' },
hat: { signature: 'm' },
tilde: { signature: 'm' },
check: { signature: 'm' },
bar: { signature: 'm' },
widehat: { signature: 'm' },
widetilde: { signature: 'm' },
overset: { signature: 'm m' },
underset: { signature: 'm m' },
overbrace: { signature: 'm' },
Expand All @@ -43,6 +46,8 @@ export function parseLatex(value: string) {
overleftarrow: { signature: 'm' },
stackrel: { signature: 'm m' },
mathop: { signature: 'm' },
bf: { signature: 'm' },
textstyle: { signature: 'm' },
// color: { signature: 'm m' }, // This doesn't work, changing it below manually
},
})
Expand Down Expand Up @@ -78,6 +83,9 @@ export function walkLatex(node: LatexNode) {
next.args = [...(next.args?.slice(1) ?? []), ...args];
skip += nodesRemoved;
}
if (next.type === 'macro' && next.content === 'textstyle') {
next.content = 'text';
}
if (
next.type === 'macro' &&
(next.content === 'overbrace' || next.content === 'underbrace')
Expand All @@ -92,6 +100,20 @@ export function walkLatex(node: LatexNode) {
next.args = [...(next.args ?? []), ...args[0].content[0].args];
skip += nodesRemoved;
}
if (
args[0].content.length === 1 &&
args[0].content[0].type === 'string' &&
((args[0].content[0].content === '^' && next.content === 'overbrace') ||
(args[0].content[0].content === '_' && next.content === 'underbrace'))
) {
// need to get another argument, the _/^ was treated as a string, not an arg
const { args: doubleArgs, nodesRemoved: doubleNodesRemoved } = gobbleArguments(
array.slice(i + 1),
'm m',
);
next.args = [...(next.args ?? []), doubleArgs[1]];
skip += doubleNodesRemoved;
}
}
if (next.type === 'macro' && next.content === 'middle' && array[i + 1]?.content === '|') {
skip += 1;
Expand Down Expand Up @@ -133,7 +155,7 @@ class State implements IState {
if (!this._value) return;
if (lastChar.match(/^(["\s_^{(-])$/)) return;
const lastTwoChar = this.value.slice(-2);
if (!this._value || lastTwoChar === ')[') return; // e.g. `#text(fill: red)[V]
if (!this._value || lastTwoChar === ')[' || lastTwoChar === '[$') return; // e.g. `#text(fill: red)[V]
this._value += ' ';
}

Expand Down
14 changes: 12 additions & 2 deletions src/macros.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function createBrackets(scale: string): (state: IState, node: LatexNode) => stri
const b = (args?.[0].content?.[0] as LatexNode).content as string;
const typstB = brackets[b];
if (!typstB) throw new Error(`Undefined left bracket: ${b}`);
return `#scale(x: ${scale}, y: ${scale})[$ ${typstB} $]`;
return `#scale(x: ${scale}, y: ${scale})[$${typstB}$]`;
};
}

Expand Down Expand Up @@ -73,8 +73,11 @@ export const typstMacros: Record<string, string | ((state: IState, node: LatexNo
return 'root';
},
vec: 'arrow',
check: 'caron',
bar: 'macron',
mathbf: 'bold',
boldsymbol: 'bold',
bf: 'bold',
mathrm: 'upright',
textrm: 'upright',
rm: 'upright',
Expand Down Expand Up @@ -176,6 +179,7 @@ export const typstMacros: Record<string, string | ((state: IState, node: LatexNo
cap: 'sect',
cup: 'union',
widehat: 'hat',
widetilde: 'tilde',
// Spaces
',': 'thin',
':': 'med',
Expand Down Expand Up @@ -238,7 +242,7 @@ export const typstMacros: Record<string, string | ((state: IState, node: LatexNo
const [fill, children] = node.args ?? [];
const color = (fill.content?.[0] as LatexNode)?.content as string;
node.args = [];
state.openFunction(`#text(fill: ${color})`, { openToken: '[$ ', closeToken: ' $]' });
state.openFunction(`#text(fill: ${color})`, { openToken: '[$', closeToken: '$]' });
state.writeChildren(children as LatexNode);
state.closeFunction();
return '';
Expand All @@ -262,4 +266,10 @@ export const typstEnvs: Record<string, (state: IState, node: LatexNode) => void>
bmatrix: matrixEnv('['),
Bmatrix: matrixEnv('{'),
vmatrix: matrixEnv('|'),
aligned(state, node) {
state.writeChildren(node);
},
['aligned*'](state, node) {
state.writeChildren(node);
},
};
63 changes: 57 additions & 6 deletions tests/math.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ cases:
typst: |-
overbrace([ frac(1, Delta t) frac(diff bold(theta)^(n + 1), diff bold(psi)^(n + 1)) -bold(D) "diag"(bold(G) bold(psi)^(n + 1)) frac(diff bold(k)_(A v), diff bold(psi)^(n + 1)) -bold(D) "diag"(bold(k)_(A v)(bold(psi)^(n + 1) comma bold(m))) bold(G) -bold(G)_z frac(diff bold(k)_(A v), diff bold(psi)^(n + 1)) ], bold(A)_0(bold(psi)^(n + 1))) frac(diff bold(psi)^(n + 1), diff bold(m)) \
+ underbrace([ -frac(1, Delta t) frac(diff bold(theta)^n, diff bold(psi)^n) ], bold(A)_(-1)(bold(psi)^n)) frac(diff bold(psi)^n, diff bold(m)) = underbrace([ -bold(D) "diag"(bold(G) bold(psi)^(n + 1)) frac(diff bold(k)_(A v), diff bold(m)) -bold(G)_z frac(diff bold(k)_(A v), diff bold(m)) ], bold(B)(psi^(n + 1))) &
- title: underbraces inside of a function
description: For some reason the "_" here is treated as text, not a macro.
tex: |
\color{red}{\underbrace{
\color{black}{\begin{bmatrix}
0 & 1 \\
-1 & 0
\end{bmatrix}}
}_{\textstyle A} }
typst: '#text(fill: red)[$underbrace(#text(fill: black)[$mat(delim: "[", 0, 1; -1, 0)$], "A")$]'
- title: leading underscore
tex: _2
typst: '""_2'
Expand All @@ -123,6 +133,9 @@ cases:
- title: ddot
tex: 'q, \dot{q}, \ddot{q}'
typst: q, dot(q), dot.double(q)
- title: dot
tex: '\dot x^2'
typst: 'dot(x)^2'
- title: mat
tex: 'x(t) = \left[ \begin{array}{c} q(t) & x \\ \dot{q}(t) & x \end{array}\right]'
typst: 'x(t) = [ mat(delim: #none, q(t), x; dot(q)(t), x) ]'
Expand Down Expand Up @@ -235,7 +248,7 @@ cases:
typst: 'V = {"\"ng\",\"mr\",\"sr\""}'
- title: color
tex: '\color{red}{V}'
typst: '#text(fill: red)[$ V $]'
typst: '#text(fill: red)[$V$]'
- title: bmatrix
tex: |
\begin{bmatrix}
Expand All @@ -252,7 +265,7 @@ cases:
=
\color{red}{ad} - \color{blue}{bc}.
# The `] ;` space is important for some reason!
typst: 'mat(delim: "[", #text(fill: red)[$ a $], #text(fill: blue)[$ b $] ; #text(fill: blue)[$ c $], #text(fill: red)[$ d $]) = #text(fill: red)[$ a d $] -#text(fill: blue)[$ b c $].'
typst: 'mat(delim: "[", #text(fill: red)[$a$], #text(fill: blue)[$b$] ; #text(fill: blue)[$c$], #text(fill: red)[$d$]) = #text(fill: red)[$a d$] -#text(fill: blue)[$b c$].'
- title: bmatrix shapes
tex: |
-2
Expand All @@ -278,13 +291,51 @@ cases:
typst: 'mat(delim: "[", p_0; p_1; p_2; dots.v; p_(T -1); p_T)'
- title: Big
tex: '\Big|'
typst: '#scale(x: 180%, y: 180%)[$ bar.v $]'
typst: '#scale(x: 180%, y: 180%)[$bar.v$]'
- title: Big{
tex: '\Big\{'
typst: '#scale(x: 180%, y: 180%)[$ brace.l $]'
typst: '#scale(x: 180%, y: 180%)[$brace.l$]'
- title: big
tex: '\big|'
typst: '#scale(x: 120%, y: 120%)[$ bar.v $]'
typst: '#scale(x: 120%, y: 120%)[$bar.v$]'
- title: Bigl
tex: '\Bigl| \frac{\lambda-\alpha(1-\lambda)}{1-\alpha(1-\lambda)} \Bigr| < 1'
typst: '#scale(x: 180%, y: 180%)[$ bar.v $] frac(lambda -alpha(1 -lambda), 1 -alpha(1 -lambda)) #scale(x: 180%, y: 180%)[$ bar.v $] < 1'
typst: '#scale(x: 180%, y: 180%)[$bar.v$] frac(lambda -alpha(1 -lambda), 1 -alpha(1 -lambda)) #scale(x: 180%, y: 180%)[$bar.v$] < 1'
- title: big no space
tex: '\theta = \tan^{-1} \Big( \frac{y}{x} \Big)'
typst: 'theta = tan^(-1) #scale(x: 180%, y: 180%)[$paren.l$] frac(y, x) #scale(x: 180%, y: 180%)[$paren.r$]'
- title: hat group
tex: '{\hat x}'
typst: 'hat(x)'
- title: hat function
tex: '\hat{x}'
typst: 'hat(x)'
- title: check
tex: '\check p_{-1}, \check \pi_{-1}^*'
typst: 'caron(p)_(-1), caron(pi)_(-1)^(*)'
- title: bar
tex: '\bar x'
typst: 'macron(x)'
- title: hat
tex: '\hat x'
typst: 'hat(x)'
- title: accents
tex: 'B_{-1}- \check B_{-1} = \frac{\widetilde R}{p_0} \left( \check m_0 - m_0 \right)'
typst: 'B_(-1) -caron(B)_(-1) = frac(tilde(R), p_0) (caron(m)_0 -m_0)'
- title: bf
tex: '{\bf R}^2'
typst: 'bold(R)^2'
- title: bf
tex: '{\bf R}^2'
typst: 'bold(R)^2'
- title: aligned
tex: |
\begin{aligned}
35p_0 - 5p_1 - 5p_2 = 100 \\
-5p_0 + 25p_1 - 10p_2 = 75 \\
-5p_0 - 5p_1 + 15p_2 = 55
\end{aligned}
typst: |-
35 p_0 -5 p_1 -5 p_2 = 100 \
-5 p_0 + 25 p_1 -10 p_2 = 75 \
-5 p_0 -5 p_1 + 15 p_2 = 55
Loading