In a LaTeX document, I use the fancyref package for in-document references. However, I need a bunch of custom prefixes to reference lemmas, definitions and theorems, which fancyref dos not provide. Following the documentation, adding a prefix which supports both vario and plain for both fref and Fref takes a lot of text, and it's all the same all the time. I'd like to avoid this using a macro which does it all for me, and I got stuck with that.
Here's my current attempt:
\documentclass[a4paper]{article}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage[plain]{fancyref}
% command to define a fancyref prefix
\makeatletter
\def\mkfancyprefix#1#2{%
\@namedef{fancyref#1labelprefix}{#1}%
\frefformat{plain}{\@nameuse{fancyref#1labelprefix}}{%
\MakeLowercase{#2}\fancyrefdefaultspacing##1%
}%
\Frefformat{plain}{\@nameuse{fancyref#1labelprefix}}{%
#2\fancyrefdefaultspacing##1%
}%
}
\makeatother
% environments and references for lemmas, ...
\newtheorem{lemma}{Lemma}
\mkfancyprefix{lem}{Lemma}
% content
\begin{document}
\begin{lemma}
\label{lem:lemma}
This is a Lemma
\end{lemma}
There's \fref{lem:lemma} around! \Fref{lem:lemma} is the same, but at the beginning of a sentence.
\end{document}
However, this fails to compile, complaining about a:
Missing \begin{document}
If I move the \mkfancyprefix{lem}{Lemma} after \begin{document}, I can see that it actually outputs fancyreflemlabelprefixfancyreflemlabelprefix. Other than that, everything works and looks as expected.
This confuses me a lot, why does the command print the expanded arguments of \@nameuse to the document? I did some experimenting and added \expandafter immediately before both occurrences of \@nameuse. That changes the output to lemlem, which does not reduce my confusion.
Why does it do that, and how can I prevent it?
Addendum:
Enrico provided a great answer to my question below. Expanding this a little yields the a command which declares a new fancyref prefix in the format variants vario and plain. If you use others (like main), you have to extend the macro accordingly.
\makeatletter
\def\mkfancyprefix#1#2{%
\expandafter\def\csname fancyref#1labelprefix\endcsname{#1}%
% plain lowercase
\begingroup\def\x{\endgroup\frefformat{plain}}%
\expandafter\x\csname fancyref#1labelprefix\endcsname
{\MakeLowercase{#2}\fancyrefdefaultspacing##1}%
% plain uppercase
\begingroup\def\x{\endgroup\Frefformat{plain}}%
\expandafter\x\csname fancyref#1labelprefix\endcsname
{#2\fancyrefdefaultspacing##1}%
% vario lowercase
\begingroup\def\x{\endgroup\frefformat{vario}}%
\expandafter\x\csname fancyref#1labelprefix\endcsname
{\MakeLowercase{#2}\fancyrefdefaultspacing##1##3}%
% vario uppercase
\begingroup\def\x{\endgroup\Frefformat{vario}}%
\expandafter\x\csname fancyref#1labelprefix\endcsname
{#2\fancyrefdefaultspacing##1##3}%
}
\makeatother
\frefformatneeds to be a csname which\@nameuseonly gives after two expansions.\@nameuse{foo}first expands to\csname foo\endcsnameand then to\foo– cgnieder Mar 03 '13 at 18:18cleverefpackage instead offancyref? Thecleverefpackage should have predefined names for all of the objects you mention. – Mico Mar 03 '13 at 18:20\csname fancyref#1labelprefix\endcsnamebut then it saysExtra \endcsname.– Ralf Jung Mar 04 '13 at 09:32cleverrefcan not automatically print the page reference the wayfancyrefdoes: Using "on the next page", leave it away when it is on the same page, and the page number otherwise. (Also, sorry for adding three comments here and constantly editing them, somehow it wouldn't let me add a newline in a comment, and automatically post it as the browser looses focus, which I did not expect) – Ralf Jung Mar 04 '13 at 09:35\csname ...\endcsnameshould work together with an\expandafterchain – cgnieder Mar 04 '13 at 09:44\@namedef{...}to\expandafter\csname fancyref#1labelprefix\endcsname. Now the macro works again without using\@namedef, but it still produces output:lemlem. Should I edit the question? Also, I don't know what an\expandafterchain is, and after some searching I have the impression it's about adding\expandafterin many places, but I can't seem to figure out the right ones. Not do I even understand what I am doing. – Ralf Jung Mar 04 '13 at 09:58cleverefinstead offancyrefwhile also making use of the capabilities of thevariorefpackage: You could type something likeas shown by \cref{type:descript} \vpageref{type:descrip}. (Here,\vpagerefwill create an "intelligent" cross-reference to the page number.) This is admittedly not as elegant as modifying/augmenting some offancyref's capabilities directly. But, depending of course on what you need to get done, the\cref/\vpagerefcombination may be good enough to satisfy to your typesetting needs. – Mico Mar 04 '13 at 17:37