9

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).

  • 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 3 '11 at 20:37
11
\documentclass[a4paper]{article}


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

Test:
\CommentText{1}
\end{document}
  • 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 3 '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 3 '11 at 17:06
  • 2
    @Leo: or the \csdef, \csuse and related macros from etoolbox. – TH. Jan 3 '11 at 19:38
7

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}
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}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.