可选内容以改善布局

可选内容以改善布局

我们每年都会出版一本类似的小册子,目前我们手工排版文档,以达到页数可以被 4 整除,同时将标题放在页面顶部并避免页面上留白。这通常包括添加或删除图像或用相同文本的较短或较长版本替换段落。大多数文本包含在多列环境中,而大多数图像则不包含在多列环境中。

有没有什么方法可以让 LaTeX 自动选择其中一种不同长度的文本变体,以最佳方式填充可用空间,同时避免\pagebreak由于内容过长而导致页面几乎完全空白?

編輯 MWE:

\documentclass[10pt,a4paper]{article}
\usepackage[latin1]{inputenc}
\usepackage{multicol}
\usepackage[english]{babel}
\usepackage{blindtext}
\begin{document}
    \begin{multicols}{2}
        \blindtext

        \blindtext

        \blindtext

        \blindtext

        \blindtext

        Hello, here is some text without a
        meaning. This text should show what
        a printed text will look like at this
        place. If you read this text, you will
        get no information. Really? Is there
        no information? Is there a di erence
        between this text and some nonsense
        like Huardest gefburn? Kjift  not at
        all! A blind text like this gives you in-
        formation about the selected font, how
        the letters are written and an impres-
        sion of the look. This text should con-
        tain all letters of the alphabet and it
        should be written in of the original lan-
        guage. 

        This is a variant, that should not be used in this case, because it really breaks the layout, and I don't want that. Word Word Word Word.
%       This is a second variant, to avoid the almost empty second page in variant one.
    \end{multicols}

\end{document}

答案1

这会处理整个文档,尝试将内容设置为 4 页的倍数。这需要多次运行 LaTeX。

怎么运行的:

如果要填充 4 页的倍数的剩余空间大于 2 页,它会尝试在每次运行时逐渐缩短内容,直到刚好低于 4 页的限制。否则,它会尝试扩展内容。此时,它会超出 4 页的限制,然后后退一步。

如果达到目标或者无法再缩短或延长内容,它就会停止。

发出警告,告诉您是否需要额外运行。

主要命令是\variant{<level>}{<short contents>}{<normal contents>}{<long contents>}<level>必须是大于 0 的整数。每次运行时,计数器都会增加(从 0 开始),如果级别小于或等于该计数器,则将使用短内容或长内容。<short contents>可以为空。如果<long contents>为空,则将改为使用。

级别\dontchangetrue计数器不会改变。只要内容仍添加到文档中,这很有用。

并且\allowedspace是最后允许的剩余空间(默认值:0pt)。

该宏会生成一个以 结尾的辅助文件.vrt。如果要重新启动,则必须删除此文件。

\documentclass[10pt,a4paper]{article}
\usepackage[latin1]{inputenc}
\usepackage{multicol}
\usepackage[english]{babel}
\usepackage{graphicx}         % for test with picture
\usepackage{xcolor}           % just for testing (color text to easy see what version is used)
\usepackage{blindtext}

\makeatletter
\newcounter{VariantLevel}
\newcounter{MaxVariantLevel}
% tristate flag, 0: less contents needed, 1: ok, 2 more contents needed
\newcounter{ContentsNeeded}
\newcounter{PrevContentsNeeded}
\newcounter{InitialContentsNeeded}
\newdimen\RemainingOnPage
\newdimen\PrevRemainingOnPage
\newdimen\InitialRemainingOnPage
\newcounter{RemainingPages}
\newcounter{PrevRemainingPages}
\newcounter{InitialRemainingPages}
\newif\iffirstrun
\newif\ifstopchange
\newif\ifdontchange
\newif\ifadditionalrunneeded
\newdimen\allowedspace

% args:
% #1: level
% #2: short contents, may be empty
% #3: normal contents
% #4: long contents, if empty, normal contents is used
\newcommand{\variant}[4]{%
    \ifnum#1>\c@MaxVariantLevel
        \global\c@MaxVariantLevel=#1\relax
    \fi
    % VariantLevel >= #1
    \@tempcnta#1\advance\@tempcnta\m@ne
    \ifnum\c@VariantLevel>\@tempcnta
        \ifcase\c@PrevContentsNeeded
            #2\relax
        \or
            #3\relax
        \or
            \def\@tempa{#4}\ifx\@tempa\@empty
                #3\relax
            \else
                #4\relax
            \fi
        \fi
    \else
        #3\relax
    \fi
}

\newcommand{\calc@remaining@pages}[1]{%
    \@tempcnta\c@page
    \advance\@tempcnta#1\relax
    \@tempcntb\@tempcnta
    \divide\@tempcnta4\relax
    \multiply\@tempcnta4\relax
    \advance\@tempcntb-\@tempcnta
    \ifnum\@tempcntb=0\else
        \advance\@tempcntb-4\fi
    \c@RemainingPages-\@tempcntb
}

\newcommand*{\checkremaining}{%
    \ifdim\pagetotal=\z@
        \calc@remaining@pages\m@one
        \RemainingOnPage\z@
    \else
        \calc@remaining@pages\z@
        \RemainingOnPage\pagegoal
        \advance\RemainingOnPage-\pagetotal
    \fi

    \@tempdima\c@RemainingPages\textheight
    \advance\@tempdima\RemainingOnPage
    \ifdim\@tempdima<\allowedspace
        \stopchangetrue
    \fi
    \advance\@tempdima-2\textheight
    \ifdim\@tempdima<\z@
        \setcounter{ContentsNeeded}{2}% more contents needed
    \else
        \ifdim\@tempdima=\z@
            \setcounter{ContentsNeeded}{1}% fits
        \else
            \setcounter{ContentsNeeded}{0}% less contents needed
        \fi
    \fi

    \ifdontchange\else    
    \ifstopchange\else
        \ifcase\c@ContentsNeeded
            \ifnum\c@PrevContentsNeeded<2\relax
                \stepcounter{VariantLevel}
                \additionalrunneededtrue
                \ifnum\c@VariantLevel>\c@MaxVariantLevel
                    \stopchangetrue
                    \additionalrunneededfalse
                \fi
            \else
                \stopchangetrue
                \additionalrunneededtrue
                \addtocounter{VariantLevel}{-1}%
                \setcounter{ContentsNeeded}{2}%
            \fi
        \or
            \stopchangetrue
            \additionalrunneededfalse
            \setcounter{ContentsNeeded}{\the\c@PrevContentsNeeded}%
        \or
            \ifnum\c@PrevContentsNeeded>\z@
                \stepcounter{VariantLevel}
                \additionalrunneededtrue
                \ifnum\c@VariantLevel>\c@MaxVariantLevel
                    \stopchangetrue
                    \additionalrunneededfalse
                \fi
            \else
                \stopchangetrue
                \additionalrunneededfalse
                \setcounter{ContentsNeeded}{0}%
            \fi
        \fi
    \fi\fi

    \iffirstrun
        \c@InitialContentsNeeded\c@ContentsNeeded
        \InitialRemainingOnPage\RemainingOnPage
        \c@InitialRemainingPages\c@RemainingPages
    \fi

    % statistics in log file
    \typeout{----------------------------------------}%
    \typeout{variants of contents}%
    \typeout{next variant level: \the\c@VariantLevel\space (max: \the\c@MaxVariantLevel)}%
    \typeout{initial run}%
    \typeout{remaining space: \the\InitialRemainingOnPage; remaining pages: \the\c@InitialRemainingPages}%
    \typeout{contents needed: \ifcase\c@InitialContentsNeeded less\or neither\or more\fi}%
    \typeout{previous run}%
    \typeout{remaining space: \the\PrevRemainingOnPage; remaining pages: \the\c@PrevRemainingPages}%
    \typeout{contents needed: \ifcase\c@PrevContentsNeeded less\or neither\or more\fi}%
    \typeout{current run}%
    \typeout{remaining space: \the\RemainingOnPage; remaining pages: \the\c@RemainingPages}%
    \typeout{contents needed: \ifcase\c@ContentsNeeded less\or neither\or more\fi}%
    % show if additional LaTeX run is needed
    \ifadditionalrunneeded
        \@latex@warning{please run LaTeX once more}%
    \else
        \@latex@warning{that's it, more can't be done}%
    \fi
    \typeout{----------------------------------------}%

    % write information needed to auxiliary file    
    \ifstopchange
        \protected@write\@auxout{}%
            {\string\@writefile{vrt}{\string\stopchangetrue}}%
    \else
        \protected@write\@auxout{}%
            {\string\@writefile{vrt}{\string\stopchangefalse}}%
    \fi
    \protected@write\@auxout{}%
        {\string\@writefile{vrt}{\string\firstrunfalse}}%
    \protected@write\@auxout{}%
        {\string\@writefile{vrt}{\string\setcounter{InitialContentsNeeded}{\the\c@InitialContentsNeeded}}}%
    \protected@write\@auxout{}%
        {\string\@writefile{vrt}{\string\InitialRemainingOnPage\the\InitialRemainingOnPage}}%
    \protected@write\@auxout{}%
        {\string\@writefile{vrt}{\string\setcounter{InitialRemainingPages}{\the\c@InitialRemainingPages}}}%
    \protected@write\@auxout{}%
        {\string\@writefile{vrt}{\string\setcounter{VariantLevel}{\the\c@VariantLevel}}}%
    \protected@write\@auxout{}%
        {\string\@writefile{vrt}{\string\setcounter{PrevContentsNeeded}{\the\c@ContentsNeeded}}}%
    \protected@write\@auxout{}%
        {\string\@writefile{vrt}{\string\PrevRemainingOnPage\the\RemainingOnPage}}%
    \protected@write\@auxout{}%
        {\string\@writefile{vrt}{\string\setcounter{PrevRemainingPages}{\the\c@RemainingPages}}}%
}

% read .vrt file
\AtBeginDocument{%
    \InputIfFileExists{\jobname.vrt}{}{}%
}

% check for remaining space and open .vrt file for LaTeX to write
\AtEndDocument{%
    \checkremaining
    \if@filesw\newwrite\tf@vrt
        \immediate\openout\tf@vrt\jobname.vrt\fi
}

% initialize
\setcounter{VariantLevel}{0}
\setcounter{MaxVariantLevel}{0}
\setcounter{ContentsNeeded}{1}
\setcounter{PrevContentsNeeded}{1}
\setcounter{InitialContentsNeeded}{1}
\RemainingOnPage\z@
\PrevRemainingOnPage\z@
\InitialRemainingOnPage\z@
\setcounter{RemainingPages}{0}
\setcounter{PrevRemainingPages}{0}
\setcounter{InitialRemainingPages}{0}
\firstruntrue
\stopchangefalse
\dontchangefalse
\allowedspace0pt

\makeatother

% uncomment until contents is completely added
%\dontchangetrue
% set to a length greater 0pt to allow for some empty space on the last page
%\allowedspace36pt


\begin{document}
\begin{multicols}{2}
\Blindtext

\variant{1}{}{{\color{blue}\blindtext}}{{\color{green}\Blindtext[2]}}
\end{multicols}

\begin{center}
\variant{2}{}{\includegraphics[height=3cm]{example-image-a.pdf}}{\includegraphics[height=6cm]{example-image-b.pdf}}
\end{center}

\begin{multicols}{2}
\Blindtext

\variant{3}{}{{\color{blue}\blindtext}}{{\color{green}\Blindtext[2]}}
\end{multicols}

\begin{center}
\variant{4}{}{\includegraphics[height=3cm]{example-image-a.pdf}}{\includegraphics[height=6cm]{example-image-b.pdf}}
\end{center}

\begin{multicols}{2}
\Blindtext

\variant{5}{}{{\color{blue}\blindtext}}{{\color{green}\Blindtext[2]}}
\end{multicols}

% uncomment this to test with too much contents
%\begin{center}
%\variant{6}{}{\includegraphics[height=3cm]{example-image-a.pdf}}{\includegraphics[height=6cm]{example-image-b.pdf}}
%\end{center}
%
%\begin{multicols}{2}
%\Blindtext
%
%\variant{7}{}{{\color{blue}\blindtext}}{{\color{green}\Blindtext[2]}}
%\end{multicols}

\end{document}

还有很多可以改进的地方,但这需要做很多工作。如果没有小册子本身,还需要很多猜测。但我认为这至少是一个开始。

您还可以查看该savetrees包,它提供了在页面上挤压更多文本的方法。

相关内容