# LaTeX to Lulu, the Making of AOSA: Custom Commands and Environments

The two volumes of The Architecture of Open Source Applications were typeset with LaTeX and printed through Lulu. I couldn’t have finished the AOSA books without the generosity of people all over the world who posted their LaTeX tips to forums and blogs. This series of posts pays some of that back by sharing what I learned.

This is the fourth post in the series.

#### LaTeX to Lulu

Today’s post is about the custom LaTeX commands and environments we created for the AOSA books.

As I said in an earlier post, we had to set up some new commands and environments to deal with the fact that each chapter of the AOSA book has a different author or team of authors. LaTeX has an author setting; we created chapterauthor.

\newcommand{\chapterauthor}{}

Our aosachapter environment takes the name of the chapter, the label (a unique string which identifies the chapter) and the author(s). It sets all the respective LaTeX settings with the appropriate values, and then populates the table of contents.

\newenvironment{aosachapter}[3]
{ \renewcommand{\chapterauthor}{#3} \chapter{#1} \label{#2}
\addtocontents{toc}{\hspace{1cm}\textit{\textsf{by \chapterauthor}}\protect\par} } {  }

We created some environments which were basically just new names for existing LaTeX environments. That was Greg’s doing, and at first it seemed pretty pointless to me. But later, when I wanted to change the design of an environment, it was really handy to have our own custom environment defined so I could futz with it.

(Having said that, clearly I didn’t futz with the following three environments.)

\newenvironment{aosasect1}[1]{\section{#1}}{}
\newenvironment{aosasect2}[1]{\subsection{#1}}{}
\newenvironment{aosasect3}[1]{\subsubsection*{#1}}{}

There is no sidebar environment in LaTeX, so I created a sidebar called aosabox using figure, minipage and the framed package. figure tells LaTeX that the sidebar is an entity that isn’t part of the text and that doesn’t break over a page. framed lets you put a box around the minipage. I also added a rule at the top and the bottom of the box to create a double line for texture.

\newenvironment{aosabox}[1]
{ \begin{figure}[h!]\vspace{-0.7cm}\centering \rule[-.7cm]{13.83cm}{0.75pt}
\begin{minipage}[t]{13.83cm}\begin{framed}\centerline{{\textbf{#1}}} }
{ \end{framed}\end{minipage} \rule{13.83cm}{0.75pt} \end{figure} }

Here’s how the sidebar looks (this is one of the lessons from the BDB chapter in Volume I):

We created custom environments to replace LaTeX’s three list types: aosadescription, aosaenumerate, and aosaitemize. This is where I did the futzing: I didn’t like the spacing in the default lists, so I spent a lot of time fiddling with these settings.

\newenvironment{aosadescription}
{\begin{description}[itemsep=-0.1ex,parsep=0.3ex,topsep=0.2ex,leftmargin=10mm]}
{\end{description}}

\newenvironment{aosaenumerate}
{\begin{enumerate}[itemsep=-0.8ex,topsep=0.2ex,leftmargin=10mm]}
{\end{enumerate}}

\newenvironment{aosaitemize}
{\begin{itemize}[itemsep=-0.8ex,topsep=0.2ex,leftmargin=8.5mm]}
{\end{itemize}}

Some chapters had lists nested within lists, and the spacing I’d set up for the outer lists didn’t work for the nested lists, so I created new environments for them.

% new environment for second-level nested enumerated lists
\newenvironment{aosaenumerate2}
{\begin{enumerate}[itemsep=-0.7ex,topsep=-1ex,leftmargin=10mm]}
{\end{enumerate}}

% new environment for second-level nested itemized lists
\newenvironment{aosaitemize2}
{\begin{itemize}[itemsep=-0.5ex,topsep=-1ex,leftmargin=9mm]}
{\end{itemize}}

We set up new commands for references. LaTeX’s default references just give you the number of the object you’re referencing (like “12.1” for the first section in the 12th chapter). Our commands are specific to the object you’re referencing — aosafigref for figures and aosasecref for sections — and they return “Figure ” or “Section ” as well as the number.

\newcommand{\aosaboxref}[1]{Box~\ref{#1}}
\newcommand{\aosachapref}[1]{Chapter~\ref{#1}}
\newcommand{\aosafigref}[1]{Figure~\ref{#1}}
\newcommand{\aosasecref}[1]{Section~\ref{#1}}
\newcommand{\aosatblref}[1]{Table~\ref{#1}}

We created a new command for images. Again, it uses LaTeX’s default figure and includegraphics settings but accepts and passes on our parameters so we can enforce consistent image layout throughout the book.

aosafigure accepts the image width, the filename of the image, the caption, and a unique label for the figure. It passes the width and filename to includegraphics, the caption to caption and the label to label. Width is an optional parameter, and if it’s not passed in we set the default to be 375 points. (LaTeX automatically scales the image and keeps the aspect ratio, so you only have to pass in width.)

\newcommand{\aosafigure}[4][375pt]{\begin{figure}[h!]\centering\includegraphics
[width={#1}]{#2}\caption{#3}\label{#4}\end{figure}}

In the aosafigure command we called figure with the h! option, which stands for “here” and means we want the figure to be placed as close to where it is defined in the source as possible. (The exclamation mark means we really mean it.) But sometimes I wanted the figure to be placed at the top of the nearest page, say if it is a large image and would look awkward with just a few lines of text above it. So I created an aosafigureTop command for those cases.

\newcommand{\aosafigureTop}[4][375pt]{\begin{figure}[t]\centering\includegraphics
[width={#1}]{#2}\caption{#3}\label{#4}\end{figure}}

We created a new command called code for code, instead of LaTeX’s texttt.

\newcommand{\code}[1]{\texttt{#1}}

I also created a “small code” command for one table in one chapter which needed a smaller text size.

\newcommand{\smcode}[1]{\small\texttt{#1}\normalsize}

That’s all our custom commands and environments. Next time: a compendium of the miscellaneous packages and settings which didn’t fit into the first four posts of this series.