Apêndice

Apêndice

Imagine que eu queira desenhar uma forma preenchida atrás de algo já escrito na página. A abordagem usual é definir um \tikzmarkcomando que simplesmente lembre uma coordenada usando as opções remember picturee overlay, e depois use essa coordenada para desenhar coisas tikz usando transparência.

Por exemplo:

\documentclass{article}
\usepackage{tikz}
\usepackage{lipsum}
\usetikzlibrary{backgrounds}
\def\tikzmark#1{\tikz[remember picture,overlay]\coordinate(#1);}
\begin{document}
\noindent\tikzmark{A}\lipsum[11]

\begin{tikzpicture}[remember picture, overlay]
  \fill[yellow, opacity=.3] (A) circle(2em);
\end{tikzpicture}
\end{document}

O que produz:

Resultado

Mas agora suponha que eu queira umsólidoamarelo. A ideia óbvia é usar pgfonlayere desenhar no fundo. No entanto, o conceito de plano de fundo/primeiro plano aparentemente só existe dentro de ambientes tikz. Como o texto principal da página já estava escrito, ele está atrás do plano de fundo do tikz:

\documentclass{article}
\usepackage{tikz}
\usepackage{lipsum}
\usetikzlibrary{backgrounds}
\def\tikzmark#1{\tikz[remember picture,overlay]\coordinate(#1);}
\begin{document}

\noindent\tikzmark{A}\lipsum[11]

\begin{tikzpicture}[remember picture, overlay]
\begin{pgfonlayer}{background}
  \fill[yellow] (A) circle(2em);
\end{pgfonlayer}
\end{tikzpicture}
\end{document}

Ruim

Isso pode ser feito?

Responder1

Obrigado a Andrew Stacey por me indicar onovo melhoradotikzmkark. Eu não estava ciente disso. Esta versão \tikzmarkpermite usar as coordenadas definidasanteso ponto de sua definição. O uso de \tikzmark{foo}uma nova coordenada chamada (pic cs:foo)está disponível e pode ser usado em qualquer lugar da página.

Usando o new \tikzmark, retirado do preâmbulo dehttps://tex.stackexchange.com/a/50054/12571o problema pode ser resolvido assim:

\begin{document}
\noindent\begin{tikzpicture}[remember picture, overlay]
  \fill[yellow] (pic cs:A) circle(2em);
\end{tikzpicture}%
\tikzmark{A}\lipsum[11]
\end{document}

Com o resultado desejado:

Bom

Apêndice

Para completar, o código de todo o documento, incluindo o preâmbulo em que o novo \tikzmarkaparece, está incluído aqui:

\documentclass{article}
\usepackage{tikz}
\usepackage{lipsum}
\makeatletter
\tikzset{%
  remember picture with id/.style={%
    remember picture,
    overlay,
    save picture id=#1,
  },
  save picture id/.code={%
    \edef\pgf@temp{#1}%
    \immediate\write\pgfutil@auxout{%
      \noexpand\savepointas{\pgf@temp}{\pgfpictureid}}%
  },
  if picture id/.code args={#1#2#3}{%
    \@ifundefined{save@pt@#1}{%
      \pgfkeysalso{#3}%
    }{
      \pgfkeysalso{#2}%
    }
  }
}

\def\savepointas#1#2{%
  \expandafter\gdef\csname save@pt@#1\endcsname{#2}%
}
\def\tmk@labeldef#1,#2\@nil{%
  \def\tmk@label{#1}%
  \def\tmk@def{#2}%
}

\tikzdeclarecoordinatesystem{pic}{%
  \pgfutil@in@,{#1}%
  \ifpgfutil@in@%
    \tmk@labeldef#1\@nil
  \else
    \tmk@labeldef#1,(0pt,0pt)\@nil
  \fi
  \@ifundefined{save@pt@\tmk@label}{%
    \tikz@scan@one@point\pgfutil@firstofone\tmk@def
  }{%
  \pgfsys@getposition{\csname save@pt@\tmk@label\endcsname}\save@orig@pic%
  \pgfsys@getposition{\pgfpictureid}\save@this@pic%
  \pgf@process{\pgfpointorigin\save@this@pic}%
  \pgf@xa=\pgf@x
  \pgf@ya=\pgf@y
  \pgf@process{\pgfpointorigin\save@orig@pic}%
  \advance\pgf@x by -\pgf@xa
  \advance\pgf@y by -\pgf@ya
  }%
}
\newcommand\tikzmark[2][]{%
\tikz[remember picture with id=#2] #1;}
\makeatother

\begin{document}
\noindent\begin{tikzpicture}[remember picture, overlay]
  \fill[yellow] (pic cs:A) circle(2em);
\end{tikzpicture}%
\tikzmark{A}\lipsum[11]
\end{document}

OBSERVAÇÃO: Qualquer pessoa disposta a votar nesta auto-resposta deve votarhttps://tex.stackexchange.com/a/50054/12571em vez de :-)


Atualizar

Conforme observado por Ulrike Fischer em um comentário, colocar o tikzpictureque desenha o fundo muito próximo do parágrafo decorado pode ter efeitos colaterais no parágrafo anterior:

\begin{document}
\lipsum[5] % <------ Added a previous paragraph
\medskip
\noindent\begin{tikzpicture}[remember picture, overlay]
  \fill[yellow] (pic cs:A) circle(2em);
\end{tikzpicture}%
\tikzmark{A}\lipsum[11]
\end{document}

Ruim :-(

Porém, separando muito o tikzpicturedo, \tikzmarkcorremos o risco de acabar com aqueles em páginas separadas e, assim, o fundo aparecerá na página errada.

A melhor solução é então usar alguma solução que "armazene" a imagem necessária e "ative" sua saída como plano de fundo ao mesmo tempo que colocamos o \tikzmark, como por exemplo a solução proposta por Ulrike no comentário.

Explorei outra opção, que é usar o maravilhosopacote de plano de fundoporGonzalo Medina(obrigado ao Andrew por sugerir isso no chat!). Usando este pacote configuramos a imagem de fundo em qualquer lugar do documento, e a "ativamos" ao \BgThispagemesmo tempo em que colocamos o arquivo \tikzmark. Usando esta abordagem, não há necessidade denovo melhoradotikzmarke em vez disso oantigo minimalistatikzmarkpode ser usado.

É importante também atribuir valores apropriados às opções placemente scale, para obter o desenho nas coordenadas apropriadas. Existe o MWE:

\documentclass{article}
\usepackage{tikz}
\usepackage[pages=some]{background}
\usepackage{lipsum}
\def\tikzmark#1{\tikz[remember picture, overlay]\coordinate(#1);}

\begin{document}
\backgroundsetup{scale=1,placement=bottom,contents={%
\noindent\begin{tikzpicture}[remember picture,overlay]
  \fill[yellow] (A) circle(2em);
\end{tikzpicture}%
}}

\lipsum[5]
\medskip
\noindent\tikzmark{A}\BgThispage\lipsum[11]
\end{document}

E depois de três (por que três?) compilações eu recebo:

Bom!

informação relacionada