忽略宏中的部分文本

忽略宏中的部分文本

考虑以下代码:

\documentclass{book}
\usepackage{pgffor}

\begin{document}
\newcommand\containers{
    \cont{aaa{\bf don't xstring me}aaa}
    \cont{bbb\large bbb}
    \containerssomemore{}
    \cont{cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccI'm very long. don't \textbf{mbox} me. I'm going to be in very odd text widths etccccccccccccccccccccccc}
    \cont{last one(\mbox{ddddd})}
}
\newcommand\containerssomemore{
    \cont{yea here i am}
    \cont{and me too}
}

\newcount\cntlines
\newcount\cntline
\newcommand\cont[1]{%
    \advance\cntline by 1\relax%
    \ifnum\cntline=\cntlines%
        #1%
    \fi%
}
\newcommand\passover[2]{%
    \cntlines=#1\relax\cntline=0\relax%
    #1
    #2%
}

\foreach\idx in {6, 5, ..., 1}{%
    \idx\footnote{\passover{\idx}{\containers}}
}
\end{document}

可以看出,代码以相反的顺序生成了 6 行脚注。我知道有更好的方法来生成此输出。这只是我需要对作为输入的文本行进行的一些(不太简单的)处理的示例。

但是,当我确实有包含在这些容器中的文本时,这很好。但我的实际输入文本将有所不同。它包含分隔符,如以下实现所示:

\documentclass{book}
\usepackage{pgffor}

\begin{document}

\newcommand\separators{%
    aaa{\bf don't xstring me}aaa
    \sep{}bbb\large bbb
    \separatorssomemore{}
    \sep{}cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccI'm very long. don't \textbf{mbox} me. I'm going to be in very odd text widths etccccccccccccccccccccccc
    \sep{}last one(\mbox{ddddd})
    \seperatorsevenmore{}
}
\newcommand\separatorssomemore{
    \sep{}yea here i am
    \sep{}and me too
}
\newcommand\seperatorsevenmore{
    \sep{}another one
}


\newcount\cntlines
\newcount\cntline   
\newsavebox\voidbox
\newcount\inbox \inbox=0\relax
\newcommand\sep{%
    \global\advance\cntline by 1\relax%
    \ifnum\cntline=\cntlines%
        \end{lrbox}%
    \fi%
    \ifnum\cntline>\cntlines\ifnum\inbox=0\relax%
        \begin{lrbox}{\voidbox}\inbox=1\relax%
    \fi\fi%
}
\newcommand\passsep[2]{%
    \cntlines=#1\relax\cntline=0\relax%
    #1
    \begin{lrbox}{\voidbox}\inbox=1\relax\sep{}#2\sep{}\end{lrbox}%
}

\foreach\idx in {6, 5, ..., 1}{%
    \idx\footnote{\passsep{\idx}{\separators}}
}

\end{document}

从中可以看出,结果几乎相同(留出空白处的某些差异 - 这将很容易修复)。

但是第二个示例的主要缺点是我没有跳过不需要的行,而是将它们全部插入到一个框中。当有 6 行时不会注意到这一点,但我的实际代码有几千行,因此时间差异变得非常明显(以分钟为单位)。

我实际上需要一种方法来使文本的部分内容无效/忽略/跳过,同时仍在其中运行一些选定的宏。我相信我需要某种方法来预先扩展输入宏,例如通过某种方式进行替换,这样最终我会得到类似于容器宏的东西,然后才真正“运行”它。

我尝试过这种方法:

\documentclass{book}
\usepackage{pgffor}
\usepackage{environ}

\begin{document}
\newcommand\separators{%
    aaa{\bf don't xstring me}aaa
    \sep{}bbbbbb
    \separatorssomemore{}
    \sep{}cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccI'm very long. don't mbox me. I'm going to be in very odd text widths etccccccccccccccccccccccc
    \sep{}last one(ddddd)
}
\newcommand\separatorssomemore{
    \sep{}yea here i am
    \sep{}and me too
}

\newcount\cntlines
\newcount\cntline
\NewEnviron{tocont}{%
    \global\advance\cntline by 1\relax%
    \ifnum\cntline=\cntlines%
        \BODY%
    \fi%
}
\newcommand\sep{%
    \end{tocont}\begin{tocont}%
}
\newcommand\passenv[2]{%
    \cntlines=#1\relax\cntline=0\relax%
    \begin{tocont}#2\end{tocont}%
}
\foreach\idx in {6, 5, ..., 1}{%
    \idx\footnote{\passenv{\idx}{\separators}}
}
\end{document}

但是它编译失败了,而且它太简单了以至于难以置信......

有人可以提出一个想法吗?

编辑:我在上面示例中的行中添加了一些属性,以强调它们可能包含脚注中允许的任何设计相关的宏。

我需要的是一种仅扩展\sep{}宏和以 开头的宏的方法\seperators(如我的示例:所有添加到文本行列表的宏都被称为\seperators<something>)。

\sep{}我想从一个宏“跳”到下一个宏(要么\seperators{}直接包含在宏中,要么在这样的子宏中\seperators...)。假设,如果这简化了,我只有一个间接级别。也就是说,一个子宏\seperators...不会调用另一个子宏\seperators...,但它可能会使用其他宏(\textbf\mbox以及您能想到的任何其他宏),当然还有\sep{}

\sep{}决定是否忽略所有文本直到下一个文本,或者展开并输出它。就像中间的文本被括在\cont{}上面的 a 中一样。

如图所示,我可以通过将内容转储到虚拟框中来实现。但是有没有一种框可以告诉 TeX“不要浪费时间组织我。只要将内容转储出来,一切都会好起来”?我想这应该相当于跳过它。

或者,一种方法是采用一个宏并基于它“创建”另一个宏,一些使用原始宏代码的“函数”,只需“替换”“ ”}\cont{而不是每个“ \sep{}”?在这种情况下,我需要 2 次传递 - 一次扩展所有“ \seperators...{}”行,第二次执行提到的字符串操作。然后我只需将结果作为宏“运行”即可定期扩展。

另一项编辑:事实证明我不需要在里面包含附加选项。也就是说,我只需要直接在宏中\seperators...处理原始命令。\sep{}

这是否可以解决该问题?

相关内容