在 \newcommand 中使用 \VerbatimOut -> FancyVerbError

在 \newcommand 中使用 \VerbatimOut -> FancyVerbError

我正在创建一个包含问题和答案文档的练习类。我有一个命令,\question{}我可以在命令中写问题。我创建了一个与问题相关的框,学生可以在其中写答案。这个框位于文档末尾的新页面中,以便在打印时将问题和答案文档分开。

这是我正在创建的类的一个最小示例。

\documentclass{article}

\usepackage[latin1]{inputenc}
\usepackage{verbatim}
\usepackage{fancyvrb}
\usepackage[theorems,breakable,skins]{tcolorbox}
\usepackage{varwidth}
\usepackage{multido}




\newcounter{question}[section]
\newcommand{\question}[1]{\noindent\stepcounter{question}
    \begin{tcolorbox}[breakable,colback=black!10!white,arc=0mm,toprule=0mm,leftrule=0mm,rightrule=0mm,bottomrule=0mm,after skip=0.2cm,before skip=0.2cm,bottom=0cm,top=0cm,left=0cm,right=0cm]
        \textbf{Q\thequestion \ :} \textit{#1}
    \end{tcolorbox}}





\newcounter{docanswer}[section]
\newcommand{\docanswer}[1]{\stepcounter{docanswer}
        \begin{tcolorbox}[enforce breakable, break at=20cm/0cm,pad at break=1mm,enhanced,colback=yellow!10!white,fonttitle=\bfseries,underlay={\begin{tcbclipinterior}\draw[help lines,step=2mm,white!95!black,shift={(interior.north west)}](interior.south west) grid (interior.north east);\end{tcbclipinterior}},arc=0mm,toprule=0.5mm,leftrule=0.5mm,rightrule=0.5mm,bottomrule=0.5mm,after skip=0cm,before skip=0cm,bottom=0cm,top=0cm,left=0cm,right=0cm]\textbf{Q\thedocanswer :\ }
            #1
        \end{tcolorbox}}



\newcommand{\answerdocument}{
            \newpage
            \multido{\numero=1+1}{\thequestion}{\docanswer{\input{answer_document_\numero.tex}}}
        }



        %% Command to minimise the code
\newcommand{\AD}[1]{
            \begin{VerbatimOut}{answer_document_\thequestion.tex}
                #1
            \end{VerbatimOut}
        }


\begin{document}

            \question{This is a first question}
            \begin{VerbatimOut}{answer_document_\thequestion.tex}
                This is the answer document for the first question
                \vspace{3cm}
            \end{VerbatimOut}


            \question{This is a second question}
            \begin{VerbatimOut}{answer_document_\thequestion.tex}
                This is the answer document for the second question
                \vspace{4cm}
            \end{VerbatimOut}


            %% This works, but I want to create a command (\AD) in order to minimise the code

            %\question{This is a third question}    
            %\AD{This is the answer document for the third question
            %   \vspace{4cm}}

            \answerdocument

\end{document}

我的问题是我想创建一个\newcommand{AD},以便如第三个问题所示,避免输入

\begin{VerbatimOut}{answer_document_\thequestion.tex}
\end{VerbatimOut}{answer_document_\thequestion.tex}

当我使用我的新命令时 \AD{This is the answer document for the third question},我有

FancyVerbError

这是有错误的代码

\documentclass{article}

\usepackage[latin1]{inputenc}
\usepackage{verbatim}
\usepackage{fancyvrb}
\usepackage[theorems,breakable,skins]{tcolorbox}
\usepackage{varwidth}
\usepackage{multido}




\newcounter{question}[section]
\newcommand{\question}[1]{\noindent\stepcounter{question}
    \begin{tcolorbox}[breakable,colback=black!10!white,arc=0mm,toprule=0mm,leftrule=0mm,rightrule=0mm,bottomrule=0mm,after skip=0.2cm,before skip=0.2cm,bottom=0cm,top=0cm,left=0cm,right=0cm]
        \textbf{Q\thequestion \ :} \textit{#1}
    \end{tcolorbox}}





\newcounter{docanswer}[section]
\newcommand{\docanswer}[1]{\stepcounter{docanswer}
        \begin{tcolorbox}[enforce breakable, break at=20cm/0cm,pad at break=1mm,enhanced,colback=yellow!10!white,fonttitle=\bfseries,underlay={\begin{tcbclipinterior}\draw[help lines,step=2mm,white!95!black,shift={(interior.north west)}](interior.south west) grid (interior.north east);\end{tcbclipinterior}},arc=0mm,toprule=0.5mm,leftrule=0.5mm,rightrule=0.5mm,bottomrule=0.5mm,after skip=0cm,before skip=0cm,bottom=0cm,top=0cm,left=0cm,right=0cm]\textbf{Q\thedocanswer :\ }
            #1
        \end{tcolorbox}}



\newcommand{\answerdocument}{
            \newpage
            \multido{\numero=1+1}{\thequestion}{\docanswer{\input{answer_document_\numero.tex}}}
        }



        %% Command to minimise the code
\newcommand{\AD}[1]{
            \begin{VerbatimOut}{answer_document_\thequestion.tex}
                #1
            \end{VerbatimOut}
        }


\begin{document}

            \question{This is a first question}
            \begin{VerbatimOut}{answer_document_\thequestion.tex}
                This is the answer document for the first question
                \vspace{3cm}
            \end{VerbatimOut}


            \question{This is a second question}
            \begin{VerbatimOut}{answer_document_\thequestion.tex}
                This is the answer document for the second question
                \vspace{4cm}
            \end{VerbatimOut}


            % This works, but I want to create a command (\AD) in order to minimise the code
            \question{This is a third question}
            % Begin of my problem
            \AD{This is the answer document for the third question
                \vspace{4cm}}
            % End of my problem             
            \answerdocument

\end{document}

答案1

这是一个带有的版本tcbverbatimwrite——tcolorbox无需加载另一个verbatim包,因为tcolorbox已经处于活动状态。

里面\AD应该\end{tcbverbatimwrite}是一个字符串而不是令牌\end{tcbverbatimwrite},所以\scantokens{...}是必要的。

然而,此代码不适用于该VerbatimOut方法。

\documentclass{article}

\usepackage[latin1]{inputenc}
\usepackage[theorems,breakable,skins]{tcolorbox}
\usepackage{varwidth}
\usepackage{multido}

\usepackage{xparse}


\newcounter{question}[section]
\newcommand{\question}[1]{\noindent\stepcounter{question}%
  \begin{tcolorbox}[breakable,colback=black!10!white,arc=0mm,toprule=0mm,leftrule=0mm,rightrule=0mm,bottomrule=0mm,after skip=0.2cm,before skip=0.2cm,bottom=0cm,top=0cm,left=0cm,right=0cm]
    \textbf{Q\thequestion \ :} \textit{#1}
  \end{tcolorbox}
}


\newcounter{docanswer}[section]
\newcommand{\docanswer}[1]{\stepcounter{docanswer}%
  \begin{tcolorbox}[enforce breakable, break at=20cm/0cm,pad at break=1mm,enhanced,colback=yellow!10!white,fonttitle=\bfseries,underlay={\begin{tcbclipinterior}\draw[help lines,step=2mm,white!95!black,shift={(interior.north west)}](interior.south west) grid (interior.north east);\end{tcbclipinterior}},arc=0mm,toprule=0.5mm,leftrule=0.5mm,rightrule=0.5mm,bottomrule=0.5mm,after skip=0cm,before skip=0cm,bottom=0cm,top=0cm,left=0cm,right=0cm]\textbf{Q\thedocanswer :\ }
    #1
  \end{tcolorbox}
}



\newcommand{\answerdocument}{%
  \newpage
  \multido{\numero=1+1}{\thequestion}{\docanswer{\input{answer_document_\numero.tex}}}
}



%% Command to minimise the code
\newcommand{\AD}[1]{%
  \scantokens{\begin{tcbverbatimwrite}{answer_document_\number\value{question}.tex}
      #1
    \end{tcbverbatimwrite}
  }%
}


\begin{document}
\question{This is a first question}
\AD{%
  This is the answer document for the first question
}


\question{This is a second question}
\AD{%
  This is the answer document for the second question
}

\question{This is a third question}
\AD{%
  This is the answer document for the third question
}
\answerdocument

\end{document}

答案2

这是回答该问题的另一种方法。

tcolorbox软件包支持将下部框部件保存到文件中。因此,答案写在后面\tcblower。为此,应使用环境。

节省是通过

savelowerto=answer_document_\thetcbcounter.tex,

要隐藏下半部分,请使用

lowerbox=ignored,

另外,我使用记录tcolorbox的特点

record={\string\docanswer{\thetcbcounter}},

这记住已经给出了这样的答案并且之后应该会用到。

最后,和\tcbstartrecording用于开始和停止记录和加载结果。\tcbstoprecording\tcbinputrecords

整个文件如下:

\documentclass{article}

\usepackage[latin1]{inputenc}
\usepackage[theorems,breakable,skins]{tcolorbox}
\usepackage{varwidth}

\newcounter{question}[section]

\newtcolorbox[use counter=question]{question}[1][]{%
  breakable,colback=black!10!white,
  arc=0mm,toprule=0mm,leftrule=0mm,rightrule=0mm,bottomrule=0mm,
  after skip=0.2cm,before skip=0.2cm,bottom=0cm,top=0cm,left=0cm,right=0cm,
  fontupper=\itshape,
  before upper={\textbf{\upshape Q\thetcbcounter\ :\ }},
  lowerbox=ignored,
  savelowerto=answer_document_\thetcbcounter.tex,
  record={\string\docanswer{\thetcbcounter}},
  #1
}

\newcommand{\docanswer}[1]{%
  \begin{tcolorbox}[breakable,break at=20cm/0cm,pad at break=1mm,enhanced,
    colback=yellow!10!white,fonttitle=\bfseries,
    underlay={\begin{tcbclipinterior}\draw[help lines,step=2mm,white!95!black,shift={(interior.north west)}](interior.south west) grid (interior.north east);\end{tcbclipinterior}},
    arc=0mm,toprule=0.5mm,leftrule=0.5mm,rightrule=0.5mm,bottomrule=0.5mm,after skip=0cm,before skip=0cm,bottom=0cm,top=0cm,left=0cm,right=0cm]
      \textbf{Q#1\ :\ }
      \input{answer_document_#1.tex}%
  \end{tcolorbox}}

\newcommand{\answerdocument}{%
  \newpage%
  \tcbinputrecords%
}

\begin{document}

\tcbstartrecording

\begin{question}
  This is a first question
\tcblower
  This is the answer document for the first question
  \vspace{3cm}
\end{question}

\begin{question}
  This is a second question
\tcblower
  This is the answer document for the second question
  \vspace{4cm}
\end{question}

\tcbstoprecording%

\answerdocument

\end{document}

相关内容