背景

背景

背景

使用本网站中的一些答案,我想出了一个解决方案,用于构建一个方程式列表(带有tocloft),以便其中两个或多个方程式可以在一个align环境中分组高级排版比较简单:

\documentclass{article}
\usepackage{xparse}
\usepackage{etoolbox}
\usepackage{amsmath}
\usepackage{tocloft}

\usepackage{blindtext}

% Add a new list for equations
\newcommand{\loename}{List of equations}
\newlistof{equations}{equ}{\loename}
\newcommand{\aligneqs}[2]%
    {\addcontentsline{equ}{equations}{\protect\numberline{\ref{#2}}#1}}
\setlength{\cftequationsnumwidth}{2.5em}

% https://tex.stackexchange.com/q/451/53787
% https://tex.stackexchange.com/q/16883/53787
\makeatletter
    % Temporary lists: store equations, references, and deferred commands
    \gdef\listeqs{}
    \gdef\listrefs{}
    \gdef\listdefers{}
    \newcounter{DeferredCommands}

    % Converts a number to Roman notation
    % https://tex.stackexchange.com/q/9718/53787
    % https://tex.stackexchange.com/q/23487/53787
    \newcommand*{\rom}[1]{\expandafter\@slowromancap\romannumeral #1@}

    % Add an element to a list
    \def\addtolist#1#2{%
        \g@addto@macro{#1}{#2,}
    }

    % Add an element to a list, expanding it first
    % https://tex.stackexchange.com/q/67367/53787
    \def\addexpandedtolist#1#2{%
        \edef\ATL@temp{\noexpand\g@addto@macro\noexpand#1{\noexpand#2,}}
        \ATL@temp
    }

    % Defers the execution of a command, storing it in a list
    \DeclareDocumentCommand{\DeferCommand}{mm}{%
        \stepcounter{DeferredCommands}
        \expandafter\def\csname DC@\rom{\arabic{DeferredCommands}}\endcsname{#2}
        \addexpandedtolist{#1}{DC@\rom{\arabic{DeferredCommands}}}
    }

    % Inserts an equation, its reference, and its TOC line to their
    % respective lists
    \DeclareDocumentCommand{\InsertEquation}{mmm}{%
        \addtolist{\listeqs}{#1}
        \addtolist{\listrefs}{#3}
        \DeferCommand{\listdefers}{\aligneqs{#2}{#3}}
    }

    % Execute all the deferred commands of the given list
    % https://tex.stackexchange.com/q/28787/53787
    \DeclareDocumentCommand{\DeferredExecute}{m}{%
        \@for \i:=#1 \do{\@nameuse{\i}}
        \setcounter{DeferredCommands}{0}
        \let#1\@empty
    }

    % http://handyfloss.net/2007.08/latex-programming-how-to-implement-conditionals/
    \newcounter{GArepnum}
    \newif\ifGA@first

    % Put all the equations inside a macro (first traversal) along
    % with placeholders for labels, substitute the placeholders with
    % their respective labels (second traversal), and show everything
    % inside an "align". After it, execute all the deferred commands
    % (stored when inserting an equation) that add the corresponding
    % lines to the list of equations.
    \DeclareDocumentCommand{\GenerateAlign}{}{%
        \def\GA@ans{}

        \setcounter{GArepnum}{1}
        \GA@firsttrue

        \@for \i:=\listeqs \do{%
            % https://tex.stackexchange.com/q/53068/53787
            \ifx\i\empty\else
                \ifGA@first
                    \GA@firstfalse
                \else
                    % https://tex.stackexchange.com/q/74707/53787
                    \edef\GA@temp{\noexpand\g@addto@macro\noexpand\GA@ans{\noexpand\\}}
                    \GA@temp
                \fi

                \edef\GA@temp{\noexpand\g@addto@macro\noexpand\GA@ans{\i ???}}
                \GA@temp
                \stepcounter{GArepnum}
            \fi
        }

        \@for \j:=\listrefs \do{%
            \ifx\j\empty\else
                % https://tex.stackexchange.com/q/104506/53787
                \begingroup\edef\GA@perform{\endgroup
                    \noexpand\patchcmd
                    {\noexpand\GA@ans}%
                    {\noexpand ???}%
                    {\noexpand\label{\unexpanded\expandafter{\j}}}%
                    {}%
                    {}%
                }%
                \GA@perform
            \fi
        }

        \begin{align}
            \GA@ans
        \end{align}
        \DeferredExecute{\listdefers}

        \let\listeqs\@empty
        \let\listrefs\@empty
    }
\makeatother

\begin{document}
    \listofequations
    \clearpage

    \section*{Important formulas}

    \blindtext

    \InsertEquation{a^2 + b^2 &= c^2}{Pythagorean theorem}{eq:first}
    Following is eq.~\ref{eq:first}, depicting Pythagora's theorem:
    \GenerateAlign

    \Blindtext

    \InsertEquation{e &= mc^2}{Einstein Relativity theory}{eq:second}
    Following is eq.~\ref{eq:second}, depicting Einstein's relativity theory:
    \GenerateAlign

    \blindtext
\end{document}

问题

当使用 进行分离和编译时latexmk -pdf,上述代码可以正常工作。但是,当尝试将此类代码集成到更大的项目(一本数学书,包含目录、参考资料等)时,我不断收到以下信息:

  1. 两者TeX input capacity exceeded (sorry)任一
  2. Runaway argument?

考虑到该解决方案单独起作用,这样的结果很奇怪。

问题

使用列表来存储命令或其他数据(就像示例中那样)与其他包结合使用时是否容易导致堆栈耗尽?

根据答案,我将发布另一个问题,关于效率的解决方案。

相关内容