4

I am trying to make some modification on the answer of Andrew Stacey of my previous question "A macro of drawing a rectangle with several parameters in TikZ".

The current code is the following:

\documentclass{article}
\usepackage[frenchb]{babel}
\usepackage{tikz}
\usetikzlibrary{fit}

\tikzset{
  my funny rectangle/.style n args={4}{%
    rectangle,
    draw,
    append after command={\pgfextra{\let\mainnode=\tikzlastnode}
      node[above right] at (\mainnode.north west) {#3}%
      node[above left] at (\mainnode.north east) {#4}%
      node[below left] at (\mainnode.north west) {#1}%
      node[above left] at (\mainnode.south west) {#2}%
    },
  }
}

\begin{document}
\begin{tikzpicture}
\node[my funny rectangle={1}{7}{4}{8}] {a text};
\node[my funny rectangle={$i$}{$i$}{4}{8}, text width={3cm}, minimum height={3cm}, text centered] (abc) at (5,5) {text};
\end{tikzpicture}
\end{document}

I would like to add a condition inside the append after command: if #1 = #2, do only node[below left] at (\mainnode.west) {#1}, else do node[below left] at (\mainnode.north west) {#1} and node[above left] at (\mainnode.south west) {#2}.

The answer that @Werner suggested works fine for arguments like {1}{7}{4}{8}, but does not work for arguments like {$i$}{$i$}{4}{8}. Does anyone have an idea?

SoftTimur
  • 19,767

1 Answers1

2

This is probably what you're after:

enter image description here

The standard TeX conditional \ifx#1#2 <true> \else <false> \fi works in this case, executing <true> if #1=#2 and <false> otherwise.

\documentclass{standalone}
%\url{http://tex.stackexchange.com/q/27278/86}
\usepackage{tikz}
\usetikzlibrary{fit}

\tikzset{
  my funny rectangle/.style n args={4}{%
    rectangle,
    draw,
    fit={(#3,#1) (#4,#2)},
    append after command={\pgfextra{\let\mainnode=\tikzlastnode}
      node[above right] at (\mainnode.north west) {#3}%
      node[above left] at (\mainnode.north east) {#4}%
      \ifx#1#2
        node[left] at (\mainnode.west) {#1}%
      \else
        node[below left] at (\mainnode.north west) {#1}%
        node[above left] at (\mainnode.south west) {#2}%
      \fi
    },
  }
}

\begin{document}
\begin{tikzpicture}
  \node[my funny rectangle={1}{1}{4}{8}] {text};
\end{tikzpicture}
\end{document}

Edit: Here's the updated code that addresses passing some non-numeric arguments to my funny rectangle. With the node no longer fitted, you need to specify additional width and height parameters:

enter image description here

\documentclass{article}
\usepackage{tikz}% http://ctan.org/pkg/pgf
%\usetikzlibrary{fit}

\tikzset{
  my funny rectangle/.style n args={4}{%
    rectangle,
    draw,
    %fit={(#3,#1) (#4,#2)},
    append after command={\pgfextra{%
      \let\mainnode=\tikzlastnode%
      \def\argone{#1}\def\argtwo{#2}}
      node[above right] at (\mainnode.north west) {#3}%
      node[above left] at (\mainnode.north east) {#4}%
      \ifx\argone\argtwo
        node[left] at (\mainnode.west) {#1}%
      \else
        node[below left] at (\mainnode.north west) {#1}%
        node[above left] at (\mainnode.south west) {#2}%
      \fi
    },
  }
}

\begin{document}
\begin{tikzpicture}
\node[my funny rectangle={$i$}{$i$}{4}{8}, text width={3cm}, minimum height={3cm}, text centered] (abc) at (5,5) {text};
\end{tikzpicture}
\end{document}
Werner
  • 603,163
  • Thanks... one thing is... it seems that ifx checks only numbers, but I often have for instance \node[my funny rectangle={$i$}{$i$}{4}{8}] {text};, do you have any idea? – SoftTimur Oct 16 '11 at 17:59
  • 1
    @SoftTimur: Is that version going to work with the main code? Since the numbers are used also as coordinates then I would be a little surprised to discover that $i$ was an acceptable argument. The definition might need a little reworking if you want to label the corners by something other than their coordinates. – Andrew Stacey Oct 16 '11 at 18:02
  • @SoftTimur: As Andrew mentioned, the problem is not so much with \ifx, but rather with the use of the arguments to specify the text block size/dimension, and $i$ has no number value. – Werner Oct 16 '11 at 18:15
  • @AndrewStacey and @Werner: sorry, actually I did not use fit={(#3,#1) (#4,#2)} in my code, but specified the wight and height in \node (e.g. \node[my funny rectangle={1}{1}{$i$}{$i$}, text width={3cm}, minimum height={3cm}, text centered] (abc) at (5,5) {text}). In this case, without the condition, the macro does accept $i$, so i would like to make the condition accept this kind of arguments. – SoftTimur Oct 16 '11 at 18:25
  • @SoftTimur: Please modify your original question to reflect this change. – Werner Oct 16 '11 at 18:27
  • @Werner: just done – SoftTimur Oct 16 '11 at 18:29
  • @SoftTimur: How about updating your post with a complete, working minimal example that shows exactly what the new structure of \tikzset is. Otherwise any attempts to solve this might be subject to slight nuances in your code, leading to more confusion. – Werner Oct 16 '11 at 18:46
  • @Werner: just did it – SoftTimur Oct 16 '11 at 19:09
  • 1
    So then \def\argone{#1}\def\argtwo{#2} ... \ifx\argone\argtwo ought to do it, shouldn't it? – Andrew Stacey Oct 17 '11 at 06:54
  • @AndrewStacey: I tried that, but I'm not sure where to make this assignment in the macro, since the contents of \tikzset are key-value pairs. Putting it in \pgfextra{...} doesn't help either. – Werner Oct 17 '11 at 07:16
  • 1
    Putting the assignment in \pgfextra works for me. Note that the assignment \let\mainnode=\tikzlastnode is in the \pgfextra so there's no grouping issues there. What really confused me is that SoftTimur put the doubled argument on the big square, not the little one! So I thought that the conditional was being evaluated the wrong way around. – Andrew Stacey Oct 17 '11 at 07:49
  • Cool, Andrew Stacey's solution works for me... For instance \pgfextra{\let\mainnode=\tikzlastnode \def\argone{#1}\def\argtwo{#2}\def\argthree{#3}\def\argfour{#4}} ... \ifx\argone\argtwo ... – SoftTimur Oct 17 '11 at 08:38