使用mdframed
或tcolorbox
(我现有的代码库使用mdframed
,我有兴趣转移到tcolorbox
),我希望获得三件事:
- 漂亮框和下一段落之间的垂直空间,但
- 垂直空间内不能有分页符或分栏符,必须至少有一行文本(最好是两行,但目前我先满足于一行),并且
- 我不想打破这个漂亮的盒子。
从这个 MWE 开始:
\documentclass[letterpaper,10pt,twocolumn,twoside,extrafontsizes]{article}
\usepackage{lipsum}
\usepackage{fp}
\usepackage{mdframed}
\usepackage{printlen}
\newlength{\testskip}
\setlength{\testskip}{1\baselineskip plus 0.5\baselineskip minus 0.5\baselineskip}
\newenvironment{test}{
\begin{mdframed}
}{
\end{mdframed}
}
\title{Suppressing Page Breaks MWE}
\begin{document}
\maketitle
\lipsum[1]
\lipsum[2]
\lipsum[3]
\lipsum[4]
\lipsum[5]
\begin{test}
Testing 1 mdframed
\end{test}
\lipsum[6]
\lipsum[7]
\end{document}
添加\nopagebreak
使我部分完成。
\newenvironment{test}{
\begin{mdframed}
}{
\end{mdframed}\nopagebreak
}
这会将段落拉近一点,为一行文本腾出空间,并从下一页复制文本行。如果我\vskip0.5\baselineskip
在上面添加\lipsum[5]
,则没有足够的空间可以减少,并且mdframed
会被推到下一页。
mdframed
到目前为止,一切都很好……但我找不到在段落和下一段之间添加垂直空间的方法。插入\vskip0.5\baselineskip
或vspace{0.5\baselineskip}
显然不仅插入了空间,而且表明这是一个绝佳的分页符位置。
看起来skipbelow
的参数mdframed
确实有一个\vskip
,所以我处于同样的情况。
我知道这个needspace
包,但我无法预测它mdframed
会有多大。如果需要的话,我想我可以将高度存储mdframed
在aux
文件中并在布局时使用它,但我宁愿不这样做。
(当我尝试tcolorbox
以类似的方式使用时,它看起来\nopagebreak
根本没有做任何事情 - 要么有足够的空间容纳一行文本,要么没有足够的空间,这就是全部。)
看起来,虽然这在分页符处确实有效,但在分栏符处似乎没有什么区别(序言不变)
\title{Suppressing Page Breaks MWE}
\begin{document}
\maketitle
\lipsum[1]
\vskip4\testskip
\lipsum[2]
\begin{test}
Testing 1 mdframed
\end{test}
\lipsum[3]
\lipsum[4]
\lipsum[5]
\lipsum[6]
\lipsum[7]
\end{document}
(就上下文而言,这是一本包含许多统计块的游戏参考书——名称和一组关于事物的统计数据——我不想将它们分开,因为跨页读取统计数据很困难。现在我正在手动调整它们,根据需要在游戏实体之前或之后插入或删除垂直空间和中断。我想使它更加自动化,如果我可以mdframed
在它之后留出不会导致分页符或列中断的空间,那么就可以实现我的目标了。是的,它有点丑,但对我的目的来说非常有用。)
深夜啊哈!......没用
显然,用 包裹mdframed
应该minipage
可以让我在 后面放置一些垂直空间mdframed
,然后在\nopagebreak
后面放置 !
\newenvironment{test}{
\noindent\begin{minipage}{\linewidth}
\begin{mdframed}
}{
\end{mdframed}\bigskip\end{minipage}\nopagebreak
}
没有像我希望的那样。我认为跳过或静止minipage
导致被nopagebreak
忽略。
2017-01-15 更新 --\needspace
行为异常
@Schweinebacke 建议的解决方案needspace
几乎有效,但我发现有些情况无效。我尚无法复制它们,但我可以描述症状。
- 我面前有一个页面,其显示的
\pagetotal
为 461.9377pt, 的\pagegoal
为 682pt。 - 传递的尺寸
\needspace
是 138.37pt。据我所知,这应该合适(461pt+138pt = 大约 600pt;剩下大约 80pt,一英寸多一点)。 - 块被移动到了下一页,块输出后,我有一个
\pagetotal
601.18pt(这应该是在以前的页面,那里是否出现了块)。
这种情况并不总是发生。大多数情况下,\needspace
它按预期工作:块被移动,并\pagetotal
在输出块之前重置为 0(即,我前面有一个,所需空间为 136.55pt,\pagetotal
块后为 124.55pt(我想要“块的高度加上一行文本,\bigskip
大约是 12pt,所以这一切加起来或多或少)。
看起来好像\needspace
确定所请求的空间是可用的,然后整个东西被移动了,尽管显然有足够的空间。
\needspace
我下面的回答有什么问题吗?
2017-01-18 更新:为什么\needspace
要使用?
浏览其他问题时,我偶然发现了一些我可能早该考虑的事情……这些区块被用作花哨的——而且大的——标题。这可能包括被包含在目录中。
有什么原因我不能使用\@startsection
?将其视为一个可能具有较大部分标题的部分(上方和下方的正空间),然后称其已完成。
答案很简单……它不能按我需要的方式工作。我可以用它来在部分标题周围绘制一个漂亮的框架(很有用),但我需要的其他元素(框架中的标题和正文内容)确实不适合部分样式的语义。如果我仔细思考一下,我就会意识到这一点。
答案1
mdframed
(和tcolorbox
)有自己的分页符算法,允许在框中分页。因此将它们放入另一个框中有点复杂。但您可以将 的内容放入mdframed
一个框中,并将此框输出到 内mdframed
。您可以测量此框的高度和深度,并将结果(和一些额外空间)用于needspace
:
\documentclass[letterpaper,10pt,twocolumn,twoside]{article}
\usepackage{lipsum}
\usepackage{mdframed}
\newlength{\testskip}
\setlength{\testskip}{1\baselineskip plus 0.5\baselineskip minus 0.5\baselineskip}
\usepackage{needspace}
\newsavebox\mybox
\newenvironment{test}{%
\par
\begin{lrbox}{\mybox}
}{
\end{lrbox}
\needspace{\dimexpr \ht\mybox+\dp\mybox+\testskip+2\fboxrule+\fboxsep+\baselineskip\relax}
\begin{mdframed}\usebox\mybox\end{mdframed}
\vskip\testskip
}
\title{Suppressing Page Breaks MWE}
\begin{document}
\maketitle
\lipsum[1]
\lipsum[2]
\lipsum[3]
\lipsum[4]
\lipsum[5]
\begin{test}
Testing 1 mdframed
\end{test}
\lipsum[6]
\lipsum[7]
\end{document}
不过,如果您不想在 内添加分页符mdframed
,则甚至不需要使用mdframed
。您可以简单地将文本放在一个框中,然后使用您想要的任何类型的框架自行构建它:
\documentclass[letterpaper,10pt,twocolumn,twoside]{article}
\usepackage{lipsum}
\newlength{\testskip}
\setlength{\testskip}{1\baselineskip plus 0.5\baselineskip minus 0.5\baselineskip}
\newsavebox\mybox
\newenvironment{test}{%
\par
\begin{lrbox}{\mybox}
\minipage[b]{\dimexpr \linewidth-\fboxsep-\fboxrule}
}{
\endminipage
\end{lrbox}
\noindent\usebox\mybox\hskip\fboxsep\rule[-\dp\mybox]{\fboxrule}{\dimexpr\ht\mybox+\dp\mybox}\linebreak\nopagebreak
\rule[\ht\strutbox]{\linewidth}{\fboxrule}
\par\nobreak\vskip\testskip\nobreak
}
\title{Suppressing Page Breaks MWE}
\begin{document}
\maketitle
\lipsum[1]
\lipsum[2]
\lipsum[3]
\lipsum[4]
\lipsum[5]
\begin{test}
\lipsum[1]
\end{test}
\lipsum[6]
\lipsum[7]
\end{document}
答案2
根据@Schweinebacke的回答,我设计了下面的方法,它似乎可以满足我的所有需求。它可以按照我的需要跨分栏符、分页符以及在双列模式和使用时工作。如果您用包围multicols
,它也可以工作。mdframed
mdframed
minipage
\documentclass[letterpaper,10pt,twoside,twocolumn]{article}
\usepackage{lipsum}
\usepackage{tcolorbox}
\usepackage{fp}
\usepackage{needspace}
\usepackage[top=1in,bottom=1in,right=1in,left=1in]{geometry}
\newlength{\NSCspace}
\newlength{\NSCspaceneeded} %debugging artifact, so I could output
\newsavebox\NSCbox
\newenvironment{needspacecalc}[1][0pt]{
\setlength{\NSCspace}{#1}
\begin{lrbox}{\NSCbox}
}{
\end{lrbox}
\setlength{\NSCspaceneeded}{\dimexpr\ht\NSCbox+\dp\NSCbox+\NSCspace\relax}
\needspace{\NSCspaceneeded}
\noindent\usebox\NSCbox
}
\title{Suppressing Page Breaks MWE}
\begin{document}
\maketitle
\lipsum[1]
\lipsum[2]
\lipsum[2]
\begin{needspacecalc}[2\baselineskip] % "need two lines after this stuff
\begin{tcolorbox}
TColorBox stuff goes in here.
\end{tcolorbox}
\end{needspacecalc}
\vskip\baselineskip
\lipsum[4]
\lipsum[5]
\end{document}
注释掉\begin{needspacecalc}
和\end{needspacecalc}
以查看这是否确实强制分列。