Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I have a macro lVars, defined using foreach from the pgffor package (part of PGF) as:

\newcommand{\lVars}[1]{\foreach \x [count=\ii] in {#1}{
  \ifnum\ii=1{} \else {,} \fi \lVar[\x]}
}

The intended use is in terms like \exists \lVars{a, b, c, d}, which produces the result \exists \lVar[a], \lVar[b], \lVar[c], \lVar[d]. The command \lVar[a] is another custom command of the form \newcommand{\lVar}[1][x]{\textsc{#1}}, but may become more complex shortly. I then use the newly quantified \lVar elements inside larger forumlae.

However, I'm extremely lazy. I'd quite like this macro to expose each list element as a new command of the form \lA, \lB etc, which themselves expand to the actual underlying \lVar[A], \lVar[B].... These new commands would make my formula notation significantly less verbose. These new commands should last until the next time a, b,... are used in the list parameter to the lVars macro. So, the overall usage will be situations like:

\begin{displaymath}
  \begin{array}{l}
    \exists \lVars{a, b, c}.~ \lA = \lB \implies \lA = \lC \\
    \lC = 0 \implies \lA = 0
    \exists \lVars{a, b}.~ \lA \neq \lB
  \end{array}
\end{displaymath}

And, as we see in the term $\lA = \lB$, the implication...

I've experimented with various permutations on \newcommand and \def within the body of the foreach, without any luck. Any advice or tips?

share|improve this question
    
Can you please expand about the intended usage? –  egreg Apr 13 '13 at 16:32
    
@egreg Easily! I've added a rough example of how I'd expect to use it. If it's stupid idea, fair enough, but at the moment, I'm getting verbosity overload in my forumlae (which are rather more complex than my examples). –  Adam Wright Apr 13 '13 at 16:36
    
The tag foreach seems to be more appropriate –  Alain Matthes Apr 13 '13 at 19:25

1 Answer 1

up vote 3 down vote accepted
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\lVars}{m}
 {
  % cycle through the argument
  \clist_map_inline:nn { #1 }
   {
    % print the variable
    \lVar[##1]
    % if the variable is a, define \lA
    \tl_to_uppercase:n
     {
      \cs_gset_protected:cpn { \c_wright_prefix_tl ##1 }
     }
     { \lVar[##1] }
   }
 }
% We need to store the `l' prefix in a control sequence to hide it from \uppercase
\tl_const:Nn \c_wright_prefix_tl { l }
\ExplSyntaxOff

\newcommand{\lVar}[1][x]{\textsc{#1}}

\begin{document}
\begin{displaymath}
  \begin{array}{l}
    \exists \lVars{a, b, c}.~ \lA = \lB \implies \lA = \lC \\
    \lC = 0 \implies \lA = 0
    \exists \lVars{a, b}.~ \lA \neq \lB
  \end{array}
\end{displaymath}

And, as we see in the term $\lA = \lB$, the implication...
\end{document}

However, the definition of \lC will survive forever; if you plan to use it in different cells of an array a global definition is necessary.

enter image description here


A version that accepts multiletter variables and defines \lFoo from \lVars{foo}:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\lVars}{m}
 {
  % cycle through the argument
  \clist_map_inline:nn { #1 }
   {
    % print the variable
    \lVar[##1]
    % build the name with the first letter uppercase
    \wright_make_var_name:n { ##1 }
    \cs_gset_protected:cpn { \l__wright_var_name_tl } { \lVar[##1] }
   }
 }
\tl_const:Nn \c_wright_prefix_tl { l }
\cs_new:Npn \wright_make_var_name:n #1
 {
  % get the first letter and uppercase it
  \tl_to_uppercase:n
   {
    \tl_set:Nx \l__wright_var_name_tl { \tl_head:n {#1} }
   }
  % add the rest
  \tl_put_right:Nx \l__wright_var_name_tl { \tl_tail:n {#1} }
  % add the prefix
  \tl_put_left:Nx \l__wright_var_name_tl { \c_wright_prefix_tl }
 }
\ExplSyntaxOff
\newcommand{\lVar}[1][x]{\textsc{#1}}

\begin{document}
\begin{displaymath}
  \begin{array}{l}
    \exists \lVars{a, b, c}.~ \lA = \lB \implies \lA = \lC \\
    \lC = 0 \implies \lA = 0
    \exists \lVars{a, b}.~ \lA \neq \lB
  \end{array}
\end{displaymath}

And, as we see in the term $\lA = \lB$, the implication...

Now $\forall\lVars{foo}\;\lFoo=0$
\end{document}

enter image description here

share|improve this answer
    
That's lovely, thanks! Just to be a pain, is there any way to combine it with the work in tex.stackexchange.com/questions/7992/… to make the upper-casing only apply to the first letter of each variable? So that \lVars{a, b, foo} defines \lA, \lB and \lFoo? I think I need to learn this xparse package! –  Adam Wright Apr 13 '13 at 17:14
1  
@AdamWright Your wish is my command. ;-) –  egreg Apr 13 '13 at 17:39
    
Thanks so much. My fingers will be eternally grateful :) –  Adam Wright Apr 13 '13 at 18:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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