After looking at the source code of contour
(at least at the pdftex
driver part) I figured that it typesets the text twice, once for the contour and once normally. The content must be short (i.e. not \long
) and is processed in restricted horizontal mode. The issue is that TikZ processes the node content as box, not as macro argument. This is normally very good because it allows verbatim content etc. in the node, but doesn't allow direct access to the un-typeset content required for \contour
and other macros.
Note that \contour
partly works with boxed content if you use \unhbox
. The issue is just that you need it twice and can't change the color! So either both have the same color which makes the contour not very useful or you only have contour without the real text. I patched the contour
source code (for pdftex
only) to get you there:
% (uncomment the `%` lines to enable typesetting of the real text, but in the same color than the contour)
\documentclass{article}
\usepackage{tikz}
\usepackage[outline]{contour}
\contourlength{.1pt}
\makeatletter
\def\tikzcontour#1{%
\begingroup
\color{#1}%
%\def\contourcolor{#1}%
\begin{lrbox}{\@tempboxa}%
}
% Mostly taken from `\@contour@outline` from `contour`s `pdftex.cnt` driver file:
% Work with pdftex only
\def\endtikzcontour{%
\end{lrbox}%
%\setbox0=\hbox{\usebox\@tempboxa}%
\begingroup
\setlength\con@length{\con@base@length}%
\setlength\con@length{2\con@length}%
\setlength\con@length{0.99626400996\con@length}%
%\color{\contourcolor}%
\con@coloroff
\pdfliteral{%
q
1 j
1 J
1 Tr
\strip@pt\con@length\space w
}%
%\rlap
\mbox% change back to `\rlap` when "real" text is drawn
{\unhbox\@tempboxa}%
\pdfliteral{%
Q
}%
\endgroup
%\unhbox0
\endgroup
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node [execute at begin node={\tikzcontour{red}},execute at end node={\endtikzcontour}] {Text};
\end{tikzpicture}
\end{document}
This gives:
However it is possible to collect the content of the TikZ node with the same technique my collcell
package uses to collect the content of a tabular
cell, i.e. to skip the internal code header and read it token by token until the end is reached.
Here some proof-of-concept quick&dirty solution which reuses code from collcell
. Do not use \collectcell
with tables in the same file. I will write a dedicated, more stable solution when I find the time.
\documentclass{article}
\usepackage{tikz}
\usepackage[outline]{contour}
\contourlength{.05em}
\usepackage{collcell}
\makeatletter
\def\collect@cell@look@{%
\cc@case
\@sptoken{%
\edef\collect@cell@spaces{\collect@cell@spaces\space}%
\collect@cell@eatspace
}%
\bgroup{\collect@cell@group}%
\egroup{\afterassignment\collect@cell@end\let\@let@token=}%
%\egroup{\collect@cell@end}%
\default{\collect@cell@arg}%
\endcc@case
}
\def\tikzcontour#1#2{\@tikzcontour{#1}#2\@endtikzcontour}
\def\@tikzcontour#1#2\ignorespaces#3\@endtikzcontour{%
\bgroup%
\ifx\tikz@textcolor\pgfutil@empty%
\else%
\pgfutil@colorlet{.}{\tikz@textcolor}%
\fi%
\pgfsetcolor{.}%
\setbox\tikz@figbox=\box\pgfutil@voidb@x%
\tikz@uninstallcommands%
\tikz@halign@check%
\contour{#1}{\ignorespaces #3\unskip}%
\egroup
\tikz@fig@collectresetcolor%
}
\let\collcell@afteruser=\empty
\makeatother
\tikzset{contour/.style={execute at begin node={\collectcell{\tikzcontour{#1}}\ignorespaces}}}
\begin{document}
\begin{tikzpicture}
\node [draw,green,contour=red,circle] {Text};
\end{tikzpicture}
\end{document}
\bgroup
and\egroup
? If you look at the code for the keymatrix of nodes
in thematrix
library then that's what it does (according to the manual - I didn't look at the code).\node
but typeset as a box. Also with "function" you mean "macro", right?