Skip to content
avelouxPublic

About

A rewritten typesetting system known as LaTeX, celebrated for its professionalism and written in C++ for maximum compatibility and speed.

Topics

Resources

Code of conduct

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

mLaTeX

A LaTeX typesetting engine, rewritten from the ground up in modern C++.

C++ Standard Build Status Platforms GitHub Stars GitHub Issues PRs Welcome Last Commit AGPL v3 License

mLaTeX (Modernized LaTeX) reads LaTeX as people already write it and turns it into PDF with a single program. There is no TeX distribution behind it, no format files, no package tree on disk and no auxiliary files between runs. The lexer, macro expander, parser, line breaker, page builder, font shaper and PDF writer are all part of one engine, written in C++26.

The language stays the same. A document written for pdfLaTeX, its preamble included, is meant to compile unchanged. What changes is the machinery underneath: the work LaTeX does with thousands of lines of TeX macros is done once, in compiled code.

Highlights

  • Reads existing LaTeX. 509 packages and 14 document classes, each checked by a sample document of its own in tests/packages/, plus a glossary of about 630 more commands from CTAN packages that have no folder of their own. An unknown package produces a warning, not a failed build.
  • Fast. On a release build, a one-page article takes a few milliseconds, and the 11-page sample paper in build/main.mtex, two passes included, takes under 30 ms.
  • Self-contained. Packages and English hyphenation are compiled into the binary. Fonts (New Computer Modern, STIX Two, Fira Math, TeX Gyre and others) and hyphenation patterns for 79 languages and variants ship in assets/.
  • The parts people use. Mathematics; tables; floats; cross-references resolved by a second pass in memory; tables of contents and indexes; hyperref links and bookmarks; TikZ, pgfplots, tikz-cd, xy-pic and forest pictures; beamer slides with overlays and themes; BibTeX bibliographies in the standard, natbib and biblatex styles; right-to-left and CJK text; PNG, JPEG, WebP, EPS and SVG pictures; PDF/A.
  • Embeddable. The same engine is available as a C++ library, a C library that any language with a foreign-function interface can bind, and a WebAssembly module. Programs can supply values, commands they implement, and files from memory, then get the PDF back as bytes -- a whole document, or a snippet: one formula, table or picture on a page cropped to it, to show inside an app or a web page.
  • Safe by design. A document cannot run shell commands (\write18 does not exist), cannot write files, and never loads .sty or .cls code from disk. With --offline it cannot reach the network either. See SECURITY.md.

Status

mLaTeX is pre-release software (version 0.1.0). The aot target, which writes the PDF directly, is complete. The command line's jit target is accepted but not yet implemented; it is reserved in src/jit. WebAssembly is not a target of the command line but a build of the engine itself, for browsers and Node; see Embedding the engine. See CHANGELOG.md for what has been done and what is intentionally left out.

Installation

Prebuilt packages have not been published yet. When they are, each release will include:

Platform Package Installs to
Windows .msi installer, .zip C:\Program Files\mLaTeX
macOS .pkg installer /Applications/mLaTeX
macOS .dmg disk image, .tar.gz, .zip wherever the mLaTeX folder is dragged or unpacked
Linux .deb, .rpm /opt/mlatex
Linux .tar.gz, .zip wherever it is unpacked
Web -wasm.zip: latex.js, latex.wasm, latex.data beside the page or script that loads it

Each package is named for its platform and architecture, for example mlatex-0.1.0-windows-x64.msi or mlatex_0.1.0_arm64.deb. The program is bin/mlatex inside the installed folder. Add that bin folder to your PATH to run it from anywhere. It is named mlatex so that it never collides with the latex a TeX distribution installs.

Building from source

Requirements

  • CMake 3.25 or later and Ninja.
  • A C++26 compiler with #embed: Clang 19 or later, or GCC 15 or later. On Windows, use the clang-cl that Visual Studio installs under VC/Tools/Llvm. The build selects it automatically if your IDE profile names MSVC (cl) or MinGW.
  • vcpkg with HarfBuzz, libpng, libjpeg-turbo, libwebp and zlib installed for your target triplet.
  • gperf.
  • Optional: libcurl on Linux and macOS for \includegraphics of https:// sources (Windows uses WinHTTP); Doxygen for the API reference; WiX (version 3, or the wix .NET tool, version 4 or later) for an .msi. WiX 7 needs its EULA accepted once per machine, wix eula accept wix7, and the WixToolset.UI.wixext and WixToolset.Util.wixext extensions (wix extension add --global ...); see WiX's maintenance fee.
vcpkg install harfbuzz libpng libjpeg-turbo libwebp zlib

Build and test

cmake -B cmake-build-release -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=<vcpkg>/scripts/buildsystems/vcpkg.cmake
cmake --build cmake-build-release
ctest --test-dir cmake-build-release --output-on-failure

On Windows, the debug, release and wasm presets in CMakePresets.json set all of this up (cmake --preset release). If you leave out the toolchain file, the build looks for vcpkg in VCPKG_ROOT and then in C:/vcpkg.

The build produces three targets: latex (the command-line program, built as mlatex), core (the engine as a static library, which every other target links) and ffi (the C library, latex_ffi). Every source file has a matching test under tests/.

Packaging

From a Release build tree:

cpack --config cmake-build-release/CPackConfig.cmake

This puts the packages listed under Installation for the platform and architecture of the build into the release/ folder at the top of the project. To package another architecture, run a separate build for it, for example clang-cl targeting ARM64 with the arm64-windows triplet. On macOS, -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" with universal libraries produces one disk image for both.

Usage

mlatex paper

This compiles paper.mtex or, failing that, paper.tex, and writes paper.pdf beside it. Options accept one or two dashes and are written as words separated by dashes. TeX's own spellings are accepted too, so scripts written for pdfLaTeX keep working.

mlatex --interaction=batch-mode --halt-on-error paper
mlatex --output-directory=out --job-name=final paper.tex
mlatex -I styles -I figures paper
mlatex --watch --open paper
mlatex --time paper
Option Meaning
-o, --output-directory=DIR Write the PDF into DIR
-j, --job-name=NAME Name the PDF NAME.pdf
-n, --draft-mode Check the document and write no PDF
--halt-on-error Write no PDF if the document has an error
-I, --include-directory=DIR Also look in DIR for inputs, packages, pictures and bibliographies
--offline Make no network requests; for documents you did not write
-w, --watch Recompile every time the document is saved
-O, --open Open the PDF in the system viewer when it is written
-i, --interaction=MODE batch-mode prints only errors
--file-line-error Print errors as file:line:column: message
-T, --time Print how long the run took
--time-statistics Print every stage of the engine and its timing

mlatex --help lists every option. The exit status is 0 for a clean document, 1 for a document with errors (a PDF is still written unless --halt-on-error is given), and 2 for a mistake on the command line.

Bibliographies

\bibliography{refs} and biblatex's \addbibresource{refs.bib} read a .bib file directly, so there is no separate BibTeX step. A .bib file can also be imported with \input{refs.bib}. Running mlatex refs.bib typesets every entry in the file, which is useful for checking a bibliography before citing it.

Writing packages

A package is a folder containing main.mtex, written in the same language as a document. See src/modules/packages.md.

Embedding the engine

The command line is a thin layer over latex::Session, and every binding exposes that same interface under the same names.

C++

latex::Session session(latex::locate(program));
session.set("customer", "Acme Ltd.");
session.define({.name = "balance", .arity = 1, .handler = [&](auto arguments) {
    return ledger.balance(arguments[0]);
}});
session.provide("chart.png", png);

if (!session.typeset(document)) std::cerr << session.error;
send(session.pdf);

A whole document goes to typeset. A snippet -- a formula, a table, a picture, with no preamble -- goes to snippet, which sets it as a standalone document with amsmath and amssymb loaded and crops the page to it, for an app or a web page to show among its own content:

session.snippet(R"(\[ \int_0^1 x^2\,dx = \frac{1}{3} \])");
show(session.pdf);   // a page exactly the formula's size

\documentclass{standalone} does the same for a document written in full.

C, or any language that can call C (Python's ctypes, C#'s P/Invoke, Rust, Go). The library exports a single function, engine(), declared in include/protocols/ffi.hpp:

const Latex* table = engine();
Session* session = table->compose(NULL);
table->set(session, "customer", "Acme Ltd.");

const unsigned char* pdf;
size_t size;
if (!table->typeset(session, source, strlen(source), &pdf, &size)) {
    fprintf(stderr, "%s", table->error(session));
}

const char* formula = "\\[ e^{i\\pi} + 1 = 0 \\]";
table->snippet(session, formula, strlen(formula), &pdf, &size);
table->dispose(session);

The library ships in every package: latex_ffi.dll on Windows, liblatex_ffi.dylib on macOS and liblatex_ffi.so on Linux, with include/latex/ffi.hpp.

JavaScript, through the WebAssembly module: latex.js, latex.wasm and latex.data (the fonts), from the mlatex-<version>-wasm.zip of a release or built with the wasm preset (see include/render/wasm.hpp). It runs in a web page, a worker or Node:

const engine = await Latex();
const session = new engine.Session();
session.set("customer", "Acme Ltd.");
if (!session.typeset(source)) console.error(session.error());
const pdf = session.pdf();

session.snippet("\\[ e^{i\\pi} + 1 = 0 \\]");
const formula = session.pdf();   // a Uint8Array: hand it to PDF.js, or offer it as a download
session.delete();

Documentation

The API reference is generated from the sources with Doxygen:

cmake --build cmake-build-release --target docs

It is written to cmake-build-release/docs/html. The reference and src/modules/packages.md cover the engine's internals and package authoring. CHANGELOG.md describes every feature in detail.

Project layout

Path Contents
include/, src/ The engine: syntax (lexer, expander, parser), render (layout, typography, graphics, PDF), memory (arenas, tables), protocols (HTTP, the C library)
src/modules/ Packages and classes, one folder each, compiled into the binary
src/jit/ Reserved for the just-in-time target
assets/ Fonts, hyphenation patterns and the command glossary
build/ The sample paper, main.mtex
tests/ One test per source file, at the same relative path, and in tests/packages/ one sample document per package

Contributing

Contributions are welcome. Please open an issue to report a bug or to discuss a feature before starting on a large change. Pull requests should:

  • build without warnings and pass ctest;
  • add a test in the file that mirrors the source file they change;
  • follow the existing style: every identifier is one real word, with no underscores and no camelCase, and every declaration has a Doxygen comment;
  • add an entry to CHANGELOG.md.

Everyone taking part is expected to follow the Code of Conduct.

Support

The project's Discord server is the place to ask questions, discuss contributions and follow its direction: https://discord.gg/UUbPg5YtJF.

mLaTeX is maintained by Andres Hernandez (@ApaxPhoenix). For questions about the project or its direction, write to andromedeyz@hotmail.com. To report a security issue, follow SECURITY.md instead of opening a public issue.

License

mLaTeX is free software, licensed under the GNU Affero General Public License v3.0.

Acknowledgements

mLaTeX builds on HarfBuzz for text shaping and font subsetting, FreeType, libpng, libjpeg-turbo, libwebp and zlib. Its fonts include New Computer Modern, STIX Two, Fira Math, Asana Math and the TeX Gyre math fonts, and its hyphenation patterns come from the hyph-utf8 project. Above all, it owes its language to Donald Knuth's TeX and Leslie Lamport's LaTeX.

About

A rewritten typesetting system known as LaTeX, celebrated for its professionalism and written in C++ for maximum compatibility and speed.

Topics

Resources

Code of conduct

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages