0

I would like to create a macro which helps in combining gls-symbols. Each compound symbol should consist of a body and (optionally) a super and subscript (which are itself gls symbols and get listed in different list of symbols for sub/superscripts). Furthermore, I would like to add custom arguments for some of the compound symbols. One example of what I would like to achieve: enter image description here

The following is my problem:

  1. To make sure, that the sub/superscripts that get added after the compound are being added to the "compound" sub/superscripts, I need to use the embellishments functionality from xparse as the last two parameters of my defined macro (E{^_}{{}{}})
  2. Since I do not know in advance how many custom arguments are added via args= I do not know which parameter number the embellishments will have (i.e. I have to count the number of arguments and add the parameter numbers dynamically).

I came up with the following code (which does not work). I think the main issue here is the correct expansion such that the variables that hold the parameter numbers for the embellishments (\l_compound_supparameter_tl and \l_compound_subparameter_tl) are expanded before the macro is finally defined. Furthermore, I could only pass comma separated argument specifications to args.

\documentclass[margin=5mm]{standalone}

\usepackage[symbols]{glossaries}
\newglossaryentry{body}{
    type=symbols,
    name={body},
    symbol={B},
    description={A body.}
}
\newglossaryentry{phase}{
    type=symbols,
    name={phase},
    symbol={\alpha},
    description={A material phase.}
}
\newglossaryentry{index}{
    type=symbols,
    name={index},
    symbol={i},
    description={A body index.}
}

\ExplSyntaxOn

% Define the keys
\keys_define:nn { my/glscompound }{
    body        .tl_set:N = \l_compound_body_tl,
    args        .tl_set:N = \l_compound_args_tl,
    superscript .tl_set:N = \l_compound_superscript_tl,
    superscript .initial:n = {},
    subscript   .tl_set:N = \l_compound_subscript_tl,
    subscript   .initial:n = {},
}

\tl_new:N \l_compound_supparameter_tl  % stores the macro parameter for superscript (e.g. #3)
\tl_new:N \l_compound_subparameter_tl  % stores the macro parameter for subscript (e.g. #4)

\cs_generate_variant:Nn \exp_args:Nnnx { NnVx }

\NewDocumentCommand{\NewGlsCompound}{ m m }{
    \tl_clear:N \l_compound_body_tl
    \tl_clear:N \l_compound_args_tl
    \tl_clear:N \l_compound_superscript_tl
    \tl_clear:N \l_compound_subscript_tl
    \tl_set:Nn \l_compound_supparameter_tl { # }
    \tl_set:Nn \l_compound_subparameter_tl { # }

    \keys_set:nn { my/glscompound } { #2 }

    % convert tl to sequence of arguments
    \seq_set_split:NnV \l_tmpa_seq { , } \l_compound_args_tl

    % get the count of the seq to determine the number of custom arguments
    \int_set:Nn \l_tmpa_int { \seq_count:N \l_tmpa_seq }

    % parameter number of superscript
    \int_incr:N \l_tmpa_int 
    \tl_put_right:NV \l_compound_supparameter_tl \l_tmpa_int

    % parameter number of subscript
    \int_incr:N \l_tmpa_int 
    \tl_put_right:NV \l_compound_subparameter_tl \l_tmpa_int

    % convert the arument seq to a single tl
    \tl_set:No \l_compound_args_tl { \seq_use:Nn \l_tmpa_seq { , } }

    % append the sub/superscript arguments
    \tl_put_right:Nn \l_compound_args_tl { ~E{^_}{{}{}} }

    % Define the new command
    \exp_args:NnVx \NewDocumentCommand {#1} \l_compound_args_tl {
        \l_compound_body_tl

        % superscript

        % evaluated during runtime, if an additional superscript as parameter
        % '\l_compound_supparameter_tl' is given
        \IfValueT{ \l_compound_supparameter_tl }{ 
            % append the custom superscript to the body of the compound superscript
            \tl_put_right:Nn \l_compound_superscript_tl { \l_compound_supparameter_tl } 
        }
        % if the body of the superscript is not empty, call the superscript macro
        \tl_if_blank:VF \l_compound_superscript_tl { \sp{ \l_compound_superscript_tl } } 
        
        % subscript (same as superscript)
        \IfValueT{ \l_compound_supparameter_tl }{ 
            \tl_put_right:Nn \l_compound_subscript_tl { \l_compound_supparameter_tl }
        }
        \tl_if_blank:VF \l_compound_subscript_tl { \sb{ \l_compound_subscript_tl } }
    }
}
\ExplSyntaxOff

\NewGlsCompound{\Body}{
    body = { \glssymbol{body} },
    args = { O{arg1}, O{arg2} }, % this is comma separated list of arguments
    superscript = { \glssymbol{phase},#1 },
    subscript   = { \glssymbol{index},#2 },
}

\begin{document}
\begin{minipage}{.7\textwidth}
\renewcommand{\arraystretch}{1.5}
\begin{tabular}{l l}
    \verb+\Body+                &\(\rightarrow \Body\)\\
    \verb+\Body^{,a}_{,y}+      &\(\rightarrow \Body^{,a}_{,y}\)\\
    \verb+\Body[foo]+           &\(\rightarrow \Body[foo]\)\\
    \verb+\Body[foo]^{,x}+      &\(\rightarrow \Body[foo]^{,x}\)\\
    \verb+\Body[foo][bar]^{,x}+ &\(\rightarrow \Body[foo][bar]^{,x}\)
\end{tabular}
\end{minipage}
\end{document}

If you could help me with that expansion-mess, I would be very thankful!

2
  • I haven’t tested your code, but at least the #’s would die horribly. Should those be #1 or #2 or something? Anyway, what you are trying to achieve sounds a lot like SemanTeX, though the syntax is slightly different (disclaimer: I am the author of that package).
    – Gaussler
    Jan 11 at 15:18
  • 1
    After processing how many arguments are required by the user, I will add the correct parameter numbers to the #'s. E.g. if you ask for two arguments, the embellishments need to be #3 and #4. However, according to the error messages, you seem to be right and the #3 and #4 are not properly detected as macro arguments but as plain text... this is the expansion that I cannot handle right now. I will definitely have a look at SemanTeX. Thanks for the tip!
    – Wulle
    Jan 11 at 17:09

1 Answer 1

1
  • First of all you need a routine for counting the amount of arguments specified by an xparse-argument-signature.

    In the example below, this is the routine \MYSTUFF_xparse_arg_signature_count:n.

    I wrote it by plagiarizing the code of the routine \__cmd_split_signature:n described in the commented LaTeX 2ε Sources, File g: ltcmd.dtx Date: 2023-08-19 Version v1.2a, section "1.7.2 Showing the definition of a command".

    The routine \MYSTUFF_xparse_arg_signature_count:n takes an argument which is to form an x-parse-argument-signature for an instance of \NewDocumentCommand.
    The routine after two expansion-steps returns a sequence of digit tokens denoting the amount of arguments specified by the x-parse-argument-signature in decimal notation.

  • Another issue night be getting underscore (_) of category 8(subscript) into the embellishment specification of the E-type argument of the command defined by \NewGlsCompound when defining \NewGlsCompound while \ExplSyntaxOn is in effect so that undescore has category code 11(letter).

This is how I might go about it:

%\errorcontextlines=10000
\ExplSyntaxOn
%-------------------------------------------------------------------------------
\cs_new:Nn \MYSTUFF_xparse_arg_signature_count:n 
  {
    \exp:w \exp_after:wN \exp_after:wN \exp_after:wN \exp_end:
    \int_eval:n
      {
        0 \__MYSTUFF_xparse_arg_signature_count_loop:Nw #1 
        \q_recursion_tail \q_recursion_stop
      }
  }
\cs_new:Npn \__MYSTUFF_xparse_arg_signature_count_loop:Nw #1
  {
    \quark_if_recursion_tail_stop:N #1
    \tl_if_exist:cTF
      { c_MYSTUFF_xparse_map_arg_type_to_argclass_\tl_to_str:n{#1}_tl }
      {
        \tl_use:c
          { c_MYSTUFF_xparse_map_arg_type_to_argclass_\tl_to_str:n{#1}_tl }
      }
      { +1 \__MYSTUFF_xparse_arg_signature_count_loop:Nw }
  }
\cs_set:Npn \__cmd_tmp:w #1 #2
  {
    \quark_if_nil:nF
      {#1}
      { 
        \tl_const:cn { c_MYSTUFF_xparse_map_arg_type_to_argclass_#1_tl } {#2} 
        \__cmd_tmp:w 
      }
  }
\__cmd_tmp:w
  t{\__MYSTUFF_xparse_arg_remove_arg_specification_of_class_delim:w}
  r{\__MYSTUFF_xparse_arg_remove_arg_specification_of_class_delims:w}
  d{\__MYSTUFF_xparse_arg_remove_arg_specification_of_class_delims:w}
  R{\__MYSTUFF_xparse_arg_remove_arg_specification_of_class_delims_opt:w}
  D{\__MYSTUFF_xparse_arg_remove_arg_specification_of_class_delims_opt:w}
  O{\__MYSTUFF_xparse_arg_remove_arg_specification_of_class_opt:w}
  e{\__MYSTUFF_xparse_arg_remove_arg_specification_of_class_e:w}
  E{\__MYSTUFF_xparse_arg_remove_arg_specification_of_class_E:w}
  +{\__MYSTUFF_xparse_arg_remove_arg_specification_of_class_prefix:w}
  !{\__MYSTUFF_xparse_arg_remove_arg_specification_of_class_prefix:w}
  >{\__MYSTUFF_xparse_arg_remove_arg_specification_of_class_processor:w}
  ={\__MYSTUFF_xparse_arg_remove_arg_specification_of_class_processor:w}
  \q_nil \q_nil
  %------------
\cs_new:Npn \__MYSTUFF_xparse_arg_remove_arg_specification_of_class_delim:w
            #1
            { +1 \__MYSTUFF_xparse_arg_signature_count_loop:Nw }
\cs_new:Npn \__MYSTUFF_xparse_arg_remove_arg_specification_of_class_delims:w
            #1 #2
            { +1 \__MYSTUFF_xparse_arg_signature_count_loop:Nw }
\cs_new:Npn \__MYSTUFF_xparse_arg_remove_arg_specification_of_class_delims_opt:w
            #1 #2 #3
            { +1 \__MYSTUFF_xparse_arg_signature_count_loop:Nw }
\cs_new:Npn \__MYSTUFF_xparse_arg_remove_arg_specification_of_class_opt:w
            #1
            { +1 \__MYSTUFF_xparse_arg_signature_count_loop:Nw }
\cs_new:Npn \__MYSTUFF_xparse_arg_remove_arg_specification_of_class_e:w
            #1
            { +\tl_count:n{#1} \__MYSTUFF_xparse_arg_signature_count_loop:Nw }
\cs_new:Npn \__MYSTUFF_xparse_arg_remove_arg_specification_of_class_E:w
            #1 #2
            { +\tl_count:n{#1} \__MYSTUFF_xparse_arg_signature_count_loop:Nw }
\cs_new:Npn \__MYSTUFF_xparse_arg_remove_arg_specification_of_class_prefix:w
            { \__MYSTUFF_xparse_arg_signature_count_loop:Nw }
\cs_new:Npn \__MYSTUFF_xparse_arg_remove_arg_specification_of_class_processor:w
            #1
            { \__MYSTUFF_xparse_arg_signature_count_loop:Nw }
%-------------------------------------------------------------------------------
\cs_if_exist:NF \IfBlankF { \cs_new_eq:NN \IfBlankF \tl_if_blank:nF }
\cs_if_exist:NF \IfBlankT { \cs_new_eq:NN \IfBlankT \tl_if_blank:nT }
\cs_if_exist:NF \IfBlankTF { \cs_new_eq:NN \IfBlankTF \tl_if_blank:nTF }
%-------------------------------------------------------------------------------
\tl_new:N \l_MYSTUFF_GLSCOMPOUND_body_tl
\tl_new:N \l_MYSTUFF_GLSCOMPOUND_args_tl
\tl_new:N \l_MYSTUFF_GLSCOMPOUND_superscript_tl
\tl_new:N \l_MYSTUFF_GLSCOMPOUND_subscript_tl
\tl_new:N \l_MYSTUFF_GLSCOMPOUND_supparameter_tl
\tl_new:N \l_MYSTUFF_GLSCOMPOUND_subparameter_tl
%-------------------------------------------------------------------------------
\keys_define:nn { MYSTUFF/GLSCOMPOUND }{
  body.tl_set:N = \l_MYSTUFF_GLSCOMPOUND_body_tl,
  args.tl_set:N = \l_MYSTUFF_GLSCOMPOUND_args_tl,
  superscript.tl_set:N = \l_MYSTUFF_GLSCOMPOUND_superscript_tl,
  subscript.tl_set:N = \l_MYSTUFF_GLSCOMPOUND_subscript_tl,
}
% ------------------------------------------------------------------------------
% Use expl3-infrastructure for providing error-message in case the key
% "body" is not specified in the 2nd argument of \NewGlsCompound.
% ..............................................................................
\prop_gput:Nnn \g_msg_module_type_prop { MYSTUFF_GLSCOMPOUND } {}
\prop_gput:Nnn
  \g_msg_module_name_prop
  { MYSTUFF_GLSCOMPOUND } 
  {Macro-Defined-In-Preamble:}
\msg_new:nnnn {MYSTUFF_GLSCOMPOUND} 
              {No Value specified}
              {Macro~#1:~No~value~for~key~"#3"~specified.}
              {In~the~#2~argument~a~value~for~key~"#3"~must~be~specified~%
               when~calling~macro~#1.}
\cs_new:Npn \NoValueSpecifiedError #1#2#3 {
  \exp_args:Nne \use:nn {
    \msg_error:nnnnn {MYSTUFF_GLSCOMPOUND} {No Value specified}
   }{{\iow_char:N \\ \cs_to_str:N#1}}{#2}{#3}
}%
%-------------------------------------------------------------------------------
% In order to get _ of category 8(subscript) and ^ of category 7(superscript)
% into the embellishment specification of the E-type argument of the command
% defined via \NewGlsCompound, define a scratch variant of \NewGlsCompound
% which as arguments grabs these tokens and redefines itself.
\group_begin:
\cs_set:Npn \NewGlsCompound #1#2
  {
    \group_end:
    \NewDocumentCommand \NewGlsCompound {mm} {
      \group_begin:
      \exp_args:Nnx \keys_set:nn { MYSTUFF/GLSCOMPOUND } { 
        body={\exp_not:o{\c_novalue_tl}},
        args={},
        superscript={},
        subscript={}
      }
      \keys_set:nn { MYSTUFF/GLSCOMPOUND } { ##2 }
      \exp_args:NV \tl_if_novalue:nTF
        \l_MYSTUFF_GLSCOMPOUND_body_tl
        { \group_end: \NoValueSpecifiedError{\NewGlsCompound}{second}{body} }
        {
          \tl_set:Nf \l_MYSTUFF_GLSCOMPOUND_supparameter_tl 
            {
              \int_eval:n
                {
                  \exp_args:No \MYSTUFF_xparse_arg_signature_count:n
                               {\l_MYSTUFF_GLSCOMPOUND_args_tl} + 1 
                } 
            }
          \tl_set:Nf \l_MYSTUFF_GLSCOMPOUND_subparameter_tl
            {
              \int_eval:n
                {
                  \tl_use:N \l_MYSTUFF_GLSCOMPOUND_supparameter_tl + 1
                }
            }
          \tl_put_left:Nn \l_MYSTUFF_GLSCOMPOUND_supparameter_tl {####}
          \tl_put_left:Nn \l_MYSTUFF_GLSCOMPOUND_subparameter_tl {####}
          \tl_put_right:Nn \l_MYSTUFF_GLSCOMPOUND_args_tl { E{#1#2}{{}{}} }
          \__MYSTUFF_GLSCOMPOUND_set_scriptdirective_to_tokenlist:NNN
              \l_MYSTUFF_GLSCOMPOUND_superscript_tl
              \l_MYSTUFF_GLSCOMPOUND_supparameter_tl
              #1
          \__MYSTUFF_GLSCOMPOUND_set_scriptdirective_to_tokenlist:NNN
              \l_MYSTUFF_GLSCOMPOUND_subscript_tl
              \l_MYSTUFF_GLSCOMPOUND_subparameter_tl
              #2
          \exp_args:Nnx 
            \use:nn 
            { \group_end: \NewDocumentCommand {##1} }
            {
              { \exp_not:o{\l_MYSTUFF_GLSCOMPOUND_args_tl} }
              {
                \exp_not:o{ \l_MYSTUFF_GLSCOMPOUND_body_tl}
                \exp_not:o{\l_MYSTUFF_GLSCOMPOUND_superscript_tl}
                \exp_not:o{\l_MYSTUFF_GLSCOMPOUND_subscript_tl} 
              }
            }
        }
    }
  }
\char_set_catcode_math_superscript:N \^
\char_set_catcode_math_subscript:N \_
\NewGlsCompound{^}{_}
% Scratch-\NewGlsCompound im the line above does 
% \group_end:
%--------------------
\cs_new:Nn \__MYSTUFF_GLSCOMPOUND_set_scriptdirective_to_tokenlist:NNN
  {
    % #1 = \l_MYSTUFF_GLSCOMPOUND_superscript_tl / 
    %      \l_MYSTUFF_GLSCOMPOUND_subscript_tl
    % #2 = \l_MYSTUFF_GLSCOMPOUND_supparameter_tl /
    %      \l_MYSTUFF_GLSCOMPOUND_subparameter_tl
    % #3 = _ (subscript) or  ^ (subscript)
    \__MYSTUFF_GLSCOMPOUND_set_scriptdirective_to_tokenlist:NVVN#1#1#2#3
  }
\cs_new:Nn \__MYSTUFF_GLSCOMPOUND_set_scriptdirective_to_tokenlist:NnnN
  {
    % #1 = \l_MYSTUFF_GLSCOMPOUND_superscript_tl /
    %      \l_MYSTUFF_GLSCOMPOUND_subscript_tl
    % #2 = content of \l_MYSTUFF_GLSCOMPOUND_superscript_tl /
    %      content of \l_MYSTUFF_GLSCOMPOUND_subscript_tl
    % #3 = content of \l_MYSTUFF_GLSCOMPOUND_supparameter_tl /
    %      content of \l_MYSTUFF_GLSCOMPOUND_subparameter_tl
    % #4 = _ (subscript) or  ^ (subscript)
    \tl_if_blank:nTF{#2}
      {
        \tl_set:Nn
          #1 
          { 
            \tl_if_blank:oF 
              {
                \exp:w
                \tl_if_blank:nTF{#3}{\use:n}{\use_ii_i:nn{#3}}{\exp_end:} 
              }
              {
                #4
                {
                  \exp:w
                  \tl_if_blank:nTF{#3}{\use:n}{\use_ii_i:nn{#3}}{\exp_end:}
                }
              }
          }
      }
      {
        \tl_set:Nn
          #1
          { 
            \tl_if_blank:oF
              {
                \exp:w 
                \tl_if_blank:nTF{#3}{\use:n}{\use_ii_i:nn{,#3}}{\exp_end:#2}
              }
              {
                #4
                {
                  \exp:w
                  \tl_if_blank:nTF{#3}{\use:n}{\use_ii_i:nn{,#3}}{\exp_end: #2}
                }
              }
          }
      }
  }
\cs_generate_variant:Nn
  \__MYSTUFF_GLSCOMPOUND_set_scriptdirective_to_tokenlist:NnnN
  { NVVN }
\ExplSyntaxOff


\documentclass[margin=5mm]{standalone}

\usepackage{array}

\usepackage[symbols]{glossaries}
\newglossaryentry{body}{
    type=symbols,
    name={body},
    symbol={B},
    description={A body.}
}
\newglossaryentry{phase}{
    type=symbols,
    name={phase},
    symbol={\alpha},
    description={A material phase.}
}
\newglossaryentry{index}{
    type=symbols,
    name={index},
    symbol={i},
    description={A body index.}
}

\NewGlsCompound{\Body}{
  body = {\glssymbol{body}},
  args = {O{arg1} O{arg2}}, 
  superscript = {\glssymbol{phase}\IfBlankF{#1}{,#1}},
  subscript   = {\glssymbol{index}\IfBlankF{#2}{,#2}}
}

%\NewGlsCompound{\Stuff}{
%%  body = {stuff},
%  args = { }, 
%  superscript = {up},
%  subscript   = {down}
%}

\begin{document}

\begin{minipage}{\textwidth}
%  \(\Stuff^{2up}_{2down}\) \par\bigskip
\renewcommand{\arraystretch}{1.5}
\begin{tabular}{l>{\(\rightarrow\)}c>{\(}l<{\)}}
\verb|\Body|&&\Body\\
\verb|\Body[foo]|&&\Body[foo]\\
\verb|\Body[foo][bar]|&&\Body[foo][bar]\\
\verb|\Body^{X}|&&\Body^{X}\\
\verb|\Body[foo]^{X}|&&\Body[foo]^{X}\\
\verb|\Body[foo][bar]^{X}|&&\Body[foo][bar]^{X}\\
\verb|\Body_{Y}|&&\Body_{Y}\\
\verb|\Body[foo]_{Y}|&&\Body[foo]_{Y}\\
\verb|\Body[foo][bar]_{Y}|&&\Body[foo][bar]_{Y}\\
\verb|\Body^{X}_{Y}|&&\Body^{X}_{Y}\\
\verb|\Body[foo]^{X}_{Y}|&&\Body[foo]^{X}_{Y}\\
\verb|\Body[foo][bar]^{X}_{Y}|&&\Body[foo][bar]^{X}_{Y}\\
\multicolumn{3}{l}{Behavior when specifying optional arguments blank:}\\
\verb|\Body[ ]|&&\Body[ ]\\
\verb|\Body[ ][ ]|&&\Body[ ][ ]\\
\verb|\Body[ ]^{X}|&&\Body[ ]^{X}\\
\verb|\Body[ ][ ]^{X}|&&\Body[ ][ ]^{X}\\
\verb|\Body[ ]_{Y}|&&\Body[ ]_{Y}\\
\verb|\Body[ ][ ]_{Y}|&&\Body[ ][ ]_{Y}\\
\verb|\Body[ ]^{X}_{Y}|&&\Body[ ]^{X}_{Y}\\
\verb|\Body[ ][ ]^{X}_{Y}|&&\Body[ ][ ]^{X}_{Y}\\
\multicolumn{3}{l}{Behavior when specifying embellishments blank:}\\
\verb|\Body^{ }|&&\Body^{ }\\
\verb|\Body[foo]^{ }|&&\Body[foo]^{ }\\
\verb|\Body[foo][bar]^{ }|&&\Body[foo][bar]^{ }\\
\verb|\Body_{ }|&&\Body_{ }\\
\verb|\Body[foo]_{ }|&&\Body[foo]_{ }\\
\verb|\Body[foo][bar]_{ }|&&\Body[foo][bar]_{ }\\
\verb|\Body^{ }_{ }|&&\Body^{ }_{ }\\
\verb|\Body[foo]^{ }_{ }|&&\Body[foo]^{ }_{ }\\
\verb|\Body[foo][bar]^{ }_{ }|&&\Body[foo][bar]^{ }_{ }\\
\multicolumn{3}{l}{Behavior when specifying optional args and
                   embellishments blank:}\\
\verb|\Body[ ]^{ }|&&\Body[ ]^{ }\\
\verb|\Body[ ][ ]^{ }|&&\Body[ ][ ]^{ }\\
\verb|\Body[ ]_{ }|&&\Body[ ]_{ }\\
\verb|\Body[ ][ ]_{ }|&&\Body[ ][ ]_{ }\\
\verb|\Body[ ]^{ }_{ }|&&\Body[ ]^{ }_{ }\\
\verb|\Body[ ][ ]^{ }_{ }|&&\Body[ ][ ]^{ }_{ }
\end{tabular}
\end{minipage}

\end{document}

enter image description here

Caveats:

  • Please don't do things like \Body^_{down} where _ will be taken for the value of the embellishment-argument ^.

  • Besides the optional embellishment arguments denoted by ^ and _ the macro \Body also has two subsequent [...]-delimited optional arguments. Therefore there is no way to deviate from the default value only for the second of these [...]-delimited optional arguments while sticking to the default value of the first [...]-delimited optional argument other than explicitly specifying the first [...]-delimited optional argument also, providing its default value.

  • Seems currently (January 13, 2024, 07:18:40 (UTC + 0000)) there is no proper official interface for counting the arguments denoted by an xparse-argument-signature.
    Thus \MYSTUFF_xparse_arg_signature_count:n might break when with future LaTeX releases internal things change - e.g., in case more xparse-argument-types with non-standard parsing/counting are added so that the mechanism for parsing the argument-signature needs to be adapted.

  • With \MYSTUFF_xparse_arg_signature_count:n there is no error-checking implemented on the argument being a valid xparse-argument-signature. Neither is error-checking implemented on the value of the key args of the second argument of the macro \NewGlsCompound being a valid xparse-argument-signature. Therefore in case that value does not form a valid xparse-argument-signature attempts triggered by \NewGlsCompound at defining via \NewDocumentCommand the command denoted in its first argument may yield error-messages about unknown argument types and the like.

2
  • Wow, I am amazed at the complexity required for this seemingly simple problem. Thank you for the solution. It works as expected!
    – Wulle
    Jan 13 at 2:50
  • @Wulle I think most of the complexity is due to the circumstance that there is no proper official interface for counting the arguments denoted by an xparse-argument-signature. Therefore \MYSTUFF_xparse_arg_signature_count:n might break when with future LaTeX releases internal things change - e.g., more xparse-argument-types are added so that the mechanism for parsing the argument-signature needs to be enhanced/adapted. Jan 13 at 7:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .