我有以下代码,它使用文档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}
当我然后include
或input
该片段时,它将不起作用,除非\QuestionPointValue
已经定义,然后它将在任何地方使用\QuestionPointValue
在TempFile
有没有办法定义,以便当我最终将它包含在另一个将生成我的答案键的 .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}
怎么运行的?
- 它将每个环境之前
TempFile.tex
的明确定义写入文件中。\newcommand
Sol
- 为了做到这一点,它使用命令
Writetofile
(在指定文件上写入一些字符串,进行命令替换\newcommand
)和环境Filesave
(允许在文件上按原样写入 LaTeX 代码,而不进行命令替换等)。 - 要做到这一点,语法有点难以处理,事实上,为了正确定义,
\QuestionPointValue
您必须使用Filesave
,但后者不会替换内容,因此您需要定义另一个命令,称为\pippo
并通过来定义它\Writetofile
。 - 但是,如果您
\pippo
在里面使用\Writetofile
,它会产生错误,因为它会尝试用其内容替换它。唯一的方法是在前面放置\protect
(如文档中所写answer
)以表明\Writetofile
您正在编写关键字。但最后,\protect
仍然在定义中,您无法正确运行\def
。 - 所以你需要定义
\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
环境之前。