3

I want to save a variable value between calls of a macro, the intention being not to have to repeat a whole lot of parameters in successive calls. It all works as intended if in textmode. If I invoke mathmode individually for each call, i.e. $\myMacro$, which is what I want to do, the variable is reset for each call. Is there a workaround?

\documentclass{article}
\usepackage{xparse}
\usepackage{amsmath}
\ExplSyntaxOn
%   VARIABLE DECLARATIONS:
\tl_new:N \savevar_rn_tl
\tl_set:Nn \savevar_rn_tl {INIT}
\NewDocumentCommand\myMacro{O{1}O{Z}}   
{
    !*\tl_use:N \savevar_rn_tl*!        \\
    \str_case:nn {#1} 
        {
            {1}
            {
                #2\\        
                \tl_set:Nn \savevar_rn_tl {#2@#2}
            }
            {2}
            {
                \tl_use:N \savevar_rn_tl \\
                \tl_set:Nn \savevar_rn_tl {RESET}
            }
        }
}
\ExplSyntaxOff
\begin{document}
\section{The way I want to use it, but savevar is not preserved between calls:}
$\myMacro$\\
$\myMacro[2]$\\
$\myMacro[1][\alpha]$\\
$\myMacro[2]$\\
\section{savevar is preserved between calls, but only if calls are made in textmode:}
\myMacro\\
\myMacro[2]\\
\myMacro[1][W]\\
\myMacro[2]\\
\end{document} 
  • 1
    I think, this is an grouping issue. Use \tl_gset:Nn – user31729 Sep 13 '15 at 7:54
  • I'm not sure what's the purpose of saving the value Z as Z@Z. – egreg Sep 13 '15 at 9:30
  • @egreg Just for the purpose of the MWE - an easily recognisable value to see if it is preserved correctly. – Reinhard Neuwirth Sep 13 '15 at 10:06
  • Instead of two optional arguments, you could use \myMacro where you now use \myMacro[1] and \myMacro* for the “use and reset case”. This way you don't have to use [1] when you need the optional argument. So the calls would be $\myMacro$ $\myMacro*$ $\myMacro[\alpha]$ $\myMacro*$. – egreg Sep 13 '15 at 10:12
4

Switching to math mode enters a group, so \tl_set:Nn sets the value only within the group, but not outside. If the value should be preserved, \tl_gset:Nn (global set) has to be used.

The apparent 'reset' is just due to the fact that \savevar_rn_tl outside still has the value of the initial setting and the filling with #2@#2 is only locally, within the group.

\documentclass{article}
\usepackage{xparse}
\usepackage{amsmath}
\usepackage{mathtools}
\ExplSyntaxOn
%   VARIABLE DECLARATIONS:
\tl_new:N \g_savevar_rn_tl
\tl_set:Nn \g_savevar_rn_tl {INIT}
\NewDocumentCommand\myMacro{O{1}O{Z}}   
{
    !*\tl_use:N \g_savevar_rn_tl*!        \\
    \str_case:nn {#1} 
        {
            {1}
            {
                #2\\ 
                Value\space before:\tl_use:N \g_savevar_rn_tl \\
                \tl_gset:Nn \g_savevar_rn_tl {#2@#2}
                Value\space after:\tl_use:N \g_savevar_rn_tl \\
              }
            {2}
            {
              Before: \tl_use:N \g_savevar_rn_tl \\
              \tl_gset:Nn \g_savevar_rn_tl {RESET}
              Value: \tl_use:N \g_savevar_rn_tl \\
            }
        }
}
\ExplSyntaxOff
\begin{document}
\section{The way I want to use it, but savevar is not preserved between calls:}
$\myMacro$\\
$\myMacro[2]$\\
$\myMacro[1][\alpha]$\\
$\myMacro[1][\beta]$
\section{savevar is preserved between calls, but only if calls are made in textmode:}
\ExplSyntaxOn
\tl_clear:N \g_savevar_rn_tl
\ExplSyntaxOff
\myMacro[1][A]\\
\myMacro[2]\\
\myMacro[1][W]\\
\myMacro[2]\\
\end{document} 

enter image description here

  • 1
    The name of the variable should be \g_savevar_rn_tl (every variable should have either the g or the l prefix). – egreg Sep 13 '15 at 9:18
  • @egreg: Yes, agreed, but \tl_gset:Nn is needed anyway, I suppose? The \g_ is only a name convention – user31729 Sep 13 '15 at 9:20
  • 1
    Yes, of course, but the g_ prefix will also help in remembering what function to use. – egreg Sep 13 '15 at 9:22
  • @egreg: Yes, that's true. I changed it -- please bear me, I am still new in expl3 ;-) – user31729 Sep 13 '15 at 9:25
  • @ChristianHupfer Thanks, it is another step forward. – Reinhard Neuwirth Sep 13 '15 at 10:01

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.