11

How do I construct a string in LaTeX (perhaps with variables) that calls the LaTeX macro with the corresponding name?

For example, say I have defined a comment as \def\Comment1{Example text.} and \def\CommentText[#1]{\comment#1} and I want \CommentText[1] to produce "Example text".

I am pretty sure the above does not work.

Is there any way to make it work? Is there some good way to achieve the same result with another method (assuming I have about 50 comments that I want to name with names that make them easy for others to understand).

Hendrik Vogt
  • 37,935
  • Thanks for the excellent answers. Let me add that I did not really want to index the comments by integers (although I would like to have the option); I am more thinking of a case where I have the comments in a file indexed by "key words", where someone else not so knowledgeable in LaTeX can easily edit them. I will not be able to test until tomorrow, but I believe that the answers given covers this case as well. – Carl Johan Jan 03 '11 at 20:37

3 Answers3

13
\documentclass[a4paper]{article}


\begin{document}
\expandafter\def\csname Comment1\endcsname{Example}
\newcommand\CommentText[1]{\csname Comment#1\endcsname}

Test:
\CommentText{1}
\end{document}
Ulrike Fischer
  • 327,261
  • 2
    I would add that doing directly \def\Comment1{Example} does not define a macro \Comment1. Instead, it defines the macro \Comment and tells LaTeX that it has to be followed by 1 (indeed, names of control words only contain letters). Ulrike's method using \csname ...\endcsname allows to put almost anything inside the name of the macro. But you cannot write \Comment1 in your text: it will need to be \csname Comment1\endcsname. – Bruno Le Floch Jan 03 '11 at 16:13
  • 1
    How about to use \@namedef and \@nameuse from LaTeX2e kernel instead of \csname ...\endcsname? It seems more clearly. – Leo Liu Jan 03 '11 at 17:06
  • 2
    @Leo: or the \csdef, \csuse and related macros from etoolbox. – TH. Jan 03 '11 at 19:38
8

If you really want to make a list of comments indexed by an integer, why not use the arrayjobx package?

\documentclass{article}
\usepackage{arrayjobx}
\newarray\Comment
\Comment(1)={Example}
\Comment(42)={Another Example}

\begin{document}
\Comment(1)
\Comment(42)
\end{document}
Matthew Leingang
  • 44,937
  • 14
  • 131
  • 195
5

Ulrike's excellent answer could perhaps benefit from a little more macrology:

\documentclass[a4paper]{article}

\newcommand\defComment[2]{\expandafter\def\csname Comment#1\endcsname{#2}}
\newcommand\CommentText[1]{\csname Comment#1\endcsname}
\begin{document}

\defComment{1}{Example}
\defComment{42}{Another example}

Test:
\CommentText{1} \CommentText{42}
\end{document}