我有一个 latex 文档,其主要部分列出了许多“任务”(供学生解决);每个任务都属于一个“脚本”,但是,所有脚本都应该打印在文档末尾的附录中。为此,构建了环境“skript”以将其内容复制到文件中,并在 LaTeX 运行结束时重新插入。任务和脚本都有编号,并且编号应该相互对应。
问题就在这里:TeX 似乎只有在将脚本重新插入到文档末尾后才会扩展脚本编号。然而,此时任务计数器显然处于最大值,导致所有脚本都获得相同的编号。
有没有办法让 TeX 在将任务计数器存储到外部文件之前扩展它?
最小示例如下(其中 count 是任务编号):
\documentclass{article}
\usepackage{skripts}
\newcounter{count}
\begin{document}
\refstepcounter{count}
Here comes task \thecount:
\begin{skript}
\thecount
\end{skript}
\refstepcounter{count}
Here comes task \thecount:
\begin{skript}
\thecount
\end{skript}
\refstepcounter{count}
Here comes task \thecount:
\begin{skript}
\thecount
\end{skript}
\refstepcounter{count}
Here comes task \thecount:
\begin{skript}
\thecount
\end{skript}
Now insert the scripts corresponding to the tasks at the document's end:
\includeSkripts
\end{document}
输出:
显然\thecount
,在“skript”环境中使用时,仅在计数器设置为最高值后才进行评估。
包“skripts”(也是最小版本)如下所示:
\ProvidesPackage{skripts}[2009/11/03 v0.1 Styledefinitionen]
\usepackage{verbatim}
\newenvironment{ex@skripts}[1]{#1}{}
\newwrite\verbatim@outSkr % Define file.
\immediate\openout\verbatim@outSkr=\jobname.skr % Open file for writing.
\def\skript{
\@bsphack
\let\do\@makeother\dospecials
\catcode`\^^M\active
\def\verbatim@processline{%
\immediate\write\verbatim@outSkr{\the\verbatim@line}}%
\immediate\write\verbatim@outSkr{\string\begin{ex@skripts}{Script}}
\verbatim@start}
\def\endskript{%
\immediate\write\verbatim@outSkr{\string\end{ex@skripts}}
\@esphack}
\newcommand*{\includeSkripts}{%
\immediate\closeout\verbatim@outSkr % Close file.
\InputIfFileExists{\jobname.skr}{}{}
\newwrite\verbatim@outSkr % Datei wird definiert
\immediate\openout\verbatim@outSkr=\jobname.skr % Open file for writing.
}
现在,我知道根据这个最小示例,我的问题有几种解决方案(例如将“count”作为参数提供给“skript”环境)。但是,在我实际的更复杂的环境中,重要的是在所描述的设置中解决问题,而无需对环境进行任何结构性更改。
编辑:我已经尝试过这个相当疯狂的破解:
\romannumeral-`X\foo
我从这里。
答案1
实现这一点的一种方法是通过将计数器值的内容明确写入文件\string
,前逐字逐句的内容开始了。
\immediate\write\verbatim@outSkr{%
\string\setcounter{count}{\number\value{count}}%
}%
逐字写入\thecount
脚本文件是没有用的,因为它总是使用最后一个计数器值(在本例中为 4),而不是logical
属于实际脚本编号的值。
\documentclass{article}
\usepackage{skripts}
\newcounter{count}
\begin{document}
\refstepcounter{count}
Here comes task \thecount:
\begin{skript}
\thecount
\end{skript}
\refstepcounter{count}
Here comes task \thecount:
\begin{skript}
\thecount
\end{skript}
\refstepcounter{count}
Here comes task \thecount:
\begin{skript}
\thecount
\end{skript}
\refstepcounter{count}
Here comes task \thecount:
\begin{skript}
\thecount
\end{skript}
Now insert the scripts corresponding to the tasks at the document's end:
\includeSkripts
\end{document}
\ProvidesPackage{skripts}[2009/11/03 v0.1 Styledefinitionen]
\usepackage{verbatim}
\newenvironment{ex@skripts}[1]{#1}{}
\newwrite\verbatim@outSkr % Datei wird definiert
\immediate\openout\verbatim@outSkr=\jobname.skr % Datei wrid zum
Schreiben geöffnet
\def\skript{%
\immediate\write\verbatim@outSkr{%
\string\setcounter{count}{\number\value{count}}%
}%
\@bsphack
\let\do\@makeother\dospecials \catcode`\^^M\active
\def\verbatim@processline{%
\immediate\write\verbatim@outSkr{\the\verbatim@line}}%
\immediate\write\verbatim@outSkr{\string\begin{ex@skripts}{Script}}
\verbatim@start}
\def\endskript{%
\immediate\write\verbatim@outSkr{\string\end{ex@skripts}} \@esphack}
\newcommand*{\includeSkripts}{%
\immediate\closeout\verbatim@outSkr %schließt die Datei
\InputIfFileExists{\jobname.skr}{}{}
% No good idea!!!!!!
%\newwrite\verbatim@outSkr % Datei wird definiert
%\immediate\openout\verbatim@outSkr=\jobname.skr % Datei wrid zum Schreiben geöffnet
}
答案2
您可能需要处理更多的计数器,因此我定义了一个\skriptcounters
接受计数器名称列表的宏;这样的列表用于将第二个参数写入ex@Skript
形式\setcounter{<name>}{<value>}
,其中的值是在skript
环境启动时计算的。
只是为了展示事物如何工作,我还使用了计数器section
(尽管更改文档中间的值并不是很好;它只是作为示例)。
\documentclass{article}
%\usepackage{skripts} % the code is in the document
\usepackage{verbatim}
\makeatletter
% here starts the code of skripts.sty
\newenvironment{ex@skripts}[2]{#2#1}{\par}
\newwrite\verbatim@outSkr % Datei wird definiert
\immediate\openout\verbatim@outSkr=\jobname.skr % Datei wrid zum Schreiben geöffnet
\newcommand{\skriptcounters}[1]{%
\gdef\skript@counters{#1}%
}
\skriptcounters{}% initialize
\newenvironment{skript}
{%
\@bsphack
\let\do\@makeother\dospecials
\catcode`\^^M\active
\def\verbatim@processline{%
\immediate\write\verbatim@outSkr{\the\verbatim@line}%
}%
\toks@={}%
\@for\next:=\skript@counters\do{%
\edef\skript@temp{\the\toks@\string\setcounter{\next}{\the\value{\next}}}%
\toks@=\expandafter{\skript@temp}%
}
\immediate\write\verbatim@outSkr{%
\string\begin{ex@skripts}{Script}{\the\toks@}%
}
\verbatim@start
}
{%
\immediate\write\verbatim@outSkr{\string\end{ex@skripts}}%
\@esphack
}
\newcommand*{\includeSkripts}{%
\immediate\closeout\verbatim@outSkr % schließt die Datei
\InputIfFileExists{\jobname.skr}{}{}
% \immediate\openout\verbatim@outSkr=\jobname.skr % Datei wrid zum Schreiben geöffnet
}
% end of code for skripts.sty (uncomment the \immediate line above)
\makeatother
\newcounter{count}
\skriptcounters{count,section}
\begin{document}
\section{Title}
\refstepcounter{count}
Here comes task \thecount:
\begin{skript}
\thecount\ in Section \thesection
\end{skript}
\refstepcounter{count}
Here comes task \thecount:
\begin{skript}
\thecount\ in Section \thesection
\end{skript}
\section{Another}
\refstepcounter{count}
Here comes task \thecount:
\begin{skript}
\thecount\ in Section \thesection
\end{skript}
\refstepcounter{count}
Here comes task \thecount:
\begin{skript}
\thecount\ in Section \thesection
\end{skript}
Now insert the scripts corresponding to the tasks at the document's end:
\section{Scripts}
\includeSkripts
\end{document}
最后\immediate
已被注释掉只是为了检查skript
环境的内容。
请注意,\end{skript}
指令应该不是缩进,否则环境将会收到一个空行。
以下是该文件的内容.skr
:
\begin{ex@skripts}{Script}{\setcounter{count}{1}\setcounter{section}{1}}
\thecount\ in Section \thesection
\end{ex@skripts}
\begin{ex@skripts}{Script}{\setcounter{count}{2}\setcounter{section}{1}}
\thecount\ in Section \thesection
\end{ex@skripts}
\begin{ex@skripts}{Script}{\setcounter{count}{3}\setcounter{section}{2}}
\thecount\ in Section \thesection
\end{ex@skripts}
\begin{ex@skripts}{Script}{\setcounter{count}{4}\setcounter{section}{2}}
\thecount\ in Section \thesection
\end{ex@skripts}