3

I want to be able to modify the style of some parts of a complex picture depending on a tag on nodes or pathes (precisely, I have a complex architecture schematic and I want to selectively highlight some datapathes). And I to facilitate maintenance of the picture, I prefer a single source.

One way to do that is:

  1. to declare the tags as empty pgfkeys styles
  2. and to modify their value on demand.

\documentclass{article}
\usepackage{tikz}
\begin{document}
    \pgfkeys{/tikz/.cd,<slide 1>/.style={}}
    \pgfkeys{/tikz/.cd,<slide 2>/.style={}}
    \pgfkeys{/tikz/.cd,<slide 3>/.style={}}
    \pgfkeys{/tikz/.cd,<slide 4>/.style={}}

    \newcommand{\complexpicture}{

  \node[draw, <slide 1>] at (0,0) {box 1};  
  \node[draw, <slide 2>] at (2,0) {box 2};
  \node[draw, <slide 3>] at (4,0) {box 3};
  \node[draw, <slide 4>] at (6,0) {box 4};
}

General overview (all tags are ignored)
\begin{tikzpicture}
  \complexpicture
\end{tikzpicture}

Highlight first item    
\begin{tikzpicture}[<slide 1>/.style={very thick}]
  \complexpicture
\end{tikzpicture}

Highlight second item
\begin{tikzpicture}[<slide 2>/.style={very thick}]
  \complexpicture
\end{tikzpicture}
\end{document}

enter image description here

Of course, it works, but the need to previously declare tags is unflexible and inelegant.

So I tried to filter out < tags > with pgfkeys, except when a style exists. I used first char syntax to detect an initial <.

I did not succeed to declare styles starting with a <. So tikzpicture styles are in /tag/name/.style and I filter out < name > pgfkey, unless /tag/name exist.

\documentclass{article}

\usepackage{tikz}

\begin{document}
\newcommand{\complexpicture}{
  \node[draw, <slide 1>] at (0,0) {box 1};  
  \node[draw, <slide 2>] at (2,0) {box 2};
  \node[draw, <slide 3>] at (4,0) {box 3};
  \node[draw, <slide 4>] at (6,0) {box 4};
}

\pgfkeys{
  /handlers/first char syntax=true,
  /handlers/first char syntax/the character </.initial=\mykeymacro
}
\def\mykeymacro#1{\mykeyparser#1\someendtext}
\def\mykeyparser<#1>\someendtext{
  \pgfkeysifdefined{/tag/#1}{\pgfkeysvalueof{/tag/#1}}{}
}

General overview (all tags are ignored)\\
\begin{tikzpicture}
  \complexpicture
\end{tikzpicture}

Highlight first item\\
\begin{tikzpicture}[/tag/slide 1/.style={very thick}]
  \complexpicture
\end{tikzpicture}

Highlight second item\\
\begin{tikzpicture}[/tag/slide 2/.style={very thick}]
  \complexpicture
\end{tikzpicture}


\end{document}

enter image description here

Actually, it does not work. < tags > are properly filtered out and there is no pgfkeys error, but all theses keys are suppressed and the styles declared in the \tikzpicture are never activated. I tried some variations on this scheme, but none did work.

Probably I am missing something...

AndréC
  • 24,137
  • Welcome to TeX.SE! Could you please elaborate a tiny bit more on what you are trying to achieve, and, in particular, why? The current output can easily be achieved by putting the nodes in a matrix and saying column 2/.style={thick}, say. (Most likely I just do not understand the purpose of that exercise.) –  Dec 12 '18 at 19:03
  • This is a MWE. Actually, the picture is ~200 lines and describes the architecture of a processor, with registers, operators and busses. What I want to do is to have several versions. The regular one and others where the path used to implement some instructions is highlighted in red. The picture is fairly complex and can be largely improved,so I want a unique version and a way to easily modify styles of some parts of the picture with a unique code.. – Alain Merigot Dec 12 '18 at 21:53
  • @Peter Grill Thanks for the links. Actually, the problem is not a problem of key choice. I want to tag some parts of a picture and say "apply this style where tag=sometag". But a node can have either no tag or one or several tags, and even a picture can define styles for several tags (for instance to highlight step1, step2..step9 and to highlight all the steps at once). – Alain Merigot Dec 12 '18 at 22:10
  • I had a similar issue and the solution I used is to have my picture in a separate file (using the standalone class). Each picture sets all the necessary styles required by the figure: \tikzset{Draw Style 1/.provide style={}}, ..., \tikzset{Node Style 1/.provide style={}}, etc (or those can be set to some default value if needed). That way, when I invoke this figure, I can override a select subset of the styles as desired. The handler .provide style is defined in Is there something like \providetikzstyle similar to \providecommand?. – Peter Grill Dec 12 '18 at 22:20

1 Answers1

1

I finally found a solution thanks to the unkonw handler and this trick can be useful to others.

Just define an unknown handler for a complete family that provides an empty style. And it is sufficient to redefine the style in the tikzpicture.

Here is a working example with several tags and several styles.

\documentclass{article}

\usepackage{tikz}

\begin{document}
\newcommand{\complexpicture}{
  \node[draw, blue, /tag/slide 1] at (0,0) {box 1};  
  \node[draw, rounded corners, /tag/slide 2, /tag/slide 3] at (2,0) {box 2}; % double tag
  \node[draw, green, /tag/slide 3] at (4,0) {box 3};
  \node[draw, /tag/slide 4] at (6,0) {box 4};
}

\pgfkeys{/tikz/highlight/.style={red, very thick}}
\pgfkeys{/tikz/grey out/.style={opacity=0.4}}

\pgfkeys{/tag/.is family, /tag, 
.unknown/.code = {
    \pgfkeyssetvalue{\pgfkeyscurrentpath/\pgfkeyscurrentname}{}
}

General overview (all tags are ignored)\\
\begin{tikzpicture}
  \complexpicture
\end{tikzpicture}

Highlight first item\\
\begin{tikzpicture}[/tag/slide 1/.style=highlight]
  \complexpicture
\end{tikzpicture}

Highlight second item and grey out slide 3 and 4\\
\begin{tikzpicture}[/tag/slide 2/.style=highlight, /tag/slide 3/.style=grey out,
                    /tag/slide 4/.style=grey out]]
  \complexpicture
\end{tikzpicture}
\end{document}

enter image description here

Maybe it is also possible to define hierarchical tags in order to be able to change the style of either individual tags /tag/foo/bar or of a tag hierarchy /tag/foo/* at once.

Thanks to all.