第一个解决方案

第一个解决方案

与我的问题相关xsim 这里

我想使用命令\ExOption\ExPart更轻松地在包中实现我的集合xsim。但我面临的问题是我的命令无法扩展\DeclareExerciseCollection{\ExOption_\ExPart}。在aux文件中我可以找到这一行:\XSIM {collection:\ExOption _\ExPart }{}它指出没有扩展。

如何才能使命令在宏之前展开\DeclareExerciseCollection{}并避免在宏之后由 TeX 实现空格?我读过一些有关的信息\expandafter\edef我认为它可能有用,但这是我第一次处理这些命令。

以下是 MWE:

\documentclass[10pt,a4paper]{book}
\usepackage[verbose,clear-aux]{xsim}


%%Declaration exercices
    \edef\ExOption{default}
    \edef\ExPart{default}

%%Declaration Collection
    \renewcommand{\ExOption}{5M4}
    \renewcommand{\ExPart}{AlgebreFinanciere}

    \DeclareExerciseCollection{\ExOption_\ExPart}       %%With custom commands produce wrong output
%   \DeclareExerciseCollection{5M4_AlgebreFinanciere}   %%With applicable name produce good output
\begin{document}
\chapter{Where i want exercises}
%%Collecting exercises
    \collectexercises{\ExOption_\ExPart}                %%With custom commands produce wrong output
        \begin{exercise}
            Can you print me ?
        \end{exercise}
        \begin{solution}
            Yes, you can !
        \end{solution}
    \collectexercisesstop{\ExOption_\ExPart}

%   \collectexercises{5M4_AlgebreFinanciere}            %%With applicable name produce good output
%       \begin{exercise}
%           Can you print me ?
%       \end{exercise}
%       \begin{solution}
%           Yes, you can !
%       \end{solution}
%   \collectexercisesstop{5M4_AlgebreFinanciere}

%%Print
Output of the command in LaTeX \verb|\ExOption_\ExPart| : \ExOption\_\ExPart


    \printcollection{5M4_AlgebreFinanciere}
\end{document} 

答案1

使用当前版本的 pdftex(定义\expanded),您可以定义命令的扩展版本,如下所示。

对于没有的旧实现,\expanded您可以使用\edef

\newcommand\xDeclareExerciseCollection[1]{%
  \edef\tmp{\noexpand\DeclareExerciseCollection{#1}}\tmp}

另外两个命令也类似。

\documentclass[10pt,a4paper]{book}
\usepackage[verbose,clear-aux]{xsim}

\newcommand\xDeclareExerciseCollection[1]{%
  \expandafter\DeclareExerciseCollection\expandafter{\expanded{#1}}}
\newcommand\xcollectexercises[1]{%
  \expandafter\collectexercises\expandafter{\expanded{#1}}}
\newcommand\xcollectexercisesstop[1]{%
  \expandafter\collectexercisesstop\expandafter{\expanded{#1}}}

%%Declaration exercices
    \edef\ExOption{default}
    \edef\ExPart{default}

%%Declaration Collection
    \renewcommand{\ExOption}{5M4}
    \renewcommand{\ExPart}{AlgebreFinanciere}

    \xDeclareExerciseCollection{\ExOption_\ExPart}       %%With custom commands produce wrong output
%   \DeclareExerciseCollection{5M4_AlgebreFinanciere}   %%With applicable name produce good output
\begin{document}
\chapter{Where i want exercises}
%%Collecting exercises
    \xcollectexercises{\ExOption_\ExPart}                %%With custom commands produce wrong output
        \begin{exercise}
            Can you print me ?
        \end{exercise}
        \begin{solution}
            Yes, you can !
        \end{solution}
    \xcollectexercisesstop{\ExOption_\ExPart}

%   \collectexercises{5M4_AlgebreFinanciere}            %%With applicable name produce good output
%       \begin{exercise}
%           Can you print me ?
%       \end{exercise}
%       \begin{solution}
%           Yes, you can !
%       \end{solution}
%   \collectexercisesstop{5M4_AlgebreFinanciere}

%%Print
Output of the command in LaTeX \verb|\ExOption_\ExPart| : \ExOption\_\ExPart


    \printcollection{5M4_AlgebreFinanciere}
\end{document} 

答案2

我在这里提出两种解决方案。

第一个解决方案

这与 David Carlisle 的解决方案精神相同,只是只需为所有内容定义一个命令。您不需要为\DeclareExerciseCollection、 for \collectexercises、 for\collectexercisesstop等指定特定命令。此外,该命令是用 LaTeX3 实现的 — 因此不是 David Carlisle 解决方案的仿制品。:-)

\documentclass{book}
\usepackage[verbose,clear-aux]{xsim}
\usepackage{xparse}

\ExplSyntaxOn

\cs_new_protected:Npn \pirooh_call_with_one_arg:Nn #1#2
  {
    #1 {#2}
  }

\cs_generate_variant:Nn \pirooh_call_with_one_arg:Nn { Nx }

\NewDocumentCommand \callWithExpandedArg { m m }
  {
    % Perform full expansion on what #2 stands for, then call #1
    % with the result.
    \pirooh_call_with_one_arg:Nx #1 {#2}
  }

\ExplSyntaxOff

\newcommand*{\ExOption}{5M4}
\newcommand*{\ExPart}{AlgebreFinanciere}

\callWithExpandedArg{\DeclareExerciseCollection}{\ExOption_\ExPart}

\begin{document}
\chapter{Where i want exercises}

\callWithExpandedArg{\collectexercises}{\ExOption_\ExPart}

\begin{exercise}
    Can you print me ?
\end{exercise}
\begin{solution}
    Yes, you can !
\end{solution}

\callWithExpandedArg{\collectexercisesstop}{\ExOption_\ExPart}

\callWithExpandedArg{\printcollection}{\ExOption_\ExPart}
\end{document}

第二种解决方案

这里的方法不同。有一个命令来定义每个参数值,不像David Carlisle 的解决方案中那样,按照诸如 、和之xsim类的命令。此处,命令是针对参数值定义的(您可能想要调整其名称)。\DeclareExerciseCollection\collectexercises\collectexercisesstop\printcollection\callWithPredefinedArg5M4_AlgebreFinanciere

这个解决方案并不比其他解决方案更好,只是在精神上有所不同。代码对定义的时间\ExOption进行了全面扩展(如果需要,可以更改)。\ExPart\callWithPredefinedArg

\documentclass{book}
\usepackage[verbose,clear-aux]{xsim}

\newcommand*{\ExOption}{default}
\newcommand*{\ExPart}{default}

\renewcommand*{\ExOption}{5M4}
\renewcommand*{\ExPart}{AlgebreFinanciere}

% This recursively expands \ExOption and \ExPart and “freezes”
% the result in the definition of \callWithPredefinedArg.
\edef\callWithPredefinedArg#1{#1{\ExOption_\ExPart}}

% Of course, you could achieve the same with:
%\def\callWithPredefinedArg#1{#1{5M4_AlgebreFinanciere}}

\callWithPredefinedArg\DeclareExerciseCollection

\begin{document}
\chapter{Where i want exercises}

\callWithPredefinedArg\collectexercises

\begin{exercise}
    Can you print me ?
\end{exercise}
\begin{solution}
    Yes, you can !
\end{solution}

\callWithPredefinedArg\collectexercisesstop

\callWithPredefinedArg\printcollection

% If you have another chapter/module to start here, you could do
% \def\callWithPredefinedArg#1{#1{6N5_GeometrieFinanciere}}
% \callWithPredefinedArg\collectexercises
% etc.
\end{document}

答案3

这是通过定义相应内部宏的变体实现的另一种可能性 -x变体首先扩展它们的参数,然后再将实际的宏应用于它(最终这与 David 的解决方案相同):

\documentclass[]{article}
\usepackage{xsim}

\ExplSyntaxOn
\cs_generate_variant:Nn \xsim_new_collection:n   {x}
\cs_generate_variant:Nn \xsim_start_collection:n {x}
\cs_generate_variant:Nn \xsim_stop_collection:n  {x}

\NewDocumentCommand \xDeclareExerciseCollection {m}
  { \xsim_new_collection:x {#1} }

\NewDocumentCommand \xcollectexercises {m}
  { \xsim_start_collection:x {#1} }

\NewDocumentCommand \xcollectexercisesstop {m}
  { \xsim_stop_collection:x {#1} }
\ExplSyntaxOff

\newcommand*{\ExOption}{default}
\newcommand*{\ExPart}{default}

\renewcommand*{\ExOption}{5M4}
\renewcommand*{\ExPart}{AlgebreFinanciere}

\xDeclareExerciseCollection{\ExOption_\ExPart}

\begin{document}

\xcollectexercises{\ExOption_\ExPart}
\begin{exercise}
  Can you print me?
\end{exercise}
\begin{solution}
  Yes, you can!
\end{solution}
\xcollectexercisesstop{\ExOption_\ExPart}

\printcollection{5M4_AlgebreFinanciere}

\end{document}

相关内容