I want a macro that somehow replaces whitespace (spaces, newlines, tabs?) from the start of a string.
Something like
mystring.replace(/^\s*/g, "")
in JavaScript.
Is that possible?
Removing space tokens at the begin of a string is possible, but a little cumbersome:
\documentclass{article}
\makeatletter
\let\TrSp@X\relax
\let\TrSp@Y\relax
\edef\TrSp@XSpXNil{%
\TrSp@X\space\TrSp@X
\noexpand\noexpand\noexpand\TrSp@NIL
}
\long\edef\trim@pre@spaces#1{%
\noexpand\romannumeral0%
\noexpand\TrSp@pre@spaces\TrSp@X#1\TrSp@Y\TrSp@XSpXNil
}
\@firstofone{\long\def\TrSp@pre@spaces#1\TrSp@X} %
#2\TrSp@X#3\TrSp@NIL{%
\csname TrSp@pre#3\endcsname{#1}{#2}%
}
\long\def\TrSp@pre#1#2{%
\expandafter
\TrSp@pre@\expandafter\space\@gobble#1%
}
\long\def\TrSp@pre@#1\TrSp@Y{#1}
\long\expandafter\edef\csname TrSp@pre X\endcsname#1#2{%
\noexpand\TrSp@pre@spaces\TrSp@X#2\TrSp@XSpXNil
}
\def\TrSp@X{X}
\let\TrSp@Y\TrSp@NIL
\let\trimstartspaces\trim@pre@spaces
\newcommand*{\trimstartspacesin}[1]{%
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter#1%
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter{%
\expandafter\trimstartspaces\expandafter{\foo}%
}%
}
\makeatother
% create a text with several spaces in a row using a trick:
\newcommand*{\deffoo}[1]{%
\newcommand*{\foo}{#1#1#1#1a b c }%
}
\deffoo{ }
\let\trimmedfoo\foo
\trimstartspacesin\trimmedfoo
\typeout{[\expandafter\trimstartspaces\expandafter{\foo}]}
\typeout{[\trimmedfoo]}
\begin{document}
[\foo] $\rightarrow$ [\expandafter\trimstartspaces\expandafter{\foo}]
or [\trimmedfoo]
\end{document}
Package trimspaces
already provides \trim@pre@space
or \trim@pre@space@in
.
Manually it can be done by
\romannumeral-`\.
\romannumeral
applied to negative numbers vanishes and TeX keeps looking for an optional space after the character constant `\.
.
If the text is inside a macro \foo
, then an optional space can be stripped
at the beginning by:
\expandafter\def\expandafter\foo\expandafter{%
\romannumeral-\expandafter`\expandafter\.\foo
}%
Full example:
\documentclass{article}
\newcommand*{\foo}{ a b c }
\expandafter\def\expandafter\trimmedfoo\expandafter{%
\romannumeral-\expandafter`\expandafter\.\foo
}%
\typeout{[\meaning\trimmedfoo]}
\begin{document}
[\foo] $\rightarrow$ [\trimmedfoo]
\end{document}
Usually removing one optional space is enough, because it is not too easy entering more than one space in a row (TeX collapses them to one space during tokenizing).
\@ifnextchar
removes spaces before testing the "next" character. In non expandable contexts it can be used to remove infinite spaces from the begin of the text:
\documentclass{article}
% create a text with several spaces in a row using a trick:
\newcommand*{\deffoo}[1]{%
\newcommand*{\foo}{#1#1#1#1a b c }%
}
\deffoo{ }
\makeatletter
\newcommand*{\stripstartspaces}{%
\expandafter\@ifnextchar\expandafter X\expandafter{\expandafter
}\expandafter{\expandafter}%
}
\makeatother
\begin{document}
[\foo] $\rightarrow$ [\stripstartspaces\foo]
\end{document}
\stripstartspaces
works perfectly for my case. Thanks, accepting.
Commented
Jun 2, 2014 at 14:27
The stringstrings
package has a \removeleadingspaces
macro, which will remove any combination of blanks and hard spaces at the the beginning of the passed text string. The package is generally intended to operate only upon text strings, and has only a very limited ability (not shown in this answer) to handle arguments containing macros.
By default, the macro will output the result immediately to the screen. However, if the processed but unprinted result is desired, a [q]
optional argument will instead put the result in \thestring
via an \edef
for later access. There is also an [e]
"encoded" mode, which applies if one is trying to process strings containing a limited number of user-predefined macros (but that's for a different question).
\documentclass{article}
\usepackage{stringstrings}
\begin{document}
.\removeleadingspaces{abc def}
.\removeleadingspaces{ abc def}
.\removeleadingspaces{ abc def}
.\removeleadingspaces{~abc def}
.\removeleadingspaces{~~abc def}
.\removeleadingspaces{~ ~ abc def}
.\removeleadingspaces{~ ~ abc def}
\end{document}
\removeleadingspaces
started to make some problems with "forced" breaking words with \-
, which for unknown reasons started to expand as ......
. \stripstartspaces
from the other answer works better, I am sorry :)
Commented
Jun 2, 2014 at 14:26
stringstrings
suffers severe limitations. I'm glad you found an answer that works for you.
Commented
Jun 2, 2014 at 14:33
stringstrings
package has a macro\removeleadingspaces[mode]{string}
. Whether this is applicable for you will strongly depend on whether the argument you pass to the macro is pure text or has embedded macros.