Skip to content
Content
Skill

/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,

From plugin
open-academic-paper-machine
1817 skills4 agents21 commands
Install
$ npx -y skills add TobiasBlask/open-paper-machine --skill latex-engine --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/latex-engine

Context preview

The summary Claude sees to decide when to auto-load this skill.

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,

SKILL.md

latex-engine.SKILL.md
name: latex-engine
description: >
  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 Pattern | LaTeX 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;;Univers
Read more
Ships withopen-academic-paper-machine

A Claude Code plugin that autonomously writes academic papers — from literature search to production-ready LaTeX/PDF. Scope note.

Get the whole plugin