使用 \small 和 extsizes 尺寸会导致问题

使用 \small 和 extsizes 尺寸会导致问题

我使用extsizes9 号字体设置一本书,并且使用此解决方案在文本部分之间创建一个不可见的分隔符,除非它是页面的最后一行。它工作得很好,但当我使用命令时除外\small;然后,无论分隔符在页面上的位置如何,它都会变为可见:

\documentclass[9pt]{book}
\usepackage{extsizes}
\usepackage{xcolor}
\usepackage{xparse}

% Create semi-invisible separator:
\makeatletter
\ExplSyntaxOn
\box_new:N \g_hide_box

\AtBeginDocument {
  \vbox_set:Nn \g_hide_box {
    \color@begingroup
    \color { white }
    \hrule width \linewidth height \baselineskip depth \c_zero_dim
    \color@endgroup
  }
}

\NewDocumentCommand \ornament { } {
  \par
  \nopagebreak
  \centerline { $ * \quad * \quad * $ }
  \vskip -0.8\baselineskip
  \cleaders \box_use:N \g_hide_box \vskip 1.1\baselineskip
  \par
}
\ExplSyntaxOff
\makeatother

\begin{document}
Blah blah blah.
\ornament

Blah blah blah.

\small
Blah blah blah.
\ornament

Blah blah blah.
\end{document}

MWE 输出

以下任何一种操作都可以使分隔符再次不可见:

  • 将书中的字体大小设置为 LaTeX 默认支持的字体大小(即 10、11 或 12 点)
  • 未加载extsizes
  • 不使用\small命令

有人知道可以让我保留所有这些设置的解决方案吗?

编辑:\baselineskip系数增加到约 1.25 可以解决该问题,但也会使和中的垂直间隙变得过\normalsize\small

答案1

不幸的是,包含更改当前墨水颜色指令的节点是不可丢弃的,因此您需要将它们埋在一个\leaders框内;这不允许\leaders直接使用规则(例如\leaders \hrule width \linewidth \vskip ...)。

\leaders不过,每次调用命令时重建使用的框就可以了\ornament,而不必在钩子处一次性打包\begin{document},这样它就符合当前的字体大小了。这是一个可编译的示例:

\documentclass[9pt]{extbook}
\usepackage[T1]{fontenc}
\usepackage{color}

\makeatletter

\newsavebox\@hide@ornament@box
\newcommand*\ornament[1][\baselineskip]{%
    \par
    \setbox\@hide@ornament@box \vbox{%
        \kern \dp\strutbox
        \color@begingroup
            % \color{white}% for deployment
            \color{yellow}% for testing
            \hrule
                \@width  \linewidth
                \@height \baselineskip
                \@depth  \z@
        \color@endgroup
        \kern -\dp\strutbox
    }%
    \skip@ #1%
    \advance \skip@ -\baselineskip
    \divide \skip@ \tw@
    % Or:
    % \skip@ \glueexpr (#1-\baselineskip)/\tw@ \relax
    \nobreak \vskip\skip@
    \centerline{$*\quad*\quad*$}
    \nobreak \vskip\skip@
    \penalty\z@ % breakpoint; adjust penalty value as you please
    \vskip -\glueexpr \skip@+\baselineskip \relax
    \cleaders \box\@hide@ornament@box
        \vskip \baselineskip
    \vskip\skip@
    \vskip\z@skip % allow for "\addvspace"
}

% \showboxbreadth   = \@M
% \showboxdepth     = \sixt@@n
% \tracingonline    = 1

\makeatother

\newcommand*{\Text}{Blah blah blah:
    This meaningless sample text
    is used for testing purposes only.
    It should be long enough to fill up,
    in print, a couple of lines at least.}



\begin{document}

\Text \ornament

\Text \ornament[1cm plus 3mm minus 2mm]

% \showlists

\small

\Text \ornament

\Text \ornament[1cm plus 3mm minus 2mm]

\footnotesize

\Text \ornament

\Text \ornament[1cm plus 3mm minus 2mm]

\normalsize

\Text

\Text

\Text \ornament[4cm plus 1cm]

\Text

\Text \ornament[4cm plus 1cm]

\Text

However, this trick does not work as expected
if a new page is started with an explicit
\verb|\newpage| command.

\ornament

\newpage

\Text

\end{document}

一些评论:

  1. 我是一个讨厌的家伙,但仍然喜欢摆弄内部 LaTeX 宏和 TeX 原语,正如您从代码中看到的那样。

  2. 我没有加载包,而是extsizes使用extbook类:这对于当前的问题没有什么区别,而且是推荐的。

  3. 命令中的可选参数\ornament允许您指定应跳过的垂直空间量;默认值为\baselineskip,即当前大小下一行打印文本占用的垂直空间。

  4. 代码目前绘制的是黄色规则,而不是白色规则:这样做是为了让您确切地看到这些规则的位置。您应该在部署代码之前(以明显的方式)更改代码。

  5. 该代码包含(注释掉的)诊断代码,您可以激活它以便准确查看正在构建的垂直列表中的内容。

最后请注意,如果使用明确的命令启动新页面,此技巧将无法按预期工作\newpage

为了完整起见,这里是输出第一页的图片:

代码输出的第一页

相关内容