我有一个奇怪的格式要求。对于图形及其标题太大而无法放在一页上的情况,标题需要单独出现在标题之前的页面上。此外,此页面的格式非常具体(并且涉及几何变化,这很像双面打印中的偶数页,即使文档是单面的,参见此问题—这要怪设计论文格式要求的人,而不是我)。
构建带有标题的页面和带有图片的页面非常简单。我需要的是一种将材料插入到 LaTeX 用于输出图片的任何队列中的方法,并进一步确保两个页面保持在一起。
请注意,我不想使用\FloatBarrier
宏,因为目标不是现在开始输出浮点数,我只需要添加两个新的浮点数并让它们保持在连续的页面上。
它看起来有点像我可以用\@freelist
它来抓取插入号、为页面构建一个框,然后导致调用输出例程,但内核源代码对我来说还不清楚。
答案1
以下是我在 ConTeXt 中执行此类操作的方法。也许这会给你一些关于 LaTeX 解决方案的想法。
解决方案的关键是两个属性
可以在一个页面上只放置一个浮动对象。在 ConTeXt 中,你可以使用
\placefigure[...][page]{....}{....}
我不知道
p
LaTeX 中的浮点数说明符是否以相同的方式工作。能够插入任意文本下一个页面。在 ConTeXt 中,您可以使用
\startpostponing[+1] .... \stoppostponing
事实上,除了
+1
,您还可以使用+2
在两页后插入一些内容,等等。我不知道是否有提供此功能的 LaTeX 包。
那么,解决方案就是将这两个特征结合起来:
\开始推迟[+1] \placefigure[page]{图片标题}{\strut} \页 \placefigure[page,nonumber]{} {\externalfigure[...][width=\textwidth,height=\textheight]} \停止推迟
在我尝试的几个例子中,这似乎有效。这是一个完整的工作示例:
\useMPlibrary[dum] %用于虚拟图形 % 任意文本 \启动缓冲区 \dorecurse{5}{ \输入 knuth \endgraf \dorecurse{4} { \placefigure[此处,顶部,底部] {任意浮动图形} {\externalfigure[dummy][宽度=0.4\textwidth,高度=0.3\textheight]} } \输入 knuth \endgraf } \停止缓冲区 \开始文本 \获取缓冲区 \开始推迟[+1] \placefigure[page]{图片标题}{\strut} \page \placefigure[page,nonumber]{}{\externalfigure[dummy][width=\textwidth,height=\textheight]} \停止推迟 \获取缓冲区 \停止文本
答案2
下面的代码似乎在极少的测试下工作(即单面、单列、没有颜色)。不过这是一个相当大的 hack。我绝对愿意接受更好的方法来实现这一点或改进此代码。
代码分为两部分。第一部分是一个新的浮动环境。
\newbox\my@captionbox
\newenvironment{facingcaption}[1]{%
\let\my@saved@caption\@caption
\global\setbox\my@captionbox\box\voidb@x
\long\def\@caption##1[##2]##3{%
\global\setbox\my@captionbox\color@vbox\vbox{%
\my@saved@caption##1[##2]{##3}%
}\color@endbox
\def\caption{\ClassError{mydissertation}{%
Only one \noexpand\caption\space per
facingcaption}{}}%
}%
\@xfloat{#1}[p]%
}{%
\@endfloatbox
\let\@endfloatbox\relax
\ifvoid\my@captionbox\else
\ht\my@captionbox\z@
\dp\my@captionbox1sp
\global\setbox\@currbox\vbox{%
\box\@currbox
\nointerlineskip
\box\my@captionbox
\vskip-1sp
}%
\ht\@currbox\textheight
\fi
\end@float
}
该代码重新定义\@caption
,以便它在 内排版标题\vbox
。(我不确定是否需要颜色。它似乎没有坏处,至少在未使用颜色时。)
然后,它不再以 结束浮动\end@float
,而是以 — 开始的框结束浮动\@xfloat
,这通常是以 结束的\end@float
,因此将其设置为\relax
。如果标题框不是空的,则当前浮动框\@currbox
将被重新定义为由\vbox
3 个项目组成的:原始 中的浮动材料\@currbox
、高度为 0 且深度为 1sp 的标题框以及跳跃为 -1sp 的框。最后,我们将框的高度设置为 ,\textheight
以便输出例程在实际构建页面时自行将浮动粘贴在页面上。
最后,\end@float
实际上会调用输出例程两次,这将导致浮点数进入延迟列表,但实际上不会构建和输出任何页面。
代码的第二部分是对输出例程的修改。在实际生成输出页面时,将逐个处理浮点列表。由于框具有适合页面的最大高度,因此它将单独放置。特别是,将对\@wtryfc
适合页面的框列表中的每个框执行 。通常,它只是将其参数(框)和一些空间添加到\@outputbox
。
如果输出框的高度为 0,此代码就会劫持并调用我自己的例程(这只是一种优化)。
\let\my@saved@wtryfc\@wtryfc
\def\@wtryfc#1{%
\ifdim\dimexpr\ht\@outputbox + \dp\@outputbox=\z@
\my@wtryfc{#1}%
\else
\my@saved@wtryfc{#1}%
\fi
}
\my@wtryfc
需要检查其参数是否是这些特殊框之一。它通过取消装箱来做到这一点,检查最后一个跳过是否为 -1sp,并且之前的框的深度为 1sp。如果是,则将其取消装箱并保存。最后,唯一剩下的框(参数中的第一个框\@wtryfc
)是原始图形框,因此保存它。
\newbox\my@outputcaptionbox
\newbox\my@outputfigurebox
\def\my@wtryfc#1{%
\begingroup
\global\setbox\my@outputcaptionbox\box\voidb@x
\setbox\z@\vbox{%
\unvcopy#1%
\ifdim\lastskip=-1sp
\unskip
\setbox\z@\lastbox
\ifdim\dp\z@=1sp
\global\setbox\my@outputcaptionbox\vbox{%
\unvbox\z@
}%
\global\setbox\my@outputfigurebox\lastbox
\fi
\fi
}%
\ifvoid\my@outputcaptionbox
\my@saved@wtryfc{#1}%
\else
\if\dim\dimexpr\ht\z@+\dp\z@>\z@
\message{Output box not torn apart!}%
\fi
\global\setbox\@outputbox\vbox to\textheight{%
\vfill
\box\my@outputcaptionbox
\vfill
\vfill
}%
\my@savespecial
\ps@facingcaption
\@specialpagefalse
\@outputpage
\my@restorespecial
\global\setbox\@outputbox\vbox{}%
\my@saved@wtryfc{\my@outputfigurebox}%
\fi
\endgroup
}
\def\my@savespecial{%
\let\my@specialpage\if@specialpage
}
\def\my@restorespecial{%
\global\let\if@specialpage\my@specialpage
}
\vbox{figure}\vbox{caption}\vskip-1sp
在 中查找 之后\setbox
,如果没有发现标题框,则使用 LaTeX 的常规方法\@wtryfc
将框添加到\@outputbox
。否则,在 中构建一个与对面标题页相对应的框\@outputbox
。保存特殊的页面样式条件(这可能是不必要的,我不确定),然后facingcaption
执行页面样式的页面样式命令(\thispagestyle{facingcaption}
不适\AtBeginShipout
用于包使用的 ,showframes
因为边距需要更改)。接下来,它实际使用 输出的页面\@outputpage
。清除 并对图形框执行\@outputbox
常规操作。\@wtryfc