6

I tried creating a new command with an underscore as shown below, but doesn't work.

\newcommand{\h\_world}[1]{Hello World #1}

At the output I see without even initiating the command : worldHello World 1

2 Answers2

9

Don't do it, unless there is a special reason to.

Underscores have special meaning (category code 8), to denote a subscript in math mode. Only catcode 11 (alphabetic) characters can be invoked in a macro name as \macroname.

Other approaches could be used to place an underscore in a macro name as shown below, but gyrations are required to invoke the macro name.

\documentclass{article} 
\begin{document}
\expandafter\newcommand\csname h_world\endcsname[1]{Hello World #1}

\csname h_world\endcsname{!!!}
\end{document}

enter image description here

Note the space before the exclamation points is there because !!! is the argument to \csname h_world\endcsname, and shows up, after as space, as #1 in the output of that macro.

See https://en.wikibooks.org/wiki/TeX/catcode for more explanation of available catcodes.

ADDENDUM

If you were crazy and had to implement, without the use of \csname a syntax of \h_world, here is a possibility:

\documentclass{article}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\makeatletter
\newcommand\h{\@ifnextchar_{\haux}{\loneh}}
\makeatother
\def\tmpcompare{world}
\def\haux_#1 {\def\tmp{#1}\ifx\tmp\tmpcompare Hello World \else\loneh_#1 \fi}
\begin{document}
\newcommand\loneh{[\string\h{} undefined]}

\h blah

$\h_something blah$

\h_world blah

\bigskip\renewcommand\loneh{H}

\h blah

$\h_something blah$

\h_world blah
\end{document}

enter image description here

The first group of 3 lines tests

  1. \h by itself, whose action is now defined in \loneh

  2. \h_<incorrect keyword> where incorrect keyword is anything other than the string world. It produces the result \loneh_<incorrect keyword> where the underscore is taken with the traditional meaning.

  3. \h_world, with the desired output.

In the first group of 3 lines \loneh is defined as [\string\h{} undefined] and in the second group of 3 lines, it is defined simply as H.

2

Using \def it may seem that you can use underscores in macros:

\def\nr_b{3}
\def\h_w#1{Hello #1 world!}
the number \nr_b is 3,
\h_w{wonderful}

will work exactly as requested by the OP, and produce

the number 3 is 3, Hello wonderful world!

(I tested it with pdftex , xetex , luatex, and also the respective LaTeX enginges ; all from TeX Live 2016).

I am no expert in TeX, but I think that, though, the above does not define a macro named \nr_b but rather a macro named \nr that can be only used when followed by \_b.

Moreover using underscores can have unpleasant side effects, as in this example

\def\int_{ARGH}
\[\int_\alpha\]

so I recommend against using underscores in macros.

am70
  • 153
  • Let me also add kudos to the authors of plastex: they reimplemented the TeX engine so well that it mimics also the weird behaviour above, and the errors you get when trying to use the macro \nr – am70 Oct 30 '19 at 10:11
  • 1
    Welcome to TeX.SX! Nice answer! That's exactly what happens. Indeed if you try to define \nr_somethingelse the previous \nr_b will no longer exist, because the actual macro is \nr in both cases. However if you change the category code of _ (with \catcode`\_=11) or use \csname nr_b\endcsname then _ will be valid in macro names. For example in expl3 we change the catcode of both _ and : so that they can be used in macro names (the change happens inside \ExplSyntaxOn/Off). See this question for an example: https://tex.stackexchange.com/q/513196/134574 – Phelype Oleinik Oct 30 '19 at 11:56
  • "using underscores can have unpleasant side effects, as in this example" - could you please comment on your example? I don't fully understand what you mean. Do you mean that you silently overwrote the standard macros \int and got problems because of that? But if you name your macros as int_argh, will it stop interfering with int? – Yaroslav Nikitenko Jun 14 '23 at 16:07