使用 TikZ 安装背景和前景页面层

使用 TikZ 安装背景和前景页面层

有几次我发现需要在页面文本的后面和顶部绘制 TikZ 材料(如何在文本下方而不是上方绘制文本锚定的 tikz 线?测试某个段落是否有分页符?并且 LaTeX 中的酷炫文本突出显示)。大多数时候我需要从文本中的开始标记向结束标记绘制。只要它们之间没有分页符,我就可以在从结束标记向后绘制时在文本前景中绘制(因为文本之前已经排版)或从开始标记向前绘制时在背景中绘制(因为文本之后排版)。但是,如如何在文本下方而不是上方绘制文本锚定的 tikz 线?当向右下方绘制时,这会覆盖左侧的现有文本,因此这种方法并不完美。此外,如果这些标记之间有一个(甚至多个!)分页符,则必须将绘图拆分为多个操作。这样就很难确保所有材料都放置在正确的图层中。

我现在的想法是这样的:我喜欢为整个页面安装一个背景层和一个前景层,并允许宏在这些层上放置绘图命令。我认为所有命令都可以累积起来,然后在页面发出时进行处理。为此,我找到了一个atbegshi包,它以盒子的形式提供对页面的访问。我现在通过将这个盒子放在 TikZ 图片中来操纵它,该图片存储在同一个盒子寄存器中。请参阅下面的示例代码。

我现在的问题是:

这是合适的方法吗?即像这样操作页面框是否安全?或者有没有更好的方法?

我现在了解了\AtBeginShipoutUpperLeft等等,但在使用 TikZ 时遇到了问题。因此,我在节点中使用了该框。

\documentclass{article}

\usepackage{atbegshi}
\usepackage{tikz}
\usetikzlibrary{backgrounds}
\usepackage{lipsum}

% Proof-of-concept
% Later these would be numbered to allow multiple per page
\def\mybgstart{%
    \tikz[overlay,remember picture] { \draw [yellow] circle (1pt); \coordinate (bgstart); }%
    \gdef\drawinbackground{\draw [yellow,line width=5mm] (bgstart) -- (bgend);}%
}
\def\mybgend{\tikz[overlay,remember picture] { \draw [blue] circle (1pt); \coordinate (bgend); }}

\def\myfgstart{%
    \tikz[overlay,remember picture] { \draw [yellow] circle (1pt); \coordinate (fgstart); }%
    \gdef\drawinforeground{\draw [purple,line width=5mm] (fgstart) -- (fgend);}%
}
\def\myfgend{\tikz[overlay,remember picture] { \draw [blue] circle (1pt); \coordinate (fgend); }}

\begin{document}
\lipsum[1-3] % for comparison
\clearpage

\makeatletter
\AtBeginShipout{%
\setbox\AtBeginShipoutBox\hbox{%
    \color@setgroup
    \begin{tikzpicture}[line width=1cm,remember picture]%
        \path [use as bounding box] node [inner sep=0pt,outer sep=0pt] (A) {\box\AtBeginShipoutBox};
        \begin{pgfonlayer}{background}
        \draw [green,line width=1cm] (A.north east) -- (A.south west);
        \drawinbackground
        \global\let\drawinbackground\empty
        \end{pgfonlayer}
        \draw [red] (A.north west) -- (A.south east);
        \drawinforeground
        \global\let\drawinforeground\empty
    \end{tikzpicture}%
    \color@endgroup
}}
\makeatother

\lipsum[1]
\mybgstart\lipsum*[2]\unskip\mybgend

\lipsum[3]

\myfgstart\lipsum*[4]\unskip\myfgend

\lipsum[5-10]


\end{document}

结果

PS:上面的代码运行良好,pdflatex但我在(DVI 模式)下得到了偏移latex。有了它,.aux文件会保留不同的\pgfsyspdfmark值。有办法解决这个问题吗?

答案1

我的方法可以达到类似的效果。为 TikZ 全局声明背景:

\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}

然后在普通文本中放置“标记”的命令:

% place an inline node that is remembered for tikz
% \tikzremember{<node name>}
%   note: you have to compile twice
\newcommand{\tikzremember}[1]{{
  \tikz[remember picture,overlay]{\node (#1) at (0,11pt) { };}
}}

并在文档中使用它:

\tikzremember{bgstart}\lipsum*[2]\unskip\tikzremember{bgend}

现在,我在页面上有了 TikZ 节点,可以随心所欲地使用它们绘制任何我想要的图层。例如,一条大绿线:

\begin{tikzpicture}[remember picture,overlay]
\begin{pgfonlayer}{background}
\draw [green,line width=1cm] (bgstart.north east) -- (bgend.south west);
\end{pgfonlayer}{background}
\begin{pgfonlayer}{foreground}
\draw [green,line width=1cm] (bgstart.north east) -- (bgend.south west);
\end{pgfonlayer}{foreground}
\end{tikzpicture}

此技术窃自http://www.texample.net/tikz/examples/oxidation-and-reduction/

答案2

我对于此事的“应该”和“不应该”并没有什么可说的,因为我并不太清楚其中涉及的潜在问题,但我想分享一下前几天遇到的一些可能有用的东西。

在尝试弄清楚 beamer 如何构建框架(在此处插入链接)时,我仔细查看了 beamer 代码。结果发现背景层是通过挂接到页眉和页脚来插入的。由于 TeX 将页眉和页脚放在第一的它们可用于将内容放在页面后面。我不知道这是否比你正在做的更好,而且它只解决了背景部分,但这是一个可以突出显示的概念验证。

实际的突出显示并不是那么复杂(因为这是一个概念验证)。它所做的就是想象你有一支荧光笔,并在页面上画出它,从某个点开始,到另一个点结束。因此,具体来说,它不会尝试跟随文本行,但它确实确保它获取起点和终点之间的所有内容。

当然,人们需要小心实际的standalone标题以确保它们排版正确。另外,据我所知,它对类来说不值得。

结果:

突出显示页面后面的内容

代码:

\documentclass{article}
\pagestyle{empty}
\usepackage{tikz}
\makeatletter
\newbox\bg@tempbox
\newdimen\bg@tempdim
\def\ps@background{%
  \def\@oddhead{%
  \begingroup
  \setbox\bg@tempbox=\hbox{\begin{tikzpicture}[remember picture,overlay]
      \coordinate (page west);
      \coordinate (path north);
      \path  (\textwidth,0) coordinate (page east);
      \path (0,\textheight) coordinate (page south);
      \bg@contents
    \end{tikzpicture}}%
    \wd\bg@tempbox=0pt\ht\bg@tempbox=0pt\dp\bg@tempbox=0pt%
    \vbox{\hbox{\box\bg@tempbox}}%
    \global\let\bg@contents=\@empty
    \endgroup\hfil}
  \let\@evenhead\@oddhead
}
\pagestyle{background}
\def\bg@contents{%
}
\newcommand{\tikzmark}[1]{\tikz[remember picture,overlay] \coordinate (#1);}

\newcommand{\addtobg}[1]{%
  \g@addto@macro\bg@contents{#1}%
}

\newcounter{highlight}
\newcommand{\hlstart}{\tikz[remember picture,overlay,baseline=-0.7ex] \coordinate (hlstart\the\value{highlight});\hl@start}
\newcommand{\hlend}{\tikz[remember picture,overlay,baseline=-0.7ex] \coordinate (hlend\the\value{highlight});\hl@end\stepcounter{highlight}}

\newcommand{\hl@start}{%
  \edef\@temp{%
    \noexpand\addtobg{\noexpand\hl@draw{\the\value{highlight}}}%
  }%
  \@temp
}

\newcommand{\hl@end}{}

\newcommand{\hl@draw}[1]{%
  \path (hlstart#1);
  \pgfgetlastxy{\hlsx}{\hlsy}%
  \path (hlend#1);
  \pgfgetlastxy{\hlex}{\hley}%
  \ifdim\hlsy=\hley\relax
  \draw[highlight] (hlstart#1) -- (hlend#1);
  \else
  \draw[highlight] (hlstart#1) -- (hlstart#1 -| page east);
  \pgfmathtruncatemacro{\bg@lines}{int((\hley - \hlsy)/12pt) + 1}%
  \foreach \bg@line in {-1,...,\bg@lines} {
    \path (hlstart#1) ++(0,\bg@line * 12pt) coordinate (bgtmp);
    \draw[highlight] (bgtmp -| page west) -- (bgtmp -| page east);
  }%
  \path (hlstart#1) ++(0,\bg@lines * 12pt - 12pt) coordinate (bgtmp);
  \draw[highlight] (bgtmp -| page west) -- (hlend#1);
  \fi
}

\tikzset{%
  highlight/.style={
    yellow,
    line width=12pt,
  }
}

\makeatother


\begin{document}

One of the suggested uses for this blog is to \hlstart highlight great questions\hlend\ and answers.
I'm proposing the following question for a \textbf{Great Question}.
(I'm linking to it early in case you get bored with the blog post and just want to look at the question.)

Good keyboard layouts for typing (La)TeX.

To encourage you to look at that, let me first divulge my reason why I consider that a Great Question (and no, it's not because I answered it).
\hlstart I don't intend to be prescriptive about what a Great Question is, but certainly one good indicator is that it is a question that you should read even if you don't know that you should read it\hlend.
What I mean by that is that this question is probably one that you would pass in the street if you came upon it, but that once you've actually read it you will (I hope) think, ``I wish I'd read that years ago!''.

The rest of this post is for those of you who want a little more reason for reading it, or who having read it don't quite get what I'm making all the fuss about.
\end{document}

相关内容