0

This question is related to Execute list of commands generated by pairing elements from two \clist s or \seq s.

I am trying to perform a sequence of commands of the form

\def\alpha {^^^^03b1}

with \seq_\map_pairwise_function:ccN. I would prefer to pass in arguments in the form "03B1 rather than ^^^^03b1 and I think I have figured out how to do that. This code appears to function correctly.

\documentclass{article}
\usepackage{fontspec}
\usepackage{nopageno}

\newfontfamily\mathematica{Mathematica}[% NFSSFamily=mathematica,Scale=MatchUppercase,% Extension=.ttf,% UprightFont=,% BoldFont=-Bold] \DeclareSymbolFont{wm}{TU}{mathematica}{m}{n} \DeclareSymbolFont{wmb}{TU}{mathematica}{b}{n}

\ExplSyntaxOn

\Umathcode"03B1 = 0 \symwm "003B1 \Umathcode"03B2 = 0 \symwm "003B2

\NewDocumentCommand{\mapcommandfunction}{mm}{\cs_set:cpn {#1} {\codepoint_generate:nn{#2}{11}}}

\mapcommandfunction{alphatwo}{"03B1} \mapcommandfunction{beta}{"03B2}

\ExplSyntaxOff

\begin{document} $$\alphatwo\beta$$ \end{document}

(substitute your font of choice). But if I replace the code between \ExplSyntaxOn and \ExplSyntaxOff with

\Umathcode"03B1  = 0 \symwm  "003B1
\Umathcode"03B2  = 0 \symwm  "003B2

\NewDocumentCommand{\mapcommands}{mm} { \seq_set_from_clist:cc {cmds}{#1} \seq_set_from_clist:cc {chars}{#2} \seq_map_pairwise_function:ccN{cmds}{chars}{\mapcommandfunction} }

\NewDocumentCommand{\mapcommandfunction}{mm}{\cs_set:cpn {#1} {\codepoint_generate:nn{#2}{11}}}

\mapcommands{alphatwo,beta}{"03B1,"03B2}

I get the error shown in the title. I have no idea what I am doing wrong or how to discover it. More specifically, I get

! Missing \endcsname inserted.
<to be read again> 
                   \alphatwo,beta 
l.27 \mapcommands{alphatwo,beta}{"03B1,"03B2}

The control sequence marked <to be read again> should not appear between \csname and \endcsname.

How do I fix this?

  • 1
    \seq_set_from_clist:cc {cmds}{#1} has cc arguments, so both should be the name of a command, but you are passing in alphatwo,beta – David Carlisle Jul 23 '23 at 14:04
  • @DavidCarlisle Ahhh... Changed both to cn and it works! Thank you! – Mike Pugh Jul 23 '23 at 14:06
  • @DavidCarlisle Actually, in the larger program, I needed to change the second one back to cc to get it to work. I'm sure I don't understand the distinction. What is going on? – Mike Pugh Jul 23 '23 at 14:21

2 Answers2

3

You need to watch the argument specifications to control expansion.

The first version works but defines

> \alphatwo=\long macro:
->\codepoint_generate:nn {"03B1}{11}.
l.22 \show\alphatwo

so the codepoint lookup happens every time it is used.

If you use \cs_set:cpx the lookup happens just once:

> \alphatwo=\long macro:
->α.
l.22 \show\alphatwo

Personally I would have used \cs_set:Npx and used a syntax

\mapcommandfunction\alphatwo{"03B1}

as I don't see any advantage in using a name here rather than the token directly.

\documentclass{article}
\usepackage{fontspec}
\usepackage{nopageno}

\newfontfamily\mathematica[NFSSFamily=mathematica]{STIX Two Math}%

\DeclareSymbolFont{wm}{TU}{mathematica}{m}{n} \DeclareSymbolFont{wmb}{TU}{mathematica}{b}{n}

\ExplSyntaxOn

\Umathcode"03B1 = 0 \symwm "003B1 \Umathcode"03B2 = 0 \symwm "003B2

\NewDocumentCommand{\mapcommandfunction}{mm}{\cs_set:Npx #1 {\codepoint_generate:nn{#2}{11}}}

\mapcommandfunction\alphatwo{"03B1} \mapcommandfunction\beta{"03B2}

\ExplSyntaxOff

\show\alphatwo \begin{document} $$\alphatwo\beta$$ \end{document}

Similarly in the second version

\seq_map_pairwise_function:ccN

an N should be a single token so \mapcommandfunction not {\mapcommandfunction} although an expl3 name would be more idiomatic.

\seq_set_from_clist:cc the second c makes a csname from the whole of #1 so it is never used as a list.

\documentclass{article}
\usepackage{fontspec}
\usepackage{nopageno}

\newfontfamily\mathematica[NFSSFamily=mathematica]{STIX Two Math}%

\DeclareSymbolFont{wm}{TU}{mathematica}{m}{n} \DeclareSymbolFont{wmb}{TU}{mathematica}{b}{n}

\ExplSyntaxOn

\Umathcode"03B1 = 0 \symwm "003B1 \Umathcode"03B2 = 0 \symwm "003B2

\NewDocumentCommand{\mapcommands}{mm} { \seq_set_from_clist:Nn\l_cmds{#1} \seq_set_from_clist:Nn\l_chars{#2} \seq_map_pairwise_function:NNN\l_cmds\l_chars\mapcommandfunction }

\NewDocumentCommand{\mapcommandfunction}{mm}{\cs_set:Npx #1 {\codepoint_generate:nn{#2}{11}}}

\mapcommands{\alphatwo,\beta}{"03B1,"03B2}

\ExplSyntaxOff

\show\alphatwo \begin{document} $$\alphatwo\beta$$ \end{document}

David Carlisle
  • 757,742
  • I am not sure I would have gleaned these facts just from interface3.pdf. And while there are lots of examples on the web, you usually only get a piece of the puzzle at a time. Here, I got several at once. Thank you! – Mike Pugh Jul 23 '23 at 18:45
  • I do have another question, though. What happens if I attempt to pass in a command that has not yet been defined as, say, \koppa instead of koppa? – Mike Pugh Jul 23 '23 at 18:55
  • 1
    @MikePugh that works just as it's not an error to pass an undefined command to \newcommand as demonstrated here \alphatwo – David Carlisle Jul 23 '23 at 18:58
  • I don't know if this is something I should post as a separate question; if so, I will. I am getting errors like ! LaTeX Error: Command `\Gamma` already defined. for all the usually defined capital Greeks. I'm guessing this is coming indirectly from the .cls file. Is there a way to force redefinition? I have tried using \cs_undefine:N #1 inside the \mapcommandfunction just prior to \cs_set:Npx but that is either incorrect or doesn't work. – Mike Pugh Jul 23 '23 at 20:03
  • 1
    @MikePugh \usepackage[no-math]{fontspec} look at the location it is from \begin{document} not your code, no-math will fix – David Carlisle Jul 23 '23 at 20:06
0

I think that the specification with two separate clist that need to stay in sync will be hard to maintain and keep track of. Instead, I'd either suggest to drop the mapping variant and only use your \mapcommandfunction, or use key=value based input.

Also, just like @DavidCarlisle I don't see the advantage of inputting alphatwo instead of \alphatwo.

As a last note: Don't use $$ for displayed maths in LaTeX, instead use \[ and \], or the equation environment, or the amsmath environments. $$ can lead to inconsistent spacing and is not supported in LaTeX.

\documentclass{article}
\usepackage{fontspec}
\usepackage{nopageno}

\newfontfamily\mathematica{Mathematica}[% NFSSFamily=mathematica,Scale=MatchUppercase,% Extension=.ttf,% UprightFont=,% BoldFont=-Bold] \DeclareSymbolFont{wm}{TU}{mathematica}{m}{n} \DeclareSymbolFont{wmb}{TU}{mathematica}{b}{n}

\ExplSyntaxOn

\Umathcode"03B1 = 0 \symwm "003B1 \Umathcode"03B2 = 0 \symwm "003B2

\NewDocumentCommand{\mapcommandfunction}{mm}{\cs_set:Npn #1 {\codepoint_generate:nn{#2}{11}}}

\msg_new:nnn { mike-pugh } { missing-value } { Missing~ value~ for~ `#1'. } \NewDocumentCommand \mapcommands { m } { \keyval_parse:nnn { \msg_error:nnn { mike-pugh } { missing-value } } { \mapcommandfunction } {#1} }

\mapcommands{\alphatwo="03B1, \beta="03B2}

\ExplSyntaxOff

\begin{document} [\alphatwo\beta] \end{document}

Skillmon
  • 60,462