Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I have to get value of a dynamical macro where the index is given by \ref{mymarker}. Is it possible to do? I define a set of macros with a predefined counter 'mycounter' as

\expandafter\newcommand\csname mymacro\the\value{mycounter} \endcsname{mytext} 

where 'mytext' depends on the value of counter.

After that I define a new command

\newcommand{\anotherref}[1]{\csname mymacro\ref{#1} \endcsname}

the code like

\anotherref{mymarker}

does not work. The idea is that this command should give not the counter value related to 'mymarker', like \ref{mymarker} gives, but rather the text 'mytext', which is also related to 'mymarker'.

share|improve this question
2  
Look at the package refcount and \getrefnumber –  egreg Sep 20 '12 at 12:10
    
What should happen if the reference mymarker is undefined? How should \anotherref behave, if the macro to be used is not defined? Also you have a space at the end of the macro name (on purpose or accidentally). –  Heiko Oberdiek Sep 20 '12 at 12:49
    
Thank you very much for the answers and comments! Everything works with the package refcount. –  Andrew Sep 20 '12 at 13:41
1  
Since people have found the question interesting they will want to know the answer. Why not post yours, as a complete MWE? –  Ethan Bolker Sep 20 '12 at 14:45
add comment

2 Answers

up vote 5 down vote accepted

The following example shows an implementation using package refcount.

  • \mymacrodef defines \mymacro<num> using the current counter value of mycounter for <num>. The definition starts with \newcommand{\mymacro<num>}.

  • \mymacroget{<num>} calls \mymacro<num>.

  • \mymacroundefined is used if \mymacroget could not find \mymacro<num>.

  • \mymacroref{<label>} extracts the number from the specified label and calls \mymacroget with the number. If the reference <label> is undefined, \mymacroundefined is used. The label name may contain babel shorthand characters.

  • \mymacrorefexp{<label>} behaves like \mymacroref with the following differences:

    • The macro can be used in expandable context, because it is expandable in exact two expansion steps, see example below.

    • Babel shorthand characters are not supported, because this requires an assignment that breaks expandability.

    • If the reference is undefined, then the user is not given a warning, because that breaks expandability. If possible, use \refused{<label>} outside the expandable context to get the warning in case of an undefined reference.

The example:

\documentclass{article}
\usepackage{refcount}[2010/12/01]
\usepackage{ltxcmds}

\newcounter{mycounter}

\makeatletter

% \mymacrodef defines a macro \mymacro<number> that gets
% the number from the current counter setting for `myounter`.
\newcommand*{\mymacrodef}{%
  \expandafter\newcommand
  \csname mymacro\the\value{mycounter}\endcsname
}

% \mymacroget{<number>} calls \mymacro<number>
% if the macro exists and \mymacroundefined otherwise.
% It is expandable in two expansion steps.
\newcommand*{\mymacroget}[1]{%
  \romannumeral-`\x
  \ltx@ifundefined{mymacro\number#1}{%
    \ltx@space
    \mymacroundefined
  }{%
    \expandafter\ltx@space
    \csname mymacro\number#1\endcsname
  }%
}   

\newcommand*{\mymacroundefined}{\textbf{??}}

% \mymacroref{<label>} is not expandable and gets the number
% from the reference <label>
\newcommand*{\mymacroref}[1]{%
  \refused{#1}%
  \IfRefUndefinedBabel{#1}{%
    \mymacroundefined
  }{%
    % with babel shorthand support
    \begingroup
      \csname @safe@actives@true\endcsname
    \expandafter\endgroup
    \expandafter\mymacroget\expandafter{%
      \number\getrefnumber{#1}%
    }%
  }%
}

\newcommand*{\mymacrorefexp}[1]{%
  \romannumeral-`\x
  \IfRefUndefinedExpandable{#1}{%
    \ltx@space
    \mymacroundefined
  }{%
    \expandafter\expandafter\expandafter\ltx@space
    \mymacroget{\getrefnumber{#1}}%
  }%
}   
\makeatother

\begin{document}

\mymacrodef{Text zero.}
\refstepcounter{mycounter}
\mymacrodef{Text one.}
\label{mylabel}
\refstepcounter{mycounter}
\mymacrodef{Text one again.}

\begin{itemize}
\item[0:] \mymacroget{0}
\item[1:] \mymacroget{1}
\item[42:] \mymacroget{42}
\item[mylabel:] \mymacroref{mylabel}
\item[undef:] \mymacroref{undef}

% Expandable stuff. Define macro \my that has the meaning
% of the macro \mymacro<number>, where <number> is stored
% in label `mylabel':

\refused{mylabel}
\expandafter\expandafter\expandafter\let
\expandafter\expandafter\expandafter\my 
\mymacrorefexp{mylabel}

\item[\texttt{\string\my}:] \texttt{\meaning\my}

\end{itemize}

\end{document}

Test output

share|improve this answer
add comment

Here is my toy example. I hope this can be useful for somebody. The problem is to define the command \editor and to use it for forming the title page. Each editor has his own original number and represents a certain country. In the main text names of editors, their numbers and the corresponding countries are also mentioned. The suggestion to use the package refcount allows me to resolve this problem in the following way:

\documentclass{article}
\usepackage{refcount}

\makeatletter

% Definition of the command \editor{name}{country}
\newcounter{editor@index}
\newcommand\editor[2]{\refstepcounter{editor@index}
\expandafter\newcommand\csname
 @editor@name\the\value{editor@index} \endcsname{#1}
\expandafter\newcommand\csname
 @editor@country\the\value{editor@index} \endcsname{#2}%
}

% Definition of the commands \nameref{marker} and \countryref{marker}
\newcommand{\nameref}[1]{\csname
@editor@name\getrefnumber{#1} \endcsname}
\newcommand{\countryref}[1]{\csname
@editor@country\getrefnumber{#1} \endcsname}

\makeatother

\begin{document}

% With the command \editor one can define the list of editors.
% It can also be used in the redefinition of \maketitle with 
% accessing to the name with 
% \csname @editor@name\the\value{editor@index} \endcsname and to the
% country with \csname @editor@country\getrefnumber{#1} \endcsname.
% One can also mark the editors with \label.

\editor{John Smith}{UK}\label{JS}
\editor{John Doe}{USA}\label{JD}

% Now one can change the order of \editor and always have the correct 
% referencing.

\nameref{JS} from~\countryref{JS} is referred as editor~\ref{JS}.
\nameref{JD} from~\countryref{JD} is referred as editor~\ref{JD}. 

\end{document}

Thank you very much again for the comments and suggestions!

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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