26

I am writing a text document in LaTeX where I need a lot a words with underscores: foo_bar_1, more_bar_2_long_expression_3.

I know about the underscore package, but for some reason the [strings] option doesn't work for me (I get e.g. Extra \endcsname. ...oncluding Chapter~\ref{ch:summary_outlook}).

So my idea would be to define a new command or environment

\newcommand{escunderscore}[1]{...}

in which basically _ would be replaced by \_, so that I then can write \escunderscore{foo_bar_1} in my text whenever I need underscores. Is this possible and how do I do this?

9
  • 1
  • Looks like a dupe of the question Martin has linked to.
    – Joseph Wright
    Jun 16, 2011 at 9:14
  • I think you'd be better off if you fix the broken strings option (it worked fine for me in a quick test). Wrapping words with underscores in an \esc_underscore command is not really more convenient or readable than manually escaping the underscores. Perhaps ask a new question about the [strings]underscore issue including a minimal example that reproduces your problem
    – Jake
    Jun 16, 2011 at 9:17
  • The underscore package {without any special strings option}seems to work just fine for me, so not exactly sure what the problem Jun 16, 2011 at 9:18
  • 3
    @Martin, @Joseph: If I understand correctly, the answer to the linked question is to use the underscore package, which doesn't work for fuenfundachtzig, so it's not really a duplicate.
    – Jake
    Jun 16, 2011 at 9:18

2 Answers 2

27

You can do even better: say

\usepackage[T1]{fontenc}
\catcode`\_=12

in your preamble and you'll be allowed to use the underscore as a printable character anywhere (requires a T1-encoded font, so the first line). For subscripts you can then use \sb.

A command for temporary escaping the underscore can be the following:

\makeatletter
\newcommand{\escapeus}{\begingroup\@makeother\_\@escapeus}
\newcommand*{\@escapeus}[1]{#1\endgroup}
\makeatother

that, however, will not be usable in the argument of any command, because of the change in the category code (still requires a T1-encoded font).

If T1-encoded fonts are not available, something more complicated is needed:

\makeatletter
\newcommand{\escapeus}{\begingroup\@activeus\@escapeus}
\newcommand*{\@escapeus}[1]{#1\endgroup}
\begingroup\lccode`\~=`\_\relax
   \lowercase{\endgroup\def\@activeus{\catcode`\_=\active \let~\_}}
\makeatother

Again, the \escapeus command cannot be used as the argument of another command. If you really need it there's a way:

\makeatletter
\DeclareRobustCommand*{\escapeus}[1]{%
  \begingroup\@activeus\scantokens{#1\endinput}\endgroup}
\begingroup\lccode`\~=`\_\relax
   \lowercase{\endgroup\def\@activeus{\catcode`\_=\active \let~\_}}
\makeatother
7
  • 2
    Thanks, also. This is exactly the solution I was looking for. The underscore package was too aggressive for my purposes: It escapes things like \label{tag_with_underscores}, \input{file_with_underscores} and |short_verbatim_with_underscore|. A command that lets me have control of the process is perfect. Jun 19, 2011 at 11:08
  • The last solution also works in caption etc. Sep 22, 2011 at 8:35
  • @fuenfundachtzig Yes, it should, since it delays until the very last minute the interpretation of _.
    – egreg
    Sep 22, 2011 at 8:39
  • @egreg: I used your last solution and together with @DavidCarlisle answer (is.gd/FOv6dA) it works very well. However, I tried to understand the magic for some time now and I fail. Can you please add some explanations? In particular, the order of grouping and the re-definition of _.
    – Dror
    Sep 11, 2013 at 7:25
  • @Dror There's nothing special: the main command just calls \@activeus and then uses \scantokens so the argument will be reprocessed based on the current catcodes (where _ is active). The second part is the activation code: _ is made active and defined to be equivalent to \_.
    – egreg
    Sep 11, 2013 at 8:43
16
\documentclass{article}
\usepackage{url}
\DeclareUrlCommand\UScore{\urlstyle{rm}}
\begin{document}

foo \UScore{foo_bar_1} bar

\end{document}
0

You must log in to answer this question.

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