我找到了我的问题的部分答案,因此我更新了问题,并将未修改的原始帖子保留在下面以供参考。
剩下的唯一问题是如何在创建宏时将命令的实际值传递给宏,而不是在调用宏时对其进行评估。尝试了很多次\edef
,\expandafter
...没办法!
这个问题是课堂笔记中的练习没有预先确定的位置
那里的问题是在文本的任何地方写练习(如果论证逻辑的一部分被推迟到练习中,这对作者来说非常有用),然后再决定将它们放在何处(例如在章节的末尾)。
那里提供的答案确实很好,简单有效。这几乎就是我需要的,因为此外,我还想写下答案,并将它们全部发布在书的末尾。出于这个原因,我尝试以这种方式修改代码:
\documentclass{book}
\usepackage{amsthm}
\theoremstyle{remark}
\newtheorem*{SolInternal}{}
\newtheorem{ExInternal}{Exercise}[section]
\makeatletter
\let\@solutions\@empty%
\let\@exercises\@empty%
\newcommand\exercise[3][]{%
\g@addto@macro\@exercises{%
\begin{ExInternal}[#1]%
\label{exercise:\theExInternal}%
#2%
\end{ExInternal}%
}%
\global\edef\ExerciseLabel{\theExInternal}%
\g@addto@macro\@solutions{%
\begin{SolInternal}[\ExerciseLabel]%
#3%
\end{SolInternal}%
}%
}
\newcommand\exerciseshere{%
\subsection*{Exercises}
\@exercises%
\global\let\@exercises\@empty%
}
\newcommand\solutionshere{%
\chapter*{Solutions of the Exercises}
\@solutions%
\global\let\@solutions\@empty%
}
\makeatother
\begin{document}
\chapter{This is a chapter}
\section{This is a section}
You mat try exercise \ref{myExercise}
\exercise{\label{myExercise}Show that \(2+2=4\).}{\(2+2=1+1+1+1=4\).}
\exercise{Show that \(4+4=8\)}{Apply exercise \ref{myExercise}}
And there is more text around.
\exerciseshere % creates the exercises of the section
\section{This is another section}
Here we have fun.
\exercise{Prove that \(1+1=10\).}{Use the binary system.}
\exerciseshere
\solutionshere % creates the solutions of all the book
\end{document}
这很好用,它会自动为练习创建唯一的标签;但我找不到将它们传递给相应解决方案的方法。所有解决方案都获得相同的标签,即最后一个练习的标签,因为它们是在调用宏时进行评估的。我尝试使用 edef,但显然它没有达到我想要的效果……
原始帖子:
那里的问题是在文本的任何地方写练习(如果论证逻辑的一部分被推迟到练习中,这对作者来说非常有用),然后再决定将它们放在何处(例如在章节的末尾)。
那里提供的答案确实很好,简单有效。这几乎就是我需要的,因为此外,我还想写下答案,并将它们全部发布在书的末尾。出于这个原因,我尝试修改代码并将其与包合并answers
。更准确地说,我在宏的定义中添加了一个\begin{sol}#3\end{sol}
,并将参数数量增加到 3。它不起作用,结果是Runaway Error ! File ended while scanning use of \next
。临时文件已创建,但很乱。有什么解决办法吗?
我尝试过的代码:
\documentclass{article}
\usepackage{amsthm,answers}
\Newassociation{sol}{Solution}{ans}
\theoremstyle{remark}
\newtheorem{ExInternal}{Exercise}[section]
\makeatletter
\let\@exercises\@empty%
\newcommand\exercise[3][]{%
\g@addto@macro\@exercises{%
\begin{ExInternal}[#1]%
#2%
\begin{sol}%
#3%
\end{sol}%
\end{ExInternal}%
}%
}
\newcommand\exerciseshere{%
\subsection*{Exercises}
\@exercises%
\global\let\@exercises\@empty%
}
\makeatother
\begin{document}
\Opensolutionfile{ans}[ans1]
\section{Prime Numbers}
A \emph{prime number} is a positive integer other than $1$ that is only divisible by $1$ and itself.
\exercise[Euclid's Theorem]{\label{ex:euclid}Show that there are infinitely many prime numbers.}{\(n!+1\) is prime for every \(n\).}
\exerciseshere
\Closesolutionfile{ans}
\section{Solutions}
\input{ans1}
\end{document}
这是我得到的临时文件:
$ cat ans1.tex
\begin{Solution}{1.1}
n!+1\) is prime for every \(n\).\end {sol}\end {ExInternal}\global \let \@exercises \@empty
\Closesolutionfile{ans}
\section{Solutions}
\input{ans1}
\end{document}
$
答案1
感谢 Joseph Wright 对问题的回答何时使用 \edef、\noexpand 和 \expandafter?以及大卫·卡莱尔 将当前命令内容传递给宏我最终想出了一个完全令人满意(对我来说)的代码:
\documentclass{article}
\usepackage{amsthm} % used for `exercise' and `solution' environments
\usepackage{lipsum}
%*******************************************************************
% set of macros for exercises *
% (seek for ^^ to find end) *
%vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
\makeatother\theoremstyle{remark}
\newtheorem*{SolInternal}{}
\newtheorem{ExInternal}{Exercise}[section]
\makeatletter
\let\@solutions\@empty%
\let\@exercises\@empty%
\newcommand\exercise[3][]{%
% use:
% \exercise['optional label']{'text of exercise'}{'text os solution'}
% to be placed everywhere in the text, does not produce output
%
\g@addto@macro\@exercises{%
\begin{ExInternal}[#1]%
\label{exercise:\theExInternal}%
#2%
\end{ExInternal}%
\wlog{Created exercise \theExInternal}%
\edef\ExerciseLabel{[exercise:\theExInternal]}%
\expandafter\addsolution\ExerciseLabel{#3}%
}%
}
\newcommand\exerciseshere{%
%
% places all the exercises created after the last call of \exerciseshere
%
\subsection*{Exercises}% change this to whatever environment you like
\@exercises%
\global\let\@exercises\@empty%
}
\newcommand\solutionshere{%
%
% places all the solutions of the exercises from last call of \solutions
%
\section{Solutions of the Exercises}% change this to whatever environment you like
\@solutions%
\global\let\@solutions\@empty% uncomment this
}
\def\addsolution[#1]#2{%
%
% helper macro automatically called by \exercise
%
\g@addto@macro\@solutions{%
\begin{SolInternal}[{\bfseries \ref{#1}}, Page \pageref{#1}]%
\wlog{Added solution to #1}
#2%
\end{SolInternal}%
}%
}
\makeatother
%^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
% end of macros for exercises *
% (seek for vv to find beginning) *
%*******************************************************************
\begin{document}
\section{First Section}
\lipsum[1]
\exercise{compute 1+1.}{The answer is 2.}
\lipsum[2]
\exercise{\label{base3}compute 2+2.}{The answer is 4.}
\exerciseshere
\section{Second Section}
\exercise{{In which base the solution of exercise \ref{base3} is 11?}{In base 3.}
\lipsum[3]
\exerciseshere
\appendix
\solutionshere
\end{document}
请注意,可以给练习贴上标签,因为一个环境可以有多个标签。结果是: