Department of Engineering

IT Services

Extending LaTeX

LaTeX lets you write new commands (or adapt old ones), create or adapt environments, and write your own packages and even classes. This document will give detailed descriptions on how to do simple things, but won't cover all the issues relating to class creation.

Simple Macros

Sometimes you might want to repeat a long expression. The tidy way to do this is to use \def (or \newcommand). The following defines \xdt to produce something like X.desktop

\def\xdt{$\cal X\!\!$\texttt{.desktop}}

One problem that can arise is that your new code can introduce unwanted space. The Spaces in macros section of the FAQ covers this issue.

Commands

Use \newcommand to create a command and \renewcommand to over-write an existing one. You can use only letters in the names of commands.

  • \newcommand - A completely new command can be created using
    \newcommand{\ commandname}[number of arguments]{ command text, using #1, #2 etc to denote arguments}
    For example,
       \newcommand{\ve}[1]{\(#1_1 ... #1_n\)}
       \ve{x}
    
    produces as output x1 ... xn. A problem with this example is that it shouldn't change to math mode if LaTeX is already in that mode. A better try would be
       \newcommand{\ve}[1]{\ensuremath{#1_1 ... #1_n}}
    
    which will only change to math mode if it's necessary.
    The following weekday macro uses the ifthen package. Note the use of '%' characters to suppress spaces in the final output. weekday{3} should print out Wednesday.
    \usepackage{ifthen}
    \newcommand{\weekday}[1]%
    {%
    \ifthenelse{\equal{#1}{1}}{Monday}{}%
    \ifthenelse{\equal{#1}{2}}{Tuesday}{}%
    \ifthenelse{\equal{#1}{3}}{Wednesday}{}%
    \ifthenelse{\equal{#1}{4}}{Thursday}{}%
    \ifthenelse{\equal{#1}{5}}{Friday}{}%
    \ifthenelse{\equal{#1}{6}}{Saturday}{}%
    \ifthenelse{\equal{#1}{7}}{Sunday}{}%
    }
    
    \weekday{3}
    
  • \renewcommand - Let's start with some short though useful examples. Suppose you wanted to have References in a book rather than Bibliography. If you look in book.cls you'll see
       \newcommand\bibname{Bibliography}
    
    so adding
       \renewcommand{\bibname}{References}
    
    to your file should achieve what you want. Counters (e.g. figure - a variable that stores the figure number) have related commands (e.g. thefigure) to control their appearance, so they're easy to customise
       \renewcommand\thefigure{\roman{figure}}
    
    produces figure numbers in lower case roman numerals. Longer commands can be adapted too. Remember however, that if the command involves a @ character you have to enclose your changes in \makeatletter ... \makeatother or put the code into a package. Here's an example that changes the appearance of section headings, making them into centred small caps -
       \makeatletter
       \renewcommand{\section}{\@startsection{section}{1}{0mm}
       {\baselineskip}%
       {\baselineskip}{\normalfont\normalsize\scshape\centering}}%
       \makeatother
       \begin{document}
    
    The following's adapted from the TeX Frequently Asked Questions - Rather than overwriting an old command it's common to want to add some code at the beginning or the end of it. Suppose we want a version of a command that does some small extension of its original definition: we might try:
      \renewcommand{\splat}{addedcode\splat}
    
    However, this would not work: a call to \splat would execute addedcode, and then call the redefined \splat again; this is an infinite recursive loop. Fortunately, the TeX primitive \let command comes to our rescue; it allows us to take a "snapshot" of the current state of a command, which we can then use in the redefinition of the command. So:
      \let\Oldsplat\splat
      \renewcommand{\splat}{addedcode\Oldsplat}
    
    effects the required patch, safely. Adding things at the end of a command works similarly.

    If \splat takes arguments, one must pass them on:

      \renewcommand{\splat}[2]{addedcode\Oldsplat{#1}{#2}}
    

Environments

A new environment is slightly more difficult to create, because you can define what you want to happen on entering and leaving the environment.

\newenvironment{\ environmentname}[number of arguments][ default value of the 1st (optional) argument]{ entry code, using #1, #2 etc to denote arguments} { exit code - arguments can't be used}

Simple use isn't as painful as it looks - the following provides a variant of the itemize command, emphasising the items.

   \newenvironment{emlist}{\begin{itemize} \em}{\end{itemize}}
   \begin{emlist}
   \item first comment
   \item second comment
   \end{emlist}
   The end of the environment ends the scope of the emphasis.

produces

  • first comment
  • second comment

The end of the environment ends the scope of the emphasis.

\renewenvironment is used to change existing environments, but you can't change the number of arguments an environment takes.

Packages

A package needn't have any special code, but usually it starts with some special package commands

  • \NeedsTeXFormat{LaTeX2e}[1994/12/01] - means that the package requires a version of LaTeX2e dating no further back than 1994/12/01.
  • \ProvidesPackage{amsmath}[2000/07/18 v2.13 AMS math features] - defines the package name (in this case amsmath) and a string to be printed out when the package is used.
  • \RequirePackage{amssymb,mathptm} - tries to load in any prerequisite packages if they haven't been loaded in already
  • \DeclareOption{intlimits}{\let\ilimits@\displaylimits} - creates and defines an option for the package
  • \DeclareOption{nonamelimits}{\PassOptionsToPackage{nonamelimits}{amsopn}} - creates an option, in this case passing the option onto another package (but you have to load the package later)
  • \ExecuteOptions{nointlimits,sumlimits,namelimits,centertags} - executes some default options
  • \ProcessOptions - processes the code of each option that was both specified and declared

When writing a package you should try to minimize name-clashes

  • Prefix each variable and command name by the package name
  • Use @ in the name of internal variables so that users can't access them directly

Useful utilities from builting packages include

Classes

Creating a class file needs more work than package creation does. A class file can use many of the commands mentioned in the Packages section. In addition it can use

  • \ProvidesClass{handout} - to define its name.
  • \LoadClass[12pt,twoside,openright]{book} - to load in an existing class (one wouldn't normally write a class file from scratch).

See Also

See

for more details.