Wrapfig 带非丑陋的分页符

Wrapfig 带非丑陋的分页符

我编写了一个经过修改的包,当对象与页面末尾重合wrapfig时,我有点厌倦了难看的分页符。它的工作原理是将内容放入一个框中,测量高度,然后使用该包强制执行最小空间要求,非常简单。wrapfigneedspace

以下是代码:

%-----------------------------------------------------
%Ensures no ugly page breaks by 
%first measuring the minimum amount of space required
%Using a savebox.
%-----------------------------------------------------
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{adpwrapfig}[2013/07/28 ADP's Wrapfig Class]

%Requirements.
\RequirePackage{wrapfig,calc,needspace,etoolbox,ifthen}

%Objects in this class.
\newlength{\@@wf@ht}%
\newsavebox{\@@wf@savebox}%
\newcounter{@@wf@cnt}

%Create a boolean switch, for the case when the user specifies
%the number of lines, and, 
\newbool{@@wf@alwaysspace}\booltrue{@@wf@alwaysspace} 

%Backup existing definitions.
\let\@wf\wrapfigure\let\@endwf\endwrapfigure

%-----------------------------------------------------
%Redefine the wrapfigure environment.
%-----------------------------------------------------
\renewenvironment{wrapfigure}[3][-1]{%
    \setcounter{@@wf@cnt}{#1}\def\@inpA{#2}\def\@inpB{#3}%

    %Process the box.
    \begin{lrbox}{\@@wf@savebox}%
        \minipage{\@inpB}%
}{  %<<<<<<BODY CONTENT
        \endminipage%
    \end{lrbox}%

    %Determine the required height
    \settoheight{\@@wf@ht}{\usebox{\@@wf@savebox}}%

    %Min Required Vertical Space.
    \def\@wf@ns{\Needspace{\dimexpr\@@wf@ht+\intextsep\relax}}

    %Enforce the required height
    \ifthenelse{\the@@wf@cnt<1}{\@wf@ns}{\ifbool{@@wf@alwaysspace}{\@wf@ns}{}}%

    %Now execute the existing environment
    \ifthenelse{\the@@wf@cnt>0}%
        {\@wf[\the@@wf@cnt]{\@inpA}{\@inpB}} %TRUE, When Lines are Specified
        {\@wf{\@inpA}{\@inpB}}               %FALSE, When Not.
            \usebox{\@@wf@savebox}%
    \@endwf%
}

以下 MWE 可以清楚地看出差异:

\documentclass[a5paper]{article}
\usepackage[margin=1in]{geometry}

\usepackage[demo]{graphicx}
\usepackage{lipsum,caption}

\usepackage{wrapfig}    %Standard
\usepackage{adpwrapfig} %Modified

\begin{document}
    \lipsum[1-2]

    \begin{wrapfigure}{l}{0.5\linewidth}
        \includegraphics[width=\linewidth,height=2.95in]{demo}
        \captionof{figure}{This is my caption for this use of this figure}
    \end{wrapfigure}
    \lipsum[1-10]

\end{document}

如果使用该包或不使用该包,则会产生以下两个不同的输出。

标准输出(将段落转至下一页)

前

新输出:(不会产生错误)

后

我的问题是,我想删除小页面的使用,而使用盒子原语,但是,我似乎无法让它在上下文中工作。

有人可以提供一些建议吗?

干杯。

更新:根据 David Carlisle 对我最初问题的解决方案以及 Barbara Beeton 的建议,更新如下。总之,在needspace包中插入了一个钩子,用于确定是否会出现分页符,如果出现分页符,则内容会被缩回以\intextsep实现顶部对齐。

%-----------------------------------------------------
%Ensures no ugly page breaks by 
%first measuring the minimum amount of space required
%Using a savebox.
%-----------------------------------------------------
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{adpwrapfig}[2013/07/28 ADP's Wrapfig Class]

%Requirements.
\RequirePackage{wrapfig}
\RequirePackage{calc,needspace,etoolbox,ifthen,caption}

%Objects in this class.
\newsavebox{\@@wf@savebox}          %Box to save.
\newlength{\@@wf@ht}                %Height
\newlength{\@@wf@wd}                %Width
\newcounter{@@wf@cnt}               %Linecount if specified
\newcommand{\@@wf@capprop}{0.95}    %Caption Proportion
\newbool{@@wf@break}                %For needspace page break hook

%Create a boolean switch, for the case when the user specifies
%the number of lines, and, @@wf@bre@kreq
\newbool{@@wf@alwaysspace}\booltrue{@@wf@alwaysspace}

%Backup existing definitions.
\let\@wf\wrapfigure\let\@endwf\endwrapfigure

%Patch the neespace commands.
\patchcmd{\@sneedsp@}{\break}{\booltrue{@@wf@break} \break}{}{}
\patchcmd{\@needsp@}{\break}{\booltrue{@@wf@break} \break}{}{}

%-----------------------------------------------------
%Redefine the wrapfigure environment.
%-----------------------------------------------------
\renewenvironment{wrapfigure}[3][-1]{%
    \setcounter{@@wf@cnt}{#1}%
    \def\@inpA{#2}%
    \setlength{\@@wf@wd}{#3}
%Process the box.
    \setbox\@@wf@savebox\vbox\bgroup\bgroup%
        \setlength\hsize\@@wf@wd
        \textwidth\hsize
        \linewidth\hsize
        \@parboxrestore
        \@minipagerestore
        \@setminipage
        \captionsetup{width=\@@wf@capprop\linewidth}
}{  %<<<<<<BODY CONTENT
        \par\egroup\egroup%
    \@@wf@ht\ht\@@wf@savebox%

    %Command to enforce the required height
    \def\@ns{\Needspace{\dimexpr\@@wf@ht+\intextsep\relax}}

    %Two conditions on whether to enforce
    \ifthenelse{\the@@wf@cnt<1}{\@ns}{}%
    \ifbool{@@wf@alwaysspace}{\@ns}{}%

    %Start with not requiring pagebreak.
    %needspace has been patched to set this to true if 
    %it intends to enforce a break.
    \boolfalse{@@wf@break} 

    %Now execute the existing environment
    \par\ifthenelse{\the@@wf@cnt>0}%
        {\@wf[\the@@wf@cnt]{\@inpA}{\@@wf@wd}} %TRUE, When Lines are Specified
        {\@wf{\@inpA}{\@@wf@wd}}               %FALSE, When Not.
            %Resolve the hook made by needspace, retracting by intxtsep
            %Retrace
                    \ifbool{@@wf@break}{\vspace*{-\intextsep}}{}
            %Execute
            \usebox{\@@wf@savebox}%
                    %Tighten
                    \ifbool{@@wf@break}{\vspace*{-2\intextsep}}{\vspace*{-\intextsep}}%
    \@endwf%
}

\endinput
%Tada.

更新

答案1

minipage只是\vbox或多或少(或实际上\vcenter是默认的)但是您还需要设置内容,以便乳胶构造知道它们处于减小的宽度,所以您最终复制了相当多的定义minipage

    %Process the box.
    \setbox\@@wf@savebox\vbox\bgroup\bgroup
        \setlength\hsize\@inpB
        \textwidth\hsize
        \linewidth\hsize
        \@parboxrestore
        \@minipagerestore
        \@setminipage
}{  %<<<<<<BODY CONTENT
         \par\egroup\egroup

    %Determine the required height
    \@@wf@ht\ht\@@wf@savebox

相关内容