![将 \$ 解析为改进的 \getargs 命令的一部分](https://linux22.com/image/263997/%E5%B0%86%20%5C%24%20%E8%A7%A3%E6%9E%90%E4%B8%BA%E6%94%B9%E8%BF%9B%E7%9A%84%20%5Cgetargs%20%E5%91%BD%E4%BB%A4%E7%9A%84%E4%B8%80%E9%83%A8%E5%88%86.png)
作为 的作者stringstrings
,我深知它的缓慢。对于小任务来说,这种缓慢可能会令人烦恼。对于较大的任务来说,这种缓慢可能会让人望而却步。
最近,在使用数据列作为 pgfplotstable 表中的“轴”,我提出了一个解决方案,使用\getargs
(stringstrings
包的)命令作为解决方案的一部分,用于读取和存储二维数组以供将来使用(\getargs
将参数解析为单个单词)。该解决方案设想了一种语法,例如
\readArray{\dataA}{arA}{4}
\readArray{\dataB}{arB}{4}
用于将数据列表读入(例如)4 列,并通过唯一标识符(例如 arA、arB 等)标识数组,以便以后构建表格时可以使用
\Arrayij{arA}{1}{1} & \Arrayij{arA}{1}{4} & \Arrayij{arB}{1}{4} to call back various elements of the input arrays. I could immediately see that these datasets could become large, and I feared the `\getargs` command developed for `stringstrings` would be too slow for processing a large array.
因此,我尝试从完全不同的角度重写\getargs
(称之为\getargsFAST
) 的快速版本,使用简化的递归,而不是\if\else\fi
允许stringsstrings
处理扩展字符集的详尽方法。我理解并接受这两个版本的行为不会完全相同。我认为数据数组 (为其\getargsFAST
设计) 将主要包含数字,可能包含一些单词 (用于单位或案例) 和 (对于财务人员) 美元符号\$
。而美元符号目前让我感到困惑。
我尝试了各种方法,但无法将其作为输入数据的一部分\getargsFAST
进行处理\$
。对于那些精通低级 TeX 的人来说,是否有明显的解决办法,而我并不精通。
以下是作为示例的例程及其输出。注意:我没有\$
在输入中使用,因为那样我就没有任何输出可以发布给您了。
\documentclass[10pt]{article}
\usepackage{ifnextok}
\makeatletter
\def\stringend{$}
\newcounter{arg@index}
\def\getargsFAST#1{\edef\argi{}\setcounter{arg@index}{1}%
\expandafter\parse@Block#1\stringend}
\def\parse@Block{\IfNextToken\stringend%
{\edef\narg{\arabic{arg@index}}\@gobble}%
{\IfNextToken\@sptoken{\addtocounter{arg@index}{1}%
\expandafter\edef\csname arg\roman{arg@index}\endcsname{}%
\add@to{\parse@Block}}%
{\add@to{\parse@Block}}}}
\def\add@to#1#2{\expandafter\edef\csname arg\roman{arg@index}\endcsname%
{\csname arg\roman{arg@index}\endcsname#2}#1}
\makeatother
\parskip 0.9ex \parindent 0in
\begin{document}
Test of getargsFAST (fast alternative to getargs of stringstrings package):
\def\myarg{This is a ~~test of the emergency $x_i^2\alpha$ broadcast system}
Original argument:\par
\verb,This is a ~~test of the emergency $x_i^2\alpha$ broadcast system,
\getargsFAST{\myarg}
Number of args is \narg, given as follows:\par
\argi \par
\argii \par
\argiii \par
\argiv \par
\argv \par
\argvi \par
\argvii \par
\argviii \par
\argix \par
\argx \par
Differences from getargs are probably numerous. Here are some: hard
spaces are retained by FAST version only; FAST version has no built-in
argument size limit; FAST version chokes on the \verb,\$, character.
Like getargs, getargsFAST can process only a very limited set of math
tokens. Obviously, \verb,#,, without a backslash, causes result to
choke.
Unlike getargs, getargsFAST provides no workarounds for processing
characters that cannot be put into an edef, such as \dag, \ddag, \P, \d
x, \t x, \b x, \copyright, as well as (in OT1 encoding) \_, \{, \}, \S,
\c x, and \pounds.
Other characters that will confound getargsFAST include the
\verb,&, (when entered without the backslash), and most of the
diacritical markings.
I will probably add this command to the stringstrings package when play
testing is complete.
\end{document}
答案1
这里没有什么特别的\$
,只是你永远不应该将其应用于\edef
LaTeX 中任意用户提供的输入。只有当所涉及的标记在你的控制之下时,使用它才是安全的\protected@edef
。我认为使用事情会按照你的意图进行。
\def\parse@Block{\IfNextToken\stringend%
{\edef\narg{\arabic{arg@index}}\@gobble}%
{\IfNextToken\@sptoken{\addtocounter{arg@index}{1}%
\expandafter\def\csname arg\roman{arg@index}\endcsname{}%
\add@to{\parse@Block}}%
{\add@to{\parse@Block}}}}
\def\add@to#1#2{\expandafter\protected@edef\csname arg\roman{arg@index}\endcsname%
{\csname arg\roman{arg@index}\endcsname#2}#1}