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