我使用由以下定义的环境“exo”
\usepackage{amsmath}
\newtheorem{exo}{Exercice}
我想选择性地在文档的后面添加一些练习,使用以下内容:
\makeatletter
\newcounter{nbexosfac}
\setcounter{nbexosfac}{0}
\newcommand{\exofacultatif}[2][]{
\stepcounter{nbexosfac}
\edef\tmp{\string\thenbexosfac}
\expandafter\def\csname exosfacopt\tmp\endcsname{#1}
\expandafter\def\csname exosfaccorps\tmp\endcsname{#2}
}
\newcounter{myaux}
\newcommand{\restitueexos}{
\ifnum\thenbexosfac>0%
\begin{center} Exercices supplémentaires \end{center}
\setcounter{myaux}{0}
\@whilenum\value{myaux}<\value{nbexosfac}\do{
\stepcounter{myaux}
\edef\tmp{\string\themyaux}
\begin{exo}[\csname exosfacopt\tmp\endcsname]
\csname exosfaccorps\tmp\endcsname
\end{exo}
}
\setcounter{nbexosfac}{0}
\fi
}
\makeatother
但是它不能按照文档中预期的那样工作:
\begin{document}
\begin{exo}
Texte 1
\end{exo}
\exofacultatif{Texte 2}
\begin{exo}[essai 3]
Texte 3
\end{exo}
\exofacultatif[essai 4]{Texte 4}
\restitueexos
\end{document}
存储的数据不会被检索,但是它增加了一个多余的“()”:\exofacultatif{}
不等同于\begin{exo}[] \end{exo}
。
任何想法 ?
编辑:我删除了多余的\def\withexosfac{}
和\ifdefined\withexosfac
。
修改 2:egreg 的解决方案更好。不过,我找到了一个似乎可行的解决方案,尽管我不确定为什么:
\makeatletter
\newcounter{nbexosfac}
\setcounter{nbexosfac}{0}
\newcommand{\exofacultatif}[2][]{
\stepcounter{nbexosfac}
\expandafter\def\csname exosfacopt\string{\thenbexosfac}\endcsname{#1}
\expandafter\def\csname exosfaccorps\string{\thenbexosfac}\endcsname{#2}
}
\newcounter{myaux}
\newcommand{\restitueexosfac}{
\ifnum\thenbexosfac>0%
(...)
\setcounter{myaux}{0}
\@whilenum\value{myaux}<\value{nbexosfac}\do{
\stepcounter{myaux}
\edef\tmp{\csname exosfacopt\string{\themyaux}\endcsname}
\ifx\tmp\empty
\begin{exo}
\else
\begin{exo}[\tmp]
\fi
\csname exosfaccorps\string{\themyaux}\endcsname
\end{exo}
}
\setcounter{nbexosfac}{0}
\fi
}
\makeatother
编辑 3:因此,基于 egreg 的代码,我写道
\documentclass{article}
\usepackage{amsmath}
\usepackage{hyperref}
\newtheorem{exo}{Exercise}
\ExplSyntaxOn
\seq_new:N \exof_seq
\NewDocumentEnvironment{exo*}{+b}
{
\seq_gput_right:Nn \exof_seq { \begin{exo} #1 \end{exo} }
}{}
\newcommand{\restitueexosfac}{
\seq_if_empty:NF \exof_seq {%
\section*{Exercices~complémentaires}%
}
\seq_use:Nn \exof_seq {}
\seq_clear:N \exof_seq
}
\ExplSyntaxOff
\begin{document}
\section{Titre 1}
\begin{exo}
Texte 1
\end{exo}
\begin{exo*}
Texte 2
\end{exo*}
\section*{Autre titre}
\begin{exo}[essai 3]
Texte 3
\end{exo}
\begin{exo*}[essai 4]
Texte 4
\end{exo*}
\restitueexosfac
\section{Titre 2}
\begin{exo}
Texte 5
\end{exo}
\restitueexosfac
\end{document}
编辑4:以下内容不再相关。
\section*
但是,您可以看到中的命令中空格丢失了\restitueexosfac
。为什么它在这里丢失,而在\section*{Autre titre}
其他地方的命令中却没有丢失?我可以使用~
或\
,但我希望进行更改,\restitueexosfac
这样就没有必要了。有什么想法吗?
答案1
我建议将任意练习按您最终可以提供的顺序存储。
\documentclass{article}
\usepackage{amsmath}
\usepackage{amsthm}
\newtheorem{exo}{Exercice}
\ExplSyntaxOn
\seq_new:N \g_dominique_exof_seq
\NewDocumentEnvironment{exo*}{+b}
{
\seq_gput_right:Nn \g_dominique_exof_seq { \begin{exo} #1 \end{exo} }
}
{}
\NewDocumentCommand{\restituteexos}{}
{
\section*{Exercices~supplémentaires}
\seq_use:Nn \g_dominique_exof_seq {}
}
\ExplSyntaxOff
\begin{document}
\begin{exo}
Texte 1
\end{exo}
\begin{exo*}
Texte 2
\end{exo*}
\begin{exo}[essai 3]
Texte 3
\end{exo}
\begin{exo*}[essai 4]
Texte 4
\end{exo*}
\restituteexos
\end{document}
通过+b
参数类型,您可以输入exo*
类似的内容exo
,并且可以轻松地将一种类型转换为另一种类型。
答案2
egreg 提供的代码绝对是更好的,因为它开辟了更多的可能性。
下面 - 仅显示初始发布的代码中存在的问题 - 与初始发布的代码相比,更改尽可能少的变体:
\documentclass{article}
\usepackage{amsmath}
\newtheorem{exo}{Exercice}
\makeatletter
\newcounter{nbexosfac}
\setcounter{nbexosfac}{0}
\begingroup
\def\passtodefinitions#1{%
\endgroup
\newcommand*\mynovaluemarker{#1}%
\newcommand{\exofacultatif}[2][#1]%
}%
\catcode`\-=3 %
\expandafter\passtodefinitions\expandafter{\expandafter-\detokenize{NoValue-}}{%%
\@bsphack
\stepcounter{nbexosfac}%%
%% \edef\tmp{\string\thenbexosfac}%% <- This does not make sense! Don't do this! Don't stringify the token \themyaux !!!
\begingroup\toks@{#1}\edef\tmp{\the\toks@}\expandafter\endgroup\ifx\tmp\mynovaluemarker\else
\expandafter\@ifdefinable\csname exosfacopt\number\value{nbexosfac}\endcsname{%
\global\@namedef{exosfacopt\number\value{nbexosfac}}{#1}%%
}%
\fi
\expandafter\@ifdefinable\csname exosfaccorps\number\value{nbexosfac}\endcsname{%
\global\@namedef{exosfaccorps\number\value{nbexosfac}}{#2}%%
}%
\@esphack
}
\newcounter{myaux}
\newcommand{\restitueexos}{%%
\ifnum\thenbexosfac>0 %%<- leave this space - it terminates the number-quantity !!!
\begin{center}Exercices supplémentaires\end{center}%%
\setcounter{myaux}{0}%%
\@whilenum\value{myaux}<\value{nbexosfac}\do{%%
\stepcounter{myaux}%%
%% \edef\tmp{\string\themyaux}%% <- This does not make sense! Don't do this! Don't stringify the token \themyaux !!!
\@ifundefined{exosfaccorps\number\value{myaux}}{}{%
\@ifundefined{exosfacopt\number\value{myaux}}{%
\begin{exo}%%
}{%
\begin{exo}[\@nameuse{exosfacopt\number\value{myaux}}]%%
}%
\@nameuse{exosfaccorps\number\value{myaux}}%%
\end{exo}%%
}%
}%%
\setcounter{nbexosfac}{0}%%
\fi
}
\makeatother
\begin{document}
\begin{exo}
Texte 1
\end{exo}
\exofacultatif{Texte 2}
\begin{exo}[essai 3]
Texte 3
\end{exo}
\exofacultatif[essai 4]{Texte 4}
\restitueexos
\end{document}
答案3
除了计数器和宏之外,\addtocontents
- -\@starttoc
机制可能是一种选择。使用这种机制,您可以将补充练习放在文档中的任何位置,而不仅仅是放在所有其他练习之后。
\documentclass{article}
\usepackage{amsmath}
\newtheorem{exo}{Exercice}
\usepackage{hyperref}
\makeatletter
\newcounter{nbexosfac}
\newcommand\PassFirstToSecond[2]{#2{#1}}
\NewDocumentCommand{\exofacultatif}{om}{%%
\Hy@SaveLastskip
\IfNoValueTF{#1}{%
\addtocontents{exo}{\ExoDelayed{#2}\protected@file@percent}%
}{%
\addtocontents{exo}{\ExoDelayed[{#1}]{#2}\protected@file@percent}%
}%
\Hy@RestoreLastskip
}
\NewDocumentCommand{\ExoDelayed}{om}{%%
\IfNoValueTF{#1}{\begin{exo}}{\begin{exo}[{#1}]}#2\end{exo}%
}%%
\newcommand*\restitueexos{%
\section*{Exercices supplémentaires}%
\begingroup
\providecommand\lastExo{0}%
\expandafter\PassFirstToSecond\expandafter{\number\value{exo}}{%
\setcounter{exo}{\lastExo}%
\@starttoc{exo}%
\setcounter{exo}%
}%
\endgroup
}%
\AtEndDocument{%
\protected@write\@auxout{}{\string\gdef\string\lastExo{\number\value{exo}}}%
}
\makeatother
\begin{document}
\restitueexos
\bigskip\hrule\bigskip
\begin{exo}
Texte 1
\end{exo}
\exofacultatif{Texte 2}%
\begin{exo}[essai 3]
Texte 3
\end{exo}
\exofacultatif[essai 4]{Texte 4}%
\end{document}
另一个选择可能是使用“datatool”包来维护两个补充练习数据库:
一个数据库用于向其中添加数据。它是在 LaTeX 运行期间创建的。在 LaTeX 运行结束时,它将被写入 .csv 文件或类似文件。
另一个数据库用于在 LaTeX 运行期间获取数据。它是在 LaTeX 运行开始时通过读取 .csv 文件(如果存在)创建的。
您可以根据需要随时处理文档中用于在 LaTeX 运行期间获取数据的数据库,并根据需要对条目进行排序。这可能对每个部分或章节的补充练习等有用。