在自定义环境中使用超目标时无分页符

在自定义环境中使用超目标时无分页符

我正在尝试创建一个环境,该环境会根据全局计数器自动为每个实例创建标签。这是我正在尝试做的典型示例。

\documentclass{article}

\usepackage{hyperref}
\usepackage{titlesec}

\newcounter{TotalCounter}
\newenvironment{example}{
    \stepcounter{TotalCounter}
    \hypertarget{exampleRef\theTotalCounter}{\relax}
    \textbf{Example \theTotalCounter.}
}{}


\begin{document}

    \begin{example}This is an example.
    \end{example}

    \begin{example}This is an example.
    \end{example}

    \begin{example}This is an example.
    \end{example}

    % repeat this 100 times

\end{document}

但是,当我通过此方法运行 PDF-LaTex 时,生成的文档由一页组成,其中有 57 个示例,一直到页面底部。当然,我希望在 45 个示例之后会有一个分页符,其余的会继续在新的页面上。如果我删除超目标部分,问题就会消失。有没有一种简单的方法来修改它,但仍然保留我在环境中定义的标签系统。

答案1

尝试使用以下定义example

\newenvironment{example}{%
  \par
  \stepcounter{TotalCounter}%
  \hypertarget{exampleRef\theTotalCounter}{}%
  \textbf{Example \theTotalCounter.}
}{\par\penalty0}

\par它在环境的开始和结束时插入一个“图形断点”,但还将\penalty跨页面断点(在环境的末尾)设置为 0。

%请注意在定义行末尾(未打印)的使用。这可确保您不会在输出中收到虚假空格。

答案2

如果你输入以下几行

\showboxbreadth = 1000 %  more than necessary
\showboxdepth = 10 % much more than necessary
\showlists

比如说,第二次出现

\begin{example}This is an example.
\end{example}

TeX 将在转录文件中写入它正在构建的垂直列表的描述。查看此描述的开头,我们发现

### vertical mode entered at line 0
### current page:
\write-{}
\pdfdest name{Doc-Start} xyz
\pdfdest name{exampleRef1} xyz
\glue(\topskip) 3.05556
\hbox(6.94444+1.94444)x345.0, glue set 183.73628fil
.\hbox(0.0+0.0)x15.0
.\OT1/cmr/bx/n/10 E
.\OT1/cmr/bx/n/10 x
.\OT1/cmr/bx/n/10 a
.\OT1/cmr/bx/n/10 m
.\OT1/cmr/bx/n/10 p
.\OT1/cmr/bx/n/10 l
.\OT1/cmr/bx/n/10 e
.\glue 3.83331 plus 1.91666 minus 1.27777
.\OT1/cmr/bx/n/10 1
.\OT1/cmr/bx/n/10 .
.\kern 0.0
.\glue 4.44444 plus 4.99997 minus 0.37036
.\OT1/cmr/m/n/10 T
.\OT1/cmr/m/n/10 h
.\OT1/cmr/m/n/10 i
.\OT1/cmr/m/n/10 s
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 i
.\OT1/cmr/m/n/10 s
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 n
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 e
.\OT1/cmr/m/n/10 x
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 m
.\OT1/cmr/m/n/10 p
.\OT1/cmr/m/n/10 l
.\OT1/cmr/m/n/10 e
.\OT1/cmr/m/n/10 .
.\penalty 10000
.\glue(\parfillskip) 0.0 plus 1.0fil
.\glue(\rightskip) 0.0
\pdfdest name{exampleRef2} xyz
\penalty 10000
\glue(\parskip) 0.0 plus 1.0
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x345.0, glue set 183.73628fil
.\hbox(0.0+0.0)x15.0
.\OT1/cmr/bx/n/10 E
.\OT1/cmr/bx/n/10 x
.\OT1/cmr/bx/n/10 a
.\OT1/cmr/bx/n/10 m
.\OT1/cmr/bx/n/10 p
.\OT1/cmr/bx/n/10 l
.\OT1/cmr/bx/n/10 e
.\glue 3.83331 plus 1.91666 minus 1.27777
.\OT1/cmr/bx/n/10 2
.\OT1/cmr/bx/n/10 .

等等。让我们跳过前六行:第七行表示\hbox包含单词“例 1.这是一个例子。”(对于每个字符,也显示了其排版字体)。结尾\hbox是这样的

.\glue(\rightskip) 0.0

紧接着盒子本身,我们发现

\pdfdest name{exampleRef2} xyz

这是使用该命令创建的“目标” \hypertarget。现在,超链接\penalty 10000在目标下方立即插入一个,以明确禁止在该点进行分页,因为这样的分页会将目标锚点与它应该链接到的材料分离。如果没有这个,TeX 可能会在下一个\glue项目(标记为的项目\parskip)处分页,事实上,你会发现,没有这个\hypertarget命令,一切都会正常工作;但是,就目前情况而言,上面显示的垂直列表只是有段落之间允许有断点。但如果段落有几行长,则有合法的断点之内段落本身。

Werner 已经指出了一个可能的解决方案:使用命令“手动”插入允许的断点\penalty0。不过,我建议进行以下重新定义

\makeatletter
\newcounter{TotalCounter}
\newenvironment{example}{%
    \par
    \addpenalty{-\@lowpenalty}%
    \stepcounter{TotalCounter}%
    \hypertarget{exampleRef\theTotalCounter}{\relax}%
    \textbf{Example~\theTotalCounter.} % intentional
    \ignorespaces
}{
    \par
    \addpenalty{-\@lowpenalty}%
}
\makeatother

更为稳健(\addpenalty{-\@lowpenalty}温和地鼓励在环境上方或下方进行分页example)。此外,如果您\stepcounter用替换\refstepcounter,您将能够使用\label/\ref机制来引用您的示例。

相关内容