实现相当于数千个 \savebox 的功能

实现相当于数千个 \savebox 的功能

我有一个很大的文件索引(大约 600 页),每个文件条目都需要大量计算才能添加额外的链接。计算这些链接需要相当多的时间,而且由于每个文件名都出现在索引中的多个位置,因此这些链接在索引过程中会重复生成多次。

我目前的方法是将与每个链接相关的数据缓存在 中def,但即使这样,运行也需要大约 6 个小时,而且这个时间会随着时间的推移而增加。我的想法是将此输出缓存在 中\savebox,但基于Savebox 相当于 \csname?,看来这不是一个好办法。

主要问题:

如果我不应该使用\saveboxs,我还能如何实现类似的功能,即缓存输出(至少针对几千种不同的情况)?例如,假设\MyComplicatedCode下面的 MWE 中的宏要复杂得多。除了调整之外,我还能做什么\MyComplicatedCode,并且能够重用输出而无需重新计算它?

  • 即使我完全理解扩展,我认为尝试扩展代码以便仅存储要添加的最终链接仍需要大量工作。

  • 将代码排版成 .pdf 也不起作用,因为该代码会生成指向其他文件的链接。

子问题:

  • 允许的 s数量限制是多少\savebox
  • 可以通过改变一些参数来增加这些吗?

笔记:

  • 我目前需要大约 1,500\savebox秒,并且随着时间的推移可能会增加到大约 5,000 秒。

参考:

代码:

由于使用\savebox不是一个好主意,因此这个 MWE 并不那么重要。在煮熟的下面的例子中,我正在缓存从给定的分层文件名中提取的文件的名称。如果我创建一个,该示例可以正常工作\def,但我似乎无法使用实现相同的功能\savebox。目前产生的结果如下:

在此处输入图片描述

\documentclass{article}
\usepackage{pgffor}
\usepackage{xstring}

\newcommand*{\MyFileNames}{%
    ../../DirNameA/FileA1.tex,%
    ../../DirNameA/FileA2.tex,%
    ../../DirNameB/FileB1.tex,%
    ../../DirNameB/FileB2.tex%
}%

\newcommand*{\MyComplicatedCode}[4][1]{%
    \StrBehind[#1]{#2}{#3}[#4]%
}%


\begin{document}
%% Create \newcommands
\foreach \X in \MyFileNames {%
    \MyComplicatedCode[3]{\X}{/}{\ExtractedFileName}%
    \expandafter\xdef\csname MyCommand\X\endcsname{File Name = \ExtractedFileName}%
    %\par\string\MyCommand\X: \expandafter\csname MyCommand\X\endcsname
}%

%% Now use the \newcommands
Command ../../DirNameB/FileB1.tex:
\expandafter\csname MyCommand../../DirNameB/FileB1.tex\endcsname


\bigskip
\foreach \X in \MyFileNames {%
    \MyComplicatedCode[3]{\X}{/}{\ExtractedFileName}%
    \expandafter\newsavebox\csname MySaveBox\X\endcsname%
    \expandafter\savebox\csname MySaveBox\X\endcsname{Savebox Value = \ExtractedFileName}%
}%

%% Now use the \savebox
Savebox ../../DirNameB/FileB1.tex:
\expandafter\usebox\csname MySaveBox../../DirNameB/FileB1.tex\endcsname%

\end{document}

答案1

您需要\X在将其传递给字符串拆分函数之前进行扩展,并且如果使用循环结构,则需要使框分配全局化。

\documentclass{article}
\usepackage{pgffor}
\usepackage{xstring}

\newcommand*{\MyFileNames}{%
    ../../DirNameA/FileA1.tex,%
    ../../DirNameA/FileA2.tex,%
    ../../DirNameB/FileB1.tex,%
    ../../DirNameB/FileB2.tex%
}%

\newcommand*{\MyComplicatedCode}[4][1]{%
    \StrBehind[#1]{#2}{#3}[#4]%
}%


\begin{document}
%% Create \newcommands
\foreach \X in \MyFileNames {%
    \MyComplicatedCode[3]{\X}{/}{\ExtractedFileName}%
    \expandafter\xdef\csname MyCommand\X\endcsname{File Name = \ExtractedFileName}%
    %\par\string\MyCommand\X: \expandafter\csname MyCommand\X\endcsname
}%

%% Now use the \newcommands
Command ../../DirNameB/FileB1.tex:
\expandafter\csname MyCommand../../DirNameB/FileB1.tex\endcsname


\bigskip
\foreach \X in \MyFileNames {%
    \edef\tmp{\noexpand\MyComplicatedCode[3]{\X}{/}{\noexpand\ExtractedFileName}}%
    \tmp
    \expandafter\newsavebox\csname MySaveBox\X\endcsname%
    \global\expandafter\setbox\csname MySaveBox\X\endcsname\hbox{Savebox Value = \ExtractedFileName}%
}%

%% Now use the \savebox
Savebox %../../DirNameB/FileB1.tex:
\expandafter\usebox\csname MySaveBox../../DirNameB/FileB1.tex\endcsname%

\end{document}

虽然您可能应该只使用宏而不是框来实现这一点。或者您可以使用单个框,这取决于它们的使用方式。为每个框使用单独的寄存器有点浪费,但它可以轻松地以任意顺序访问各个条目。如果您实际上要按顺序处理所有项目,则可以将它们存储在一个框中。(无论如何,您都可以将它们存储在一个框中,但访问除第一个或最后一个之外的项目可能会变慢)

相关内容