0

Is it possible to define a multipart variable and then check for its definition and use its multiple parts later? Here's what I mean:

\documentclass{article}
\usepackage{pgfplots}
\usepackage{etoolbox}

\begin{document}

    %Define macro
    \def\myMacro{

        %Check for multipart variable definition
        \ifdef{\VariableOne}{
            ##1

            ##2

            ##3 
        }{}

        #1
    }

    %Define multipart variable
    \def\VariableOne#1#2#3{
        {1}
        {2}
        {3}
    }
    \myMacro{4}
\end{document}

I know this task can be accomplished this way:

\documentclass{article}
\usepackage{pgfplots}
\usepackage{etoolbox}


\begin{document}
    \def\myMacro#1{
        \ifdef{\VariableOne}{   
            \foreach \x/\y/\z in \VariableOne{
                \x

                \y

                \z  
            }
        }{}

        #1
    }

    \def\VariableOne{1/2/3}

    \myMacro{4}
\end{document}

I also know that you could just pass in all of the variables to \myMacro, but I'm curious if this is doable using the methods in the first block of code.

10
  • You could use a property list or a clist of LaTeX3, but honestly I don't quite get your point: You want to know whether code that does not work works? – TeXnician May 25 '18 at 15:12
  • No, I want to know if there is a way to define a multipart variable like \VariableOne. – Kevin Gregory May 25 '18 at 15:18
  • it's a rather hard to guess the intended behaviour here, I thought you wanted to declare a macro holding a number of items and \mymacro{4} would select the 4th but your example only has three fields, so what is the intended behaviour of \mymaco{4}? – David Carlisle May 25 '18 at 15:29
  • The point of \myMacro is twofold: First, it checks to see if \VariableOne is defined, and if it is, the macro prints out the three parts of the variable. If \VariableOne isn't defined, it just moves on. Second, the macro just prints out the argument passed to it. In this case, just the 4. – Kevin Gregory May 25 '18 at 15:35
  • in your second "working" example the argument to myMacro isn't used at all other than printed out after the loop, you would get te same if you defined it to have no #1 argument at all, and just wrote \myMacro 4 – David Carlisle May 25 '18 at 15:38
2

Perhaps this snippet of code does what you want:

\documentclass{article}
%\usepackage{pgfplots}
\usepackage{etoolbox}

% \myMacro{<Tokens to spit out in case macro \VariableOne is undefined>}%
%         {<Tokens forming whatsoever "value">}%
%
% In case the macro \VariableOne is undefined, 
% <Tokens to spit out in case macro \VariableOne is undefined>
% trailed by <Tokens forming whatsoever "value">
% will be "spit out".
%
% Otherwise the expansion of \VariableOne which delivers 
% \VariableOne's three components will be delivered to the
% macro \ProcessVariableOnesThreeComponentsAndWhatsoeverValue
% which in turn will process these three components and the
% <Tokens forming whatsoever "value">.
\newcommand\myMacro[2]{%
  % Check whether macro holding vaule(s) of "multi-component variable"
  % is defined:
  \ifdef{\VariableOne}%
        {\expandafter\ProcessVariableOnesThreeComponentsAndWhatsoeverValue\VariableOne{#2}}%
        {#1#2}%
}%

\newcommand\ProcessVariableOnesThreeComponentsAndWhatsoeverValue[4]{%

  This is \texttt{\string\VariableOne}'s first component: 
  \texttt{#1}

  This is \texttt{\string\VariableOne}'s second component:
  \texttt{#2}

  This is \texttt{\string\VariableOne}'s third component:
  \texttt{#3}

  This is whatsoever value:
  \texttt{#4}

}%


\begin{document}

% To make \VariableOne undefined, \let it equal to an undefined token.
% \let\VariableOne=\UndFInEdVeRYBiZarReConTRoLWORd
At this stage, the "multi-component variable" is undefined:

\myMacro{The macro \texttt{\string\VariableOne} is undefined!}{Whatsoever Value}%


\hrulefill


% Now define/initialize "multi-component variable":
\newcommand\VariableOne{%
  {Component 1}%
  {Component 2}%
  {Component 3}%
}%

At this stage, the "multi-component variable" is defined:

\myMacro{The macro \texttt{\string\VariableOne} is undefined!}{Whatsoever Value}%

\end{document}

enter image description here

3

With a flexible syntax for allowing different ways to display the values. In the optional argument to \usevariable you use #1 for representing the current value; the default is #1\par.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\setvariable}{mm}
 {% #1 = variable name
  % #2 = comma separated list of values
  \seq_clear_new:c { l_kevin_multivar_#1_seq }
  \seq_set_from_clist:cn { l_kevin_multivar_#1_seq } { #2 }
 }

\NewDocumentCommand{\usevariable}{+omm}
 {% #1 = optional way to use the values (+ means that \par is allowed)
  % #2 = variable to use
  % #3 = tokens to be displayed after the values
  \seq_if_exist:cTF { l_kevin_multivar_#2_seq }
   {
    \group_begin:
    \IfValueT { #1 }
     {
      \cs_set:Nn \__kevin_multivar_use:n { #1 }
     }
    \seq_map_function:cN { l_kevin_multivar_#2_seq } \__kevin_multivar_use:n
    \group_end:
   }
   { !!~Variable~`#2'~not~defined~yet~!! }
   #3
 }

\cs_new:Nn \__kevin_multivar_use:n { #1 \par } % default action

\ExplSyntaxOff

\begin{document}

\usevariable{VariableOne}{Something}

\setvariable{VariableOne}{A,B,C}

\usevariable{VariableOne}{Something}

\usevariable[#1--]{VariableOne}{Something}

\end{document}

enter image description here

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.