I built Tylax because I wanted to migrate my old LaTeX papers to Typst but found existing regex-based scripts too fragile for nested environments.
Tylax parses LaTeX into an AST (using mitex-parser) and converts it to Typst code. It supports: - Full document structure (not just math snippets) - Complex math (matrices, integrals) - Experimental TikZ -> CeTZ graphics conversion - Runs in browser via WASM
Repo: https://github.com/scipenai/tylax Web Demo: https://convert.silkyai.cn/
Happy to answer any questions!
\newcommand{\foo}[1]{\bar{#1}} \renewcommand{\bar}[1]{\foo{#1}} % mutual recursion \foo{x} \def\x{\y}\def\y{z}\x % chained expansion
+>
#set page(paper: "a4") #set heading(numbering: "1.") #set math.equation(numbering: "(1)") /* \foo / / \y /
\foo{x} → \bar{x} → \foo{x} → ∞ Expected: hit depth limit, emit warning, output either x or the unexpanded \foo{x} Actual: / \foo */ — silently converted to a comment, lost the argument x entirely
I've traced the issue in the codebase: 1. The recursion depth limit *is* triggering correctly (preventing an infinite loop). 2. However, when it bails out, it returns the partially expanded macro call (e.g., `\foo{x}`). 3. Since the macro definition was removed during the preprocessing step, the parser then sees `\foo` as an unknown command and converts it into an error comment, accidentally discarding the argument `{x}` in the process.
*The intended behavior* should definitely be to preserve the content (the `x`) even if the macro logic fails. I will fix the fallback logic to ensure it fails gracefully without eating the arguments.
Thanks again for the sharp eye! These kinds of checks are super helpful.