5

I'm using LaTeX and have a string that I want to remove underscores from, and convert to lower case (in either order). The individual steps work:

\MakeLowercase{AB\_CD} \StrSubstitute{AB\_CD}{\_}{}

yields

ab_cd ABCD

but I get errors for either:

\StrSubstitute{\MakeLowercase{AB\_CD}}{\_}{}

or:

\MakeLowercase{\StrSubstitute{AB\_CD}{\_}{}}

I need to do this in a LaTeX macro, and put the result of this (lower-cased and underscore-stripped) to be usable as an argument to another command, or to be captured into a variable for such use.

Evidently I don't understand how macro substitution really works, but I can't seem to find a good explanation.

2
  • Welcome to TeX.SX!
    – Markus
    Oct 31, 2014 at 13:14
  • Thanks Markus! I hope to become proficient with LaTeX and use it for most of my documentation.
    – Eric Smith
    Oct 31, 2014 at 23:18

4 Answers 4

1

The stringstrings package is slow and has other problems, but here it can do what you ask:

\documentclass{article}
\usepackage{stringstrings}
\begin{document}
\def\x{AB\_CD}Was: \x

\caselower[e]{\x}
\convertchar[q]{\thestring}{\_}{}
IS: \retokenize[v]{\thestring}
\end{document} 

enter image description here

If you are using T1 encoding, it is easier still.

\documentclass{article}
\usepackage{stringstrings}
\usepackage[T1]{fontenc}
\begin{document}
\def\x{AB\_CD}Was: \x
\caselower[e]{\x}
IS: \convertchar[v]{\thestring}{\_}{}
\end{document} 
2
  • This solution works pretty well for me. I don't mind if it's slow, but is there somewhere I can read about the "other problems" you referenced?
    – Eric Smith
    Nov 1, 2014 at 3:32
  • @EricSmith It was one of the earliest packages I wrote, when I knew very little about LaTeX. So I did things very inefficiently. I don't recall the details, but one user reported a conflict with another package. The package has the ability but only in a very limited way, to process macros in its arguments. If you are sticking to manipulating pure text and character macros like \_, etc., it should suffice. Nov 1, 2014 at 14:22
4

\MakeLowercase expands its argument to get the string to lowercase, but the string replace you are using does not work by expansion. Here though you don't really need a string replace, just locally make \_ expand to nothing.

\documentclass{article}

\begin{document}

{\renewcommand\_{}\MakeLowercase{AB\_CD}}

\end{document}
2
  • That might be workable, but how to I get the original definition of _ back? For instance, if I use it in a command: \newcommand{\munge}[1]{ \renewcommand\_{}\MakeLowercase{#1} }
    – Eric Smith
    Nov 1, 2014 at 2:52
  • @EricSmith it is a local redefinition, the original definition is restored at the } at the end of the line shown. Your \newcommand would want {} around the setting as in \newcommand{\munge}[1]{ {\renewcommand\_{}\MakeLowercase{#1}} } Nov 1, 2014 at 9:24
3

Do it in two separate steps:

\documentclass{article}
\usepackage{xstring}

\begin{document}

\StrSubstitute{AB\_CD}{\_}{}[\SUBtemp]\MakeLowercase{\SUBtemp}

\end{document}

enter image description here

4
  • Is there some fundamental limitation in the way that macros (or commands, or whatever they are) work that requires the use of the temporary variable rather than directly using the result of one as the argument of the other?
    – Eric Smith
    Oct 31, 2014 at 13:28
  • 1
    @EricSmith Yes: \lowercase doesn't execute what's passed to it and \MakeLowercase adds a layer over it. So \lowercase{\StrSubstitute{AB\_CD}{\_}{}} would work by lowercasing before doing \StrSubstitute, but with \MakeLowercase this is not possible, because basically it scans its input token by token applying \lowercase when needed.
    – egreg
    Oct 31, 2014 at 15:45
  • I didn't originally state it in the question, but I need to use the output of \MakeLowercase as an argument to something else, either directly or via another temporary variable, and I can't seem to do that. My failed attempt: \newcommand{\munge}[1]{ \StrSubstitute{#1}{\_}{}[\SUBtemp] \def\SUBtemp2{\MakeLowercase{\SUBtemp}} \SomeOtherRandomCommand{\SUBtemp2} }
    – Eric Smith
    Nov 1, 2014 at 3:08
  • @EricSmith You can't pass the output of \MakeLowercase to any macro: what it produces is just for printing, more or less. Do you really need \MakeLowercase because of accents or are your strings just letters and simple commands like \_?
    – egreg
    Nov 1, 2014 at 9:26
2

With an up-to-date expl3:

\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\cs_new_eq:NN \LowerCase \text_lowercase:n
\ExplSyntaxOff
\usepackage{xstring}
\begin{document}
\StrSubstitute{\LowerCase{AB\_CD}}{\_}{}
\end{document}

This works because \text_lowercase:n in expl3 does not use \lowercase and so is expandable (contrast with the comment on egreg's answer).

1
  • In principle I like the idea of being forward-looking and using expl3, even if the details may change in the future. However, at the moment I'm struggling with LaTeX 2, so I'm not sure I want to throw LaTeX 3 stuff into the mix.
    – Eric Smith
    Nov 1, 2014 at 3:17

You must log in to answer this question.

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