如何获得“不间断垂直空间”?

如何获得“不间断垂直空间”?

使用mdframedtcolorbox(我现有的代码库使用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\baselineskipvspace{0.5\baselineskip}显然不仅插入了空间,而且表明这是一个绝佳的分页符位置。

看起来skipbelow的参数mdframed确实有一个\vskip,所以我处于同样的情况。

我知道这个needspace包,但我无法预测它mdframed会有多大。如果需要的话,我想我可以将高度存储mdframedaux文件中并在布局时使用它,但我宁愿不这样做。

(当我尝试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,一英寸多一点)。
  • 块被移动到了下一页,块输出后,我有一个\pagetotal601.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,它也可以工作。mdframedmdframedminipage

\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}以查看这是否确实强制分列。

相关内容