2

I'm working with the letter class, and have created a custom .cls file in which most formatting of a letter is taken care off. From a .tex file used to produce the letter (or call, as I may have referred to it below) I specify the from and to addresses, etc. Ideally I would specify these files by filename. There have been suggestions to use the catchfile package file for this. In the custom class file, I can manually enter an address as the argument to an instance of the letter environment, however, I cannot seem to use catchfile to refer to a to address residing in a separate file, e.g. an entry of an address book.

Here is a working example in which catchfile is used to read a from address.

Common files:

address.tex

868 Sunrise Ave. \\
Garden City \\

body.tex

\lipsum[1]

thelettera.cls

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{thelettera}[]
\LoadClass[]{letter}
\RequirePackage{lipsum}
\RequirePackage{catchfile}
\RequirePackage[textwidth=345.0pt,%
top=2in,
headheight=1.0in,
headsep=0.20in]{geometry}
\newcommand{\getfromaddress}[1]{\CatchFileDef{\thefromaddress}{#1}{}}
\signature{Mae L. Mann}
\AtBeginDocument{%
\pagestyle{empty}
\makeatletter
\let\ps@firstpage\ps@plain
\makeatother
  \begingroup\def\tempa{\endgroup\begin{letter}{1234 Central St. \\ Western City}}
    \expandafter\tempa\expandafter{\thefromaddress}%
  \opening{\theopening}
}%
\AtEndDocument{%
\closing{\theclosing}
\ps{\thepostscript}
\end{letter}
}

lettera.tex

\NeedsTeXFormat{LaTeX2e}
\documentclass{thelettera}
\getfromaddress{address.tex}
\newcommand{\theopening}{Dear Recipient}
\newcommand{\theclosing}{Sincerely,}
\newcommand{\thepostscript}{}
\begin{document}
\input{body.tex}
\end{document}

To illustrate the issue, if I use this class file

theletterb.cls

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{theletterb}[]
\LoadClass[]{letter}
\RequirePackage{lipsum}
\RequirePackage{catchfile}
\RequirePackage[textwidth=345.0pt,%
top=2in,
headheight=1.0in,
headsep=0.20in]{geometry}
\newcommand{\getfromaddress}[1]{\CatchFileDef{\thefromaddress}{#1}{}}
\newcommand{\gettoaddress}[1]{\CatchFileDef{\thetoaddress}{#1}{}}
\signature{Mae L. Mann}
\AtBeginDocument{%
\pagestyle{empty}
\makeatletter
\let\ps@firstpage\ps@plain
\makeatother
  \begingroup\def\tempa{\endgroup\begin{letter}{\thetoaddress}}
    \expandafter\tempa\expandafter{\thefromaddress}%
  \opening{\theopening}
}%
\AtEndDocument{%
\closing{\theclosing}
\ps{\thepostscript}
\end{letter}
}

and this call of the class file

letterb.tex

\NeedsTeXFormat{LaTeX2e}
\documentclass{theletterb}
\getfromaddress{address.tex}
\gettoaddress{address.tex}
\newcommand{\theopening}{Dear Recipient}
\newcommand{\theclosing}{Sincerely,}
\newcommand{\thepostscript}{}
\begin{document}
\input{body.tex}
\end{document}

I get an error:

! LaTeX Error: There's no line here to end.

Any comments or suggestions are greatly appreciated. I wouldn't be surprised if the solution is a simple one.

3

The argument to \begin{letter} is processed in a peculiar way: the first \\ is an argument delimiter for another macro, rather than simply a line break command. Therefore \begin{letter} must see an explicit \\, which it doesn't if the argument is \thetoaddress.

With \expandonce (that's provided by etoolbox, so I use \providecommand just in case you decide to load also this package) we expand the argument just once and make it unexpandable in the \edef.

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{theletterb}[]
\LoadClass[]{letter}
\RequirePackage{lipsum}
\RequirePackage{catchfile}
\RequirePackage[
  textwidth=345.0pt,%
  top=2in,
  headheight=1.0in,
  headsep=0.20in
]{geometry}

\newcommand{\getfromaddress}[1]{\CatchFileDef{\thefromaddress}{#1}{}}
\newcommand{\gettoaddress}[1]{\CatchFileDef{\thetoaddress}{#1}{}}
\providecommand{\expandonce}{\unexpanded\expandafter}

\signature{Mae L. Mann}
\AtBeginDocument{%
  \pagestyle{empty}
  \let\ps@firstpage\ps@plain
  \begingroup\edef\x{\endgroup
    \noexpand\begin{letter}{\expandonce{\thetoaddress}}
      {\expandonce{\thefromaddress}}}\x
  \opening{\theopening}
}%
\AtEndDocument{%
  \closing{\theclosing}
  \ps{\thepostscript}
  \end{letter}
}

A couple of remarks: the command \NeedsTeXFormat{LaTeX2e} is not for documents (although it doesn't harm) but rather for classes and packages. There is no need to issue \makeatletter and \makeatother in an \AtBeginDocument in a class file and in case you need to use @-commands in one given in a document the two declarations must go around \AtBeginDocument.

  • I tested this; works in my code successfully! Thank you very much for the additional comments, they are appreciated. – John Chris Apr 12 '14 at 0:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.