11

I need to collect data (a sequence of input strings) in the preamble of a document, but the strings are to be typeset later in the document and must obey the line breaks set when typing the strings at the keyboard. Here is an MWE:

\documentclass[12pt]{memoir}

\newcommand{\makeAddress}[1]{
   \def\address{%
       {\obeylines #1}
   }
}

\makeAddress{First line
Second line}

\begin{document}

Some text here just to fill before typesetting the line-break obeying lines.

\address

And now more text, not obeying line breaks verbatim.

\end{document}

What I find is that I write the argument to the command \makeAddress as shown, namely, with a single stroke of my keyboard's RETURN key, I get a single output line for \address, whereas if I use two strokes, leaving a blank line in the argument between the strings "First line" and "Second line", I get the expected behavior: two output lines. What am I doing wrong?

Ian Thompson's answer set the line breaking issue straight. That was my original question in this post, hence his reply qualifies as answer. But my point is now, how can I do that and at the same time not have the text typeset until the point where it is supposed to?

4
  • I don't think that inputting the address with line breaks is the best approach: I'd use \\ to mark the end of lines.
    – egreg
    Commented Jul 28, 2012 at 21:13
  • @egreg: Sure. But this is in the context of a small class intended to provide a layout for letters which are to be used by people who should remain as unaware as possible of TeX-LaTeX when typing the document's contents. Something like a tiny showcse of the efficiency of TeX-based document generation by stressing the separation from highly-automated, but flexible nonetheless, document layout to content. There are still those used to things like MS Word asking for a non-intimidating and clear chance to discern.
    – Marcos
    Commented Jul 28, 2012 at 22:36
  • 1
    The biggest problem I see in terminating lines with end-of-lines only is exactly that a clear markup is missing. With \\ you can even type the address on one line and not rely on editor's features.
    – egreg
    Commented Jul 29, 2012 at 15:54
  • @egreg: Absolutely. I agree that's better even as a final user, but some people coming from the WYSIWYG world need to take some things one at a time and I'd need to go step by step. Moreover, I'd like, even if only in order to improve my skills as a TeXnician, to learn how to solve the issue that remains open in my question. Thanks for your remarks.
    – Marcos
    Commented Jul 29, 2012 at 18:14

1 Answer 1

13

The problem is that TeX isn't obeying line breaks when it reads the argument of \makeAddress, so it ignores the single carriage return. With two carriage returns, TeX inserts a \par, so you do get a line break in the output. To make it work with one carriage return, you just need to change the order in which things happen.

\documentclass[12pt]{memoir}
\makeatletter
\newcommand{\@makeAddress}[1]{
    \def\address{%
        {#1
        }
    \par\noindent}
    \address
\egroup}
\newcommand\makeAddress{\bgroup\obeylines\@makeAddress}
%
\begin{document}
\makeAddress{First line
Second line}
\end{document}

EDIT

You also need to use grouping to prevent \obeylines from staying in effect after \makeAddress is executed. Note that \egroup cannot be placed directly after \@makeAddress because that macro expects to find an argument.

8
  • Thanks so much, that works and I do appreciate that you also explained where I was wrong.
    – Marcos
    Commented Jul 28, 2012 at 12:28
  • I was just going to ask you about it. The ways of TeX are convoluted indeed! But then the braces around #1 in the definition of \address are not really necessary, and the \par\noindent goes actually after the call to \address.
    – Marcos
    Commented Jul 28, 2012 at 12:47
  • 1
    @Marcos: I think it is more LaTeX like to use the command \obeylines inside an environment instead of a command. Commented Jul 28, 2012 at 12:59
  • @Marco Daniel: I can agree. Nonetheless, I want to collect those lines first at some point in the preamble and typeset them only later. What would you suggest in order to do so? Maybe a macro containing the environment with the text passed to the latter as an argument?
    – Marcos
    Commented Jul 28, 2012 at 13:07
  • Actually, while Ian's answer is useful for my question proper, I need more than that for the problem that motivated my question but that I didn't include: I want to collect those lines first at some point in the preamble and typeset them only later, not at the point where they are collected. What would you suggest in order to do so?
    – Marcos
    Commented Jul 28, 2012 at 13:19

You must log in to answer this question.

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