Custom commands

Perhaps TeX’s most remarkable feature is its longevity. In the technology world, two or three year old software can look long in the tooth, and although product lines such as Microsoft Office and Adobe Photoshop have persisted for decades, they have been completely rewritten at least once in that time and it is unlikely that any of the original code has survived. This makes it all the more remarkable that TeX could survive forty years virtually unchanged. The secret to TeX’s eternal youth is its extensibility. TeX is not really a typesetting system, so much as it is a programming language with a fantastic standard library aimed at typesetting. For most users TeX and LaTeX are synonymous, but the latter is in fact a set of packages running on top of the TeX binary. Plain TeX and ConTeXt are different sets of packages running on the same TeX binary. This article will explain how the average user can use TeX’s flexibility to his or her benefit, focussing on LaTeX.

The easy way - \newcommand

A simple and common use case is that the paper you are working on is littered with references to e.g. the mathematical object $E_8^{+++}$, a real handful to type every sentence. A simple solution to this is to define a new command at the top of your document.

\newcommand{\E}{$E_8^{+++}$}

From this point on type \E in the LaTeX source and TeX will replace it with $E_8^{+++}$. A more sophisticated example would be if you habitually write all section names with Section:. For example you may usually write

\section{Section: Something}
\section{Section: Introduction}

You can save time by defining a \seclab command by

\newcommand{\seclab}[1]{\section{Section: #1}}

Then you only need type

\seclab{Something}
\seclab{Introduction}

I will break down and explain the \newcommand line in more detail.

  • The first curly bracket delimited parameter is the name of the command you wish to define \seclab
  • The square bracket delimited parameter is the number of parameters taken by this new command, that is to say the number of curly bracket parameters that should follow the command, for example \frac{x}{y} has 2 parameters and \section{foo} has one.
  • The final argument is the text that this command should be expanded to, in this case \section{Section: #1}. The first argument to the command is assigned to #1, the second argument ton#2, and so on.

Replacing built in commands

There are situations where you may wish to alter the behaviour of existing commands, this is common with publishing houses who wish to enforce a house style. In this case you can use \renewcommand, which works exactly the same as \newcommand, except it will not throw an error when that command is already defined. If you type

\renewcommand{\section}[1]{\centerline{Section: #1}}

Then the section command will be changed to output a centered line with the section title prefixed by Section:, nevertheless, the other magic performed by \section, placing an entry in the index, and the title at the top of the page, will be missing. We really want to adapt the behaviour of the old command. To do this we assign the old command to a new name, then redefine the command.

\let\oldsection\section
\renewcommand{\section}[1]{\centerline{Section: #1}}

TeX macros

Some users may be used to defining commands with \def, for example the first example could be written

\def \E {$E_8^{+++}$}

Although this is perfectly valid, and in fact slightly more flexible, for the most part \def is the old TeX convention, and it should be replaced by \newcommand, the LaTeX convention, which is designed to be cleaner and easier to read.

Environments (begin/end blocks)

Environments are easy to define too, use the newenvironment command

\newenvironment{ruled}{before\hrule}{after\hrule}

Where the arguments are

  • the name of the environment
  • the commands to insert when opening the environment
  • the commands to insert when closing the environment

Now you can write

\begin{ruled}
  some text
\end{ruled}

And you will see the text surrounded by horizontal rules. There is a corresponding \renewenvironment command.