11

Following this answer to Is it possible to use some sort of internationalization in LaTeX? I'm setting up my own dictionaries.

When compiling the files I get this error:

! Use of \if doesn't match its definition.

and I guess is why I named a term as if_foreign_buyer

\def \if_foreign_buyer{You can only...}

removing starting if solves the problem

Any solution, other than not starting terms with if?

Moreover I would like to start all terms with a underscore _ so I can grab them with a sed command and create dictionaries from terms in the master file.

Also this seems not allowed. Really?

neurino
  • 213
  • 1
  • 5

4 Answers4

18

The problem here is that non-letters like _ are not allowed in macro names and not taken as part of the name. Any text after \def\themacro and the { of the macro replacement text is taken as the parameter text which must match the actual input. With your code you are (re-)defining the TeX primitive \if as a macro which awaits and removes _foreign_buyer after it and replaces it with You can only.... Then the first use of \if (inside a package or a LaTeX core macro) which isn't followed by _foreign_buyer throws a TeX error.

You shouldn't use _ as part of macro names and if you do you need to ensure that they have the correct catcode, namely 11 "letter", while being defined and when used. This can be done using \catcode`\_=11\relax but is not recommended and will break code which relies on the default meaning of _ as an subscript command in math-mode.

Having if in front of a macro name is not a problem and fully OK. The only restriction are \ifxxxs defined by \newif where it is assumed that they start with if. The first two letters are then always stripped to produce \xxxtrue and \xxxfalse. This doesn't affect macro definitions though.

Martin Scharrer
  • 262,582
  • 4
    Just remember that plenty of short command name starting with \if are "reserved": \if, \ifx, \ifnum, \ifcat, ... – yo' Jan 03 '13 at 13:10
  • 4
    I'd underline that this is not related to \if: also \def\box_good{...} will have catastrophic consequences. – egreg Jan 03 '13 at 13:56
  • What about a tip to how naming \def names so I can grep them easily with a regexp? C gettext is always aliased as _ that's why I wanted to start terms' name with a underscore... – neurino Jan 03 '13 at 13:58
  • Actually, the current LaTeX definition of \newif doesn't require that the following control sequence's name starts with if. You can get funny consequences from \newif\xyz, \newif\xy and \newif\x (in order of increasing fun). Also \expandafter\newif\csname\endcsname is quite interesting. – egreg Jan 03 '13 at 16:04
  • @egreg: Didn't I wrote this? "assumed to be if" ... "first two letters are always stripped" etc. – Martin Scharrer Jan 03 '13 at 18:32
  • @MartinScharrer I just wanted to point that out explicitly; somebody could not be aware of it. Another subtle point is that \newif doesn't check whether the following conditional is already defined. – egreg Jan 03 '13 at 18:40
9

There is almost nothing really bad if you use _ in command names, provided you have

\catcode`\_=11

before starting the definition of those commands and never revert the choice.

You can even continue to use _ in math formulas by adding

\mathcode`\_=\string"8000
\begingroup
\catcode`\_=\active
\global\let_\sb
\endgroup

However such a naming scheme is non standard and definitely not recommendable. With some babel languages it may even go wrong.

I don't see how

\command_with_underscore

will increase readability over

\NEcommand

that's as easily searchable.

An example, just to show how this can work.

\documentclass{article}

% Start of document commands
\catcode`\_=11
\mathcode`\_=\string"8000
\begingroup
\catcode`\_=\active
\global\let_\sb
\endgroup

\newcommand{\foreign_buyer}{whatever}

\begin{document}
Here we use \foreign_buyer, and also a formula $a_{1}$.
\end{document}

enter image description here

Starting a command name with \if is definitely bad practice, unless it is a real conditional, introduced with \newif.


Notice that without \catcode`\_=11, when you say

\def\if_foreign_buyer{...}

you're actually (re)defining the very important primitive command \if and this will cause sure disasters with any document.


Note. The command \sb is defined by \let\sb=_ in the LaTeX kernel, so its meaning doesn't change when one modifies the category code of the underscore character. So it's always available as a substitute for it.

In this application we are telling TeX that _ in math mode should behave like a command, which expands to \sb, that is it will just do the right thing. However, macros that rely on the presence of _ will be fooled by this, so some package or macro might fail (not commonly used, but I've seen some cases where a macro tests for a following _).

egreg
  • 1,121,712
  • You don't see how \command_with_underscore will increase readability over \NEcommand probably because never followed python's creator Guido Van Rossum' Style Guide for Descriptive Names ;) Anyway... LaTeX is all but readability and Python zen. Try this: python -c "import this" | grep -i readability – neurino Jan 03 '13 at 16:54
  • 2
    @neurino For us TeX people, @ is the magic letter so \command@with@extr@s or similar would be 'normal' :-) – Joseph Wright Jan 03 '13 at 17:00
  • @neurino I don't find any guide there, just a list of common conventions. As long as you stick to a convention, there's no difference between them. Of course, different backgrounds can lead to different opinions about readability. – egreg Jan 03 '13 at 17:06
  • @egreg: no intention to be polemic — get it as a joke ;) — but if someone like python's dad names a document Style Guide I'd definitively get it as... a guide. :)) I agree about different backgrounds but having used both I can't say a LaTeX script is as readable as a python script, however I look at it. Moreover if you have to tweak something to your needs. My humble opinion tho. – neurino Jan 03 '13 at 17:15
  • @neurino From that "Style guide": "The naming conventions of Python's library are a bit of a mess, so we'll never get this completely consistent". ;-) – egreg Jan 03 '13 at 17:26
2

Use the hyphen instead and it is easier:

\documentclass{minimal}
\makeatletter
\@namedef{if-foreign-buyer}{You can only...}
\makeatother
\begin{document}

\csname if-foreign-buyer\endcsname

\end{document}  
  • Probably should avoid the minimal class: Why not use the minimal class. – Peter Grill Jan 03 '13 at 20:21
  • No! Not when using examples without any font settings. –  Jan 03 '13 at 20:22
  • 3
    Ok. I was just thinking that the more examples newbies see with minimal class will result in more people using it for a MWE as there is no indication in the answer as to the specific reason why you used the minimal class. – Peter Grill Jan 03 '13 at 20:27
  • that is only one part of the story the other one is that it is much more easier to find problems whithout using a lot of unneeded code. –  Jan 03 '13 at 20:32
  • I don't get it: I need to change the definition '\def \termName{term translation}` to @namedef{term-name}{term translation} and change the name it's invoked, right? Will it work with arguments too? – neurino Jan 04 '13 at 13:54
0
\documentclass{article}
\makeatletter
\let\mydef\@namedef
\let\myuse\@nameuse
\makeatother

\begin{document}

\mydef{foreign_buyer}{jfbu}
\mydef{foreign_seller}{egreg}


The foreign seller \myuse{foreign_seller} is definitely infinitely more of a
\TeX pert than the foreign buyer \myuse{foreign_buyer}.


\end{document} 
  • Maybe a word or two how \@namedef and \@nameuse work, and what the difference to \let are, would be helpful. – mafp Jan 03 '13 at 20:22
  • 1
    @mafp I used \let simply to avoid having all the time in the document to say \makeatletter and \makeatother. As for how they work, they are just wrappers around the basic \csname..\endcsname construction which allows to build control sequences with non-letters (it turns out that in the case of the underscore, contrarily to %, { or } or an active character expanding to something else than ultimately some characters, it goes through without trouble within such a construction). –  Jan 03 '13 at 20:28
  • and if in the above you then at the end do \catcode`_=11 you can check that \foreign_buyer acts as expected. –  Jan 03 '13 at 20:33
  • let me state more precisely that you can use { and } inside \csname...\endcsname, however not when using the wrappers \@namedef and \@nameuse. –  Jan 03 '13 at 20:49
  • See Herbert answer: will it work with arguments too? – neurino Jan 04 '13 at 13:55