TransWikia.com

Assigning a numerical variable with Tikz pgfmathtruncatemacro

TeX - LaTeX Asked by kebs on December 27, 2020

I am struggling with some basic computations with Tikz and I have a problem assigning a value to a variable inside a local scope.

Consider the following MVCE:

documentclass{article}
usepackage{ifthen}
usepackage{tikz}

newcommand{mycommand}
{
    defmyvar{0};
    defmyresult{3};
    ifnummyvar=0
    {
        defmyresult{4};
        draw (0,1) node {Test is true!};
    }
    fi;
    draw (0,0) node {myresult=myresult !!!};
}

begin{document}
begin{tikzpicture}
mycommand
end{tikzpicture}
end{document}

Written that way, the “Test is true!” is printed, but the value of myresult stays to 3.

So I assume that the second def command creates a new variable, whose scope is limited to the if block.
After searching a bit, it seems I can get out by defining the variable as “global”, using the global command:

newcommand{mycommand}
{
    defmyvar{0};
    globaldefmyresult{3};
    ifnummyvar=0
    {
        globaldefmyresult{4};
        draw (0,1) node {Test is true!};
    }
    fi;
    draw (0,0) node {myresult=myresult !!!};
}

That way, it works, although I am not sure this is optimal (global seems to be a TeX command, and I’ve read many times that it’s a bad idea to use low-level TeX commands inside a LaTeX source…)

But now, my real code is a bit more complicated, and inside the “if” bloc, its actually a pgfmathtruncatemacro that is used.
Say something like:

newcommand{mycommand}
{
    defmyvar{0};
    globaldefmyresult{3};
    ifnummyvar=0
    {
        pgfmathtruncatemacro{myresult}{4}
    }
    fi;
    draw (0,0) node {myresult=myresult !!!};
}

Then I get the same problem as above: pgfmathtruncatemacro seems to declare a new variable, as I stay with the value 3

And both

globalpgfmathtruncatemacro{myresult}{4}

or

pgfmathtruncatemacro{globalmyresult}{4}

fail to compile.

How can I get out of this problem ?

2 Answers

Here is a rather safe how one can "broadcast" results, i.e. make them available outside a group.

  • In this case, you could just use xdef. Is xdef dangerous? Well, this depends on the context. Not if you pay attention not to redefine known macros. Whether or not someone ever bothered to provide a more fool-proof version of xdef I don't know. In case of doubt, one should of course check with @ifdefined whether a command is defined. If desired, I could try to cook up something along these lines, but there are others who can do that much better, so you might want to ask a separate question on this.
  • If you do a computation with, say, pgftruncatemacro you could broadcast the result with something of the sort pgfmathtruncatemacro{myresult}{4}xdefmyresult{myresult}
  • There exist situations, e.g. when playing with pgfkeys, when you cannot just use xdef. In these you could play around with globaldefs. However, I stress that I do not recommend doing this unless you are absolutely sure of what you're doing. (I used it once in an answer, but it really caused problems when the OP started to modify it, so I will be very very reluctant to go that route.

Here's an MWE.

documentclass{article}
usepackage{tikz}

newcommand{mycommand}
{
    defmyvar{0}
    defmyresult{3}
    ifnummyvar=0
    {
        xdefmyresult{4}
        draw (0,1) node {Test is true!};
    }
    fi
    draw (0,0) node {myresult=myresult !!!};
}

begin{document}

begin{tikzpicture}
mycommand
end{tikzpicture}

renewcommand{mycommand}
{
    defmyvar{0}
    globaldefmyresult{3}
    ifnummyvar=0
    {
        pgfmathtruncatemacro{myresult}{4}
        xdefmyresult{myresult}
    }
    fi
    draw (0,0) node {myresult=myresult !!!};
}

begin{tikzpicture}
mycommand
end{tikzpicture}
end{document}

enter image description here

Correct answer by user121799 on December 27, 2020

enter image description here

Your initial code was almost correct. The problem was triggered by too many unnecessary but harmful semicolumns.

Note that final semicolumns are used only to end TikZ command lines.

documentclass[11pt, border=1cm]{standalone}
usepackage{ifthen}
usepackage{tikz}

newcommand{mycommand}{%
  defmyvar{0}
  defmyresult{3}
  ifnummyvar=0 defmyresult{4}{
    draw (0,1) node {the test is {color{blue}True}};
  }
  fi
  {
    draw (0,0) node {and textit{myresult} is myresult};
  }
}

begin{document}

begin{tikzpicture}
  mycommand
end{tikzpicture}

end{document}

Answered by Daniel N on December 27, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP