latex-engine

Activate when the user wants to export a completed paper draft to production-ready LaTeX (.tex) and PDF. Converts draft.md + references.bib + figures/ into a complete arxiv-style LaTeX project with properly resolved \citep/\citet citations, booktabs tables, figure environments, and compiled PDF output.

Orchestration Log: When this skill is activated, append a log entry to outputs/orchestration_log.md:

### Skill Activation: LaTeX Engine
**Timestamp:** [current date/time]
**Actor:** AI Agent (latex-engine)
**Input:** [brief description of the export request]
**Output:** [brief description of what was produced — e.g., "Compiled paper.tex to PDF (24 pages), no errors"]

LaTeX Engine

Core Principle

The paper machine works in markdown throughout Phases 1-5 for speed and flexibility. This engine is the final production step: it takes the completed draft.md, references.bib, and figures/ and produces a submission-ready LaTeX project with compiled PDF using the arxiv-style template (https://github.com/kourgeorge/arxiv-style).

Prerequisites

Required files in the working directory:

  • draft.md — complete paper draft from Phase 5
  • references.bib — BibTeX file from literature search
  • figures/ — directory with generated PNG figures (optional but recommended)

Required system packages for PDF compilation:

  • texlive or equivalent LaTeX distribution with pdflatex and bibtex
  • Install if missing: apt-get install -y texlive-latex-base texlive-latex-extra texlive-fonts-recommended texlive-bibtex-extra

Plugin files used:

  • templates/arxiv.sty — the arxiv-style LaTeX style file
  • scripts/md_to_latex.py — the markdown-to-LaTeX converter

When to Activate

  • User says "export to LaTeX", "generate PDF", "make it submission-ready"
  • After Phase 5 (Assembly) completes in the paper machine pipeline
  • User explicitly asks for .tex output
  • User mentions arXiv submission preparation

Conversion Pipeline

Step 1: Prepare the LaTeX Project Directory

Create a latex/ subdirectory with the proper structure:

latex/
├── arxiv.sty          ← copied from templates/
├── paper.tex          ← generated by md_to_latex.py
├── references.bib     ← copied from working dir
├── figures/           ← copied from working dir
│   ├── fig_method_*.png
│   ├── fig_results_*.png
│   └── ...
└── paper.pdf          ← compiled output

Step 2: Run the Converter

import sys, shutil
from pathlib import Path

# Paths
plugin_dir = Path(".")  # or wherever the plugin is
work_dir = Path(".")     # project working directory
latex_dir = work_dir / "latex"
latex_dir.mkdir(exist_ok=True)

# Copy arxiv.sty
shutil.copy(plugin_dir / "templates" / "arxiv.sty", latex_dir / "arxiv.sty")

# Copy references.bib
shutil.copy(work_dir / "references.bib", latex_dir / "references.bib")

# Copy figures
figures_src = work_dir / "figures"
if figures_src.exists():
    figures_dst = latex_dir / "figures"
    if figures_dst.exists():
        shutil.rmtree(figures_dst)
    shutil.copytree(figures_src, figures_dst)

# Run converter
sys.path.insert(0, str(plugin_dir / "scripts"))
from md_to_latex import md_to_latex, compile_pdf

tex_content = md_to_latex(
    md_path=str(work_dir / "draft.md"),
    bib_path=str(work_dir / "references.bib"),
    title=None,       # auto-detect from draft.md
    authors=None,      # user provides or TODO marker
    header_right="A Preprint",
)

tex_path = latex_dir / "paper.tex"
tex_path.write_text(tex_content, encoding="utf-8")
print(f"LaTeX written: {tex_path}")

Step 3: Compile to PDF

# Compile: pdflatex → bibtex → pdflatex → pdflatex
pdf_path = compile_pdf(str(tex_path))
if pdf_path:
    print(f"PDF ready: {pdf_path}")
else:
    print("Compilation had issues — check paper.log")

Step 4: Validate Output

After compilation, verify:

  1. Citation resolution: Check for undefined references in the .log file
  2. Figure inclusion: Verify all \includegraphics paths resolve
  3. BibTeX entries: Check that all \citep/\citet keys exist in .bib
  4. Page count: Report total pages
  5. TODO markers: List any remaining % TODO: comments
import re

log_path = latex_dir / "paper.log"
if log_path.exists():
    log_text = log_path.read_text(encoding="utf-8", errors="ignore")

    # Undefined references
    undef = re.findall(r"Citation `([^']+)' undefined", log_text)
    if undef:
        print(f"⚠️  Undefined citations: {undef}")

    # Missing figures
    missing_figs = re.findall(r"File `([^']+)' not found", log_text)
    if missing_figs:
        print(f"⚠️  Missing figures: {missing_figs}")

    # Page count
    pages = re.findall(r"Output written on .+ \((\d+) page", log_text)
    if pages:
        print(f"📄 PDF: {pages[0]} pages")

# TODO markers in .tex
tex_text = tex_path.read_text(encoding="utf-8")
todos = re.findall(r"% TODO: (.+)", tex_text)
if todos:
    print(f"📝 Remaining TODOs ({len(todos)}):")
    for t in todos:
        print(f"   - {t}")

Citation Conversion Details

The converter handles these citation patterns:

Markdown PatternLaTeX Output
(Smith, 2023)\citep{smith2023}
(Smith & Jones, 2023)\citep{smithjones2023}
(Smith et al., 2023)\citep{smithetal2023}
Smith (2023)\citet{smith2023}
Smith et al. (2023)\citet{smithetal2023}
(Smith, 2023; Jones, 2024)\citep{smith2023, jones2024}

Resolution process:

  1. Parse all BibTeX entries → extract (LastName, Year) pairs
  2. For each citation in markdown, match against the BibTeX index
  3. Exact match → use BibTeX key directly
  4. Fuzzy match → try without accents, partial first name
  5. No match → generate fallback key, leave % TODO comment

Author Block

Authors can be provided in three ways:

Option A: Via command arguments

--author "Tobias Blask;;University of Applied Sciences;;[email protected]"
--author "Co-Author Name;;Other University;;[email protected]"

Option B: Via the converter function

tex = md_to_latex(
    md_path="draft.md",
    bib_path="references.bib",
    authors=[
        "Tobias Blask;;HTW Berlin;;[email protected]",
        "Co-Author;;Institution;;[email protected]",
    ],
)

Option C: Edit the .tex file directly The generated .tex has a clear author block section to edit manually.


Table Conversion

Markdown tables are converted to LaTeX booktabs tables:

| Column A | Column B | Column C |
|----------|----------|----------|
| Data 1   | Data 2   | Data 3   |

Becomes:

\begin{table}[htbp]
\centering
\begin{tabular}{lll}
\toprule
\textbf{Column A} & \textbf{Column B} & \textbf{Column C} \\
\midrule
Data 1 & Data 2 & Data 3 \\
\bottomrule
\end{tabular}
\end{table}

For concept matrix tables (which can be wide), the converter wraps in \adjustbox{max width=\textwidth}.


Figure Handling

From figure-engine (LaTeX already in draft.md): If the draft already contains \begin{figure}...\end{figure} blocks (from the figure-engine), they are passed through as-is.

From markdown images: ![Caption](figures/filename.png) is converted to:

\begin{figure}[htbp]
\centering
\includegraphics[width=\linewidth]{figures/filename.png}
\caption{Caption}
\label{fig:auto_label}
\end{figure}

Troubleshooting

ProblemSolution
arxiv.sty not foundEnsure arxiv.sty is copied to the same directory as paper.tex
Citation undefinedBibTeX key mismatch — check references.bib has the expected keys
Missing figureCheck figures/ directory is in the latex/ folder
Font not foundInstall texlive-fonts-recommended
natbib errorsEnsure natbib package is installed (texlive-latex-extra)
Compilation hangsCheck for infinite loops in .tex — usually malformed tables

arXiv Submission Preparation

For arXiv upload, the user needs:

  1. paper.tex — the generated .tex file
  2. arxiv.sty — the style file
  3. references.bib — OR the .bbl file (generated during compilation)
  4. figures/ — all PNG figures

Important: arXiv doesn't always process .bib files correctly. To be safe:

  1. Copy the contents of paper.bbl (generated during compilation)
  2. Paste into paper.tex replacing the \bibliography{references} line
  3. Comment out the \bibliographystyle and \bibliography lines

The converter can prepare this automatically with --arxiv-bundle (copies .bbl inline).