问题陈述
我想有条件地在某些段落或图形的开头添加 TikZ 覆盖。
在这个例子中(见下面的代码),我想有条件地在“第 3 段”和“外部文件”的第一个字符周围插入红色方框。但是,由于外部文件包含空行,TeX 会将我的覆盖图片单独设置在单独的段落中。有人可能会说我应该简单地将命令放入\RedBox
实际figure1.tex
内容的前面。但是,为了便于讨论,我们假设包含的文件是外部提供的,并且不容易修改。
问题是红框不在第一个字符周围,因为命令\tikz
开始了一个新段落。我认为这是因为它强制 TeX 进入水平模式或类似的东西。更多详细信息可以在问题中找到带有覆盖层的 Tikzpicture 占用空间。
\documentclass{article}
\usepackage{tikz}
\usepackage{lipsum}
\def\RedBox{\tikz[overlay, remember picture] \draw[red] (0,0) rectangle (0.6em, 1em);}
\begin{filecontents}{figure1.tex}
% Some random definitions which may or may not contain whitespace or newlines
\def\MyHelperMacro{foo}
External file which may or may not contain empty lines. \MyHelperMacro
\end{filecontents}
\begin{document}
Paragraph 1 bla bla
Paragraph 2 bla bla
% Here the overlay works as expected
\RedBox
Paraghraph 3 bla bla.
% Here the overlay starts a new paragraph, which is undesired!
\RedBox
\input{figure1.tex}
Paragraph 5
\end{document}
不是一个解决方案
问题带有覆盖层的 Tikzpicture 占用空间解释了为什么会出现这种情况,以及为什么无法轻易修复(据称是因为该\tikz
命令创建了一个'那是什么',无论它是什么)。建议使用\nointerlineskip
,但这并不能解决问题,无论是在命令中\RedBox
(如下所示)还是在包含的文件中(有时不可行;输出仍然错误,但这里没有显示)。
\def\RedBox{\nointerlineskip\tikz[overlay, remember picture] \draw[red] (0,0) rectangle (0.6em, 1em);}
部分解决方案?
所以我想,是否有可能将\tikz
命令存储在某个地方,只有当某个命令开始一个新段落时,才会发出该命令其他以下内容,那么它就不会单独开始一个新的段落。事实证明,其中有 ,\everypar{stuff}
它会添加stuff
到以下所有段落的前面。因此,下面的代码实现了预期的效果,但仍然存在一些问题。
\def\RedBox{%
\everypar{%
\tikz[overlay, remember picture] \draw[red] (0,0) rectangle (0.6em, 1em);%
\everypar{}%
}%
}
例如,如果您添加了\GreenCircle
使用相同机制的第二个命令,则不能在同一段落中同时使用 a\RedBox
和 a,因为第二个命令会删除第一个命令设置的 。如果您有另一个设置 的包,那么第一次使用其中一个覆盖命令时就会出现混乱。\GreenCircle
\everypar
\everypar
最后,经过大量的设置和解释之后,我们得到了实际的问题:
有没有更好的方法可以在下一个段落的开头注入内容,而又不会影响其他用法\everypar
?
答案1
如何真正地在每个段落的开头插入一张图片,但只使用诸如 等宏来更改其\RedBox
内容\GreenCircle
?
\documentclass{article}
\usepackage{tikz}
\usepackage{lipsum}
\begin{filecontents}{figure1.tex}
% Some random definitions which may or may not contain whitespace or newlines
\def\MyHelperMacro{foo}
External file which may or may not contain empty lines. \MyHelperMacro
\end{filecontents}
\newcommand{\ResetPar}{\tikzset{every par/.code={}}}
\newcommand\RedBox{\tikzset{every par/.append code={\draw[red] (0,0) rectangle (0.6em,
1em);}}}
\newcommand\GreenCircle{\tikzset{every par/.append code={\draw[green!70!black] (0.3em,0.4em)
circle[x radius=0.3em,y radius=0.4em];}}}
\ResetPar
\begin{document}
\everypar{%
\tikz[overlay, remember picture]{
\tikzset{every par}
% \draw[red] (0,0) rectangle (0.6em, 1em);%
}%
}%
Paragraph 1 bla bla
Paragraph 2 bla bla
% Here the overlay works as expected
\RedBox
Paraghraph 3 bla bla.
% Here the overlay starts a new paragraph, which is undesired!
%\RedBox
\input{figure1.tex}
\ResetPar
Paragraph 5
\GreenCircle
Paraghraph 6 bla bla.
% Here the overlay starts a new paragraph, which is undesired!
%\RedBox
\input{figure1.tex}
\ResetPar
Paragraph 7
\RedBox\GreenCircle
Paraghraph 8 bla bla.
% Here the overlay starts a new paragraph, which is undesired!
%\RedBox
\input{figure1.tex}
\ResetPar
\end{document}