3

I have a macro which generates a structure (rule) and a reference to that structure. It does not behave when inside a tikzpicture. How to make the function robust to reference the structure even when inside tikzpicture? (I also want to get rid of the error message "mevp not defined")

\documentclass[12pt,a4paper]{book}
\makeatletter
%\usepackage[utf8]{inputenc}
\usepackage{graphicx}
\usepackage{ifthen}
\usepackage{tikz}
\newcounter{strctz}
\DeclareRobustCommand{\strct}[1]{%
%  \ifthenelse{\isundefined{\c#1}} %
%     {
       \refstepcounter{strctz}%
       \textbf{#1}\textbf{\Large({\thestrctz})}%
       \\[2mm]%
       \rule{2cm}{5mm}%
       \begingroup
       \expandafter\protected@edef\csname c#1\endcsname{\thestrctz}%
       \expandafter\endgroup
       \expandafter\DeclareRobustCommand
       \csname c#1\expandafter\expandafter\expandafter\endcsname
       \expandafter\expandafter\expandafter{\csname c#1\endcsname}%
 %    }
 %    {#1%
 %    \\[2mm]%
 %    \rule{2cm}{5mm}%
 %      (\c#1)%
 %    }
 }
 \makeatother
 \begin{document}
 \strct{mevalonate}
 (\cmevalonate) and

  \strct{ohpregnenolone}

  Structure (\cohpregnenolone) and structure (\cmevalonate) and
  Structure (\cohpregnenolone)

 \strct{alanine}  and (\calanine) (\cmevalonate) (\cohpregnenolone)

 \strct{mevalonate}

  %Isoprenyl-Bildung, Dimethyl-Allyl-Bildung aus Mevalonat
 %
  \tikzstyle{prenPP}= [rectangle,minimum size=2.4cm,text width=3.8cm,text  centered,inner sep=.05cm]
  \begin{tikzpicture}
  \node [prenPP%
         ,text width=4.6cm%
        ]      (mev)        at (0,8) {\strct{mevalonate}};
   node [prenPP%
         ,text width=4.6cm%
   ] (mevP)       at (8,8) {\strct{mevalonateP}};
   \draw[->,shorten >=0.5cm,shorten <=0.5cm,very thick]
     (mev)   -- node[below=0.5pt] {\parbox{2.5cm}{%
       \begin{center}%
         enzym{mevalonate kinase}
       \end{center}}}%
     (mevP) ;
   \end{tikzpicture}
 \cmelonalonateP
 \end{document}
  • 1
    Welcome to TeX.SE. It would be helpful if you turned your code snippet into a fully compilable MWE including \documentclass and the appropriate packages that sets up the problem. While solving problems can be fun, setting them up is not. Then, those trying to help can simply cut and paste your MWE and get started on solving the problem. – Peter Grill Nov 26 '14 at 5:25
  • Paul Gaborit did it for me. Thank you, Paul – Bernhard Kleine Nov 26 '14 at 9:30
  • I can't get it to compile at all. No error message, it just hangs. – John Kormylo Nov 26 '14 at 14:32
  • I have code which compiles here well. I would like to add the ifthenelse part but then breaks even the macros outside the tikz environnement. I am at a loss. – Bernhard Kleine Nov 29 '14 at 9:46
4

Basically this is a typo - the macro you call at the end, \cmelonalonateP, is not the one, \cmevalonateP, defined in the node. Additionally the unknown shape comes from a missing \ before the corresponding defining node command.

However, ifthenelse would be much better replaced by using macros from the package etoolbox. This would allow you to shorten the code and make it clearer. In particular etoolbox provides \ifcsdef, \csuse and \protected@csxdef amongst other things, which work with macro names rather than you having to issue \csname...\endcsname and keep track of expansion.

For example

\ifcsdef{c#1}{TRUE}{FALSE}

checks whether the macro \ followed by c and then the contents of #1 is defined and acts accordingly.

\documentclass[12pt,a4paper]{book}

\usepackage{graphicx}
\usepackage{tikz,etoolbox}
\newcounter{strctz}

\makeatletter
\DeclareRobustCommand{\strct}[1]{%
  \ifcsdef{c#1}{%
    #1\\[2mm]%
    \rule{2cm}{5mm}%
      (\csuse{c#1})%
    }{%
       \refstepcounter{strctz}%
       \textbf{#1}\textbf{ -- def. ({\thestrctz})}%
       \\[2mm]%
       \rule{2cm}{5mm}%
       \protected@csxdef{c#1}{\thestrctz}%
       \expandafter\DeclareRobustCommand
       \csname c#1\expandafter\expandafter\expandafter\endcsname
       \expandafter\expandafter\expandafter{\csname c#1\endcsname}%
    }%
 }
\makeatother

\begin{document}

\parindent=0pt

\strct{mevalonate} (\cmevalonate) and

\strct{ohpregnenolone}

Structure (\cohpregnenolone) and structure (\cmevalonate) and
structure (\cohpregnenolone)

\strct{alanine}  and (\calanine) (\cmevalonate) (\cohpregnenolone)

\strct{mevalonate}

\tikzstyle{prenPP}=[rectangle, minimum size=2.4cm, text width=3.8cm,
  text centered, inner sep=.05cm]
\begin{tikzpicture}
  \node [prenPP,text width=4.6cm]
  (mev) at (0,8) {\strct{mevalonate}};
  \node [prenPP,text width=4.6cm]
  (mevP) at (8,8) {\strct{mevalonateP}};
  \draw[->,shorten >=0.5cm,shorten <=0.5cm,very thick]
  (mev)   -- node[below=0.5pt] {\parbox{2.5cm}{%
  \begin{center}%
    enzym{mevalonate kinase}
  \end{center}}}%
  (mevP) ;
\end{tikzpicture}

Here we see (\cmevalonateP) is defined.

\end{document}

Sample output

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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