4

Is there a way to define TeX commands with names containing (almost) arbitrary characters, like :, -, _, numbers etc., perhaps even spaces? These are the characters I shall need apart from the standard letters, but of course, if it can be made to support more characters, that wouldn't hurt.

What I want is a command like \newmycommand that works a bit like in the following code. Preferably, it should be possible to use it also outside the preamble. I don't need the commands it defines to support arguments, but if it does not make everything harder, I suggest that you include it in an answer for the sake of other people who may need this.

\documentclass{memoir}

\def\newmycommand#1#2{%define a new command as #1 with code #2
}

\def\usemycommand#1{%apply command #1
}

\newmycommand{my-first-command:day-one}{Day one is a great day}%defines the command "my-first-command:day-one" to be the text "Day one is a great day"

\begin{document}

\usemycommand{my-first-command:day-one}%use the command defined above

\newmycommand{my-second-command}{Last command}%define another command inside the document

\usemycommand{my-second-command}%use this command

\end{document}
2

1 Answer 1

4

You could use \@namedef and \@nameuse, just by providing aliases; but this wouldn't trap errors.

Here's an emulation of \newcommand and \renewcommand (no *-version):

\newcommand{\newlcommand}[1]{\expandafter\newcommand\csname#1\endcsname}
\newcommand{\renewlcommand}[1]{\expandafter\renewcommand\csname#1\endcsname}
\makeatletter
\newcommand{\uselcommand}[1]{%
  \ifcsname#1\endcsname
    \@latex@error{Undefined control sequence}
      {The control sequence at the end of the top line\MessageBreak
       of your error message was never \string\def'ed.}%
  \else
    \csname#1\expandafter\endcsname
  \fi
}
\makeatother

Full example

\documentclass{article}

\newcommand{\newlcommand}[1]{\expandafter\newcommand\csname#1\endcsname}
\newcommand{\renewlcommand}[1]{\expandafter\renewcommand\csname#1\endcsname}
\makeatletter
\newcommand{\uselcommand}[1]{%
  \ifcsname#1\endcsname
    \csname#1\expandafter\endcsname
  \else
    \@latex@error{Undefined control sequence}
      {The control sequence at the end of the top line\MessageBreak
       of your error message was never \string\def'ed.}%
  \fi
}
\makeatother

\newlcommand{my-first-command:day-one}{Day one is a great day}
\newlcommand{my-second-command}[1]{Last command called with #1}
\newlcommand{my-second-command}{whatever}% ERROR

\begin{document}

\uselcommand{my-first-command:day-one}

\uselcommand{my-second-command}{``Hello''}

\uselcommand{joiewo--:}% ERROR

\end{document}

See What exactly do \csname and \endcsname do? to know what characters are allowed.

For conditionals you could do like this:

\newcommand{\newlif}[1]{\expandafter\newif\csname if#1\endcsname}
\newcommand\lcond[1]{T\expandafter T\expandafter\fi\csname if#1\endcsname}
\newcommand\ltrue[1]{\csname#1true\endcsname}
\newcommand\lfalse[1]{\csname#1false\endcsname}

Here's a test

\newlif{my-if} % starts out false

\if\lcond{my-if}%
  true
\else
  false
\fi

\ltrue{my-if} % change the truth value

\if\lcond{my-if}%
  true
\else
  false
\fi

You can use \global in front of \ltrue and \lfalse.

5
  • One last question: Can I do something similar with \newif? That is, create an \if<something>, where <something> can be (almost) arbitrary characters?
    – Gaussler
    Jul 17, 2014 at 13:19
  • Thank you again! Can I ask: What is the idea behind the two Ts? :-)
    – Gaussler
    Jul 17, 2014 at 13:55
  • 1
    @Gaussler That's a trick by Knuth himself; you find a description here
    – egreg
    Jul 17, 2014 at 13:58
  • 1
    @egreg Two redundant \expandafters are in your line \newcommand\lcond.... The TT\fi\csname if#1\endcsname is sufficient.
    – wipet
    Jul 18, 2014 at 8:00
  • @wipet Probably so.
    – egreg
    Jul 18, 2014 at 9:19

You must log in to answer this question.

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