\openin 使用来自包收集的 \includecollection 时出错

\openin 使用来自包收集的 \includecollection 时出错

我正在为软件设计文档编写一个包。其中有一节涉及模块之间的软件接口,另一节描述每个模块。这里有一个模块使用的接口(函数和变量)的摘要,它们是使用包从上一节收集的collect

我创建了一些宏来创建接口(并收集所需的信息),并创建了其他宏来将收集到的信息放置到所需的位置,但编译文档时多次出现以下错误:

! You can't use a prefix with `\openin'.
<to be read again> 
                   \openin 
l.306 \insertprovidedinterfaces{SUP}

键入r运行 pdfLaTeX 到最后,结果正是预期的,但我无法理解/摆脱这些消息。

有什么提示吗?

以下是 MWE:

\documentclass[a4paper, oneside, 10pt]{article}
\usepackage[english]{babel}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\renewcommand*\familydefault{\sfdefault} 
\usepackage[table, svgnames]{xcolor}
\usepackage{booktabs}
\usepackage{xparse}
\usepackage{xstring}
\usepackage{longtable}
\usepackage{collect}
\usepackage{tikz}%
\usepackage{hyperref}
%%
\colorlet{IFcolor}{Yellow!30!Blue!20}
\colorlet{IFVcolor}{Yellow!80!Blue!20}
%
% definitions of variables containing modules list, later used
% to avoid re-defining an already defined collection
% pfun -> provided functions
% nfun -> needed functions
% pvar -> provided variables
% nvar -> needed variables
\def\pfuncollectionlist{}
\def\nfuncollectionlist{}
\def\pvarcollectionlist{}
\def\nvarcollectionlist{}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% environment for interfaces - functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Usage: 
% param 1: Provider acronym
% param 2: name of function including ()
% param 3: comma-separated caller list
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\NewDocumentEnvironment{int-interface}{mmm}%
{%before
  \phantomsection\label{iifprovided#1-#2}%
  % provided function interfaces
  \newpfuncollection{#1-provided-fun}%  
  \begin{collect} {#1-provided-fun}{}{}% 
  \item \hyperref[iifprovided#1-#2]{#1\_#2}
  \end{collect}%
  % 
  % needed function interfaces
  \def\callers{#3}
  \foreach \caller in \callers%
  {%
    \newnfuncollection{\caller-needed-fun}%  
    \begin{collect}{\caller-needed-fun}{}{}% 
    \item \hyperref[iifprovided#1-#2]{#1\_#2}%
    \end{collect}%
}%
%
\small     
\longtable[htbp]{>{\columncolor{IFcolor}}p{3.5cm}p{12cm}}\kill%\toprule
\endfirsthead
\multicolumn{2}{l}{\footnotesize\emph{Follows from previous page}} \\
\endhead
% normal foot
\multicolumn{2}{r}{\footnotesize\emph{Continue in the next page}} \\
\endfoot
% last foot
\bottomrule
\endlastfoot
%
% here the stationary contents
\toprule
Syntax & #1\_#2 \\
}%
{%
%after
Callers & #3 \\%
\endlongtable
}%
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% environment for interfaces - variables
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Usage: 
% param 1: Provider acronym
% param 2: name of variable
% param 3: comma-separated caller list, read access
% param 4: comma-separated caller list, write access
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\NewDocumentEnvironment{int-interface-var}{mmmm}%
{%before
  \phantomsection\label{iifprovided#1-#2}%
%  provided function interfaces
  \newpvarcollection{#1-provided-var}%  
\begin{collect}{#1-provided-var}{}{}% 
\item \hyperref[iifprovided#1-#2]{#1\_#2}
\end{collect}%
%
%
% needed interfaces 
% two consecutive \foreach are used to decide whether writing R, W or R/W
% first loop search for every read caller in writecaller list; 
% if read caller is found in writecallers list, 
% a 'R/W' is appended; elsewhere, it is 'only' R. 
% Then similar thing is done starting from writecaller list:
% if actual writecaller is NOT found in readcaller list, it is marked only W;
% elsewhere nothing has to be done, because R/W has been already treated in 
% previous loop (RW)
\def\callersreadlist{#3}
\def\callerswritelist{#4}
% detecting RW or R
\foreach \readcaller in \callersreadlist
{
  \IfSubStr{\callerswritelist}{\readcaller}
  {
    \newnvarcollection{\readcaller-needed-var}%  
    \begin{collect}{\readcaller-needed-var}{}{}% 
    \item \hyperref[iifprovided#1-#2]{#1\_#2} [Read/Write]
    \end{collect}%
  }%
  % else%
  {%
    \newnvarcollection{\readcaller-needed-var}%  
    \begin{collect}{\readcaller-needed-var}{}{}% 
    \item \hyperref[iifprovided#1-#2]{#1\_#2} [Read only]
    \end{collect}%
  }%
}
% detecting W  
\foreach \writecaller in \callerswritelist
{
  \IfSubStr{\callersreadlist}{\writecaller}
  {
    % if found, nothing to do
  }%
  % else%
  {%
    \newnvarcollection{\writecaller-needed-var}%  
    \begin{collect}{\writecaller-needed-var}{}{}% 
    \item \hyperref[iifprovided#1-#2]{#1\_#2} [Write only]
    \end{collect}%
  }%
}   
%
% write longtable
\small    
  % didascalia ed etichetta
\longtable[htbp]{>{\columncolor{IFVcolor}}p{3.5cm}p{12cm}}\kill%\toprule
\endfirsthead
\multicolumn{2}{l}{\footnotesize\emph{Follows from previous page}} \\
\endhead
% piede normale
\multicolumn{2}{r}{\footnotesize\emph{Continue in the next page}} \\
\endfoot
% piede finale
\bottomrule
\endlastfoot
%
% here the stationary contents
\toprule
Syntax & #1\_#2 \\%
}%
{%
%after
% do the same search as before, to build list of read only, write only and read/write access modules
\def\callersreadlist{#3}%
\def\callerswritelist{#4}%
Accessed by: & %
\foreach\readcaller in \callersreadlist
{%
  \IfSubStr{\callerswritelist}{\readcaller}%
{%
    % if found
\readcaller{} \accessmode{rw}$\quad$%
}%
  % else%
{%
\readcaller{} \accessmode{r}$\quad$%
}%
}%
%  
%
\foreach\writecaller in \callerswritelist
{%
  \IfSubStr{\callersreadlist}{\writecaller}%
{%
}%
  % else%
{%
\writecaller{} \accessmode{w}$\quad$%
%
}%
}%
\\   
\endlongtable
}%
%
%
%
%
%
\newcommand{\accessmode}[1]{%
  (#1),
}%
%
\DeclareRobustCommand{\insertprovidedinterfaces}[1]{%
  \paragraph{Function interfaces}
  \IfSubStr{\pfuncollectionlist}{#1}{%
%    Collection '#1-provided-fun' exists
    \begin{itemize}
      \includecollection{#1-provided-fun}%
    \end{itemize}
  }{%   
    None.
  }%
  \paragraph{Variable interfaces}
  \IfSubStr{\pvarcollectionlist}{#1}{%
%    Collection '#1-provided-var' exists
    \begin{itemize}
      \includecollection{#1-provided-var}%
    \end{itemize}
  }{%   
    None.
  }%
}%
%
\DeclareRobustCommand{\insertneededinterfaces}[1]{%
  \paragraph{Function interfaces}
  \IfSubStr{\nfuncollectionlist}{#1}{%
%    Collection '#1-needed-fun' esists
    \begin{itemize}
      \includecollection{#1-needed-fun}%
    \end{itemize}
  }{%   
    None.
  }%
  \paragraph{Variable interfaces}
  \IfSubStr{\nvarcollectionlist}{#1}{%
%    Collection '#1-needed-var' esists
    \begin{itemize}
      \includecollection{#1-needed-var}%
    \end{itemize}
  }{%   
    None.
  }%
}%
%
\DeclareRobustCommand{\newpvarcollection}[1]{%
  \IfSubStr{\pvarcollectionlist}{#1}{%
  }{%
    \xdef\pvarcollectionlist{\pvarcollectionlist{} #1}
    \definecollection{#1}%
  }%
}%
%
\DeclareRobustCommand{\newnvarcollection}[1]{%
  \IfSubStr{\nvarcollectionlist}{#1}{%
  }{%
    \xdef\nvarcollectionlist{\nvarcollectionlist{} #1}
    \definecollection{#1}%
  }%
}%
%
\DeclareRobustCommand{\newpfuncollection}[1]{%
  \IfSubStr{\pfuncollectionlist}{#1}{%
  }{%
    \xdef\pfuncollectionlist{\pfuncollectionlist{} #1}
    \definecollection{#1}%    
  }%
}%
%
\DeclareRobustCommand{\newnfuncollection}[1]{%  
  \IfSubStr{\nfuncollectionlist}{#1}{%
  }{%
    \xdef\nfuncollectionlist{\nfuncollectionlist{} #1}
    \definecollection{#1}%
  }%
}%
%
\begin{document}
\section{Interfaces}
Here some software interfaces:
\begin{int-interface}{SUP}{eGetActualSystemStatus}{ICP}
  Parameters  & None                                        \\
  Return type & System status code. Codified value          \\
  Purpose     & Obtain actual system status from \emph{SUP} \\
\end{int-interface}
%
\begin{int-interface}{SUP}{eSetOverrideRequest()}{SMB}
  Parameters  & Request code: ENTER, EXIT                   \\
  Return type & Operation result. Codified value.           \\
  Purpose     & To set an override request to \emph{SUP}    \\
\end{int-interface}
%
\begin{int-interface-var}{HAL}{ausInputVoltageSamples}{SENS, I2C}{I2C, ICP}
  Type           & Buffer of 5 samples \\
  Purpose        & To store acquired input voltage samples\\
\end{int-interface-var}
%
\section{Modules description}
Some descriptive stuff\ldots

\subsection{SUP module}
Other descriptions\ldots

Here is a list of provided interfaces:
\insertprovidedinterfaces{SUP}

\subsection{HAL module}
Other descriptions\ldots

Here is a list of provided interfaces:
\insertprovidedinterfaces{HAL}
\end{document}

答案1

collect.sty您可以修补似乎导致应用程序中出现错误的命令。这不应涉及 的其他用途collect

\makeatletter
\def\CE@ensure@opened#1{%
  \@ifundefined{ifCE@@#1@open}{%
    \PackageError{collect}{Collection `#1' has not been defined}{\@ehc}%
  }{%
    \csname ifCE@@#1@open\endcsname\else
    \immediate\expandafter\openout\csname CE@@#1@out\endcsname=\jobname.#1\relax
    \@ifundefined{CE@@#1@opentrue}{}{\global\csname CE@@#1@opentrue\endcsname}%
    \fi
  }%
}
\def\CE@ensure@closed#1{%   
  \@ifundefined{ifCE@@#1@open}{%
    \PackageError{collect}{Collection `#1' has not been defined}{\@ehc}%
  }{%
    \csname ifCE@@#1@open\endcsname
    \immediate\expandafter\closeout\csname CE@@#1@out\endcsname
    \@ifundefined{CE@@#1@openfalse}{}{\global\csname CE@@#1@openfalse\endcsname}%
    \fi
  }%   
}   
\makeatother

代码应该放在序言中;您的 MWE 似乎运行时没有错误。


以下似乎是您的最小示例(相同的文档语法)的正确重新实现,没有使用collect,但利用了expl3

\documentclass[a4paper, oneside, 10pt]{article}
\usepackage[english]{babel}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\renewcommand*\familydefault{\sfdefault} 
\usepackage[table, svgnames]{xcolor}
\usepackage{booktabs}
\usepackage{xparse}
\usepackage{longtable}
\usepackage{tikz}%
\usepackage{hyperref}
%%
\colorlet{IFcolor}{Yellow!30!Blue!20}
\colorlet{IFVcolor}{Yellow!80!Blue!20}
%
% definitions of variables containing modules list, later used
% to avoid re-defining an already defined collection
% pfun -> provided functions
% nfun -> needed functions
% pvar -> provided variables
% nvar -> needed variables

\ExplSyntaxOn
\clist_new:N \g_cbe_pfuncollectionlist_clist
\clist_new:N \g_cbe_nfuncollectionlist_clist
\clist_new:N \g_cbe_pvarcollectionlist_clist
\clist_new:N \g_cbe_nvarcollectionlist_clist
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% environment for interfaces - functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Usage: 
% param 1: Provider acronym
% param 2: name of function including ()
% param 3: comma-separated caller list
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\NewDocumentEnvironment{int-interface}{mmm}
 {
  \cbe_int_interface_start:nnn {#1}{#2}{#3}
 }
 {
  \cbe_int_interface_end:nnn {#1}{#2}{#3}
 }
\cs_new_protected:Npn \cbe_int_interface_start:nnn #1 #2 #3
 {
  \phantomsection\label{iifprovided#1-#2}%
  % provided function interfaces
  \cbe_newpfuncollection:n { #1 }%  
  \cbe_collect:nn {#1-provided-fun}{\item \hyperref[iifprovided#1-#2]{#1\_#2}}
  % needed function interfaces
  \clist_map_inline:nn { #3 }
   {
    \cbe_newnfuncollection:n { ##1 }%  
    \cbe_collect:nn {##1-needed-fun}{\item \hyperref[iifprovided#1-#2]{#1\_#2}}
   }
  %
  \small
  \longtable[htbp]{>{\columncolor{IFcolor}}p{3.5cm}p{12cm}}\kill%\toprule
  \endfirsthead
  \multicolumn{2}{l}{\footnotesize\emph{Follows~from~previous~page}} \\
  \endhead
  % normal foot
  \multicolumn{2}{r}{\footnotesize\emph{Continue~in~the~next~page}} \\
  \endfoot
  % last foot
  \bottomrule
  \endlastfoot
  % here the stationary contents
  \toprule
  Syntax & #1\_#2 \\
 }
\cs_new_protected:Npn \cbe_int_interface_end:nnn #1 #2 #3
 {
  Callers & #3 \\
  \endlongtable
  }
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% environment for interfaces - variables
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Usage: 
% param 1: Provider acronym
% param 2: name of variable
% param 3: comma-separated caller list, read access
% param 4: comma-separated caller list, write access
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\NewDocumentEnvironment{int-interface-var}{mmmm}
 {
  \cbe_int_interface_var_start:nnnn {#1}{#2}{#3}{#4}
 }
 {
  \cbe_int_interface_var_end:nnnn {#1}{#2}{#3}{#4}
 }
\cs_new_protected:Npn \cbe_int_interface_var_start:nnnn #1 #2 #3 #4
 {
  \phantomsection\label{iifprovided#1-#2}
  % provided function interfaces
  \cbe_newpvarcollection:n { #1 }
  \cbe_collect:nn {#1-provided-var}{\item \hyperref[iifprovided#1-#2]{#1\_#2}}
  % needed interfaces 
  % two consecutive \foreach are used to decide whether writing R, W or R/W
  % first loop search for every read caller in writecaller list; 
  % if read caller is found in writecallers list, 
  % a 'R/W' is appended; elsewhere, it is 'only' R. 
  % Then similar thing is done starting from writecaller list:
  % if actual writecaller is NOT found in readcaller list, it is marked only W;
  % elsewhere nothing has to be done, because R/W has been already treated in 
  % previous loop (RW)
  % detecting RW or R
  \clist_map_inline:nn { #3 }
   {
    \clist_if_in:nnTF { #4 } { ##1 }
     {
      \cbe_newnvarcollection:n { ##1 }
      \cbe_collect:nn { ##1-needed-var }{ \item \hyperref[iifprovided#1-#2]{#1\_#2} [Read/Write] }
     }
     {
      \cbe_newnvarcollection:n { ##1 }
      \cbe_collect:nn { ##1-needed-var }{ \item \hyperref[iifprovided#1-#2]{#1\_#2} [Read~Only] }
     }
   }
  % detecting W  
  \clist_map_inline:nn { #4 }
   {
    \clist_if_in:nnF { #4 } { ##1 }
     {
      \cbe_newnvarcollection:n { ##1 }
      \cbe_collect:nn { ##1-needed-var }{\item \hyperref[iifprovided#1-#2]{#1\_#2} [Write~only]}
     }
   }
  % write longtable
  \small    
  % didascalia ed etichetta
  \longtable[htbp]{>{\columncolor{IFVcolor}}p{3.5cm}p{12cm}}\kill%\toprule
  \endfirsthead
  \multicolumn{2}{l}{\footnotesize\emph{Follows from previous page}} \\
  \endhead
  % piede normale
  \multicolumn{2}{r}{\footnotesize\emph{Continue in the next page}} \\
  \endfoot
  % piede finale
  \bottomrule
  \endlastfoot
  %
  % here the stationary contents
  \toprule
  Syntax & #1\_#2 \\
 }
\cs_new_protected:Npn \cbe_int_interface_var_end:nnnn #1 #2 #3 #4
 {
  % do the same search as before, to build list of read only, write only and read/write access modules
  Accessed~by: & 
  \clist_map_inline:nn { #3 }
   {
    \clist_if_in:nnTF { #4 } { ##1 }
     {
      ##1 ~ \cbe_accessmode:n { rw } \quad
     }
     {
      ##1 ~ \cbe_accessmode:n { r } \quad
     }
   }
  \clist_map_inline:nn { #4 }
   {
    \clist_if_in:nnF { #3 } { ##1 }
     {
      ##1 ~ \cbe_accessmode:n { w } \quad
     }
   }
  \\   
  \endlongtable
 }
%
\cs_new_protected:Npn \cbe_accessmode:n #1
 {
  (#1),
 }
%
\NewDocumentCommand{\insertprovidedinterfaces}{m}
 {
  \paragraph{Function~interfaces}
  \clist_if_in:NnTF \g_cbe_pfuncollectionlist_clist { #1 }
   {
    % Collection '#1-provided-fun' exists
    \begin{itemize}
      \cbe_includecollection:n {#1-provided-fun}
    \end{itemize}
   }
   {
    None.
   }
  \paragraph{Variable~interfaces}
  \clist_if_in:NnTF \g_cbe_pvarcollectionlist_clist { #1 }
   {
    % Collection '#1-provided-var' exists
    \begin{itemize}
      \cbe_includecollection:n {#1-provided-var}
    \end{itemize}
   }
   {
    None.
    }
 }
%
\NewDocumentCommand{\insertneededinterfaces}{m}
 {
  \paragraph{Function interfaces}
  \clist_if_in:NnTF \g_cbe_nfuncollectionlist_clist { #1 }
   {
    % Collection '#1-needed-fun' esists
    \begin{itemize}
      \cbe_includecollection:n {#1-needed-fun}
    \end{itemize}
   }
   {
    None.
   }
  \paragraph{Variable~interfaces}
  \clist_if_in:NnTF \g_cbe_nvarcollectionlist_clist { #1 }
   {
    % Collection '#1-needed-var' esists
    \begin{itemize}
      \cbe_includecollection:n {#1-needed-var}%
    \end{itemize}
   }
   {
    None.
   }
 }
%
\cs_new_protected:Npn \cbe_newpvarcollection:n #1
 {
  \clist_if_in:NnF \g_cbe_pvarcollectionlist_clist { #1 }
   {
    \clist_gput_right:Nn \g_cbe_pvarcollectionlist_clist { #1 }
   }
  \cbe_newcollection:nn { #1 } { provided-var }
 }
%
\cs_new_protected:Npn \cbe_newnvarcollection:n #1
 {
  \clist_if_in:NnF \g_cbe_nvarcollectionlist_clist { #1 }
   {
    \clist_gput_right:Nn \g_cbe_nvarcollectionlist_clist { #1 }
   }
  \cbe_newcollection:nn { #1 } { needed-var }
 }
%
\cs_new_protected:Npn \cbe_newpfuncollection:n #1
 {
  \clist_if_in:NnF \g_cbe_pfuncollectionlist_clist { #1 }
   {
    \clist_gput_right:Nn \g_cbe_pfuncollectionlist_clist { #1 }
   }
 \cbe_newcollection:nn { #1 } { provided-fun }
 }
%
\cs_new_protected:Npn \cbe_newnfuncollection:n #1
 {
  \clist_if_in:NnF \g_cbe_nfuncollectionlist_clist { #1 }
   {
    \clist_gput_right:Nn \g_cbe_nfuncollectionlist_clist { #1 }
   }
  \cbe_newcollection:nn { #1 } { needed-fun }
 }

\cs_new_protected:Npn \cbe_newcollection:nn #1 #2
 {
  \tl_if_exist:cF { g_cbe_collection_#1-#2_tl }
   { \tl_new:c { g_cbe_collection_#1-#2_tl } }
 }

\cs_new_protected:Npn \cbe_collect:nn #1 #2
 {
  \tl_gput_right:cn { g_cbe_collection_#1_tl } { #2 }
 }

\cs_new_protected:Npn \cbe_includecollection:n #1
 {
  \tl_use:c { g_cbe_collection_#1_tl }
 }
\ExplSyntaxOff

\begin{document}
\section{Interfaces}
Here some software interfaces:
\begin{int-interface}{SUP}{eGetActualSystemStatus}{ICP}
  Parameters  & None                                        \\
  Return type & System status code. Codified value          \\
  Purpose     & Obtain actual system status from \emph{SUP} \\
\end{int-interface}
%
\begin{int-interface}{SUP}{eSetOverrideRequest()}{SMB}
  Parameters  & Request code: ENTER, EXIT                   \\
  Return type & Operation result. Codified value.           \\
  Purpose     & To set an override request to \emph{SUP}    \\
\end{int-interface}
%
\begin{int-interface-var}{HAL}{ausInputVoltageSamples}{SENS, I2C}{I2C, ICP}
  Type           & Buffer of 5 samples \\
  Purpose        & To store acquired input voltage samples\\
\end{int-interface-var}
%
\section{Modules description}
Some descriptive stuff\ldots

\subsection{SUP module}
Other descriptions\ldots

Here is a list of provided interfaces:
\insertprovidedinterfaces{SUP}

\subsection{HAL module}
Other descriptions\ldots

Here is a list of provided interfaces:
\insertprovidedinterfaces{HAL}
\end{document}

我维护四个 clist 变量,用于检查接口是否已经存在,并将每个函数和变量描述添加到名为\g_cbe_<interface>-provided-fun_tl\g_cbe_<interface>-needed-fun_tl\g_cbe_<interface>-provided-var_tl、的标记列表变量中\g_cbe_<interface>-needed-var_tl,然后在\insertprovidedinterfaces{<interface>}调用时使用该变量。

至少对于这个例子,我得到了和你相同的结果。

在此处输入图片描述

答案2

它是一个远的最小示例,我不知道预期的输出应该是什么样的,但是

\DeclareRobustCommand{\insertprovidedinterfaces}[1]{%
\begingroup
\let\oldopenin\openin
\def\openin{\def\zzzz{}\oldopenin}

  \paragraph{Function interfaces}
  \IfSubStr{\pfuncollectionlist}{#1}{%
%    Collection '#1-provided-fun' exists
    \begin{itemize}
      \includecollection{#1-provided-fun}%
    \end{itemize}
  }{%   
    None.
  }%
  \paragraph{Variable interfaces}
  \IfSubStr{\pvarcollectionlist}{#1}{%
%    Collection '#1-provided-var' exists
    \begin{itemize}
      \includecollection{#1-provided-var}%
    \end{itemize}
  }{%   
    None.
  }%
\endgroup}%

\openin使错误消失。可能它只是掩盖了代码中其他地方的错误使用。

相关内容