TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I’d like to set up a tikz style, say /uml/interface, that would modify the node content following some macro of my choosing. For example, it would prefix the node text with some text of my choosing. I would use it as follows.

\path node[/uml/interface] (MyInterface) {MyInterface};

And as a result of applying the /uml/interface style the node content would become <<interface>> \\ MyInterface.

I have used the font change command, as follows.

\tikzset{/uml/interface/.style={rectangle, draw, every text node/.style={font=\bfseries}}}

But I did not find in the PGF manual how to programmatically modify the node text itself.

Ideally, I would do something like this:

\tikzset{/uml/interface/.style={…, every text node/.style={applyMacro=\umlinterface}}}

and

\newcommand{\umlinterface}[1]{<<interface>> \\ \textbf{#1}}

. As a workaround I could typeset my node as follows:

\path node[/uml/interface] (MyInterface) {\umlinterface{MyInterface}};

, but I’d prefer having a clean node content part (for consistence, maintenance, readability, and avoiding refactoring all my related node commands when I decide to add a prefix).

share|improve this question
4  
TikZ v3 has a key node content – percusse Jan 6 at 16:22
up vote 8 down vote accepted

You can apply a macro to the node text by injecting it with execute at begin node. This works, because in the TikZ code this key is immediately followed by \bgroup.

/uml/interface/.style={
  rectangle, draw,
  execute at begin node=\umlinterface
}

To be safe, I added another level of grouping.

\documentclass{article}
\usepackage[T1]{fontenc} % just for the guillemets
\usepackage{tikz}
\begin{document}
\newcommand{\umlinterface}[1]{<<interface>> \\ \textbf{#1}}
\tikzset{
  /uml/interface/.style={
    rectangle, draw,
    execute at begin node=\umlinterface\bgroup,
    execute at end node=\egroup
  }
}
\begin{tikzpicture}
  \path node[/uml/interface] (MyInterface) {MyInterface};
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
    
Nice! (+1) Just add align=left to the style to allow the linebreak to work properly. – Paul Gessler Jan 6 at 16:48
    
@PaulGessler Unfortunately, my solution breaks align=left. I don't know why, yet. I have to explicitely put text width=…. – Henri Menke Jan 6 at 16:50
    
@HenriMenke Thanks, this looks like a good solution for me… If we manage to solve the align problem! – Olivier Cailloux Jan 7 at 9:36
    
Also the suggested strategy has odd behavior inside a beamer frame. It works with execute at begin node=\textbf but not with execute at begin node=\myowncommand, not sure why. I guess it is related to align-not-working anyway so I’ll wait to see if anybody better acquainted to (la)tex than me can work it out… – Olivier Cailloux Jan 7 at 13:56
    
Here is a patch to render execute at begin node compatible with align=. Unfortunately it involves fiddling with the inner workings of tikz. I would not go that far just to get my "prefix" functionality. I’d like to find a simpler solution, but I guess none exist currently. – Olivier Cailloux Feb 8 at 10:21

Slightly different from your expected input, but here's one approach using the node contents key mentioned by percusse.

I use the interface name as an argument to the style, and piece together the full node contents inside the definition of the style.

\documentclass[tikz]{standalone}
\usepackage[T1]{fontenc} % just for the guillemets
\tikzset{/uml/interface/.style={
  % ... more style defs as needed ...
  rectangle, draw, align=left,
  node contents={<<interface>> \\ \textbf{#1}},
}}

\begin{document}
\tikz{\node[/uml/interface=MyInterface];}
\end{document}

enter image description here

share|improve this answer
    
Clever use of node contents! I’d favor Henri’s solution if we can make it work, but it is good to have a backup solution. – Olivier Cailloux Jan 7 at 9:41

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.