5

The following code works well enough:

envelopea.tex

\documentclass[12pt]{letter}
\usepackage[businessenvelope,customenvelopes]{envlab}

\SetEnvelope[2.0in]{240mm}{145mm}
\setlength{\EnvelopeTopMargin}{0.75in} % 0.5
\setlength{\EnvelopeLeftMargin}{1.25in} % 2.0

\begin{document}
\startlabels
\mlabel{%
1234 Center Lane \\
Long Mile Village \\
92319%
}%
{%
239 Mill Lake Rd \\
Centreville \\
78392%
}%
\end{document}

I would, however, like to use the catchfile package in order to retrieve the addresses from an external file. An implementation might look something like this.

addressa.tex

1234 Center Lane \\%
Long Mile Village \\%
92319%

addressb.tex

239 Mill Lake Rd \\%
Centreville \\%
78392%

letterb.tex

\documentclass[12pt]{letter}
\usepackage[businessenvelope,customenvelopes]{envlab}
\usepackage{catchfile}

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

\getfromaddress{addressa.tex}
\gettoaddress{addressb.tex}

\SetEnvelope[2.0in]{240mm}{145mm}
\setlength{\EnvelopeTopMargin}{0.75in} % 0.5
\setlength{\EnvelopeLeftMargin}{1.25in} % 2.0

\begin{document}
\startlabels
\mlabel{%
\expandonce{\thefromaddress}%
}%
{%
\expandonce{\thetoaddress}%
}%
\end{document}

When I compile this code I receive an error message which complains of unbalanced curly brackets. At first glance, things appear to be balanced. I'm not too familiar with the use of \expandafter and \expandonce. I figure that someone might be able to make this work quite easily. Any comments/suggestions are greatly appreciated.

Output from the working example

I have incorporated code presented in this post together with code suggested by egreg in order to yield a .cls file for letters which can be called by specifying the following info:

  1. File in which from address resides
  2. File in which to address resides
  3. Letter opening/salutation
  4. Letter closing
  5. Letter post script
  6. Letter signature
  7. Envelope dimensions

I have included the code below:

theletter.cls

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{theletterb}[]
\LoadClass[]{letter}
\RequirePackage{lipsum}
\RequirePackage{catchfile}
\RequirePackage[businessenvelope,customenvelopes]{envlab}
\RequirePackage{xparse}
\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}
\ExplSyntaxOn
\NewDocumentCommand{\MLABEL}{ }
 {
  \johnchris_mlabel:oo { \thefromaddress } { \thetoaddress }
 }
\cs_set_eq:NN \johnchris_mlabel:nn \mlabel
\cs_generate_variant:Nn \johnchris_mlabel:nn { oo }
\ExplSyntaxOff
\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}
\newpage
\startlabels
\MLABEL
\end{letter}
}

letter.tex

\documentclass{theletter}
\getfromaddress{addressa.tex}
\gettoaddress{addressb.tex}
\newcommand{\theopening}{Dear Recipient}
\newcommand{\theclosing}{Sincerely,}
\newcommand{\thepostscript}{}
\signature{Mae L. Mann}
\SetEnvelope[2.0in]{240mm}{145mm}
\setlength{\EnvelopeTopMargin}{0.75in}
\setlength{\EnvelopeLeftMargin}{1.25in}
\begin{document}
\input{body.tex}
\end{document}

And again, the supporting files are:

addressa.tex

1234 Center Lane \\%
Long Mile Village \\%
92319%

addressb.tex

239 Mill Lake Rd \\%
Centreville \\%
78392%

body.tex

lipsum[1]
3

The problem is similar to the one in the other question: \mlabel needs to see the explicit delimiters \\ for working correctly. So you need to expand \thefromaddress and \thetoaddress before \mlabel starts its job.

There are some techniques to cope with this; however, since you're using just one pair of from and to addresses, you just need a parameterless command.

You can choose between

\newcommand{\MLABEL}{%
  \expandafter\expandafter\expandafter\mlabel
  \expandafter\expandafter\expandafter
    {\expandafter\thefromaddress\expandafter}\expandafter{\thetoaddress}
}

or

\newcommand{\MLABEL}{%
  \begingroup\edef\x{\endgroup
    \noexpand\mlabel{\expandonce{\thefromaddress}}
                    {\expandonce{\thetoaddress}}%
  }\x
}

or even

\newcommand{\MLABEL}{%
  \expandafter\mlabel\expandafter
   {\csname thefromaddress\expandafter\endcsname\expandafter}%
   \expandafter{\thetoaddress}%
}

All three definitions will eventually do the same. Choose the most appealing. ;-)

\documentclass[12pt]{letter}
\usepackage[businessenvelope,customenvelopes]{envlab}
\usepackage{catchfile}

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

% Definition 1
%\newcommand{\MLABEL}{%
%  \expandafter\expandafter\expandafter\mlabel
%  \expandafter\expandafter\expandafter
%    {\expandafter\thefromaddress\expandafter}\expandafter{\thetoaddress}
%}

% Definition 2
%\newcommand{\MLABEL}{%
%  \begingroup\edef\x{\endgroup
%    \noexpand\mlabel{\expandonce{\thefromaddress}}
%                    {\expandonce{\thetoaddress}}%
%  }\x
%}

% Definition 3
\newcommand{\MLABEL}{%
  \expandafter\mlabel\expandafter
   {\csname thefromaddress\expandafter\endcsname\expandafter}%
   \expandafter{\thetoaddress}%
} 


\getfromaddress{addressa.tex}
\gettoaddress{addressb.tex}

\SetEnvelope[2.0in]{240mm}{145mm}
\setlength{\EnvelopeTopMargin}{0.75in} % 0.5
\setlength{\EnvelopeLeftMargin}{1.25in} % 2.0

\begin{document}
\startlabels
\MLABEL
\end{document}

enter image description here

A more concise version uses expl3, the programming layer of LaTeX3. You might appreciate the conciseness: I copy the meaning of \mlabel into an internal function with two arguments and then generate a variant that expands the contents of the arguments before taking the normal action.

\documentclass[12pt]{letter}
\usepackage[businessenvelope,customenvelopes]{envlab}
\usepackage{catchfile}
\usepackage{xparse}

\newcommand{\getfromaddress}[1]{\CatchFileDef{\thefromaddress}{#1}{}}
\newcommand{\gettoaddress}[1]{\CatchFileDef{\thetoaddress}{#1}{}}

\ExplSyntaxOn
\NewDocumentCommand{\MLABEL}{ }
 {
  \johnchris_mlabel:oo { \thefromaddress } { \thetoaddress }
 }

\cs_set_eq:NN \johnchris_mlabel:nn \mlabel
\cs_generate_variant:Nn \johnchris_mlabel:nn { oo }
\ExplSyntaxOff

\getfromaddress{addressa.tex}
\gettoaddress{addressb.tex}

\SetEnvelope[2.0in]{240mm}{145mm}
\setlength{\EnvelopeTopMargin}{0.75in} % 0.5
\setlength{\EnvelopeLeftMargin}{1.25in} % 2.0

\begin{document}
\startlabels
\MLABEL
\end{document}
  • Thank you kindly for the insightful remarks; I do find the latter example appealing. I will have to look further into the expl3 code, as I don't understand this section. – John Chris Apr 15 '14 at 12:34

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.