![如何用相同大小的空块替换大块文本?](https://linux22.com/image/245356/%E5%A6%82%E4%BD%95%E7%94%A8%E7%9B%B8%E5%90%8C%E5%A4%A7%E5%B0%8F%E7%9A%84%E7%A9%BA%E5%9D%97%E6%9B%BF%E6%8D%A2%E5%A4%A7%E5%9D%97%E6%96%87%E6%9C%AC%EF%BC%9F.png)
我知道存在该\phantom
命令,但是它对大块文本(包含几个段落甚至几页)有效吗?
我想要的是一些命令,将它们称为\hide
和\show
,它们隐藏\显示排版的文本,并在文本应该出现的位置留出空白。为了更清楚起见,当我输入命令时\hide
,它后面出现的所有内容(直到\show
出现命令)都应该被白色空白替换。
作为一个临时解决方案,我想将文本涂成白色,但这并不总是能达到预期的效果。也许有更优雅的方法来做到这一点。
编辑:
与此同时,我想到了一个可能的替代解决方案:使用当前字体,生成具有相同度量的“空白”字体,并使用此空白字体“隐藏”文本。这可能吗?
笔记:我为这个新问题创建了一个单独的主题:使用另一种字体的度量生成“空白”字体。
答案1
宏的问题\phantom
在于它将其内容放入受限水平模式,即在一个水平框中,该框不会断开。因此它不能包含换行符或段落。通常,您可以通过先将内容放入minipage
允许多个段落的环境中来解决此问题。为了不必指定宽度,您可以使用包中的类似varwidth
环境varwidth
。然而\phantom
不幸的是,它没有被定义为长的宏,因此您不能在其中添加段落分隔符。您需要先自己框选内容,然后使用\phantom
或自己执行底层代码。第一种方法使用adjustbox
包非常简单。
\usepackage{adjustbox}
\usepackage{varwidth}
\newcommand{\Hide}{%
\adjustbox{varwidth=\linewidth,precode=\phantom}%
}
% Usage: \Hide{<content, can be multiple paragraphs>}
% or \Hide\bgroup <content, ...> \egroup
您的想法与\hide
和\show
更复杂。可以编写一些代码来实现这一点,但处理分页符很困难。
一些使用垂直框的基本代码如下:
\documentclass{article}
\newcommand{\hideit}{%
\begingroup
\par
\setbox0\vbox\bgroup
}
\newcommand{\showit}{%
\egroup
\setbox1\vbox{}%
\ht1=\ht0
\wd1=\wd0
\dp1=\dp0
\box1
\endgroup
}
\begin{document}
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
\hideit
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
\showit
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
\end{document}
但是它不支持分页符,并且无法添加与普通文本 100% 相同的高度,因为\vbox
和 周围段落之间缺少行跳转。但非常接近。例如,可以通过检查\pagetotal
和 的高度来添加分页符支持\pagegoal
。
答案2
间距可以完全保留(至少我认为这个答案做到了),允许分页符和方程式。颜色和其他在垂直模式下插入“whatsits”的工具可能会出现问题;图表和脚注可能也不受支持。
部分灵感来自 egreg 的回答。这个想法是排版您想要隐藏在垂直框内的内容,然后通过该框并将框中的每个项目转换为具有相同分页属性的等效透明项目。
也就是说,在垂直模式下可以出现四种主要类型的对象(这是一个方便的谎言!):跳过、字距、惩罚或框。跳过是可拉伸(和可收缩)的空间,它们被转换为相同数量的跳过。字距是不可拉伸的空间,它们被转换为相同数量的字距。惩罚会激励 TeX 破坏页面;同样,我们保持不变。最后,框包含要排版的材料。我们将它们转换为具有完全相同的高度和深度但没有内容的垂直框。
为了避免在堆叠\vbox
es 时出现虚假空格,我不得不将\baselineskip
、\lineskip
和设置\lineskiplimit
为零;可能还有更好的方法。整数\l_mypkg_cleanup_int
是 的第一个(可选)参数\hideit
,它负责删除大小为 的跳过、紧排和惩罚,否则会使其余代码阻塞。如果出于某种原因要隐藏的文本连续0
包含多个大小为 的跳过/紧排/惩罚,则可能需要增加此整数。0
\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn
\box_new:N \l_mypkg_box
\int_new:N \l_mypkg_cleanup_int
\DeclareDocumentCommand{\hideit}{O{1}+m}
{
\tex_setbox:D \l_mypkg_box \tex_vbox:D
{
#2\par
\dim_zero:N \tex_baselineskip:D
\dim_zero:N \tex_lineskip:D
\dim_zero:N \tex_lineskiplimit:D
\int_set:Nn \l_mypkg_cleanup_int {#1}
\mypkg_dismantle_loop:
}
\tex_unvbox:D \l_mypkg_box
}
\cs_new_protected:Npn \mypkg_dismantle_loop:
{
\prg_replicate:nn { \l_mypkg_cleanup_int }
{
\skip_if_eq:nnT { \tex_lastskip:D } { \c_zero_skip } { \tex_unskip:D }
\dim_compare:nT { \tex_lastkern:D = \c_zero_dim } { \tex_unkern:D }
\int_compare:nT { \tex_lastpenalty:D = \c_zero } { \tex_unpenalty:D }
}
\skip_if_eq:nnTF { \tex_lastskip:D } { \c_zero_skip }
{
\dim_compare:nTF { \tex_lastkern:D = \c_zero_dim }
{
\int_compare:nTF { \tex_lastpenalty:D = \c_zero }
{
\box_set_to_last:N \l_mypkg_box
\box_if_empty:NF \l_mypkg_box
{ \mypkg_dismantle_box: }
}
{ \mypkg_dismantle_penalty: }
}
{ \mypkg_dismantle_kern: }
}
{ \mypkg_dismantle_skip: }
}
\cs_new_protected:Npn \mypkg_dismantle_skip:
{ \mypkg_dismantle_aux:nN { \tex_vskip:D \skip_use:N \tex_lastskip:D } \tex_unskip:D }
\cs_new_protected:Npn \mypkg_dismantle_kern:
{ \mypkg_dismantle_aux:nN { \tex_kern:D \dim_use:N \tex_lastkern:D } \tex_unkern:D }
\cs_new_protected:Npn \mypkg_dismantle_penalty:
{ \mypkg_dismantle_aux:nN { \tex_penalty:D \int_use:N \tex_lastpenalty:D } \tex_unpenalty:D }
\cs_new_protected:Npn \mypkg_dismantle_box:
{ \mypkg_dismantle_aux:nN { \tex_vbox:D to \dim_eval:n { \box_ht:N \l_mypkg_box + \box_dp:N \l_mypkg_box } { } } \scan_stop: }
\cs_new_protected:Npn \mypkg_dismantle_aux:nN #1#2
{
\use:x
{
#2
\mypkg_dismantle_loop:
#1 \scan_stop:
}
}
\ExplSyntaxOff
\usepackage{lipsum}
\begin{document}
\lipsum[1-3]
\hideit[2]
{
\lipsum[4-5]
\begin{equation}
x^2+y^2 = z^2
\end{equation}
\lipsum[6-7]
}
\lipsum[8-10]
\end{document}
答案3
如果段落仅包含文本,但没有其他环境或显示的数学运算,则以下内容将计算行数并为段落中的每一行打印一个空白行;因此它也可以跨分页符工作:
\documentclass{article}
\usepackage{xparse,lipsum}
\ExplSyntaxOn
\cs_new:Npn \vbox_set_end_nopar: { \c_group_end_token }
\NewDocumentCommand{\hideit}{ }
{
\vbox_set:Nw \l_tmpa_box
\cs_set:Npn \par
{
\tex_par:D
\int_gset:Nn \g_tmpa_int { \prevgraf }
\vbox_set_end_nopar:
\prg_replicate:nn { \g_tmpa_int } { \mbox{}\hfill\break }
}
}
\ExplSyntaxOff
\begin{document}
\lipsum*[1]
\hideit
\lipsum*[1]
\lipsum*[1]
\end{document}
答案4
为新方法添加另一个答案,该方法使用 LuaLaTeX 和chickenize
提供\tabularasa
命令的相当新的包。
不幸的是,有些部分仍然保留,特别是规则和一些数学公式。脚注标记也保留了下来,但这可能会在软件包的后续版本中得到解决。
\documentclass{article}
\usepackage{chickenize}
\newcommand{\hideit}{\tabularasa}
\newcommand\showit{\par\untabularasa}
\textheight=.5\textheight
\begin{document}
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.\footnote{abc} $\frac{1}{2}+a\sqrt{2}$
\hideit
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.\footnote{abc} $\frac{1}{2}+a\sqrt{2}$
\showit
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.
This is a test paragraph. This is a test paragraph.\footnote{abc} $\frac{1}{2}+a\sqrt{2}$
\end{document}
剩余的文本可能会被清除(但它仍然存在,所以这可能是一个问题)
\newcommand{\hideit}{\tabularasa\color{white}}
\newcommand\showit{\par\untabularasa\color{black}}
段落内的单个单词可以输入到宏中\texttabularasa
。注意\tabularasa
并\untabularasa
处理完整的段落。