3

I want to create a custom command (control sequence) whose name contains special characters (such as numbers, underscores _, or -). In order to better distinguish different commands, my code is as follows

\documentclass{article}


\expandafter\NewDocumentCommand\csname cmd_1_a\endcsname{m O{}}{123 #1 #2}


\begin{document}


\csname cmd_1_a\endcsname{4}[6]


\end{document}

I wrap the command name in \csname and \endcsname, which is OK in order to add special characters to the name, but I also need to use \csname, \endcsname when I call it later. I don't want that. I want to be able to type its name \cmd_1_a directly like an ordinary command later.

Considering that _ can cause confusion in mathematical mode, it's okay not to join it. Anyway, I want the name of the custom command to contain non-alphabetic characters

In any way, please give me some hints. Thank you.

11
  • 4
    Welcome! This is really not a good idea. As you yourself point out, the underscore is used in maths mode. Moreover, it is used in the expl3 programming layer, which uses a distinct syntax to distinguish it from document-level code. There are much better ways to distinguish custom commands. The only way to do what you want is to alter the cat codes of the affect characters at the document level. That will cause you massive headaches because all of the commands you use in your document are based on the assumption that the category codes are as they expect.
    – cfr
    Commented May 20 at 2:03
  • @cfr Thank you for your reply. You are absolutely right. There are a lot of risks in doing so, but I still hope to add some special characters to the name without modifying the category code. But this should be done on the premise of minimizing the risk of use. I really hope to find a way to have the best of both worlds.
    – Tommk
    Commented May 20 at 2:37
  • 2
    Well, if you don't want to change the category codes and you don't want to use \csname - or, I assume, one of the equivalent wrappers - what do you want to do? You can fake something by defining a delimited command. E.g. \def\mycmd_#1_#2{...} and then you can test #1 and #2 and proceed accordingly. In simple cases, that can function as if you've defined many macros though, actually, you've only defined one. And then all that matters is that the category codes are the same when you define and use the command. But aside from that, you can't. TeX gets to _ and knows the name is over.
    – cfr
    Commented May 20 at 2:58
  • 2
    And, as pointed out above, use of _ would be especially unfortunate. (Though not as unfortunate as numbers.)
    – cfr
    Commented May 20 at 2:59
  • 2
    Can I ask how calling something \cmd_1_a helps distinguish it for a human being? You want to give your macros meaningful/descriptive names you'll find easy to remember. For example, I have an environment called infer which I use to typeset arguments in standard form (i.e. inferences). Or something like \plstyle which switches to proportional, lining figures. Either you are creating so many macros there's probably a better strategy or you're failing to imagine how little sense \cmd_1_a will make to you in 5 years time. (And I'm somebody who finds it relatively easy to remember numbers.)
    – cfr
    Commented May 20 at 3:10

1 Answer 1

9

You can make numbers catcode 11 so that \i1 works, but then they are no longer valid in lengths so \hsize=100pt would be an error, and uses such as \setbox0 or \dimen0 will all fail. Most LaTeX packages will break with such a setting.

You can use

\ExpandArgs{c}\NewDocumentCommand{a name with spaces _ and 123} {m}{...#1}

and then use it as

\UseName{a name with spaces _ and 123}{arg}

But if you have such a structured name it's usually better to expose that as arguments in the interface even if internally you use a csname.

So rather than making \foo_something_1 available in the document define custom accessors:

\def\DefineFoo#1#2{\ExpandArgs{c}\NewDocumentCommand{foo_#1_#2}{m}}
\def\Foo#1#2{\UseName{foo_#1_#2}}

Then

\DefineFoo{something}{1}{...#1...}
\Foo{something}{1}{this arg}

which will access \foo_something_1 {this arg} and produce ...this arg...

0

You must log in to answer this question.

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