0

I have several chunks of verbatim text, each of which should be placed on a separate page (and nothing else). The page size should be determined to tightly fit the largest of the chunks, while all the other chunks should just as usual start in the top-left corner and go as far as they go. The chunks can vary in their vertical and horizontal sizes and their number, and I don't know which one is the largest.

Is there a way to automatically set the required page size from within Latex?

As I'm assuming that this is NOT possible - are there any suggestions on how to do that from outside? I'm generating the chunks in Java, so I could also create a Latex header for the correct page dimensions. But what would be a good way to do that (which document class/packages would suit best (something with geometry, probably...))? The size itself should be easy to claculate as the font in Latex has fixed character size.

(I know the requirement is a little strange, but that's exactly what I need. I'd obviously prefer a Latex-only solution if there is one...)

  • I came up with a Java-based "semi-solution", setting page width and height to some constant times the max line width/number of lines, resp., using the geometry package. (Times 5.5pt for the width, around 18pt for the height.) Both dimension don't seem to grow in a linear way, though. But how can that be if the character size is constant in a verbatim environment? What am I missing? – Duke Apr 6 '17 at 9:32
  • 2
    Yes, it can be done. The solution involves writing the page size to the aux file and \documentclass{standalone}[multi=minipage] or possibly some custom environment which uses minpage. – John Kormylo Apr 6 '17 at 13:40
  • 1
    Further experiments showed that the lstlisting environment (listings package) is compatible with standalone (but not \savebox). – John Kormylo Apr 7 '17 at 4:49
2

Use the maxpage environment for cut and pasting text. Use \maxpageinput to handle chunks of text in other files. Use wrapper for each page to keep standalone happy.

\documentclass[multi=wrapper]{standalone}
\usepackage{listings}
\lstset{aboveskip=0pt,belowskip=0pt}
\newlength{\maxheight}
\newlength{\maxwidth}

\newcommand{\setpagesize}[2]{\global\maxwidth=#1\relax \global\maxheight=#2\relax}% executed with aux file read

\makeatletter
\AtEndDocument{\immediate\write\@auxout{\string\setpagesize{\the\maxwidth}{\the\maxheight}}}
\makeatother

\newenvironment{wrapper}{}{}

\newcommand{\maxpageinput}[1]% #1 = fliename
{\setbox0=\hbox{\lstinputlisting{#1}}%
  \dimen0=\ht0
  \advance\dimen0 by \dp0
  \ifdim\dimen0>\maxheight \global\maxheight=\dimen0\fi
  \ifdim\wd0>\maxwidth \global\maxwidth=\wd0\fi
  \parbox[c][\maxheight][t]{\maxwidth}{\usebox0}%
}

\lstnewenvironment{maxpage}{\setbox0=\hbox\bgroup}%
 {\egroup
  \dimen0=\ht0
  \advance\dimen0 by \dp0
  \ifdim\dimen0>\maxheight \global\maxheight=\dimen0\fi
  \ifdim\wd0>\maxwidth \global\maxwidth=\wd0\fi
  \parbox[c][\maxheight][t]{\maxwidth}{\usebox0}%
}

\begin{document}
\begin{wrapper}
\begin{maxpage}
This is a test. 
\textbullet $\sin x^2$
And it has more than one line.
In fact, it goes on and on and on and on and on and on and on until it extends quite far.
\end{maxpage}
\end{wrapper}

\begin{wrapper}
\maxpageinput{test5.tex}
\end{wrapper}
\end{document}
  • Yepp, that does it! Great, didn't think this would be possible. – Duke Apr 7 '17 at 19:08
2

Here is TeX-only solution. Use pdftex document to create the PDF (no LaTeX).

\pdfhorigin=0pt \pdfvorigin=0pt
\newdimen\tmpdim
\newdimen\cwidth \newdimen\cheight

\newread\testin  \newwrite\outfile
\def\softinput #1 {\let\next=\relax \openin\testin=#1
   \ifeof\testin \message{Warning: the file #1 does not exist, TeX me again}
   \else \closein\testin \def\next{\input #1 }\fi
   \next}  
\def\bye{\immediate\openout\outfile=\jobname.dat
   \immediate\write\outfile{%
      \string\pdfpagewidth=\the\cwidth \space
      \string\pdfpageheight=\the\cheight}
   \end
}
\pdfpagewidth=0pt \pdfpageheight=0pt
\softinput \jobname.dat

\def\chunk{\afterassignment\chunkA\setbox0=\hbox}
\def\chunkA{\aftergroup\chunkB}
\def\chunkB{
   \tmpdim=\ht0 \advance\tmpdim by\dp0
   \ifdim\pdfpagewidth<\wd0 \pdfpagewidth=\wd0 \fi
   \ifdim\pdfpageheight<\tmpdim \pdfpageheight=\tmpdim \fi
   \ifdim\cwidth<\wd0 \cwidth=\wd0 \fi
   \ifdim\cheight<\tmpdim \cheight=\tmpdim \fi
   \shipout\box0
   \advance\pageno by1
}

\chunk{first}
\chunk{Second joj}
\chunk{third}

\bye

The external file \jobname.dat is used. When TeX is run firstly then this file does not exist, so the PDF page dimensions grow from page to page. The maximum of such dimensions is saved to the .dat file when \bye macro is expanded. If TeX is run secondly (or more) then the .dat file is read and the maximal dimensions are used now form first page.

  • Very nice plain-tex solution, works perfectly! It's just that I have a working cycle that runs latexpdf by standard, which could be changed, but only with quite some effort. In general, I like your solution best, because it's so simple. – Duke Apr 8 '17 at 5:11

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.