如何存储数据以供日后使用(类似列表)

如何存储数据以供日后使用(类似列表)

我使用由以下定义的环境“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 运行期间获取数据的数据库,并根据需要对条目进行排序。这可能对每个部分或章节的补充练习等有用。

相关内容