3

Is it possible to create variables that can be defined using integers. I would create an example to work with but I have no idea how to start. Hopefully the snippet I have included makes sense.

% creates variables wk[1], wk[2], ... , wk[10]
\foreach \i in {1,2,...,10}{\newcommand\wk[\i]{}} 

% stores the value 'this is week 2' into \wk[2]
\wk[2]{this is week 2}

% outputs 'this is week 2'
\wk[2]
  • It would help if you stated the objective of this project; e.g., what you're trying to do with the elements of the wk string vector. It would also help if you stated which TeX engine you use: pdfLaTeX, XeLaTeX, LuaLaTeX, or something else? – Mico Dec 09 '18 at 07:26
  • Probably related: https://tex.stackexchange.com/questions/395752/numbers-lists-in-latex/395766#395766 –  Dec 09 '18 at 12:19

3 Answers3

2

Here's a simple version that makes use of the xparse package to define a new array-like command with a first parameter in square brackets and an optional second parameter in braces:

\documentclass{article}
\usepackage{xparse}
\usepackage{pgffor}

\newcommand\makearray[1]{%
    \expandafter\NewDocumentCommand\csname#1\endcsname{r[]g}{%
        \IfValueTF{##2}{%
            \expandafter\def\csname #1@##1\endcsname{##2}%
        }{%
            \csname #1@##1\endcsname
        }%
    }
}

\begin{document}
\makearray{wk}

\wk[1]{this is week 1}
\wk[3]{this is week 3}

\foreach \i in {1,2,3} {\wk[\i]\par}
\end{document}

You use it like

\makearray{name}

to define a new array command \name. Then your can use

\name[key]{value}

to set a value at position key, and

\name[key]

to output the stored value at position key. If no key was set before, the result is empty (or equal to \relax, to be more precise).

Thus, the output for the above example is

this is week 1
this is week 3

siracusa
  • 13,411
0

Since you seem to want it in contexts of loops, here's an implementation that allows arithmetic expressions in the argument.

I distinguish between the phases of setting and retrieving values. The syntax you propose disallows \wk being expandable, because one would have to check whether it is used for setting a value.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\wk}{m}
 {
  \prop_item:Nf \g_garth_week_prop { \int_eval:n { #1 } }
 }
\NewDocumentCommand{\setwk}{mm}
 {
  \prop_gput:Nfn \g_garth_week_prop { \int_eval:n { #1 } } { #2 }
 }

\cs_generate_variant:Nn \prop_item:Nn { Nf }
\cs_generate_variant:Nn \prop_gput:Nnn { Nf }

\prop_new:N \g_garth_week_prop

\ExplSyntaxOff

\setwk{2}{This is week two}
\setwk{2+1}{This is week three}

\begin{document}

\wk{2}

\wk{7-2*2}

\end{document}

enter image description here

Here is an abstraction layer that allows to define as many arrays as you want.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\NewArray}{m}
 {
  \prop_new:c { g_garth_#1_prop }
  \cs_new_protected:cpn { set#1 } ##1 ##2
   {
    \prop_gput:cfn { g_garth_#1_prop } { \int_eval:n { ##1 } } { ##2 }
   }
  \cs_new:cpn { #1 } ##1
   {
    \prop_item:cf { g_garth_#1_prop } { \int_eval:n { ##1 } }
   }
 }

\cs_generate_variant:Nn \prop_item:Nn { cf }
\cs_generate_variant:Nn \prop_gput:Nnn { cf }

\ExplSyntaxOff

\NewArray{wk}

\setwk{2}{This is week two}
\setwk{2+1}{This is week three}

\begin{document}

\wk{2}

\wk{7-2*2}

\end{document}
egreg
  • 1,121,712
0

Variables?

(La)TeX is a macro language with macro-expansion/replacement.

You have macros, registers and parameters.

You can use macros that don't process arguments as variables.

In any case you need to be aware of how macro-expansion works and about the order in time in which single expansion-steps and assignments are carried out.

I'd just use a macro \name which takes a sequence of tokens nested in curly braces for the name of a control-sequence-token and via \csname..\endcsname constructs/delivers that control-sequence-token while leaving things in place that possibly occur between \name and the opening-curly-brace.
That control-sequence-token in turn can be (re)defined to be a macro or can be expanded, just as you like:

\documentclass{article}
\usepackage{pgffor}

\newcommand\name{}\long\def\name#1#{\romannumeral0\innername{#1}}%
\newcommand\innername[2]{%
  \expandafter\exchange\expandafter{\csname #2\endcsname}{0 #1}%
}%
\newcommand\exchange[2]{#2#1}%

% This loop defines macros/control-word-tokens \wk[1], \wk[2], ... , \wk[10] 
% with "empty" replacement-text:
\foreach \i in {1,2,...,10}{%
   \name\newcommand*{wk[\i]}{}%
   % \foreach opens up a local scope. 
   % Thus we need to turn assignments restricted to that scope into global 
   % assignments:
   \name\name\global\let{wk[\i]}={wk[\i]}%
} %

\begin{document}

% This "stores the value 'this is week 2' into \wk[2]".
% Better: This redefines the macro \wk[2] to expand to the phrase "this is week 2".
\name\renewcommand*{wk[2]}{this is week 2}

% As there is nothing between \name and the opening brace, this just delivers the
% control-sequence-token \wk[2] which in turn gets expanded as usual while that
% expansion yields 'this is week 2':
\name{wk[2]}

% If eTeX-extensions are available, you can use \number\numexpr.. for calculations:
\name{wk[\number\numexpr(2*3)-5+1\relax]}

% this shows the definition/meaning of \wk[2] on the screen/in the .log-file:
%\name\show{wk[2]}

% this prints the meaning of \wk[2]
\texttt{\name\string{wk[2]}: \name\meaning{wk[2]}}

\end{document}
Ulrich Diez
  • 28,770