Skip to content

Typst writer: two common LaTeX constructs produce output that does not compile (\ref to a section, thebibliography) #11779

Description

@Supersynergy

Summary

Converting ordinary LaTeX to Typst produces .typ files that fail typst compile with a hard error
for two very common constructs. Unlike the HTML/DOCX writers, Typst has a compile step, so these
degrade from "renders slightly differently" to "produces no document at all".

Both have small, well-scoped fixes. Tested with pandoc 3.10.1 and typst 0.15.1.


Case A: \ref to a section

\documentclass{article}\begin{document}
\section{Intro}\label{sec:i}
See \ref{sec:i}.
\end{document}
$ pandoc -s -f latex -t typst a.tex -o a.typ
$ typst compile a.typ
error: cannot reference heading without numbering
    ┌─ a.typ:150:4

150 │ See @sec:i.
    │     ^^^^^^

    = hint: you can enable heading numbering with `#set heading(numbering: "1.")`

The writer emits @sec:i, but nothing sets heading numbering. article numbers sections by
default in LaTeX, so this affects essentially every structured LaTeX document that uses \ref.

The default Typst template already supports this. It never receives the value:

$ pandoc --print-default-template=typst | grep -n section-numbering
104:$if(section-numbering)$
105:  sectionnumbering: "$section-numbering$",

Confirmed workaround:

$ pandoc -s -f latex -t typst -M section-numbering="1.1" a.tex -o a.typ && typst compile a.typ
# succeeds

Suggested fix: have the LaTeX reader set section-numbering when the document class numbers
sections and \ref targets exist (mirroring the LaTeX default), or have the Typst writer fall back
to a plain #link(<label>)[…] when it cannot guarantee the target is numbered.


Case B: thebibliography, where the root cause is in the LaTeX reader

\documentclass{article}\begin{document}
Text \cite{k}.
\begin{thebibliography}{9}\bibitem{k} Knuth.\end{thebibliography}
\end{document}
$ pandoc -s -f latex -t typst b.tex -o b.typ
$ typst compile b.typ
error: label `<k>` does not exist in the document
    ┌─ b.typ:148:5

148 │ Text @k.
    │      ^^

The reader drops the \bibitem key entirely. The resulting Span has an empty identifier:

$ pandoc -f latex -t native b.tex | tail -4
, Div
    ( "" , [ "thebibliography" ] , [] )
    [ Para
        [ Span ( "" , [] , [] ) [ Str "9" ] , Space , Str "Knuth." ]

The \cite{k} still becomes a Cite with citationId = "k", which the Typst writer renders as
@k. Since the key never reached the bibliography entry, the label does not exist.

This is also visible (less harmfully) in the HTML writer, which emits an empty citation:

$ pandoc -f latex -t html b.tex
<p>Text <span class="citation" data-cites="k"></span>.</p>
<div class="thebibliography">
<p><span>9</span> Knuth.</p>
</div>

--citeproc is not a workaround. It compiles, but silently drops the citation:

$ pandoc -s -f latex -t typst --citeproc b.tex -o b2.typ
[WARNING] Citeproc: citation k not found

The BibTeX path works correctly, which isolates the problem to thebibliography:

$ printf '\\documentclass{article}\\begin{document}\nText \\cite{k}.\n\\bibliography{r}\n\\end{document}\n' > c.tex
$ pandoc -s -f latex -t typst c.tex -o c.typ && typst compile c.typ   # succeeds
$ grep bibliography c.typ
#bibliography(("r.bib"))

Minimal fix: preserve the \bibitem key as the identifier on the emitted Span
(or on a wrapping Div), so writers can attach a label. That alone makes the Typst output compile
and simultaneously fixes the empty data-cites span in the HTML writer.

Fuller fix: have the Typst writer emit #bibliography entries, or attach <key>
labels to each bibliography item.


Reproduction script

#!/usr/bin/env bash
set -uo pipefail
run() {
  pandoc -s -f latex -t typst "$1.tex" -o "$1.typ" || return 1
  if typst compile "$1.typ" "$1.pdf" >/dev/null 2>&1
    then printf '%-2s compiles=YES\n' "$1"
    else printf '%-2s compiles=NO\n'  "$1"; typst compile "$1.typ" "$1.pdf" 2>&1 | head -3
  fi
}
run a   # NO  — \ref to section
run b   # NO  — thebibliography
run c   # YES — \bibliography{r.bib}
run d   # YES — title/author/math

Observed on pandoc 3.10.1 / typst 0.15.1 / macOS 15 arm64.


Why this matters beyond the two cases

The Typst writer handles the rest well. Headings, labels, math, booktabs tables
(table.hline), figures, \title/\author, and \bibliography{x.bib} all convert cleanly.
These two gaps are what make "convert an existing LaTeX paper to Typst" fail in practice, since \ref and an inline
thebibliography appear in a large share of real documents, including many self-contained
conference and journal submissions where thebibliography is required rather than optional.

I am happy to prepare a PR for the reader-side \bibitem identifier fix if the approach looks right.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions