LaTeX support for Typst, powered by Rust and WASM.

Overview

MiTeX

LaTeX support for Typst, powered by Rust and WASM.

MiTeX processes LaTeX code into an abstract syntax tree (AST). Then it transforms the AST into Typst code and evaluates code into Typst content by eval function.

MiTeX has been proved to be practical on a large project. It has already correctly converted 32.5k equations from OI Wiki. Compared to texmath, MiTeX has a better display effect and performance in that wiki project. It is also more easy to use, since importing MiTeX to Typst is just one line of code, while texmath is an external program.

In addition, MiTeX is not only SMALL but also FAST! MiTeX has a size of just about 185 KB, comparing that texmath has a size of 17 MB. A not strict but intuitive comparison is shown below. To convert 32.5k equations from OI Wiki, texmath takes about 109s, while MiTeX WASM takes only 2.28s and MiTeX x86 takes merely 0.085s.

Thanks to @Myriad-Dreamin, he completed the most complex development work: developing the parser for generating AST.

MiTeX as a Typst Package

  • Use mitex-convert to convert LaTeX code into Typst code in string.
  • Use mi to render an inline LaTeX equation in Typst.
  • Use mitex(numbering: none, supplement: auto, ..) or mimath to render a block LaTeX equation in Typst.
  • Use mitext to render a LaTeX text in Typst.

PS: #set math.equation(numbering: "(1)") is also valid for MiTeX.

Following is a simple example of using MiTeX in Typst:

#import "@preview/mitex:0.2.0": *

#assert.eq(mitex-convert("\alpha x"), "alpha  x ")

Write inline equations like #mi("x") or #mi[y].

Also block equations (this case is from #text(blue.lighten(20%), link("https://katex.org/")[katex.org])):

#mitex(`
  \newcommand{\f}[2]{#1f(#2)}
  \f\relax{x} = \int_{-\infty}^\infty
    \f\hat\xi\,e^{2 \pi i \xi x}
    \,d\xi
`)

We also support text mode (in development):

#mitext(`
  \iftypst
    #set math.equation(numbering: "(1)", supplement: "equation")
  \fi

  \section{Title}

  A \textbf{strong} text, a \emph{emph} text and inline equation $x + y$.

  Also block \eqref{eq:pythagoras}.

  \begin{equation}
    a^2 + b^2 = c^2 \label{eq:pythagoras}
  \end{equation}
`)

example

MiTeX as a CLI Tool

Installation

Install it by cargo install mitex-cli or install latest nightly version by cargo install --git https://github.com/mitex-rs/mitex mitex-cli.

Usage

mitex compile main.tex
# or (same as above)
mitex compile main.tex mitex.typ

Implemented Features

  • User-defined TeX (macro) commands, such as \newcommand{\mysym}{\alpha}.
  • LaTeX equations support.
    • Coloring commands (\color{red} text, \textcolor{red}{text}).
    • Support for various environments, such as aligned, matrix, cases.
  • Basic text mode support, you can use it to write LaTeX drafts.
    • \section, \textbf, \emph.
    • Inline and block math equations.
    • \ref, \eqref and \label.
    • itemize and enumerate environments.

Features to Implement

  • Pass command specification to MiTeX plugin dynamically. With that you can define a typst function let myop(it) = op(upright(it)) and then use it by \myop{it}.
  • Package support, which means that you can change set of commands by telling MiTeX to use a list of packages.
  • Better text mode support, such as figure and description environments.

Differences between MiTeX and other solutions

MiTeX has different objectives compared to texmath (a.k.a. pandoc):

  • MiTeX focuses on rendering LaTeX content correctly within Typst, leveraging the powerful programming capabilities of WASM and typst to achieve results that are essentially consistent with LaTeX display.
  • texmath aims to be general-purpose converters and generate strings that are more human-readable.

For example, MiTeX transforms \frac{1}{2}_3 into frac(1, 2)_3, while texmath converts it into 1 / 2_3. The latter's display is not entirely correct, whereas the former ensures consistency in display.

Another example is that MiTeX transforms (\frac{1}{2}) into \(frac(1, 2)\) instead of (frac(1, 2)), avoiding the use of automatic Left/Right to achieve consistency with LaTeX rendering.

Certainly, the greatest advantage is that you can directly write LaTeX content in Typst without the need for manual conversion!

Submitting Issues

If you find missing commands or bugs of MiTeX, please feel free to submit an issue here.

Contributing to MiTeX

Currently, MiTeX maintains following three parts of code:

For a translation process, for example, we have:

\frac{1}{2}

===[parser]===> AST ===[converter]===>

#eval("$frac(1, 2)$", scope: (frac: (num, den) => $(num)/(den)$))

You can use the #mitex-convert() function to get the Typst Code generated from LaTeX Code.

Add missing TeX commands

Even if you don't know Rust at all, you can still add missing TeX commands to MiTeX by modifying specification files, since they are written in typst! You can open an issue to acquire the commands you want to add, or you can edit the files and submit a pull request.

In the future, we will provide the ability to customize TeX commands, which will make it easier for you to use the commands you create for yourself.

Develop the parser and the converter

See CONTRIBUTING.md.

Comments
  • Provide a native CLI program to convert LaTeX source into typst source.

    Provide a native CLI program to convert LaTeX source into typst source.

    If I get it correctly, for the time being, mitex only works as a WASM module and thus only works on the typst web app, but not for the CLI.

    It would be better to provide a CLI program that runs like:

    mitex -i foo.tex -o foo.typ
    

    Then we can deal with the typst source with typst-cli.

    Another benefit of this is that we can easily build a testset with a bunch of TeX sources, which will largely assure the quality and stability of mitex.

    enhancement 
    opened by KDr2 8
  • Commands to add for OI Wiki test

    Commands to add for OI Wiki test

    Scanned by script

    • [x] \notag
    • [x] \brack
    • [x] \triangle
    • [x] \impliedby
    • [x] \LaTeX
    • [x] \space
    • [x] \lnot
    • [x] \mathop
    • [x] \vert
    • [x] \middle
    • [x] \lvert
    • [x] \rvert
    • [x] \lVert
    • [x] \Bbb
    • [x] \implies
    • [x] \boxed
    • [x] \checkmark
    • [x] \substack
    • [x] \dotsb
    • [x] \dbinom
    • [x] \*
    • [x] \wedge
    • [x] \subsetneqq
    • [x] \emptyset
    • [x] \pod
    • [x] \lor
    • [x] \cr
    • [x] \tag
    • [x] \varphi*
    • [x] \brace
    • [x] \begin{alignedat}
    T Spec 
    opened by Myriad-Dreamin 4
  • Add detailed Installation Instructions to README

    Add detailed Installation Instructions to README

    I am genuinely impressed with potential of this project and excited about the possibilities it offers. However, I've encountered a bit of a roadblock. As a new user, I'm unsure about the installation process, as the current README file doesn't include an installation section. This has made it challenging for me to get started with the project.

    Could you please consider adding an installation guide to the README?

    opened by szsdk 3
  • Problems reproducing example

    Problems reproducing example

    I copied the example from the README and pasted it to the web app. The code, which is below.

    #import "@preview/mitex:0.1.0": *
    
    #assert.eq(mitex-convert("\alpha x"), "alpha  x ")
    
    Write inline equations like #mi("x") or #mi[y].
    
    Also block equations (this case is from #text(blue.lighten(20%), link("https://katex.org/")[katex.org])):
    
    #mitex(`
      \newcommand{\f}[2]{#1f(#2)}
      \f\relax{x} = \int_{-\infty}^\infty
        \f\hat\xi\,e^{2 \pi i \xi x}
        \,d\xi
    `)
    

    After trying to compile it I got "Plugin errored with error: error unknown command \f". Am I doing something wrong or is the library in the preview repository doesn't support the feature yet?

    opened by DenisLohvynov 2
  • Plan to convert users' TeX document into Typst code

    Plan to convert users' TeX document into Typst code

    Though I prefer to writing documents in pure typst, I need to write several LaTeX documents for formal publications. Typst has delightful future but we have to admit that it cannot be used for writing that documents at least in next few months.

    Now, I still want to fully make use of typst, So I want to have a MiTeX which converts at least main body part of TeX code to typst code for me. So that I can preview a LaTeX document locally without help of TeXLive or TeXStudio. I also want to have capability to embed typst content, e.g. cetz pictures into the document, so that I don't have to use tikz.

    In conclusion, I feel it useful for partially supporting to convert entire TeX document into typst. With that you can:

    • preview a TeX document instantly, without locally installed TeXLive or TeXStudio.
    • keep document in TeX format (which is still needed for formal publication).
    • export document by typst exporters, then we can share or distribute them informally.

    Convert entire document into typst sounds crazy, but we still have a chance. We can support them with some limitation, since we are converting a user document.

    • Less TeX Styles: We can show TeX content by typst rules. Therefore, we can throw most styles of a TeX document away, so that we won't touch typesetting things during convertion.
    • Less TeX Macros: We can perform calcuation via typst scripting. Therefore, it is also not quite necessary to have a fully supported macros.

    Idea follows.

    • [x] support text mode.
    • [x] convert commonly used text commands.
    • partially support context-insensitive \input{chapterN} with help of mitex(read('chapterN.tex')).
    • [x] add conditional macros, \iftypst, so that I can make hacks in my TeX document.
      • \iftypst expands only if the document is compiled by typst.
    • [x] add limited macro support, e.g. only with context-insensitive \newcommand.
      • so that I can replace some harsh commands with help of binding to typst functions

    Not quite hard, no much efforts, but looks perfect for typst users writing TeX documents!


    Postscript here. I don't mention more complex things, such as tables, since I plan to do some hacks on them. Personally, I may read and process data by typst scripting, then I either

    • render data by tablex.
    • or export them via typst query, and use TeX's tables showing data processed by typst.
    enhancement 
    opened by Myriad-Dreamin 2
  • Distinguish between inline equations and block equations

    Distinguish between inline equations and block equations

    Currently, Lexer treats a single dollar sign and multiple dollar signs as the same token, so we can't distinguish between an inline equation and a block equation.

    https://github.com/mitex-rs/mitex/blob/41a666c4e205549bd27c9a778b2c48b2fc706bdf/crates/mitex-lexer/src/lib.rs#L433-L434

    T Parser 
    opened by OrangeX4 1
  • Improve benchmarks

    Improve benchmarks

    • Add allocation profiling. I have carefully optimized it so it should not have a noticeable footprint.
    • Remove setup cost from benchmarks. Previously benchmarks would include the cost of initializing a once_cell::sync::Lazy instance. This reduces benchmarked times by 100-400µs.

    Example output:

    simple                  fastest       │ slowest       │ median        │ mean          │ samples │ iters
    ├─ alpha_x_20000        1.975 ms      │ 2.168 ms      │ 1.99 ms       │ 1.995 ms      │ 100     │ 100
    │                       alloc:        │               │               │               │         │
    │                         12          │ 12            │ 12            │ 12            │         │
    │                         960.8 KB    │ 960.8 KB      │ 960.8 KB      │ 960.8 KB      │         │
    │                       dealloc:      │               │               │               │         │
    │                         5           │ 5             │ 5             │ 5             │         │
    │                         1.579 MB    │ 1.579 MB      │ 1.579 MB      │ 1.579 MB      │         │
    │                       grow:         │               │               │               │         │
    │                         18          │ 18            │ 18            │ 18            │         │
    │                         1.578 MB    │ 1.578 MB      │ 1.578 MB      │ 1.578 MB      │         │
    ├─ alpha_x_20000_heavy  2.02 ms       │ 2.338 ms      │ 2.038 ms      │ 2.047 ms      │ 100     │ 100
    │                       alloc:        │               │               │               │         │
    │                         12          │ 12            │ 12            │ 12            │         │
    │                         960.8 KB    │ 960.8 KB      │ 960.8 KB      │ 960.8 KB      │         │
    │                       dealloc:      │               │               │               │         │
    │                         5           │ 5             │ 5             │ 5             │         │
    │                         1.579 MB    │ 1.579 MB      │ 1.579 MB      │ 1.579 MB      │         │
    │                       grow:         │               │               │               │         │
    │                         18          │ 18            │ 18            │ 18            │         │
    │                         1.578 MB    │ 1.578 MB      │ 1.578 MB      │ 1.578 MB      │         │
    ├─ alpha_x_40000        4.013 ms      │ 4.396 ms      │ 4.044 ms      │ 4.061 ms      │ 100     │ 100
    │                       alloc:        │               │               │               │         │
    │                         12          │ 12            │ 12            │ 12            │         │
    │                         1.92 MB     │ 1.92 MB       │ 1.92 MB       │ 1.92 MB       │         │
    │                       dealloc:      │               │               │               │         │
    │                         5           │ 5             │ 5             │ 5             │         │
    │                         3.152 MB    │ 3.152 MB      │ 3.152 MB      │ 3.152 MB      │         │
    │                       grow:         │               │               │               │         │
    │                         19          │ 19            │ 19            │ 19            │         │
    │                         3.151 MB    │ 3.151 MB      │ 3.151 MB      │ 3.151 MB      │         │
    ├─ alpha_x_40000_heavy  4.021 ms      │ 4.307 ms      │ 4.116 ms      │ 4.124 ms      │ 100     │ 100
    │                       alloc:        │               │               │               │         │
    │                         12          │ 12            │ 12            │ 12            │         │
    │                         1.92 MB     │ 1.92 MB       │ 1.92 MB       │ 1.92 MB       │         │
    │                       dealloc:      │               │               │               │         │
    │                         5           │ 5             │ 5             │ 5             │         │
    │                         3.152 MB    │ 3.152 MB      │ 3.152 MB      │ 3.152 MB      │         │
    │                       grow:         │               │               │               │         │
    │                         19          │ 19            │ 19            │ 19            │         │
    │                         3.151 MB    │ 3.151 MB      │ 3.151 MB      │ 3.151 MB      │         │
    ├─ slice_word           2.275 ms      │ 2.707 ms      │ 2.292 ms      │ 2.299 ms      │ 100     │ 100
    │                       alloc:        │               │               │               │         │
    │                         12          │ 12            │ 12            │ 12            │         │
    │                         960.9 KB    │ 960.9 KB      │ 960.9 KB      │ 960.9 KB      │         │
    │                       dealloc:      │               │               │               │         │
    │                         5           │ 5             │ 5             │ 5             │         │
    │                         1.579 MB    │ 1.579 MB      │ 1.579 MB      │ 1.579 MB      │         │
    │                       grow:         │               │               │               │         │
    │                         18          │ 18            │ 18            │ 18            │         │
    │                         1.578 MB    │ 1.578 MB      │ 1.578 MB      │ 1.578 MB      │         │
    ╰─ sqrt_pattern         1.598 ms      │ 1.752 ms      │ 1.609 ms      │ 1.615 ms      │ 100     │ 100
                            alloc:        │               │               │               │         │
                              7523        │ 7523          │ 7523          │ 7523          │         │
                              1.021 MB    │ 1.021 MB      │ 1.021 MB      │ 1.021 MB      │         │
                            dealloc:      │               │               │               │         │
                              8           │ 8             │ 8             │ 8             │         │
                              793 KB      │ 793 KB        │ 793 KB        │ 793 KB        │         │
                            grow:         │               │               │               │         │
                              17          │ 17            │ 17            │ 17            │         │
                              792 KB      │ 792 KB        │ 792 KB        │ 792 KB        │         │
    
    opened by nvzqz 1
  • dev(cli): fix readme, command, build script, and compile result

    dev(cli): fix readme, command, build script, and compile result

    • Add cli usage to readme.
    • Use new text mode in compile command
    • Restrict build constraints for mitex-cli, so that it doesn't always compile by cargo run --bin mitex.
    • insert handler definitions in mitex-scope before the transpiled document. They look like:
      #import "@preview/mitex:0.1.0": *
      #let mitexarray = mitex-scope.at("mitexarray", default: none);
      #let mitexbold = mitex-scope.at("mitexbold", default: none);
      #let mitexcal = mitex-scope.at("mitexcal", default: none);
      ...
      
    opened by Myriad-Dreamin 0
  • feat: generate cmd spec or use prebuilt cmd spec in build.rs

    feat: generate cmd spec or use prebuilt cmd spec in build.rs

    The key code is here

    https://github.com/mitex-rs/mitex/blob/ed4a57cbe7ac9a7668ff4fc019a120633c63d76f/crates/mitex-spec-gen/build.rs#L10-L17

    Three mode.

    • if specified feature prebuilt, get spec by running copy_prebuilt.

    • otherwise, if specified feature generate, get spec by running generate.

    • otherwise, in default, if users have typst-cli installed, run generate, otherwise run copy_prebuilt.

      if which::which("typst").is_ok() { 
         generate 
      } else { 
        // fallback to prebuilt spec 
        copy_prebuilt 
      }
      
    opened by Myriad-Dreamin 0
  • feat: basic text mode

    feat: basic text mode

    • [x] Basic text mode support, you can use it to write LaTeX drafts.
      • [x] \section, \textbf, \emph.
      • [x] Inline and block math equations.
      • [x] \ref, \eqref and \label.
      • [x] itemize and enumerate environments.

    • Use mitex-convert to convert LaTeX code into Typst code in string.
    • Use mi to embed an inline LaTeX equation into Typst.
    • Use mitex(numbering: none, supplement: auto, ..) to embed a block LaTeX equation into Typst.
    • Use mitext to embed a LaTeX text into Typst.
    #import "@preview/mitex:0.1.0": *
    
    #mitext(`
      \iftypst
        #set math.equation(numbering: "(1)", supplement: "equation")
      \fi
    
      \section{Title}
    
      A \textbf{strong} text, a \emph{emph} text and inline equation $x + y$.
      
      Also block \eqref{eq:pythagoras}.
    
      \begin{equation}
        a^2 + b^2 = c^2 \label{eq:pythagoras}
      \end{equation}
      
      \begin{enumerate}
        \item This is the first item
        \item This is the second item
        \begin{itemize}
          \item This is the first subitem
          \item This is the second subitem
        \end{itemize}
      \end{enumerate}
    `)
    
    opened by OrangeX4 0
  • Convert box commands

    Convert box commands

    No plan, but some direction:

    • find a way of ignoring all box related commands, so that it just compiles in typst instead of really layout something.
    • implement kern commands
    • implement glue commands
    • implement paragraph commands

    Materials and ideas

    Initial Idea is following.

    • The boxes are allocated by converter.
    • We may have infinite virtual box registers, since holding limit of 256 is just less meaningful but depends on implementation.
    • We won't calculate any size of boxes, but converting them with typst scripting. That means, any failed conversions will just make MiTeX ignore layout request from TeX Code.
    • For code converting layout, measure for box and box conditions:
      #locate(loc => layout(size => {
        // converted code here
      }))
      

    Examples

    Example 1 (paragraph):

    \everypar{\setbox\parbox=
    \vbox\bgroup\everypar{}%
    \def\par{\endgraf\HandleLines
    \egroup\box\parbox}}
    \def\HandleLines{ ... \lastbox ... }
    

    Example 2 (box):

    \newbox\linebox \newbox\snapbox
    \def\eatlines{
    \setbox\linebox\lastbox % check the last line
    \ifvoid\linebox
    \else % if it's not empty
    \unskip\unpenalty % take whatever is
    {\eatlines} % above it;
    % collapse the line
    \setbox\snapbox\hbox{\unhcopy\linebox}
    % depending on the difference
    \ifdim\wd\snapbox<.98\wd\linebox
    \box\snapbox % take the one or the other,
    \else \box\linebox \fi
    \fi}
    
    
    enhancement 
    opened by Myriad-Dreamin 0
🏭 Convert Markdown documents into themed HTML pages with support for code syntax highlighting, LaTeX and Mermaid diagrams.

Marky Markdown Magician ?? Features Hot reload previewing ?? Conversion to HTML / PDF ?? Themes! ✨ Extensions - Math, diagrams, syntax-highlighting ??

Vadim 12 Feb 19, 2023
Latex template handler using Rust

Latex template handler using Rust All the templates used by this program are stored in another GitHub repository. Dependencies rust & cargo How to use

Johan Rodríguez 2 Oct 19, 2022
A transpiled superset of TeX for writing LaTeX.

LiA A transpiled superset of TeX for writing LaTeX. This is more for my personal use however you're welcome to use it or contribute. These added featu

Jasper 62 Jan 5, 2023
Make beautiful colored code listings in LaTeX with the power of TreeSitter.

What is this? This is a CLI tool that consumes TreeSitter's output and transforms it into LaTeX code that will produce syntax-colored code listing. If

Tomáš Lebeda 11 Sep 4, 2023
run Typst in JavaScriptWorld.

Typst.ts Typst.ts allows you to independently run the Typst compiler and exporter (renderer) in your browser. You can: locally run the compilation via

null 9 Apr 18, 2023
Shell Escape for Typst typesetting system. Linux Only.

Shell Escape for Typst This is a simple shell escape for Typst. It allows you to run shell commands directly from Typst compiler. That said, it does n

Nikolay Stepanov 4 Jun 7, 2023
Packages for Typst.

Typst Packages An experimental package repository for Typst. A searchable list of all packages that were submitted here is available in the official d

Typst 91 Jul 4, 2023
An mdBook backend to output Typst markup, pdf, png, or svg

mdbook-typst mdbook-typst is a backend for mdBook. The backend converts the book to Typst markup and can output any format Typst can (currently pdf, p

Christian Legnitto 18 Dec 16, 2023
A tool to compare how Typst documents would look using different fonts or font variants.

typst-font-compare A tool to compare how Typst documents would look using different fonts or font variants. Installation cargo install --path . Usage

null 3 Feb 15, 2024
Verifiable and confidential computation based on ZKP and FHE, powered by risc0 zkVM.

zkFHE Verifiable and confidential computation based on ZKP and FHE, powered by risc0 zkVM. A PoC to demonstrate an approach for private computation on

Emiliano Bonassi 29 Apr 25, 2023
Rust-powered CLI tool designed to simplify and streamline the release process with help of ChatGPT

$ releasecraftsman ????‍♂️?? Automate Your Release Process with Precision and Ease. ?? Features Generate well-crafted release notes using GPT-3.5 and

Tornike Gomareli 7 Sep 21, 2023
🛠️ An experimental functional systems programming language, written in Rust and powered by LLVM as a backend.

An experimental functional systems programming language, written in Rust, and powered by LLVM as a backend. ?? Goal: The intent is to create a program

codex 3 Nov 15, 2023
A programming and system administration assistant, powered by chatGPT

TermGPT Interact with ChatGPT from your terminal! ?? ?? Install Cargo cargo install termgpt termgpt --help From source git clone [email protected]:bahdot

Gokul 5 May 11, 2023
epNFTs, the first partial program-owned NFT Standard powered by Instruction Introspection and Transfer Hooks!

epNFT Standard: A Comprehensive Guide Introduction to epNFTs Welcome to the epNFT-standard repository, where we explore the first program-owned NFT st

epPlex 6 Mar 1, 2024
UpVent Website (Powered by Rust + Svelte & Fernet Branca).

UpVent Website Source Build Status Description This is the source code for the UpVent's website under upvent.codes. Development occurs on the master b

UpVent 3 Dec 2, 2022
A syntax highlighter for Node powered by Tree Sitter. Written in Rust.

tree-sitter-highlight A syntax highlighter for Node.js powered by Tree Sitter. Written in Rust. Usage The following will output HTML: const treeSitter

Devon Govett 211 Dec 20, 2022
An Intel HAXM powered, protected mode, 32 bit, hypervisor addition calculator, written in Rust.

HyperCalc An Intel HAXM powered, protected mode, 32 bit, hypervisor addition calculator, written in Rust. Purpose None ?? . Mostly just to learn Rust

Michael B. 2 Mar 29, 2022
ChatGPT powered Rust proc macro that generates code at compile-time.

gpt-macro ChatGPT powered Rust proc macro that generates code at compile-time. Implemented Macros auto_impl!{} #[auto_test(...)] Usage Get ChatGPT API

Akira Moroo 429 Apr 15, 2023
🐚+🦞 Ultra-portable Rust game engine suited for offline 2D games powered by WebAssembly

pagurus ?? + ?? Ultra-portable Rust game engine suited for offline 2D games powered by WebAssembly. Examples Snake Traditional snake game: examples/sn

Takeru Ohta 20 Mar 7, 2023