0

This is actually a more general question, but since a MWE is almost universally called for, consider David Carlisle's code

\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}

in his answer to one of my previous questions: https://tex.stackexchange.com/a/691806/224317. To make this code do everything I would like it to do, there needs to be a companion function called \mapcodes that maps standard codes like "03B1 for a Greek alpha to the slot location in the specific font. The only essential difference is that it needs to include a third argument containing the font family and probably needs to accept a different type specifier in the first argument. A working version of that is provided by egreg here: https://tex.stackexchange.com/a/691747/224317. Now, for the tricky part and the gist of the question.

I would like both of these functions to be able to take single arguments as well as comma-separated lists where applicable. As long as the list is provided "inline", I think they will work as is. I know for a fact that

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

causes no problem, for instance. I presume the second usage is treated as a list of length one. But I also would like to be able to create and name lists with commands of the form

\DeclareCommandList{GreekCommands}{\alpha,\beta,\gamma,\delta}
\DeclareCodeList{GreekCodes}{"03B1,"03B2,"03B3,"03B4}

analogous to \defineblock in egreg's answer and then pass them as follows:

\mapcommands{GreekCommands}{GreekCodes}

I have experimented, but being new to expl3 and still a little rough in my understanding of the underlying TeX expansion mechanism, I have not yet achieved success. I am guessing there is either (a) a way to take a generalized argument and then determine its nature, doing something applicable with each case, or (b) a way to do something equivalent to function overloading. It appears that expl3 may provide something like this with variants in the l3expan package, but I'm not sure. So while I would like to solve this specific problem, I would also like to understand the differences in these two calling mechanisms in general, how to deal with them, tips for troubleshooting, and so forth.

  • \seq_set_from_clist:Ne\l_cmds{#1} would expand #1 before treating it as a list (you may need to generate that variant) but then unlike the current version, undefined commands would be an error, you need to choose what behaviour you want – David Carlisle Jul 26 '23 at 12:57
  • function overloading really goes against the tex (and L3) model which is why L3 is always explicit about argument types \seq_map_pairwise_function:NNN and \seq_map_pairwise_function:nnN are essentially overloaded signatures of the same base function but they are separate names distinguished in the call – David Carlisle Jul 26 '23 at 12:59
  • @DavidCarlisle Assuming that I can unravel how to generate the variant you mention in your first comment, given that you're saying passing in, say, \koppa when it has not been defined would cause an error, would this new problem be remedied by passing in koppa instead and then defining the command with \cs_set? – Mike Pugh Jul 26 '23 at 16:11
  • \cs_generate_variant:Nn\seq_set_from_clist:Nn{Ne} should work, yes if you ensure your lists are expandable, but seems more trouble to do that than simply have two commands – David Carlisle Jul 26 '23 at 16:15
  • I'm sure I already commented that, but: DO NOT USE $$ TO START DISPLAY MATH IN LATEX!!! And please don't show it in MWEs. This way it only spreads further :( – Skillmon Jul 26 '23 at 18:46
  • @Skillmon I assure you that outside of this MWE, which I originally slapped together at someone else's request, I ABSOLUTELY NEVER, NEVER, NEVER use $$ $$ for math. Most of the time, I use the align* environment and occasionally \[ \]. – Mike Pugh Jul 26 '23 at 19:15
  • @MikePugh and I believe you, but please, don't use it in LaTeX MWEs. Simply use \[...\] instead. – Skillmon Jul 26 '23 at 19:16

1 Answers1

1

The following adds the two macros and support for them to your MWE.

The support is added by introducing two optional stars, if either star is given the next mandatory argument is considered as a named list input instead of a comma separated list.

We could also not require the stars, and instead check whether such a list exists, if you need help with that just leave a comment.

\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 \Umathcode"03B3 = 0 \symwm "003B3 \Umathcode"03B4 = 0 \symwm "003B4

\msg_new:nnn { mike-pugh } { unknown-cmd-list } { The~ named~ cmd~ list~ #1'~ is~ unknown.~ Make~ sure~ you~ defined~ it. } \msg_new:nnn { mike-pugh } { unknown-char-list } { The~ named~ char~ list~#1'~ is~ unknown.~ Make~ sure~ you~ defined~ it. } \seq_new:N \l__mikepugh_cmds_seq \seq_new:N \l__mikepugh_chars_seq \NewDocumentCommand \mapcommands { s m s m } { \IfBooleanTF {#1} { \seq_if_exist:cTF { l__mikepugh_cmds_ \tl_to_str:n {#2} seq } { \seq_set_eq:Nc \l__mikepugh_cmds_seq { l__mikepugh_cmds \tl_to_str:n {#2} seq } } { \msg_error:nnn { mike-pugh } { unknown-cmd-list } {#2} } } { \seq_set_from_clist:Nn \l__mikepugh_cmds_seq {#2} } \IfBooleanTF {#3} { \seq_if_exist:cTF { l__mikepugh_chars \tl_to_str:n {#4} seq } { \seq_set_eq:Nc \l__mikepugh_chars_seq { l__mikepugh_chars \tl_to_str:n {#4} _seq } } { \msg_error:nnn { mike-pugh } { unknown-char-list } {#2} } } { \seq_set_from_clist:Nn \l__mikepugh_chars_seq {#4} } \seq_map_pairwise_function:NNN \l__mikepugh_cmds_seq \l__mikepugh_chars_seq \mapcommandfunction }

\NewDocumentCommand \DeclareCommandList { m m } { \seq_clear_new:c { l__mikepugh_cmds_ \tl_to_str:n {#1} seq } \seq_set_from_clist:cn { l__mikepugh_cmds \tl_to_str:n {#1} seq } {#2} } \NewDocumentCommand \DeclareCodeList { m m } { \seq_clear_new:c { l__mikepugh_chars \tl_to_str:n {#1} seq } \seq_set_from_clist:cn { l__mikepugh_chars \tl_to_str:n {#1} _seq } {#2} }

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

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

\DeclareCommandList{GreekCommands}{\alpha,\gamma,\delta} \DeclareCodeList{GreekCodes}{"03B1,"03B3,"03B4} \mapcommands{GreekCommands}{GreekCodes}

\ExplSyntaxOff

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

Skillmon
  • 60,462