24

I have been using LaTeX for a long time now, and I find myself often going to this website to solve my problems. This often includes copy pasting codes which include \newcommand, \newenvironment and \def. I think it is time I start to learn how to use them so I can solve my problems myself! It is always better if you actually know what is going on inside your code.

I am wondering if there is any turtorial or book out there that handles how to use those commands. Or is the best way to learn to just mess with a random file?

Thanks in advance!

(Also this is my first time I post here after using this website for so long, I really appreciate everyone who posts and tries to help other people here!)

5
  • 1
  • The LaTeX Wikibook has a quick introduction, and Section 8 in particular has some information about programming that can help you get started.
    – cjohnson
    Apr 20, 2014 at 13:48
  • 3
    Start with \newcommand and \newenvironment and think about \def later. The first two are LaTeX macros; the third is TeX. You should prefer the former to the latter although there are cases in which only the latter will work. But it is easier to understand when and why to use \def and friends if you first learn to use the LaTeX commands: \newcommand \newenvironment \renewcommand \renewenvironment \providecommand \provideenvironment and their starred companions.
    – cfr
    Apr 20, 2014 at 14:01
  • 1
    @cfr You should post an answer expanding on your comment :)
    – jub0bs
    Apr 20, 2014 at 14:45
  • @Jubobs Done! (I don't think there is such a command as \provideenvironment so I omitted that in writing my answer!)
    – cfr
    Apr 20, 2014 at 15:50

1 Answer 1

31

LaTeX macros for defining custom commands and environments include:

  • \newcommand
  • \newcommand*
  • \renewcommand
  • \renewcommand*
  • \providecommand
  • \providecommand*
  • \newenvironment
  • \newenvironment*
  • \renewenvironment
  • \renewenvironment*

It is best to start with these since you should prefer them to TeX macros such as \def. However, sometimes only the TeX macros will work. It is easier to understand when and why \def and friends are needed once you have a good understanding of how the LaTeX macros work.

Defining, redefining and providing commands

\newcommand[<n>][<default>]{<definition>}

where <n> is the total number of arguments and <definition> is the definition of the command. If <n> is not specified, LaTeX assumes the command cannot take arguments. If <default> is given, the first argument is optional and, if missing, <default> is used.

For example, this is how \tableofcontents is defined in article.cls:

\newcommand\tableofcontents{%
    \section*{\contentsname
        \@mkboth{%
           \MakeUppercase\contentsname}{\MakeUppercase\contentsname}}%
    \@starttoc{toc}%
    }

The command takes no arguments, either mandatory or optional, so only the macro name, \tableofcontents and the definition of the macro are given.

Here is an example with a single, mandatory argument from \ltnews.cls:

\newcommand\cs[1]{\texttt{\textbackslash#1}}

The #1 refers to the first argument.

This is an example from latex.ltx defining a new command which takes 2 arguments, one mandatory and one optional. If the optional argument is not given, the default value of 0 will be used as #1:

\newcommand\qbezier[2][0]{\bezier{#1}#2}

The number of arguments may not exceed 9 and no more than one optional argument may be specified using \newcommand. All other arguments must be mandatory. Moreover, if an optional argument is available, it must be specified first and the syntax of the defined command is always \mycommand[optional]{mandatory}{mandatory}{mand....

\newcommand checks for an existing command of the same name and produces an error if it finds one. So there is a built-in check to prevent accidentally overwriting an existing command.

\newcommand* is just like \newcommand but its arguments cannot contain paragraph breaks.

To redefine an existing command, you can use \renewcommand or \renewcommand*. In this case, LaTeX checks whether or not the command already exists and produces an error if it does not.

If you want to define a command only if it does not exist already, you can use \providecommand or \providecommand*.

Defining and redefining environments

\newenvironment{<env name>}[<n>][<default>]{<begin env>}{<end env>}

where <env name> is the name of the new environment, <n> is the number of arguments (0 if not specified) and <default> is the default value of the first argument if the first argument is optional (all arguments are mandatory if this is not specified). <begin env> and <end env> specify the code to be executed at the beginning and end of the environment.

This is very like \newcommand. <n> cannot exceed 9, only one argument may be optional and it must be the first argument, and LaTeX will complain if an environment of the same name already exists. #1,... #9 refer to the arguments given to the environment if applicable.

Here is an example from cuisine.sty with 3 arguments, all mandatory:

\newenvironment{recipe}[3]{%
  \stepcounter{r@cipenumber}
  \let\newstep\m@thodend
  \let\recipen@wpage\newpage
  \let\newpage\r@cipen@wpage
  \let\0\d@grees
  \let\degrees\d@grees
  \let\fr\fr@ction
  \let\ing\ingr@dient
  \let\ingredient\ingr@dient
  \let\freeform\fr@eform
  \n@wpagingfalse%
  \setlength{\parindent}{0pt}
  \savebox{\st@pingrbox}[\R@cipeIQUWidth]{}
  \savebox{\st@pmethodbox}[\R@cipeMethodWidth]{}
  \ifind@xing
     \addcontentsline{toc}{subsection}{#1}
  \fi
  \r@cipetitle{#1}{#2}{#3}
  \vskip0.2cm%
  \p@stingred%
}%
{%
  \pr@ingred%
  \ifnum\value{st@pnumber}=0%  then complain!
    \PackageWarning{cuisine}{The recipe did not have any steps}%
  \fi%

  \pagebreak[0]%
  \medskip%
  \@endpetrue%
}%

\newenvironment* is just like \newenvironment but its arguments cannot contain paragraph breaks.

To redefine an existing environment, use \renewenvironment or \renewenvironment*. Again, LaTeX will complain in this case if the environment does not already exist.

Beyond LaTeX 2e

When you are comfortable with these methods of customisation, you will find that there are limitations on what you can do. At this point, start to look at \def and friends. At this stage, you should probably also take a look at xparse which provides much more powerful and flexible options from the work developing LaTeX 3. But these methods will make more sense once you are familiar with the possibilities offered by the LaTeX 2e macros.

2
  • Thanks a lot, this is a major deal in understanding the basics of making your own environment and commands!
    – Pure
    Apr 20, 2014 at 20:08
  • @Pure You're welcome. You should not do this yet but don't forget to accept an answer when you've had a chance to consider those offered. (In case you are not sure, there's a faded out checkmark/tick beneath each answers score which you click to accept which ever answer you like.) Don't do this yet because although you can change your mind, seeing an accepted answer may put people off providing their own.
    – cfr
    Apr 21, 2014 at 1:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .