Programming helpers

As soon as you write nontrivial code in a package or preamble, you need things that raw TeX makes tedious: boolean flags, “is this command defined?” tests, “is this string empty?” tests, and appending to existing commands. **etoolbox supplies exactly those tools with a LaTeX-friendly feel, and pgfkeys** is the foundation for building key=value configuration interfaces. Both are staples working behind the scenes of many packages.

What etoolbox is

etoolbox (written by Philipp Lehman, now maintained by Joseph Wright) is a programming toolbox for class and package authors. It wraps the low-level primitives added by e-TeX in a LaTeX-style frontend**, and bundles in a number of handy general-purpose tools that are not strictly tied to e-TeX. Since every modern TeX engine includes e-TeX, you just write \usepackage{etoolbox} and the tools are available.

Even now that expl3 (the LaTeX3 programming layer) is widespread, etoolbox stays popular because it fits straight into the LaTeX2e world. Arguments you can write plainly as #1, the familiar {true}{false} two-way branch, and above all \patchcmd (below) for retro-fixing another package’s commands make it invaluable for real preamble work.

Boolean flags: toggles and bools

When you want to hold a true/false state — “are we in draft mode?” — etoolbox gives you two families. The recommended one is the toggle: it has its own namespace, so it never clashes with existing commands. Declare it with \newtoggle{flag}, switch it with \toggletrue{flag} / \togglefalse{flag} (or \settoggle{flag}{true}), and branch with **\iftoggle{flag}{⟨true code⟩}{⟨false code⟩}**. There is also \nottoggle{flag}{⟨if not true⟩}{⟨if not false⟩} for the inverse.

latex
\usepackage{etoolbox}

\newtoggle{draft}        % フラグを宣言 / declare the flag
\toggletrue{draft}       % 真にする / set it true

% 本文や命令の中で分岐 / branch on it
\iftoggle{draft}
  {\textbf{[DRAFT]}\ }    % 真のとき / when true
  {}                     % 偽のとき / when false

The other family is the bool: \newbool{flag} / \setbool{flag}{true} / \booltrue{flag} / \boolfalse{flag}, tested with **\ifbool{flag}{⟨true⟩}{⟨false⟩}**. Internally a bool uses the same machinery as LaTeX’s \newif, so it claims one command name, \ifflag. Toggles are enough most of the time, but bools help when you need to interoperate with \newif-based code.

CommandMeaningNotes
\newtoggle{f}Declare toggle f (false initially)Has its own namespace
\settoggle{f}{v}Set f to v (true/false)Or \toggletrue / \togglefalse
\iftoggle{f}{T}{F}T if true, F if falseTakes three arguments
\ifbool{f}{T}{F}The bool version of the branchSame machinery as \newif

Definition and string tests

To write a package safely you often want to know “is this command already defined?” or “is the argument empty?” In etoolbox every test uses the same **{⟨true⟩}{⟨false⟩} two-way branch. For definition, use \ifdef{\cmd}{⟨true⟩}{⟨false⟩}; to test by name (a string), \ifcsdef{name}{⟨true⟩}{⟨false⟩}**. The inverses \ifundef / \ifcsundef exist too.

Watch out: the similarly named **\ifdefined is an e-TeX primitive**, not an etoolbox command with a {true}{false} form. When you want the two-way branch, use etoolbox’s \ifdef (pass the actual command, backslash and all). For strings, you get **\ifblank{⟨string⟩}{⟨true⟩}{⟨false⟩} for “is it only spaces?”, its inverse \notblank, \ifstrequal{⟨string⟩}{⟨string⟩}{⟨true⟩}{⟨false⟩}** for equality of two strings, and \ifstrempty for emptiness.

latex
% 命令が未定義のときだけ用意する / provide a command only if missing
\ifdef{\highlight}
  {}                              % 既にあれば何もしない / leave it alone
  {\newcommand{\highlight}[1]{\textbf{#1}}}

% 引数が空かどうかで出し分け / vary on an empty argument
\newcommand{\field}[1]{\ifblank{#1}{(none)}{#1}}

Hooks and appending to commands

etoolbox also provides commands for working with hooks — places that hold code to run at a particular moment. The begin/end-of-document hooks \AtBeginDocument / \AtEndDocument are LaTeX-kernel features, but etoolbox complements them with **\AtEndPreamble** (the very end of the preamble), \AfterEndDocument (truly last), and hooks around a specific environment: **\AtBeginEnvironment{⟨env⟩}{⟨code⟩} / \AtEndEnvironment** / \BeforeBeginEnvironment / \AfterEndEnvironment.

To add to such hooks — or any macro — afterwards, use the appending commands. **\appto{\cmd}{⟨code⟩} appends at the end, \preto{\cmd}{⟨code⟩}** prepends at the start (\gappto is global, \eappto expands the code first). To append to a macro that takes arguments safely, use **\apptocmd{\cmd}{⟨code⟩}{⟨success⟩}{⟨failure⟩} / \pretocmd**, which carry success and failure branches.

latex
% すべての itemize の冒頭に行間設定を差し込む
\AtBeginEnvironment{itemize}{\setlength{\itemsep}{2pt}}

% 文書開始時に走るフックへ追記 / append to the begin-document hook
\appto{\@begindocumenthook}{\typeout{Hello from etoolbox}}

Patching commands with \patchcmd

The most famous tool in etoolbox is **\patchcmd. It replaces just part of an already-defined command’s body** — for when you want to tweak another package’s or the kernel’s command without redefining it wholesale. Its form takes these five arguments:

latex
\patchcmd{\cmd}{⟨search⟩}{⟨replace⟩}{⟨success⟩}{⟨failure⟩}

It searches \cmd’s definition for the first occurrence matching **⟨search⟩; if found, it substitutes ⟨replace⟩ and runs ⟨success⟩, and if not found it leaves the command untouched and runs ⟨failure⟩**. Only the first occurrence is replaced. You may leave ⟨success⟩ / ⟨failure⟩ empty, but it is safer to put a warning in the failure branch so you notice when a patch stops applying.

Two practical tips. First, the target command and the ⟨search⟩ almost always contain **@** (they are internal), so wrap the patch in \makeatletter\makeatother — or rely on the fact that \patchcmd temporarily makes @ a letter while it works. Second, when a patch will not take, put **\tracingpatches in the preamble: it writes diagnostics to the log (“undefined,” “pattern not found,” and so on). For argument specifications or replacing more than one occurrence, the xpatch** package, which extends etoolbox, is handy.

document.tex
\usepackage{etoolbox}

\makeatletter
% 例:ある内部命令 \@foo の定義中の \small を \footnotesize に差し替える
\patchcmd{\@foo}
  {\small}            % 探す / search
  {\footnotesize}     % 置き換える / replace
  {}                  % 成功時 / on success
  {\PackageWarning{mypkg}{Patch to \protect\@foo\space failed}} % 失敗時
\makeatother

Lists and loops

etoolbox also offers lightweight internal lists and ways to iterate them. Add an element with \listadd{\mylist}{⟨item⟩}, then call a one-argument handler on each element with **\forlistloop{⟨handler⟩}{\mylist}. To loop directly over a comma-separated string at hand, \docsvlist{a,b,c} and \forcsvlist{⟨handler⟩}{a,b,c}** are the quick options. There is also \DeclareListParser for building a parser with your own separator.

latex
% カンマ区切りの各要素を箇条書きにする / each CSV item becomes a bullet
\newcommand{\asitem}[1]{\item #1}
\begin{itemize}
  \forcsvlist{\asitem}{apples, pears, plums}
\end{itemize}

pgfkeys: the basis for key=value interfaces

pgfkeys is the powerful key–value engine** that ships inside PGF/TikZ. TikZ’s familiar [draw, thick, fill=blue] syntax, and the \…setup{...}-style interfaces of many packages, are largely implemented with it. The heart of it is **\pgfkeys{/my/key=value}**. Keys are organized into namespaces by /-separated paths (families), and you assign each key a handler that says “what to do when I am called.”

The handlers used to define keys are the crux. To store the value verbatim in a macro, use **.store in=\macro** (internally \def\macro{value}). To run code with the value, use **.code={... #1 ...}, where the passed value arrives as #1**. Give the value used when the key is called without =value via **.default=value, and the key’s starting value via .initial=value. There is also .is choice** for enumerating options.

latex
\usepackage{pgfkeys}

% キーを定義する / define keys under /book
\pgfkeys{
  /book/title/.store in = \bookTitle,        % 値をマクロに格納
  /book/edition/.code   = {Edition #1},       % #1 は渡された値
  /book/edition/.default = 1,                  % =値 省略時の既定
  /book/draft/.initial   = false,              % 初期値
}

% キーを設定する / set them
\pgfkeys{/book/title=TeX by Topic, /book/edition=3}

When a package exposes a \mypkgsetup{...} entry point, it sets a default path so users need not prefix /mypkg/ each time. The idiom is **\pgfqkeys{/mypkg}{⟨key list⟩}** (the “q” is for quick), a fast shorthand for \pgfkeys{/mypkg/.cd, ⟨key list⟩}. With a one-line wrapper like the one below, users configure things with short key names alone.

latex
% パッケージ側:設定窓口を一行で / the package: a one-line entry point
\newcommand{\mypkgsetup}[1]{\pgfqkeys{/mypkg}{#1}}

% 利用者側:短いキー名で設定 / the user: short key names
\mypkgsetup{title = My Report, edition = 2}

On the LaTeX3 side there is an equivalent, **l3keys** (the expl3 key–value module), which declares similar interfaces with \keys_define:nn and friends. A reasonable split: reach for l3keys when writing a new package in expl3, and for pgfkeys when matching TikZ/pgf-derived code or existing assets.