3

I am looking for an automated mechanism to change the effective \textwidth at the first pagebreak of a letter in scrpage2. I've tried \afterpage and \nextpage (ideally they would be set within \firsthead), both without success. I do not want to use the geometry package because firstly, IMO scrlttr2 should work with a change of KOMAoptions and friends and secondly, it does not seem to work anyways if used within scrlttr2 and the KOMA layout. Ideas and suggestions are very welcome.

Here's a MNWE. Page 2 and following should have a wider text block than the first page — but doesn't.

\documentclass{scrlttr2}%
\usepackage[english]{babel}
\usepackage{lipsum,afterpage}%
\setlength{\textwidth}{125mm}%
\nexthead{%
  \global\areaset{170mm}{\textheight}%
  \global\KOMAoptions{DIV=areaset}%
  \global\recalctypearea%
}
\afterpage{%
  \global\areaset{170mm}{\textheight}%
  \global\KOMAoptions{DIV=areaset}%
  \global\recalctypearea%
}
\begin{document}
\begin{letter}{Receipient}
  \opening{Dear receipient,}
  \lipsum[1-6]
  \closing{Yours}
\end{letter}
\end{document}

And BTW, I genuinely think that this is not covered by Change \textwidth and \textheight in mid-document and related questions and instead somehow relates to the internals of the KOMA classes.

bjoseru
  • 133
  • 1
    You will need to force a page break if changing the width of the text block. TeX typesets at least an entire paragraph before considering the page break and does not re-set the text on the new page so the first part of the page is always set with the settings from the previous page. By forcing a page break you ensure no text is held over. This is a basic limitation in tex/pdftex/xetex, it can be worked around with some difficulty using lua callbacks in luatex. – David Carlisle Oct 30 '12 at 16:42
  • @DavidCarlisle I see, but even when I add \eject or \clearpage as first commands into the \nexthead and \afterpage arguments, it still doesn't work. And despite an increased argument to \lipsum, the modified \textwidth does not even show at later pages. – bjoseru Oct 30 '12 at 16:52
  • 1
    No they can not work there, the heading is inserted in the output routine after the page has been broken. The text on the following page has already been set to the previous width by the time the heading code (or afterpage code) is activated. Also in you can only use \global with a single primitive assignment if you go \global\areaset you just make a single assignment at the start of the expansion of areaset global. As far as I can see this will be the assignment of \reserved@d in the middle of \@ifnextchar looking for an optional argument. No length assignments will be global. – David Carlisle Oct 30 '12 at 18:00
  • 1
    have you looked at the adjustwidth environment from the changepage package? – cmhughes Oct 30 '12 at 22:09
  • @DavidCarlisle I think I finally understand your comment, after copying the required definitions from the changepage package. This does almost what I want:
    \afterpage{% \pagebreak \global\setlength{\textwidth}{17cm}% \global\setlength{\columnwidth}{\textwidth}% \global\setlength{\hsize}{\columnwidth}% \global\setlength{\linewidth}{\hsize}}% Except that the \pagebreak (or \eject or \clearpage) does not do what I want it to do. As you say, the pagebreak has already taken place. \firstfoot does not seem to work either.
    – bjoseru Oct 31 '12 at 09:16
  • Sorry if my comments were opaque:-) @cmhughes should then make his comment an answer then you can accept that and the question can be signed off. Glad you got something working. – David Carlisle Oct 31 '12 at 09:20
  • @DavidCarlisle Well, almost working at least. I still haven't figured out how to issue the change of \textwidth at exactly the page break and not after the end of the first (broken across pagebreak) paragraph on page 2. But as I understand you, this won't be possible without additional machinery like luatex. Pity. However I think that your reply, while a negative answer, deserves the status answer. – bjoseru Oct 31 '12 at 09:28
  • @cmhughes Thanks for the pointer to the changepage package, inspection of its \ch@ngetext macro was indeed helpful. +1 – bjoseru Oct 31 '12 at 09:30
  • To change the width mid paragraph you either need luatex's linebreaking callbacks or a multi-pass algorithm that figures out how many lines of space you have left on the page, and then sets a \parshape that sets up a non-rectangular paragraph with n lines of one textwidth and then the remaining lines at the second textwidth. This is really pushing the limits of what is possible in TeX. If you allow yourself a manual forced break you can force the page break change the size and re-start the paragraph with \noindent so it is a continuation not a new para. It is so much easier:-) – David Carlisle Oct 31 '12 at 09:48

1 Answers1

2

Here is now a working example. It still requires a manual \pagebreak in the main text of the letter, but according to explanations by @DavidCarlisle, see above, this is at good as it can get without resorting to more powerful systems like luatex.

\documentclass{scrlttr2}%
\usepackage[english]{babel}
\usepackage{lipsum,afterpage}%
\setlength{\textwidth}{125mm}%
\firstfoot{%
  \afterpage{%
    \global\setlength{\textwidth}{17cm}%
    \global\setlength{\columnwidth}{\textwidth}%
    \global\setlength{\hsize}{\columnwidth}%
    \global\setlength{\linewidth}{\hsize}}%
}

\begin{document}
\begin{letter}{Receipient}
  \opening{Dear receipient,}
  \lipsum[1-2]
  \pagebreak % enfore the page break, otherwise afterpage will take
  % effect too late, i.e. after first broken paragraph on page 2.
  \lipsum[3-12]
  \closing{Yours}
\end{letter}
\end{document}

In this example the text body on the first page has a width of 12.5cm and on of 17cm on all following pages. If you want this to work in documents containing multiple letters, you should reset \textwidth on every "first page," e.g. using

\firsthead{%
    \global\setlength{\textwidth}{12.5cm}%
    \global\setlength{\columnwidth}{\textwidth}%
    \global\setlength{\hsize}{\columnwidth}%
    \global\setlength{\linewidth}{\hsize}%
}

in the preamble.

bjoseru
  • 133