在辅助文件中写入 LaTeX3 序列

在辅助文件中写入 LaTeX3 序列

下面的代码定义了一个宏\addtothelist,将水果的名称及其颜色(这只是一个例子)添加到\g_mylist_seq。它还定义了一个宏\printmylist,打印所有项目,例如:

  • 苹果:红色
  • 香蕉:黄色……

梅威瑟:

\documentclass{article}
\usepackage{expl3}

\ExplSyntaxOn
\seq_new:N \g_mylist_seq

\newcommand{\addtothelist}[2]{
    \cs_gset:cpn {mylist#1} {#2}
    \seq_gput_right:Nn \g_mylist_seq {#1}
}

\NewDocumentCommand{\printmylist}{}
 {
  \seq_if_empty:NF \g_mylist_seq {
    \begin{itemize}
    \seq_map_inline:Nn \g_mylist_seq {
      \item \use:c{mylist##1}:~##1
    }
    \end{itemize}
  }
 }

\ExplSyntaxOff

\begin{document}

\addtothelist{red}{apple}
\addtothelist{yellow}{banana}
\printmylist

\addtothelist{orange}{orange}

\end{document}

但是,orange由于它是在被调用之后\printmylist被调用的,因此它会忽略。我们可以使用aux文件来解决这个问题吗?

答案1

.aux在读取文件时构建序列,而不是在添加到列表时构建序列。

\documentclass{article}

\ExplSyntaxOn

\seq_new:N \g_mylist_seq

\NewDocumentCommand{\addtothelist}{mm}
  {
    \iow_shipout:cn { @auxout } { \ADDTOTHELIST { #1 } { #2 } }
  }

\NewDocumentCommand{\ADDTOTHELIST}{mm}
  {
   \seq_gput_right:Nn \g_mylist_seq { {#1}{#2} }
  }

\NewDocumentCommand{\printmylist}{}
  {
    \seq_if_empty:NF \g_mylist_seq
      {
        \begin{itemize}
        \seq_map_inline:Nn \g_mylist_seq { \mylist_print_item:nn ##1 }
        \end{itemize}
      }
  }

\cs_new_protected:Nn \mylist_print_item:nn
  {
    \item #1:~#2
  }

\ExplSyntaxOff

\begin{document}

Some text

\addtothelist{red}{apple}
\addtothelist{yellow}{banana}
\printmylist

\addtothelist{orange}{orange}

\end{document}

第一次运行不会产生任何结果,但第二次运行将产生预期的结果。

在此处输入图片描述

答案2

在您的示例中,您甚至不需要将 seq 写入 -file aux。您只需要将\addtothelist命令写入aux-file,即使不使用语法也可以完成此操作expl3

\documentclass{article}
\usepackage{expl3}

\ExplSyntaxOn
\seq_new:N \g_mylist_seq

\newcommand{\addtothelist}[2]{
    \cs_gset:cpn {mylist#1} {#2}
    \seq_gput_right:Nn \g_mylist_seq {#1}
}

\NewDocumentCommand{\printmylist}{}
 {
  \seq_if_empty:NF \g_mylist_seq {
    \begin{itemize}
    \seq_map_inline:Nn \g_mylist_seq {
      \item \use:c{mylist##1}:~##1
    }
    \end{itemize}
  }
 }

\ExplSyntaxOff

\makeatletter
\newcommand{\addtothelistindirect}[2]{%
  \protected@write{\@auxout}{}{\protect\addtothelist{\detokenize{#1}}{\detokenize{#2}}}% write without expanding the arguments
}
% Alternative definitions:
% \newcommand{\addtothelistindirect}[2]{%
%   \write\@auxout{\detokenize{\addtothelist{\detokenize{#1}}{\detokenize{#2}}}}% write without expanding the arguments
% }
% \newcommand{\addtothelistindirect}[2]{%
%   \protected@write{\@auxout}{}{\protect\addtothelist{#1}{#2}}% write with expansion of the argument unless \protect is used
% }

\makeatother

\begin{document}

You need at least one page of output, otherwise the write to the aux will
never happen.

\addtothelistindirect{red}{apple}
\addtothelistindirect{yellow}{banana}
\printmylist

\addtothelistindirect{orange}{orange}

\end{document}

经过两次 LaTeX 运行后,结果显示:

在此处输入图片描述

如果您希望将序列写入aux-file,可以使用 来完成\AtEndOfDocument。但在这种情况下,您需要两个序列:一个序列将填充到文档中并写入 -file ,另一个序列将从文件aux中读取并由 打印。否则,您将无法在不删除-file 的情况下删除条目。aux\begin{document}\printmylistaux

相关内容