如何将新命令的内容传递给答案包?

如何将新命令的内容传递给答案包?

我有以下代码,它使用文档exam包裹answers。我想将问题的分值传递到一个单独的文件中,以便我可以在单独的“答案键” .tex 文件中使用该问题的分值。

如果我将一个文字数字传递到开关,一切就可以正常工作。

这很有效

\documentclass[addpoints, 12pt]{exam}

% These provide a facility to collect up solutions/answers and grading guides into a separate file(s)
\printanswers 
\usepackage{answers}

\newcommand{\fnGradingGuide}{TempFile}

\Newassociation{sol}{Sol}{\fnGradingGuide} % ExamGradingGuideCore.tex is the intermediate file that stores stuff
\Newassociation{gradingGuide}{GradingGuide}{\fnGradingGuide}

\Opensolutionfile{\fnGradingGuide} 

% these are the macros that we'll use in the destination file to transform the things we stuff into the TempFile into something that the user will actually see
\renewenvironment{Sol}[2]{\textbf{Solution #1:\hfill#2 Points}\begin{flushleft}}{\end{flushleft}}
\renewenvironment{GradingGuide}[1]{\begin{flushleft}\textbf{Grading Guide for Question #1}\newline}{\end{flushleft}}

\newcommand{\QuestionPointValue}{30}

\begin{document}

    \begin{questions}


    \titledquestion{Syntax and Semantics}[\QuestionPointValue] 

    \textbf{Please write out what the program will print to the screen in this column} \\
    Please note that this code compiles, runs, and terminates. \

    \begin{sol}{30} <============ Note the literal '30' here!!!!!!!!!!!!!!!!!!!  This 30 is the points for the question
        This is the solution to question 1
    \end{sol}

    \end{questions}

    \Closesolutionfile{\fnGradingGuide}
    \centering {\Large Solutions} \\
    \input{\fnGradingGuide}

\end{document}

笔记:为了简单起见,这是一个单文件示例,但它仍然可以演示我遇到的问题。

额外文件()的内容TempFile.tex将包含:

临时文件:

\begin{Sol}{1}
{30} <====== THIS '30' IS THE THING I"M INTERESTED IN
^^I^^IThis is the solution to question 1
^^I
\end{Sol}

现在,如果我使用宏来定义点值(像这样:)\newcommand{\QuestionPointValue}{30},然后将该宏传递到sol环境中,我将得到以下内容。

新版本,这不起作用:

\documentclass[addpoints, 12pt]{exam}

% These provide a facility to collect up solutions/answers and grading guides into a separate file(s)
\printanswers 
\usepackage{answers}

\newcommand{\fnGradingGuide}{TempFile}

\Newassociation{sol}{Sol}{\fnGradingGuide} % ExamGradingGuideCore.tex is the intermediate file that stores stuff
\Newassociation{gradingGuide}{GradingGuide}{\fnGradingGuide}

\Opensolutionfile{\fnGradingGuide} 
\renewenvironment{Sol}[2]{\textbf{Solution #1:\hfill#2 Points}\begin{flushleft}}{\end{flushleft}}
\renewenvironment{GradingGuide}[1]{\begin{flushleft}\textbf{Grading Guide for Question #1}\newline}{\end{flushleft}}

\newcommand{\QuestionPointValue}{30} % <====== This time we're using this

\begin{document}

    \begin{questions}


    \titledquestion{Syntax and Semantics}[\QuestionPointValue] 

    \textbf{Please write out what the program will print to the screen in this column} \\
    Please note that this code compiles, runs, and terminates. \

    \begin{sol}{\QuestionPointValue}  % <======= literal 30 has been replaced by the macro/newcommand
        This is the solution to question 1
    \end{sol}

    \renewcommand{\QuestionPointValue}{10}
    \titledquestion{Q2}[\QuestionPointValue] 

    \textbf{Q2 body}

    \begin{sol}{\QuestionPointValue}
        This is the solution to question 2
    \end{sol}

    \end{questions}

    \Closesolutionfile{\fnGradingGuide}
    \centering {\Large Solutions} \\
    \input{\fnGradingGuide}

\end{document}

这不起作用,因为TempFile包含新命令而不是完全展开的值 30:

\begin{Sol}{1}
{\QuestionPointValue}  <================= I was hoping this would still be 30, but instead it's the new command instead
^^I^^IThis is the solution to question 1
^^I
\end{Sol}

当我然后includeinput该片段时,它将不起作用,除非\QuestionPointValue已经定义,然后它将在任何地方使用\QuestionPointValueTempFile

有没有办法定义,以便当我最终将它包含在另一个将生成我的答案键的 .TeX 文件中时,\QuestionPointValue我可以将它用作“参数” ?TempFile

我尝试在几个地方使用 \the,但遗憾的是,我近乎盲目的猜测没有奏效

答案1

环境sol尽力编写精确的环境内容复制到辅助文件中。

\Writetofile不过,您可以通过修补 的定义来自动化使用 的技巧\sol

\documentclass[addpoints, 12pt]{exam}
\usepackage{answers}
\usepackage{etoolbox}

% These provide a facility to collect up solutions/answers and grading 
% guides into a separate file(s)
\printanswers 

\newcommand{\fnGradingGuide}{TempFile}

% ExamGradingGuideCore.tex is the intermediate file that stores stuff
\Newassociation{sol}{Sol}{\fnGradingGuide} 
\Newassociation{gradingGuide}{GradingGuide}{\fnGradingGuide}

\preto{\sol}{%
  \Writetofile{\fnGradingGuide}{\def\string\QuestionPointValue{\QuestionPointValue}}%
}

\Opensolutionfile{\fnGradingGuide} 
\renewenvironment{Sol}[2]
  {\textbf{Solution #1:\hfill#2 Points}\begin{flushleft}}
  {\end{flushleft}}
\renewenvironment{GradingGuide}[1]
  {\begin{flushleft}\textbf{Grading Guide for Question #1}\newline}
  {\end{flushleft}}

\newcommand{\QuestionPointValue}{30} % <====== This time we're using this

\begin{document}

    \begin{questions}

    \titledquestion{Syntax and Semantics}[\QuestionPointValue] 

    \textbf{Please write out what the program will print to the screen in this column} \\
    Please note that this code compiles, runs, and terminates.

    \begin{sol}{\QuestionPointValue}
        This is the solution to question 1
    \end{sol}

    \renewcommand{\QuestionPointValue}{10}
    \titledquestion{Q2}[\QuestionPointValue] 

    \textbf{Q2 body}

    \begin{sol}{\QuestionPointValue}
        This is the solution to question 2
    \end{sol}

    \end{questions}

    \Closesolutionfile{\fnGradingGuide}
    \begin{center}\Large Solutions\end{center}
    \input{\fnGradingGuide}

\end{document}

在此处输入图片描述

答案2

我设法解决了这个问题,方法是使用answer包中定义的命令组合。这是一个丑陋的解决方案,因为您需要复制并粘贴相同的四行:我无法将它们嵌入\newcommand或嵌入中\newenvironment

这是解决方案,其工作原理如下。简单来说,你必须在每个sol环境之前复制并粘贴以下四行:

    \Writetofile{\fnGradingGuide}{\def\pippo{\QuestionPointValue}}
    \begin{Filesave}{\fnGradingGuide}
\renewcommand{\QuestionPointValue}{\pippo}
    \end{Filesave}

以下是完整文档:

\documentclass[addpoints, 12pt]{exam}

% These provide a facility to collect up solutions/answers and grading guides into a separate file(s)
\printanswers 
\usepackage{answers}

\newcommand{\fnGradingGuide}{TempFile}

\Newassociation{sol}{Sol}{\fnGradingGuide}
\Newassociation{gradingGuide}{GradingGuide}{\fnGradingGuide}

\Opensolutionfile{\fnGradingGuide} 
\renewenvironment{Sol}[2]{\textbf{Solution #1:\hfill#2 Points}\begin{flushleft}}{\end{flushleft}}
\renewenvironment{GradingGuide}[1]{\begin{flushleft}\textbf{Grading Guide for Question #1}\newline}{\end{flushleft}}

\newcommand{\QuestionPointValue}{30}

%%%%%%% THIS IS ONE IMPORTANT LINE
\let\pippo\protect

\begin{document}

    \begin{questions}

%%% Q1
    \titledquestion{Syntax and Semantics}[\QuestionPointValue] 

    \textbf{Please write out what the program will print to the screen in this column} \\
    Please note that this code compiles, runs, and terminates. \

%% THESE ARE THE LINES YOU NEED TO COPY AND PASTE JUST BEFORE EACH sol ENVIRONMENT
    \Writetofile{\fnGradingGuide}{\def\pippo{\QuestionPointValue}}
    \begin{Filesave}{\fnGradingGuide}
\renewcommand{\QuestionPointValue}{\pippo}
    \end{Filesave}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    \begin{sol}{\QuestionPointValue}
        This is the solution to question 1
    \end{sol}

%%% Q2
    \renewcommand{\QuestionPointValue}{10}
    \titledquestion{Q2}[\QuestionPointValue] 

    \textbf{Q2 body}


    \Writetofile{\fnGradingGuide}{\def\pippo{\QuestionPointValue}}
    \begin{Filesave}{\fnGradingGuide}
\renewcommand{\QuestionPointValue}{\pippo}
    \end{Filesave}
    \begin{sol}{\QuestionPointValue}
        This is the solution to question 2
    \end{sol}

%%% Q3
\renewcommand{\QuestionPointValue}{50}
    \titledquestion{Q3}[\QuestionPointValue] 

    \textbf{Q3 body}
    \Writetofile{\fnGradingGuide}{\def\pippo{\QuestionPointValue}}
    \begin{Filesave}{\fnGradingGuide}
\renewcommand{\QuestionPointValue}{\pippo}
    \end{Filesave}
    \begin{sol}{\QuestionPointValue}
        This is the solution to question 3
    \end{sol}

    \end{questions}

    \Closesolutionfile{\fnGradingGuide}
    \centering {\Large Solutions} \\
    \input{\fnGradingGuide}

\end{document}

如您所见,结果如下:

怎么运行的?

  1. 它将每个环境之前TempFile.tex的明确定义写入文件中。\newcommandSol
  2. 为了做到这一点,它使用命令Writetofile(在指定文件上写入一些字符串,进行命令替换\newcommand)和环境Filesave(允许在文件上按原样写入 LaTeX 代码,而不进行命令替换等)。
  3. 要做到这一点,语法有点难以处理,事实上,为了正确定义,\QuestionPointValue您必须使用Filesave,但后者不会替换内容,因此您需要定义另一个命令,称为\pippo并通过来定义它\Writetofile
  4. 但是,如果您\pippo在里面使用\Writetofile,它会产生错误,因为它会尝试用其内容替换它。唯一的方法是在前面放置\protect(如文档中所写answer)以表明\Writetofile您正在编写关键字。但最后,\protect仍然在定义中,您无法正确运行\def
  5. 所以你需要定义\protect它自己,并且,为了不破坏它的定义,我把这行放在\let\pippo\protect序言中,所以\pippo现在等于\protect,你可以简单地重新定义\pippo

我希望这能解决您的问题。然后,如果您需要将其包含在另一份文档中,请记住在序言中TempFile.tex定义该命令,否则第一个文档将无法识别它。\QuestionPointValue\renewcommand


编辑

感谢黄威利,我的回答可以简化。正如他所说

命令\Writetofile将第二个参数扩展两次

因此您只需编写一行即可:

\Writetofile{\fnGradingGuide}{\def\noexpand\noexpand\noexpand\QuestionPointValue{\QuestionPointValue}}

在每个sol环境之前。

当然,您可以创建一个如下命令:

\newcommand{\PrintPoint}[1]{\Writetofile{\fnGradingGuide}{\def\noexpand\noexpand\noexpand #1{#1}}}

你可以使用它作为

\PrintPoint{\QuestionPointValue}

在每个sol环境之前。

相关内容