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.

1 Answer 1

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.

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

You must log in to answer this question.

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