我正在设计一组宏,在书中进行练习,并在最后写出答案,同时在练习文件中的问题之后立即排版答案。(请参阅 MWE 的示例)。(这个想法是能够更新命令\answer
并在问题之后立即打印答案,但那是另一回事)。
我修改了包的代码endnotes
,并使用两个命令来回答问题\writesolutions
,\appendsolutions
这两个命令在处理脆弱命令的方式上有所不同。答案写在使用命令包含的输出文件中\printsolutions
。不知何故,输出文件在第 16384 个字符处被切断。在下面的 MWE 中,当我们添加更多行时,问题章节会扩展,\input ex1
但在 27 行之后,解决方案章节不再扩展,并且我们得到了一些错误。
编辑
mwe.exo
我不清楚文件的内容:运行后,它只包含 David Carlisle 指出的\begin{questions}
和\end{questions}
,而它应该包含所有答案的代码。我不明白这一点,但我怀疑问题与文件的截断有关。以下是我确定被截断的答案代码长度的方法:我定义了一个命令
\def\abcdefghijklmnopqrstuvwxyz{\relax}
如果我将其插入到正确的位置,我会得到错误。我使用错误消息知道一个答案的长度。请注意,对于其他内容,我会得到相同的错误,其中令牌Undefined control sequence
或任何其他已知命令名称被切入中间,但我无法计算字符数。\abcdefghijklmn
\addtoco
这个问题远远超出了我的知识范围。感谢所有愿意提供帮助的人!
平均能量损失
\documentclass{book}
\usepackage{filecontents}
\usepackage{xkeyval}
\usepackage{etoolbox}
\usepackage{enumitem}
% File management adapted from endnotes.sty ©2002 John Lavagnino
\makeatletter
\newwrite\@exsol
\newif\if@exsolopen
\global\@exsolopenfalse
\def\@openexsol{\immediate\openout\@exsol=\jobname.exo\relax
\global\@exsolopentrue}
% writesolutions does not expand fragile commands
% \strip@prefix trick given by egreg on TeX.SE (2016/11/09)
% http://tex.stackexchange.com/questions/338302/what-is-the-meaning-of-meaning
\long\def\writesolutions#1{%
\if@exsolopen \else \@openexsol \fi
\begingroup
\def\solution{#1}%
\newlinechar='40
\immediate\write\@exsol{\expandafter\strip@prefix\meaning\solution}%
\endgroup}
% \appendsolutions expands fragile commands first
\long\def\appendsolutions#1{%
\if@exsolopen \else \@openexsol \fi
\begingroup
\newlinechar='40
\let\protect\string
\immediate\write\@exsol{#1}%
\endgroup}
% printsolutions
\long\def\printsolutions{
\immediate\closeout\@exsol \global\@exsolopenfalse
\chapter{Solutions}
\input{\jobname.exo}}
% Settings for probleme environment in a book document
\newcounter{probleme}[chapter]
\def\theprobleme{\arabic{probleme}}
\def\problemename{Problem}
\newlist{questions}{enumerate}{10}
\setlist[questions]{label=\textit{\alph*}),ref=\textit{\alph*}}
\define@cmdkey[PRE]{problem}{title}{}
\presetkeys[PRE]{problem}{title=Problem}{}
\newenvironment{probleme}[1][]{
\setkeys[PRE]{problem}{#1}
\refstepcounter{probleme}
\appendsolutions{%
{\problemename~\theprobleme\, (page \thepage)}}
\par\noindent\textbf{\theprobleme. \cmdPRE@problem@title}
}
{}
\newcommand\answer[1]{\writesolutions{\par #1}}
\newcommand\noanswer{\relax}
\AtBeginEnvironment{questions}{%
\writesolutions{\begin{questions}}%
\renewcommand\answer[1]{\writesolutions{\item{#1}}}%
\renewcommand\noanswer{\writesolutions{\addtocounter{questionsi}{1}}}
}
\AtEndEnvironment{questions}{%
\writesolutions{\end{questions}}%
\renewcommand\answer[1]{\par #1}
\renewcommand\noanswer{\relax}
}
\makeatother
\begin{document}
\begin{filecontents*}{ex1.tex}
\begin{probleme}[title=Problem]
\begin{questions}
\item 1+1 \answer{2}
\item 2+2 \noanswer
\item 3+3 \answer{6}
\item 4+4
\end{questions}
\end{probleme}
\end{filecontents*}
\mainmatter
\chapter{Problems}
\input ex1
\input ex1
\input ex1
% Add as many similar lines as needed.
% On my computer the error appears when ex1.tex
% is included 27 times.
\backmatter
\printsolutions
\end{document}
答案1
我认为问题出在。它输入包含如下块的\printsolutions
文件\jobname.exo
{Problem\nobreakspace{}1\,(page 1)}
\begin{questions}
\item{2}
\addtocounter{questionsi}{1}
\item{6}
\end{questions}
现在,\begin{questions}
写入\jobname.exo
意味着你写入正在读取的文件。看似大小限制可能只是读取操作的缓冲问题。我猜命令\immediate\openout\@exsol=\jobname.exo
摧毁一个块的内容\jobname.exo
已经被读取并放入内存中,当读取缓冲区为空时,会从文件中读取新的块,但此时文件已经发生变化。
顺便说一句,写入操作也不完全正确。写入文件的块实际上看起来像
{Problem\nobreakspace
{}2\,
(page
1)}
\begin
{questions}
\item
{2}
\addtocounter
{questionsi}{1}
\item
{6}
\end
{questions}
至少%
需要\,
答案2
您正在使用相同的环境来回答问题和解决问题;除非您的\printsolutions
宏重新定义questions
,否则该环境将再次写入文件.exo
。
只需使用不同的名称即可。
\documentclass{book}
\usepackage{filecontents}
\usepackage{xkeyval}
\usepackage{etoolbox}
\usepackage{enumitem}
% File management adapted from endnotes.sty ©2002 John Lavagnino
\makeatletter
\newwrite\@exsol
\newif\if@exsolopen
\global\@exsolopenfalse
\def\@openexsol{\immediate\openout\@exsol=\jobname.exo\relax
\global\@exsolopentrue}
% writesolutions does not expand fragile commands
% \strip@prefix trick given by egreg on TeX.SE (2016/11/09)
% http://tex.stackexchange.com/questions/338302/what-is-the-meaning-of-meaning
\long\def\writesolutions#1{%
\if@exsolopen \else \@openexsol \fi
\begingroup
\def\solution{#1}%
\newlinechar='40
\immediate\write\@exsol{\expandafter\strip@prefix\meaning\solution}%
\endgroup}
% \appendsolutions expands fragile commands first
\long\def\appendsolutions#1{%
\if@exsolopen \else \@openexsol \fi
\begingroup
\newlinechar='40
\let\protect\string
\immediate\write\@exsol{#1}%
\endgroup}
% printsolutions
\long\def\printsolutions{
\immediate\closeout\@exsol \global\@exsolopenfalse
\chapter{Solutions}
\input{\jobname.exo}}
% Settings for probleme environment in a book document
\newcounter{probleme}[chapter]
\def\theprobleme{\arabic{probleme}}
\def\problemename{Problem}
\newlist{questions}{enumerate}{10}
\setlist[questions]{label=\textit{\alph*}),ref=\textit{\alph*}}
\define@cmdkey[PRE]{problem}{title}{}
\presetkeys[PRE]{problem}{title=Problem}{}
\newenvironment{probleme}[1][]{
\setkeys[PRE]{problem}{#1}
\refstepcounter{probleme}
\appendsolutions{%
{\problemename~\theprobleme\, (page \thepage)}}
\par\noindent\textbf{\theprobleme. \cmdPRE@problem@title}
}
{}
\newcommand\answer[1]{\writesolutions{\par #1}}
\newcommand\noanswer{\relax}
\AtBeginEnvironment{questions}{%
\writesolutions{\begin{questions}}%
\renewcommand\answer[1]{\writesolutions{\item{#1}}}%
\renewcommand\noanswer{\writesolutions{\addtocounter{questionsi}{1}}}
}
\AtEndEnvironment{questions}{%
\writesolutions{\end{questions}}%
\renewcommand\answer[1]{\par #1}
\renewcommand\noanswer{\relax}
}
\makeatother
\begin{document}
\begin{filecontents*}{ex1.tex}
\begin{probleme}[title=Problem]
\begin{questions}
\item 1+1 \answer{2}
\item 2+2 \noanswer
\item 3+3 \answer{6}
\item 4+4
\end{questions}
\end{probleme}
\end{filecontents*}
\mainmatter
\chapter{Problems}
\input ex1
\input ex1
\input ex1
% Add as many similar lines as needed.
% On my computer the error appears when ex1.tex
% is included 27 times.
\backmatter
\printsolutions
\end{document}
这是该文件的内容.exo
:
{Problem\nobreakspace
{}1\,
(page
1)}
\begin
{solutions}
\item
{2}
\addtocounter
{questionsi}{1}
\item
{6}
\end
{solutions}
{Problem\nobreakspace
{}2\,
(page
1)}
\begin
{solutions}
\item
{2}
\addtocounter
{questionsi}{1}
\item
{6}
\end
{solutions}
{Problem\nobreakspace
{}3\,
(page
1)}
\begin
{solutions}
\item
{2}
\addtocounter
{questionsi}{1}
\item
{6}
\end
{solutions}