`\expandafter` 和 `csname` 的问题

`\expandafter` 和 `csname` 的问题

上面有一段代码,我想进一步分解。我想以与特殊宏类似的方式定义这两个宏\exercice和,但目前我失败了。我遗漏了和的一些东西……\topic\@init@new@exo\expandaftercsname

\documentclass[12pt]{article}
\usepackage{pgfkeys}

\makeatletter
    \newcommand\@init@new@exo[1]{
        \pgfkeys{
            /#1@keys/.is family,
            /#1@keys,
                pts/.initial  = {}, % Render the subject or not
                src/.initial  = {}  % Number of the exam

        }

        \expandafter\newcommand\csname #1@number\endcsname{Nb for #1}
    }

    \@init@new@exo{topic}
    \@init@new@exo{exercice}

    \newcommand\exercice[1][]{%
        \begingroup
            \pgfkeys{/exercice@keys, #1}
            \pgfkeysgetvalue{/exercice@keys/pts}{\exercice@points}
            \pgfkeysgetvalue{/exercice@keys/src}{\exercice@source}
            exercice \exercice@number{}
            (\exercice@points{} pts) 
            [Source :\exercice@source{}] 
        \endgroup
    }

    \newcommand\topic[1][]{%
        \begingroup
            \pgfkeys{/topic@keys, #1}
            \pgfkeysgetvalue{/topic@keys/pts}{\topic@points}
            \pgfkeysgetvalue{/topic@keys/src}{\topic@source}
            topic \topic@number{}
            (\topic@points{} pts) 
            [Source :\topic@source{}] 
        \endgroup
    }
\makeatother



\begin{document}

\exercice[pts = 1, src = Imaginaire]

\exercice

\topic[pts = 1, src = Imaginaire]

\topic[pts = 2]

\end{document}

答案1

类似这样的操作会安排所有 csname 构造首先发生,因此它不会与 pgf 解析混合。

\documentclass[12pt]{article}
\usepackage{pgfkeys}

\makeatletter
    \newcommand\@init@new@exo[1]{%%
        \pgfkeys{
            /#1@keys/.is family,
            /#1@keys,
                pts/.initial  = {}, % Render the subject or not
                src/.initial  = {}  % Number of the exam

        }%%
%%
        \expandafter\newcommand\csname #1@number\endcsname{Nb for #1}%%
    }

    \@init@new@exo{topic}
    \@init@new@exo{exercice}

\newcommand\zz[1]{\expandafter\@zz
                    \csname#1\expandafter\endcsname
                    \csname#1@points\expandafter\endcsname
                    \csname#1@source\expandafter\endcsname
                    \csname#1@number\endcsname
                    {#1}}

\newcommand\@zz[5]{%
    \newcommand#1[1][]{%
        \begingroup
            \pgfkeys{/#5@keys, ##1}%%
            \pgfkeysgetvalue{/#5@keys/pts}{#2}%%
            \pgfkeysgetvalue{/#5@keys/src}{#3}%%
            #5 #4{} %%
            (#2{} pts)
            [Source :#3{}] %%
        \endgroup
    }%%
}


\zz{exercice}
\zz{topic}


\makeatother



\begin{document}

\exercice[pts = 1, src = Imaginaire]

\exercice

\topic[pts = 1, src = Imaginaire]

\topic[pts = 2]

\end{document}

答案2

您可以在“init”阶段包含命令的定义:

\documentclass[12pt]{article}
\usepackage{xparse,chngcntr}

\ExplSyntaxOn

\NewDocumentCommand{\initkeys}{mo}
 {
  \newcounter{#1}
  \IfValueT{#2} { \counterwithin{#1}{#2} }
  \projetmbc_init_keys:n { #1 }
 }

\cs_new_protected:Nn \projetmbc_init_keys:n
 {
  \keys_define:nn { projetmbc/#1 }
   {
    pts .tl_set:c = l_projetmbc_#1_pts_tl,
    src .tl_set:c = l_projetmbc_#1_src_tl,
   }
  \exp_args:Nc \NewDocumentCommand {#1} { O{} }
   {
    \refstepcounter{#1}
    \group_begin:
    \keys_set:nn { projetmbc/#1 } { ##1 }
    #1 ~ \use:c { the#1 } ~
    \tl_if_empty:cF { l_projetmbc_#1_pts_tl }
     {
      \c_space_tl
      ( \tl_use:c { l_projetmbc_#1_pts_tl } ~ pts)
     }
    \tl_if_empty:cF { l_projetmbc_#1_src_tl }
     {
      \c_space_tl
      [Source: ~ \tl_use:c { l_projetmbc_#1_src_tl } ]
     }
    \group_end:
   }
 }

\ExplSyntaxOff

\initkeys{exercice}
\initkeys{topic}[exercice]


\begin{document}

\exercice[pts = 1, src = Imaginaire]

\exercice

\topic[pts = 1, src = Imaginaire]

\topic[pts = 2]

\end{document}

在此处输入图片描述

相关内容