Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

As the author of stringstrings, I am acutely aware of its slowness. For small tasks, that slowness can be annoying. For larger tasks, it can be prohibitive.

Recently, in using data column as "axis" in table with pgfplotstable, I proposed a solution, using the \getargs command (of the stringstrings package) as part of the solution on how to read and store a 2-D array for future use (\getargs will parse an argument into individual words). That solution envisioned a syntax such as

\readArray{\dataA}{arA}{4}
\readArray{\dataB}{arB}{4}

for reading lists of data into, for example, 4 columns, and identifying the arrays by unique identifiers such as arA, arB, etc., so that, when later building a tabular, one could use

\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.

So I tried to rewrite a fast version of \getargs (call it\getargsFAST), from a completely different angle, using a streamlined recursion, rather than the exhaustive \if\else\fi approach that allows stringsstrings to handle extended character sets. I understand and accept that the two versions will not act exactly alike. I figured that an array of data (for which \getargsFAST is designed) would contain mostly numbers, maybe some words (for units or cases) and (for financial folks) the dollar sign \$. And it's the dollar sign that is confounding me at present.

I've tried various things, but can't get \getargsFAST to process \$ as part of the input data. Is there an fix apparent to those well versed in lower-level TeX, which I am not.

Here is the routine, as part of an example, and its output. Note: I did not use \$ in the input, because then I wouldn't have any output to post for you.

\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}

enter image description here

share|improve this question

1 Answer 1

up vote 8 down vote accepted

There is nothing special about \$ here, just that you should never apply \edef to arbitrary user supplied input in LaTeX. It is only safe to use that if the tokens involved are under your control. Using \protected@edef things work out as I assume you intended.

\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}
share|improve this answer
    
Amazing. Thank you. –  Steven B. Segletes Mar 4 '13 at 16:25
1  
Furthermore, your approach allows the routine to operate on a large assortment of tokens that previously didn't work, some of which are mentioned in my output. Not that I'm looking forward to it, but your answer really indicates a needed rewrite of stringstrings. –  Steven B. Segletes Mar 4 '13 at 16:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.