What makes LaTeX genuinely necessary in a linguistics paper is not trees or phonetic symbols but numbering. "See (1)", "contrast with (3b)" — example numbers are referenced from the running text over and over, and inserting one example shifts everything after it. Doing that by hand is impossible, which is how linguists arrive at gb4e and expex, the packages for numbered examples and glosses. This page is organised around that numbering machinery, and covers interlinear glosses (\gll and \glt), IPA transcription (tipa and Unicode), OT tableaux and feature structures. It also records the traps actually hit on TeX Live 2024 — a single underscore in a label name makes gb4e die without producing a PDF.
Numbered examples and sub-examples: two ways to get (1) and (1a)
There are effectively two live options: gb4e and expex. In gb4e you list \ex inside an exe environment and nest an xlist environment wherever sub-examples are needed — (1) gains an a. and a b. beneath it, and references ride on standard LaTeX \label / \ref. expex works quite differently: examples are wrapped in \pex … \xe, sub-examples take \a, and references use its own \getref rather than LaTeX's \ref. Which to choose comes down almost entirely to whether you want to sit on LaTeX's reference machinery or are happy with a separate one. linguex (v4.3) and covington (v2.14) are also in TeX Live 2024; the former is notable for a terse, punctuation-like syntax such as \ex.
| Package | In TeX Live 2024 | How references work | What needs care |
|---|---|---|---|
gb4e | yes (its change log stops in 2010) | standard LaTeX \label / \ref | dies fatally on an underscore; needs \noautomath |
expex | yes (v5.1b) | its own \getref / \getfullref / \nextx | LaTeX's \ref does not apply, nor does \cref |
langsci-gb4e | yes (dated 2022-10-21) | as gb4e | a revised gb4e maintained by Language Science Press |
linguex | yes (v4.3) | standard LaTeX | a terse, punctuation-like syntax such as \ex. |
covington | yes (v2.14) | standard LaTeX | a long-standing toolbox of examples, glosses and symbols |
avm | no | — | Manning's avm.sty is not bundled; use langsci-avm instead |
Setting interlinear glosses with gb4e: \gll and \glt
The essence of an interlinear gloss is vertical alignment word by word, and that is what \gll does. Put the source data on the first line and the word-by-word gloss on the second, close each with \\, and gb4e splits both on spaces and lines the corresponding words up vertically. The free translation goes to \glt on a third line (use \glll when you need three aligned lines). The thing to watch is that the unit of alignment is "a space-separated word". If one source word wants two words of gloss, join them with a period into a single token, this.one — which is also what the Leipzig Glossing Rules prescribe, and the leipzig package bundled with TeX Live defines the standard abbreviations such as \Erg and \Pfv. Grammaticality marks are passed in brackets, as in \ex[*]{...}. For a single example there is also a shorter form that skips the exe environment: wrap it in \ea … \z.
\documentclass{article}
\usepackage{gb4e}
\noautomath % see the next section: this line prevents a fatal error
\begin{document}
\begin{exe}
\ex \label{ex:one}
\gll Kore wa rei desu.\\
this TOP example COP\\
\glt `This is an example.'
\begin{xlist}
\ex \label{ex:sub} A sub-example, printed with the label a.
\end{xlist}
\ex[*]{ Sleep colorless green ideas furiously. }
\end{exe}
See (\ref{ex:one}) and (\ref{ex:sub}).
\end{document}When gb4e dies with ! TeX capacity exceeded, sorry [parameter stack size=20000].
The cause is the underscore, and the fix is one line, \noautomath, immediately after \usepackage{gb4e}. Writing nothing more exotic than \label{ex_one} makes pdfLaTeX on TeX Live 2024 fall over like this: ! TeX capacity exceeded, sorry [parameter stack size=20000]., with \gb@ifnextchar showing up in the traceback and the run ending on ==> Fatal error occurred, no output PDF file produced! Not one byte of PDF comes out. The same happens with \cite{smith_2020} — joining an author to a year with an underscore is an entirely ordinary BibTeX key, so the document breaks the moment you add a bibliography. With \noautomath in place, both compile.
Why it happens is spelled out in gb4e's own source. gb4e makes _ and ^ active characters so that subscripts and superscripts can be written in ordinary text. The effect is genuinely dramatic: with gb4e loaded you can type NP_i, t_j and X^0 straight into a paragraph. Without it, the same input gives ! Missing $ inserted. — and for a syntax paper that writes indexed category labels several hundred times, that is a real convenience. The price is a head-on collision with every other macro that uses _ in its TeX meaning. A note in the source says exactly that: the file allows _ and ^ in ordinary text, hence must be loaded after any file that uses them in their TeX meaning, and mentions \noautomath as the way to switch the feature off. That is the substance behind the familiar advice to "load gb4e last in the preamble".
\cref prints ?? 1: cref reference format for label type 'xnumi' undefined
The fix is two lines in the preamble: \crefname{xnumi}{example}{examples} and \crefname{xnumii}{example}{examples}. Load gb4e together with cleveref and the compile succeeds without a single error, yet \cref{ex:one} comes out as ?? 1. Look in the .aux and you find \newlabel{ex:one@cref}{{[xnumi][1][]1}...}, while the log holds LaTeX Warning: cref reference format for label type 'xnumi' undefined. cleveref keeps a name for each kind of counter, but it has never heard of gb4e's example counter xnumi (sub-examples use xnumii), so it drops ?? where the name should go. Because this is a warning and not an error, the build passes — which is how a PDF carrying two hundred instances of ?? 1 ends up being submitted. Add the two lines and \cref{ex:one} prints example 1, \cref{ex:sub} prints example 1a.
The clash with hyperref, on the other hand, which is often mentioned in the same breath, did not reproduce on TeX Live 2024. With \usepackage{hyperref} placed either before or after gb4e, examples containing \gll set without error and \ref correctly returns (1). Claims online that "gb4e and hyperref cannot be used together" look like stale information, at least for the versions bundled here. The load-order principle itself still stands, though: if you are not using \noautomath, put gb4e after any other package that uses _.
\documentclass{article}
\usepackage{gb4e}
\usepackage{cleveref}
% Without these two lines \cref prints "?? 1" and the run still succeeds:
% LaTeX Warning: cref reference format for label type `xnumi' undefined
\crefname{xnumi}{example}{examples} % top-level examples: (1), (2), ...
\crefname{xnumii}{example}{examples} % sub-examples: (1a), (1b), ...
\begin{document}
\begin{exe}
\ex \label{ex:one} A top-level example.
\begin{xlist}
\ex \label{ex:sub} A sub-example.
\end{xlist}
\end{exe}
See \cref{ex:one} and \cref{ex:sub}. % -> "example 1 and example 1a"
\end{document}expex's reference machinery: \getref, \getfullref, \nextx
In expex, labels are not written with \label but in angle brackets right after the example: \pex<top>, and \a<one> for a sub-example. References go through \getref{top}, which gives 1; a sub-example takes its parent as a prefix, so \getref{top.one} gives a; and \getfullref{top.two} gives 1b, combining the top-level number with the sub-label. For forward reference there are \nextx (the number of the next example) and \lastx (the previous one), so "see (1) below" can be written without naming a number. When a reference cannot be resolved, the output carries [one] in brackets and the log holds ====> EXPEX WARNING: tag one is called but not defined. — in not letting an unresolved reference pass silently, this is safer than the cleveref combination.
\documentclass{article}
\usepackage{expex} % lives in tex/generic: works under plain TeX too
\begin{document}
Consider (\nextx). % forward reference to the example below
\pex<top>
\a<one> \begingl
\gla Kore wa rei desu.//
\glb this TOP example COP//
\glft `This is an example.'//
\endgl
\a<two> A second sub-example.
\xe
% \getref{top} -> 1 \getref{top.one} -> a \getfullref{top.two} -> 1b
See (\getref{top}), (\getref{top.one}) and (\getfullref{top.two}).
\end{document}expex was written by John Frampton of Northeastern University; the README carries a 2006–2017 copyright, the bundled version is v5.1b, and the user's guide runs to 82 pages. What is technically interesting is where it lives: tex/generic/expex/. It is not LaTeX-specific but a macro set that runs under plain TeX as well, and expex.sty is only a thin LaTeX wrapper. The gloss syntax also differs from gb4e: inside \begingl … \endgl you place \gla (the source data), \glb (the word-by-word gloss) and \glft (the free translation), and each line is closed by //, not by \\. That // is the first thing newcomers to expex get wrong.
The Language Science Press toolkit: langsci-gb4e and langsci-avm
The most actively maintained corner of the linguistics LaTeX ecosystem right now is the set of packages published by Language Science Press, the open-access linguistics publisher. langsci-gb4e.sty (dated 2022-10-21) is a tidied-up gb4e that also folds in the functionality of cgloss and jambox. The file sits in tex/xelatex/langsci/, but kpsewhich finds it whatever the engine, and it does in fact compile without error under both pdfLaTeX and XeLaTeX. The same directory holds langscibook.cls — the actual class the press uses to typeset its own books. A publisher that gives its books away also puts the typesetting class that makes them on CTAN, so an author can build the same PDF at home that the press does.
For feature structures — attribute-value matrices — note that the avm package by Chris Manning, which older write-ups name, is not in TeX Live 2024. \usepackage{avm} stops on ! LaTeX Error: File 'avm.sty' not found. The replacement is langsci-avm (Felix Kopecky, v0.3.0, 21 February 2023), whose README states plainly that it "serves the same purpose as Christopher Manning's avm package, but shares no code base with that package". Its syntax is a command rather than an environment: \avm{ [ cat & [ head & noun \\ case & nom ] ] }, with & separating attribute from value and \\ separating rows. Square, angle, round and curly delimiters each set the matching bracket. The manual has a section on converting from Manning's avm, which is where to start if you are carrying an old manuscript.
How to set IPA: tipa, Unicode, or tipauni
pdfLaTeX wants tipa, XeLaTeX and LuaLaTeX want Unicode typed directly, and tipauni is the bridge between them. tipa (by Rei Fukui) writes IPA through an ASCII shorthand: \textipa{[tSi:z]}, where S is ʃ, T is θ, N is ŋ, @ is ə and P is ʔ. Learning that mapping is the first hurdle, but once learned the input is fast and pdfLaTeX alone suffices. Where several transcriptions run together, the IPA environment wraps a whole stretch instead of repeating \textipa{...}. If XeLaTeX or LuaLaTeX is available, the straightforward route is to select a font with IPA coverage through fontspec and type [tʃiːz] literally in the editor. TeX Live 2024 bundles Linguistics Pro (linguisticspro), an OpenType family carrying IPA symbols and tone letters, so this route is open without installing anything.
The two routes do not, however, produce the same PDF. Extract the text from a tipa-set PDF with pdftotext and what comes back is [tSi:z] — the shorthand you typed, not the IPA. pdffonts shows the embedded font as TeX-tipa10, a Type 1 face whose encoding is Builtin; the text layer of the PDF is therefore not Unicode, so a reader who copies or searches it will not find IPA there. Set the same content with XeLaTeX and Linguistics Pro and pdftotext returns [tʃiːz], [θɔːt], [sɪŋ] and [ma˥˥]. If you can imagine a reviewer searching for a transcription, or yourself pulling your own data back out of the PDF, that difference is not one to shrug off.
This is where tipauni comes in (author निरंजन, v0.7a, 13 February 2023, GPL v3+): a package that keeps the TIPA commands and emits Unicode characters instead. Swapping \usepackage{tipa} for \usepackage{tipauni} in a document and building it with LuaLaTeX made pdftotext return [tʃiːz], [θɔːt], [sɪŋ]. In other words, twenty years of \textipa{...} can move to a searchable PDF without being rewritten. Its bundled example assumes Charis SIL, but on a machine without that face it fell back to New Computer Modern and still worked. As a sibling of tipa, the same bundle includes vowel, which draws the vowel quadrilateral through \putcvowel; phonrule, for setting phonological rules, is also in TeX Live 2024.
% Three routes to IPA, and what pdftotext gets back from each PDF.
% 1. pdfLaTeX + tipa -> text layer is the shorthand, not IPA: "[tSi:z]"
\usepackage{tipa}
\textipa{[tSi:z]} \textipa{[TO:t]} \textipa{[sIN]}
% 2. LuaLaTeX + tipauni -> same commands, Unicode output: "[tSiz]" becomes IPA
\usepackage{tipauni}
\textipa{[tSi:z]}
% 3. XeLaTeX/LuaLaTeX + fontspec -> type the IPA directly
\usepackage{fontspec}
\setmainfont{LinguisticsPro-Regular.otf}[
Path = /usr/local/texlive/2024/texmf-dist/fonts/opentype/public/linguisticspro/]
% then simply: [tʃiːz] [θɔːt] [sɪŋ] [ma˥˥]| Input | Engine | What pdftotext returns |
|---|---|---|
tipa | pdfLaTeX | [tSi:z] — the shorthand; the embedded face is TeX-tipa10 |
tipauni | LuaLaTeX / XeLaTeX | [tʃiːz] — with the tipa commands unchanged |
fontspec | XeLaTeX / LuaLaTeX | [tʃiːz] — tone letters such as ˥˥ come through too |
Optimality Theory tableaux: ot-tableau and where the *! goes
OT tableaux come from the ot-tableau package and need only three commands: input, constraint and candidate. \inp{/pat/} gives the input form, a run of \const{NoCoda} places the constraints left to right, and each candidate is written as \cand{pa}{}{*}{} — the candidate form followed by its violations against each constraint. Mark the winner with \cand[\Optimal]{...} and it gets the pointing hand. A fatal violation is simply typed *! and printed as such. The important part is that the constraint ranking is nothing but the order in which you write \const, so re-ranking for an experiment means reordering those lines rather than rearranging columns by hand. The tableau environment compiled without error against the version bundled with TeX Live 2024.
\usepackage{ot-tableau}
...
\begin{tableau}{c|c|c}
\inp{/pat/}
\const{NoCoda}\const{Max}\const{Dep}
\cand[\Optimal]{pa}{}{*}{}
\cand{pat}{*!}{}{}
\cand{pati}{}{}{*!}
\end{tableau}Drawing syntax trees: forest silently misreads qtree's dot notation
Syntax trees belong to a page of their own here ("Trees (forest/qtree)"), so this section records only the point that bites during a migration. qtree and tikz-qtree put a period before the node label — \Tree [.S [.NP ] [.VP ] ] — whereas forest's notation is [S [NP] [VP]] and uses no period. Feed qtree's notation to forest and no error is raised: [.S [.NP Kim ]] is set quite happily as a node literally named .S. If you get a tree whose shape is right but whose labels all begin with a dot, this is why. For the full comparison and for forest's automatic layout, follow the related link.
Finally, what this page deliberately leaves out. Chemical formulae and reaction schemes (mhchem, chemfig) and hobby or recreational typesetting each belong to their own page. On the linguistics side, the tools left aside are the syntax of covington and linguex should you choose them, langsci-avm's semantic brackets for LFG (the lfg option, which requires XeLaTeX), and glossaries via glossaries — none of them central. The first decision in this field remains, as said, which example-numbering machinery you adopt. If it is gb4e, write the three lines of \noautomath and \crefname at the very start. If it is expex, get used to the \getref idiom. Switching after the manuscript passes a hundred examples costs more than you expect.