top | item 46527638

Show HN: Tylax – A bidirectional LaTeX to Typst converter in Rust

27 points| democat | 1 month ago |github.com

Hi HN, author here.

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!

9 comments

order

holg|1 month ago

nice job! so i tried around and so far am impressed, anyhow:

\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

democat|1 month ago

Thanks for the stress test! You are absolutely right, and I really appreciate you catching this edge case.

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.

leephillips|1 month ago

Could you briefly explain why Pandoc was not sufficient? (Obviously it can’t do the TikZ -> CeTZ conversion.)

democat|1 month ago

Great question! I love Pandoc and use it often, but as a "universal" converter, it sometimes misses the nuances of specific pairs. Tylax is designed specifically for the LaTeX $\leftrightarrow$ Typst workflow. By focusing on just this 1-on-1 pair, we can offer: Better Math & Macros: A built-in macro expander handles custom commands (\newcommand) and complex nested math that general parsers often struggle with. Cleaner Code: The output is designed to be idiomatic and human-readable (e.g., using native Typst functions), not just "compilable." WASM Support: Being written in Rust means it runs instantly in the browser, making it easy to embed in web apps without a backend. Pandoc is the Swiss Army knife; we're trying to be a specialized tool just for this specific transition.

bayesnet|1 month ago

I haven’t tried this out yet but my gripe with pandoc is that it produces latex (and typst) that no human would ever write. It looks messy and is annoying to share with coauthors.

This is not to say that pandoc isn’t a fantastic tool.