我是一个相当有经验的 LaTeX 用户。现在,我正在尝试学习 LaTeX 包和类的内部原理。我对 TeX 编码了解不多。我认为一个好的开始是尝试制作一个可以排版问题和解决方案的小包。我已经看过很多这样的包,比如、examdesign
等等。对于初学者来说,我了解其中一些类/包的总体逻辑,但不是所有的细节。所以,我想自己做一些事情来获得更多的见解。这是我对一个简单包的尝试,我称之为:exams
answers
qakeysoln
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
% This is file 'qakeysoln.sty', version 1.0, May 2015. %
% %
% This package and accompanying files may be distributed and/or %
% modified under the conditions of the LaTeX Project Public License, %
% either version 1.3 of this license or any later version. The latest %
% version of this license is in http://www.latex-project.org/lppl.txt %
% and version 1.3 or later is part of all distributions of LaTeX %
% version 2005/12/01 or later. %
% %
% The LPPL maintenance status of this software is 'author-maintained'. %
% %
% This software is provided 'as it is', without warranty of any kind, %
% either expressed or implied, including, but not limited to, the %
% implied warranties of merchantability and fitness for a particular %
% purpose. %
% %
% Copyright (c) 2015 Rav Bell. %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
\@ifpackageloaded{newenviron}{}{\RequirePackage{newenviron}}
\@ifpackageloaded{etoolbox}{}{\RequirePackage{etoolbox}}
\StyleFilePurpose{For formatting questions, optionally answer keys/hints, and solutions}
\ProvidesPackage{qakeysoln}[2015/05/11 Rav Bell]
\NeedsTeXFormat{LaTeX2e}[2011/06/27]
% Initialize a global list to hold all the solutions
\listxadd{\qaks@solutionlist}{}
% Provide a command to the user to list all the solutions
\newcommand{\thesolutionlist}{%
\show\qaks@solutionlist
\begin{enumerate}%
\renewcommand*{\do}[1]{\item ##1}
\dolistloop{\qaks@solutionlist}
\end{enumerate}
}
% Define the question environment
% to be used inside a bigger environment like essayq, shortanswer etc.
\newcommand{\qaks@DefineQuestion}{
\newenvironment{question}{\item
%Use a temporary list \temp@solnlist to store solutions. This is useful if several
%solution environments are defined by a user within one question
%environment (perhaps as alternate solutions). Then all these are
%stored in a single temp list and then the list is appended to the
%global list
% Define solution environment inside question env so that it cannot be
% used outside of the question environment
\newenviron{solution}{}{\xappto{\temp@solnlist}{\solutionbody {\@@par}}} %
}{%
%Add the solutions collected to the global list of solutions
\listxadd{\qaks@solutionlist}{%
% noexpand so that I want it to expand later when typesetting the whole
%solution list. But note that \temp@solnlist is expanded right here.
\noexpand\begin{enumerate}
\forlistloop{\noexpand\item\noexpand[\noexpand]}{\temp@solnlist}
\noexpand\end{enumerate}
}
%delete all the solutions in the temporary list for the current question
\gdef\temp@solnlist{}
}
}
% define a essay question environment:
\newenvironment{essayq}{%
\begin{enumerate}%
\qaks@DefineQuestion
}{\end{enumerate}}
这是我用来测试的示例 LaTeX 文件。
\documentclass[a4paper]{article}
\usepackage{qakeysoln}
\begin{document}
\title{A sample file to demonstrate the Questions and Solns}
\maketitle
\section{Questions}
\label{sec:questions}
\begin{essayq}
\begin{question}
What is $2\times3$?
\begin{solution}
$ 3 + 3 = 6$
\end{solution}
\end{question}
\begin{question}
What is $3\times2$?
\begin{solution}
Here is the solution: $2 + 2 + 2 = 6$
Note that this was such a trivial solution that it required no
explanations.
\end{solution}
\begin{solution}
This is an \textbf{alternative solution}:
$((2+2)+2) = 6$
\end{solution}
\end{question}
\end{essayq}
\clearpage
\section{Solutions}
\label{sec:solns}
\thesolutionlist
\end{document}
这会在编译时引发错误。结果发现问题出在\textbf{alternative solution}
。如果我删除\textbf
。它工作正常。我尝试了很多不同的东西,包括\noexpand
和\protect
。但都没有用。我觉得我在这里遇到了难题。我很确定这对这里的一些专家来说一定是小菜一碟。我期待在这里理解并找到解决方案。
答案1
您在两个地方的扩展太深了:添加\expandonce
。
第一的:
\newenviron{solution}{}{\xappto{\temp@solnlist}{\expandonce{\solutionbody} {\@@par}}} %
第二:
\listxadd{\qaks@solutionlist}{%
%noexpand so that I want it to expand later when typesetting the whole
%solution list. But note that \temp@solnlist is expanded right here.
\noexpand\begin{enumerate}
\forlistloop{\noexpand\item[]}{\expandonce{\temp@solnlist}}
\noexpand\end{enumerate}
(我删除了一些无用的\noexpand
标记)。
另一个错误:
\renewcommand{\do}[1]{\item ##1}
您有\renewcommand*
不允许\par
在参数中使用标记的情况。
帮自己一个忙,缩进您的代码。避免在定义主体中出现空行,它们会变成\par
不必要的标记。