如何让 LaTeX 在正确的位置展开?

如何让 LaTeX 在正确的位置展开?

我有一个 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}

相关内容