如何扩展基于 \romannumeral 的 \fullyexpand 来处理空/全空间参数?

如何扩展基于 \romannumeral 的 \fullyexpand 来处理空/全空间参数?

可扩展的令牌完整扩展,保留 catcodes约瑟夫·赖特给出以下代码:

\long\def\fullyexpand#1{%
  \csname donothing\fullyexpandauxi{#1}{}%
}
\long\def\fullyexpandauxi#1{%
  \expandafter\fullyexpandauxii\romannumeral -`0#1\fullyexpandend
}
\long\def\fullyexpandauxii#1#2\fullyexpandend#3{%
  \ifx\donothing#2\donothing
    \expandafter\fullyexpandend
  \else
    \expandafter\fullyexpandloop
  \fi
  {#1}{#2}{#3}%
}
\long\def\fullyexpandend#1#2#3{\endcsname#3#1}
\long\def\fullyexpandloop#1#2#3{%
  \fullyexpandauxi{#2}{#3#1}%
}
\def\donothing{}

他说道:

我还要指出的是,上面的代码需要为空白(空或全空格)参数添加一些保护,因为目前在这些情况下事情会失败。

这确实没错,即使不完全符合语法。不幸的是,我的 TeX 还不够好,所以我不知道如何添加这样的保护。有人愿意吗?

(对于我的应用程序来说,任何能在 pdfTeX 中运行的东西都可以。)

答案1

\csname此版本需要恰好两次扩展才能工作,因此通过使用两次应用来避免构造\romannumeral。外部应用确保我们恰好需要两次扩展,内部应用进行扩展:

\long\def\fullyexpand#1{%
  \romannumeral-`0%
    \fullyexpandauxi{#1}{}%
}
\long\def\fullyexpandauxi#1{%
  % The space in the following line is deliberate: it will always finish the
  % \romannumeral before \fullyexpandauxii expands
  \expandafter\fullyexpandauxii\romannumeral-`0#1 \fullyexpandend
}
\long\def\fullyexpandauxii#1{%
  \ifx\fullyexpandend#1%
    \expandafter\fullyexpandend
  \else
    \expandafter\fullyexpandauxiii
  \fi
    {#1}%
}
\long\def\fullyexpandauxiii#1#2\fullyexpandend#3{%
  \expandafter\fullyexpandauxii\romannumeral-`0#2 \fullyexpandend{#3#1}%
}
% Here, #1 will be "\fullyexpandend", as we have reached the end of the loop
\long\def\fullyexpandend#1#2{ #2}

先前版本对完全空白的参数进行了测试,但是如果参数不为空而是扩展为以下内容,则测试会失败:

\long\def\fullyexpand#1{%
  \romannumeral-`0%
    \expandafter\ifx\expandafter\relax\detokenize\expandafter
      {\gobble#1 ?}\relax
      \expandafter\fullyexpandblank
    \else
      \expandafter\fullyexpandauxi
    \fi
      {#1}{}%
}
\long\def\gobble#1{}
\long\def\fullyexpandauxi#1{%
  \expandafter\fullyexpandauxii\romannumeral -`0#1\fullyexpandend
}
\long\def\fullyexpandauxii#1#2\fullyexpandend#3{%
  \expandafter\ifx\expandafter\relax\detokenize{#2}\relax
    \expandafter\fullyexpandend
  \else
    \expandafter\fullyexpandloop
  \fi
  {#1}{#2}{#3}%
}
\long\def\fullyexpandend#1#2#3{ #3#1}
\long\def\fullyexpandloop#1#2#3{%
  \fullyexpandauxi{#2}{#3#1}%
}
\long\def\fullyexpandblank#1#2{ }

相关内容