With the following code,
\documentclass{standalone}
\newcommand{\@s}[1]{\hspace{#1pt}}
\begin{document}
text
\end{document}
I got the errors:
! LaTeX Error: Command \@ already defined.
Or name \end... illegal, see p.192 of the manual.
See the LaTeX manual or LaTeX Companion for explanation.
Type H <return> for immediate help.
...
l.2 \newcommand{\@s}[1]{\hspace{#1pt}}
Your command was ignored.
Type I <command> <return> to replace it with another command,
or <return> to continue without it.
! LaTeX Error: Missing \begin{document}.
See the LaTeX manual or LaTeX Companion for explanation.
Type H <return> for immediate help.
...
l.2 \newcommand{\@s}[1]{\hspace{#1pt}}
You're in trouble here. Try typing <return> to proceed.
If that doesn't work, type X <return> to quit.
! Missing number, treated as zero.
<to be read again>
##
l.2 \newcommand{\@s}[1]{\hspace{#1pt}}
A number should have been here; I inserted `0'.
(If you can't figure out why I needed to see a number,
look up `weird error' in the index to The TeXbook.)
! Illegal unit of measure (pt inserted).
<to be read again>
##
l.2 \newcommand{\@s}[1]{\hspace{#1pt}}
Dimensions can be in units of em, ex, in, pt, pc,
cm, mm, dd, cc, nd, nc, bp, or sp; but yours is a new one!
I'll assume that you meant to say pt, for printer's points.
To recover gracefully from this error, it's best to
delete the erroneous units; e.g., type `2' to delete
two letters. (See Chapter 27 of The TeXbook.)
! You can't use `macro parameter character #' in horizontal mode.
<recently read> ##
l.2 \newcommand{\@s}[1]{\hspace{#1pt}}
Sorry, but I'm not programmed to handle this case;
I'll just pretend that you didn't ask for it.
If you're in the wrong mode, you might be able to
return to the right one by typing `I}' or `I$' or `I\par'.
What is wrong here? And how should I fix it?
Best Answer
Several things are wrong.
@
is a special character in LaTeX. In packages, it has catcode 11, which means it is treated as a letter, but in documents, it is catcode 12, or "other". This means, in the context of your documents, it cannot be part of a multi-character string that makes up the name of a\newcommand
, unless you reenable the use of@
as a letter, which you will see in code using\makeatletter
, and then discontinued with\makeatother
. (Note: catcode "other" symbols can be made as part of a single-character macro name, like\%
,\$
, or even\@
, the source of the current issue)So,
\newcommand{\@s}[1]{\hspace{#1pt}}
, because of the status of@
as "other" tries to define the macro\@
, not\@s
. And\@
is an already defined macro, thus generating an error. You could put a\makeatletter
before the\newcommand
declaration, but if you reverted back to the normal setting with a\makeatother
following the declaration, then an invocation could not be done with\@s
(which would be tokenized as\@
ands
), but only with\csname @s\endcsname
, which is a mouthful.To use it in a normal document setting, would require something like this
It would be easier just to avoid the use of
@
altogether in naming your macro, as the intention is to allow package developers to use it only, thus avoiding the potential for conflicts with user-defined macro names.See? Doesn't that feel better already?