1

In Plain-TeX, how can I change a string that is stored in a macro so that each space in that string is turned into a dash? E.g. if \def\a{This little example}, I will like to have some procedure that applied to \a returns "This-little-example". I know I can use \obeyspaces to do the trick on a literal string,

\def\a{This little example}
{\obeyspaces\let =-%
1. This is a test, only a   test.
2. \a
}
\bye

yet that trick does not work on the string stored in macro \a (that is, the expansion of \a above is not modified, yet the first line does change into "1.-This-is-a-test,-only-a---test.").

I also tried changing the space's catcode as in

\begingroup
\catcode` =\active
\gdef\swapSpace{%
  \catcode` =\active
  \def {-}%
}
\endgroup

 My test text...% plain text not to be changed...

{\swapSpace
3. My test text... It works, for a literal string...
}

{\swapSpace
4. \a

Yet it fails for the macro above.
}
\bye

But that approach also fails as \a is expanded after all the other things.

5
  • can' t you define \a when space is active, eg in the scope of \swapspace ? Commented Jun 14, 2022 at 7:40
  • Just to be sure: do you want that the contents of \a is typeset with hyphens instead of spaces or that the spaces stored in \a become hyphens in a context where all the spaces are turned into hyphens?
    – egreg
    Commented Jun 14, 2022 at 9:21
  • @DavidCarlisle: no, I cannot define \a within the scope of \swapSpace. For a little context, I am receiving the macro \a from command line (users will run something like tex '\def\a{Blah blah}\input{program}' then within program the value of \a is used (if defined). \a is used as is, and after its spaces are swapped for dashes (so both 'Blah blah' and 'Blah-blah' are needed).
    – LuHe
    Commented Jun 14, 2022 at 19:01
  • @egreg: it is more like the second option, I need the spaces stored in \a to become hyphens in a context, while in another context I need the spaces in \a to remain spaces.
    – LuHe
    Commented Jun 14, 2022 at 19:04
  • @LuHe you can use the second form in my answer Commented Jun 14, 2022 at 19:21

3 Answers 3

2

You can replace spaces in a macro already defined by another token (or token list).

\def\replspaces#1#2{\expandafter\replspacesA\expandafter#2#1 \end}
\def\replspacesA#1#2 #3{#2\ifx\end#3\else#1\afterfi{\replspacesA#1#3}\fi}
\def\afterfi#1#2\fi{\fi#1}

% usage: \replspaces\macro{what}
% example:

\def\a{This little example}
\replspaces\a{-}

The macro \replspaces is expandable. You can replace all spaces by another token by

\def\a{This little example}
\edef\a{\replspaces\a{?}}
\meaning\a % macro:->This?little?example 
1

Your original would work if \a was defined when space is active, so

enter image description here

{\obeyspaces\let =-%
\def\a{This little example}
1. This is a test, only a   test.
2. \a
}
\bye

or

{\obeyspaces
\gdef\a{This little example}
}


{\obeyspaces\let =-%
1. This is a test, only a   test.
2. \a
}
\bye

If that is not possible you could use \scantokens if using etex (pdftex or etex binaries)

\def\a{This little example}



{\obeyspaces\let =-%
1. This is a test, only a   test.
2. \scantokens\expandafter{\a}%
}
\bye
0

You can define your strings to appear in \swapSpace with \scantokens incorporated.

\def\specialdef#1#2{%
  \def#1{%
    \ifnum\catcode`\ =\active
      \scantokens{#2\noexpand\empty}%
    \else
      #2%
    \fi
  }%
}
\begingroup
\catcode` =\active
\gdef\swapSpace{%
  \catcode` =\active
  \def {-}%
}
\endgroup

\specialdef\a{This little example}


 My test text...% plain text not to be changed...

\a\ is good

{\swapSpace
3. My test text... It works, for a literal string...
}

{\swapSpace
4. \a is good

}

\bye

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .