Math & ScienceHow do I use a loop to generate a set of related control sequences

Information and discussion about LaTeX's math and science related features (e.g. formulas, graphs).
Post Reply
jlettvin
Posts: 4
Joined: Mon Oct 15, 2018 12:03 am

How do I use a loop to generate a set of related control sequences

Post by jlettvin »

This loop works beautifully for extracting data from the \Element text block.
However, the function definitions made within the loop disappear when the loop finishes.
Is there a way to make the newly defined control sequences permanent globally?

Code: Select all

\def\Element{
1   /   H   /   Hydrogen        /   +   /   1+,
11  /   Na  /   Sodium          /   +   /   1+,
17  /   Cl  /   Chlorine        /   -   /   1-,
19  /   K   /   Potassium       /   +   /   1+,
20  /   Ca  /   Calcium         /   ++  /   2+,
}

\foreach \Z/\atom/\name/\charge/\ions in \Element{
    \global\expandafter\def\csname ion\trimspaces\atom\endcsname{${\trimspaces\atom}^{\trimspaces\charge}$}
    \immediate\write16{def{ion\trimspaces\atom}{\csname ion\trimspaces\atom \endcsname}}
}

% Without using \ionH in the text, the output looks like this:
% def{ionH}{${H}^{+}$}

% With using \ionH like below, the following error is generated:
%! Undefined control sequence.
%<argument> \atom 
%
%l.3 \ionH

% uncomment the next line to see the error.
% \ionH

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org

NEW: TikZ book now 40% off at Amazon.com for a short time.

And: Currently, Packt sells ebooks for $4.99 each if you buy 5 of their over 1000 ebooks. If you choose only a single one, $9.99. How about combining 3 LaTeX books with Python, gnuplot, mathplotlib, Matlab, ChatGPT or other AI books? Epub and PDF. Bundle (3 books, add more for higher discount): https://packt.link/MDH5p

jlettvin
Posts: 4
Joined: Mon Oct 15, 2018 12:03 am

How do I use a loop to generate a set of related control sequences

Post by jlettvin »

The answer was to use xdef. :roll:

Code: Select all

% xdef defines the new control sequence in the global dictionary.
\foreach \Z/\atom/\name/\charge/\ions in \Element{
	\expandafter\xdef\csname
	ion\trimspaces\atom\endcsname{${\trimspaces\atom}^{\trimspaces\charge}$}
	\immediate\write16{def{ion\trimspaces\atom}{\csname ion\trimspaces\atom \endcsname}}
}
User avatar
Stefan Kottwitz
Site Admin
Posts: 10335
Joined: Mon Mar 10, 2008 9:44 pm

How do I use a loop to generate a set of related control sequences

Post by Stefan Kottwitz »

Hi,

welcome to the forum!

I would use \gdef or \global\def. Here it may not matter, it's just that \xdef is equivalent to \global\edef and \edef expands the arguments at running time.

Stefan
LaTeX.org admin
jlettvin
Posts: 4
Joined: Mon Oct 15, 2018 12:03 am

How do I use a loop to generate a set of related control sequences

Post by jlettvin »

Hi Stefan,

I have so many questions, it is hard to limit myself to the few that are most challenging.
In this case, I replaced xdef with gdef (which I had tried earlier) and this code failed.
I went back to xdef and it worked again. If you have a better alternative to xdef I will try it.
But, for now, xdef actually works and I don't see where argument expansion is a problem.
I have needs for other automated control sequence construction from data arrays.
Getting this right and re-using a "best" solution would be more satisfying.
So, what would you recommend?
Stefan Kottwitz wrote:Hi,

welcome to the forum!

I would use \gdef or \global\def. Here it may not matter, it's just that \xdef is equivalent to \global\edef and \edef expands the arguments at running time.

Stefan
rais
Posts: 419
Joined: Sun Nov 16, 2014 8:51 pm

How do I use a loop to generate a set of related control sequences

Post by rais »

Why, what's best depends on the context.
In the case above, \gdef isn't enough, because you've put two local variables into the argument of your constructed variable, in this case \atom and \charge, both of which are only valid inside this \foreach statement. That's why \xdef works here (because of its argument expansion, both of \atom and \charge get expanded) and \gdef doesn't work (because both of \atom and \charge are left in your constructed variable's definition, so outside this \foreach statement's, those two are lost---hence the error about \atom).
Which could lead to weird output, if you (or some package) globally define \atom and \charge somewhere (then you won't get an `undefined control sequence' error, but the result will most probably be wrong anyway without expansion).
OTOH, if the context changes, so may my answer ;)

KR
Rainer
jlettvin
Posts: 4
Joined: Mon Oct 15, 2018 12:03 am

How do I use a loop to generate a set of related control sequences

Post by jlettvin »

So, to be brutally clear,
are you saying that my code is a competent solution in this context?
If so, thank you for your explanations.
Otherwise, I need an alternative that would meet with approval.
Post Reply