6

I want to define a command to shorten formula like this a^1,\cdots,a^n, using a placeholder (-) instead of index, the code is

\usepackage{xstring}
\newcommand{\replaceStr}[2]{\begingroup\expandarg\StrSubstitute{#1}{(-)}{#2}\endgroup}
\newcommand\coordsnn[1]{\replaceStr{#1}{^1},\cdots,\replaceStr{#1}{^n}}

It works, e.g. $\coordsnn{A(-)B(-)C}$ results in $A^1B^1C,\cdots,A^nB^nC$.

However, if I go further and extend it to situation like a_{01},\cdots,b_{0n}, the command looks like:

\newcommand\coordsnX[1]{\replaceStr{#1}{1},\cdots,\replaceStr{#1}{n}}

It doesn't work any more, leaving (-) unchanged. How to realize this kind of command? How about supscript?

Following is the sample testing code:

\documentclass{article}
\usepackage{xstring}
\newcommand{\replaceStr}[2]{\begingroup\expandarg\StrSubstitute{#1}{(-)}{#2}\endgroup}
\newcommand\coordsnn[1]{\replaceStr{#1}{^1},\cdots,\replaceStr{#1}{^n}}
\newcommand\coordsnX[1]{\replaceStr{#1}{1},\cdots,\replaceStr{#1}{n}}
\begin{document}
Working example:
$$
\coordsnn{a(-)b(-)c}
$$
Not working example:
$$
\coordsnn{a_{0(-)}b_{0(-)}c}, \coordsnn{a^{0(-)}b^{0(-)}c}
$$
\end{document}

1 Answers1

4

You have brace groups around the text you are looking for: these 'hide' it from the usual TeX approaches to doing search-and-replace. What you therefore have to do is to detokenize the input (remove category codes) and retokenize afterwards. The string packages do offer this kind of functionality, but I'd probably go with l3regex here:

\documentclass{article}
\usepackage{l3regex,xparse}
\ExplSyntaxOn
\cs_new_protected:Npn \mw_replace_all:nn #1#2
  {
    \group_begin:
      \tl_set:Nn \l_tmpa_tl {#1}
      \regex_replace_all:nnN { \(\-\) } { #2 } \l_tmpa_tl
      \tl_use:N \l_tmpa_tl
    \group_end:
  }
\NewDocumentCommand \coordsnn { m }
  {
    \mw_replace_all:nn {#1} { \cU^\cB{1\cE} }
    \cdots
    \mw_replace_all:nn {#1} { \cU^\cB{n\cE} }
  }
\NewDocumentCommand \coordsnX { m }
  {
    \mw_replace_all:nn {#1} { 1 }
    \cdots
    \mw_replace_all:nn {#1} { n }
  }
\ExplSyntaxOff
\begin{document}
Working example:
\[
  \coordsnn{a(-)b(-)c}
\]
Not working example:
\[
  \coordsnX{a_{0(-)}b_{0(-)}c}, \coordsnX{a^{0(-)}b^{0(-)}c}
\]
\end{document}

This package offers regular expression substitution and more importantly will look inside brace groups automatically. The 'match' part here is easy: \(\-\) is your string (-) but with each character escaped. The replacement is a bit more tricky: \cU^ is a catcode 'superscript' ^, \cB{ is a catcode 'begin group' { and \cE} is a catcode 'end group' } (1 needs no special handling).

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036