Skip to content

Engines

Zouhair Fouiguira edited this page Feb 28, 2026 · 1 revision

Engines

FormaTex supports four TeX engines. Choose based on what your document needs.

Quick Decision

Unicode / non-Latin scripts?         → xelatex or lualatex
Lua scripting or complex fonts?      → lualatex
Need automatic multi-pass?           → latexmk
Standard English document?           → pdflatex (default, fastest)
Not sure?                            → compile_smart() auto-detects

pdflatex (default)

result = client.compile(latex, engine="pdflatex")
  • ✅ Fastest compilation
  • ✅ Widest package compatibility
  • ❌ Limited Unicode (use inputenc + fontenc packages for accented characters)
  • ❌ No system font access

xelatex

result = client.compile(latex, engine="xelatex")
\usepackage{fontspec}
\setmainfont{Times New Roman}
  • ✅ Full Unicode support
  • ✅ System fonts via fontspec
  • ✅ Better multilingual / Arabic / CJK support
  • ❌ Slower than pdflatex
  • ❌ Some packages have reduced or no support

lualatex

result = client.compile(latex, engine="lualatex")
  • ✅ Full Unicode support
  • ✅ Lua scripting with \directlua{}
  • ✅ Best font handling (fontspec)
  • ❌ Slowest engine
  • ❌ Some packages incompatible

latexmk

result = client.compile(latex, engine="latexmk")
  • ✅ Automatically runs multiple passes (resolves cross-refs, BibTeX, indices)
  • ✅ Good for complex documents
  • ❌ Less predictable compile time

Smart Compile — auto-detect

result = client.compile_smart(latex)
print(result.analysis)  # {"engine": "xelatex", "reason": "uses fontspec"}

compile_smart() reads \usepackage declarations and picks the best engine automatically.

Multi-Pass with pdflatex/xelatex

Set runs to control compiler passes:

# 3 passes: resolves BibTeX + cross-references + TOC
result = client.compile(latex, engine="pdflatex", runs=3)
Document type Recommended runs
Simple article (no cross-refs) 1 (default)
With \ref, \label 2
With BibTeX / bibliography 3

Check Available Engines

engines = client.list_engines()
for e in engines:
    print(e["name"], "→", "available" if e["available"] else "unavailable")

Engine availability depends on your plan.

Clone this wiki locally