
Imagine que quiero dibujar una forma rellena detrás de algo que ya está escrito en la página. El enfoque habitual es definir un \tikzmark
comando que simplemente recuerda una coordenada usando remember picture
y overlay
opciones, y luego usar esa coordenada para dibujar cosas tikz usando transparencia.
Por ejemplo:
\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}
Que produce:
Pero ahora supongamos que quiero unsólidoamarillo. La idea obvia es utilizarlo pgfonlayer
y dibujarlo en el fondo. Sin embargo, el concepto de fondo/primer plano aparentemente sólo existe dentro de entornos tikz. Dado que el texto principal de la página ya estaba tipográfico, se encuentra detrás del trasfondo de 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}
Se puede hacer?
Respuesta1
Gracias a Andrew Stacey por señalarme elmejoradatikzmkark
. Yo no era consciente de ello. Esta versión de \tikzmark
permite utilizar las coordenadas definidas.antesel punto de su definición. El uso de \tikzmark{foo}
una nueva coordenada denominada (pic cs:foo)
está disponible y se puede utilizar en cualquier parte de la página.
Utilizando el nuevo \tikzmark
, tomado del preámbulo dehttps://tex.stackexchange.com/a/50054/12571el problema se puede resolver así:
\begin{document}
\noindent\begin{tikzpicture}[remember picture, overlay]
\fill[yellow] (pic cs:A) circle(2em);
\end{tikzpicture}%
\tikzmark{A}\lipsum[11]
\end{document}
Con el resultado deseado:
Apéndice
\tikzmark
Para mayor exhaustividad, se incluye aquí el código de todo el documento, incluido el preámbulo en el que aparece la novedad :
\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}
NOTA: Cualquiera que esté dispuesto a votar por esta autorespuesta, debería votar porhttps://tex.stackexchange.com/a/50054/12571en cambio :-)
Actualizar
Como señaló Ulrike Fischer en un comentario, colocar el tikzpicture
fondo demasiado cerca del párrafo decorado puede tener efectos secundarios en el párrafo 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}
Sin embargo, al separar demasiado el tikzpicture
de el \tikzmark
corremos el riesgo de terminar con ellos en páginas separadas y, por lo tanto, el fondo aparecerá en la página equivocada.
La mejor solución es entonces utilizar alguna solución que "almacene" la imagen requerida y "active" su salida como fondo al mismo tiempo que colocamos la imagen \tikzmark
, como por ejemplo la solución propuesta por Ulrike en el comentario.
Exploré otra opción, que es utilizar el maravillosopaquete de fondoporGonzalo Medina(¡gracias a Andrew por sugerirlo en un chat!). Usando este paquete configuramos la imagen de fondo en cualquier parte del documento y la "activamos" al \BgThispage
mismo tiempo que colocamos el archivo \tikzmark
. Al utilizar este enfoque no es necesariomejoradatikzmark
y en cambio elviejo minimalistatikzmark
puede ser usado.
También es importante dar valores adecuados a las opciones placement
y scale
, para obtener el dibujo en las coordenadas adecuadas. Ahí está el 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}
Y después de tres (¿por qué tres?) compilaciones obtengo: