5

I'd like to have a macro where I can insert a key as argument and get a value which I have defined before. This should be similar to Create an array of variables but with strings/text instead of numbers.

The usage should look like:

\setprefix{foaf}{http://xmlns.com/foaf/0.1/}

and later

\getprefix{foaf}

which should return http://xmlns.com/foaf/0.1/. When I try to use the code from the before mentioned question I get ! Illegal parameter number in definition of.

5
  • 1
    This is more or less exactly what LaTeX's \@namedef and \@nameuse do. Or etoolbox' \csdef and \csuse. Commented May 16, 2013 at 17:47
  • What will your definitions contain? URLs only? Commented May 16, 2013 at 18:26
  • @Werner yes only URIs. I just realized, after checking all these answers, that it didn't work for me because I had a hash # in one URI which resulted in the ! Illegal parameter number in definition of. Commented May 16, 2013 at 20:31
  • @white_gecko: Then you can include the url package and change #2 in David's answer to \url{#2}. Commented May 16, 2013 at 20:44
  • Thank you David Carlisle, egreg and Steve B. Segletes all your answer work for me :-) My final result is here: gist.github.com/white-gecko/5595112 Commented May 16, 2013 at 21:10

3 Answers 3

6
\def\setprefix#1#2{\expandafter\def\csname MY@#1\endcsname{#2}}

\def\getprefix#1{\csname MY@#1\endcsname}

Should be all you need. The MY@ internal prefix is arbitrary and just needs to be distinct from other prefixes (so don't use LT@ unless you want to break longtable). By using different strings there you can have different arrays of macros.

5

You can use \csname...\endcsname:

\documentclass{article}

\makeatletter
\newcommand\setprefix[2]{\global\@namedef{gecko@\detokenize{#1}}{#2}}
\newcommand{\getprefix}[1]{%
  \@ifundefined{gecko@\detokenize{#1}}
    {\@latex@warning{No prefix `\detokenize{#1}' defined}UNKNOWN}%
    {\@nameuse{gecko@\detokenize{#1}}}%
}
\makeatother

\setprefix{foaf}{http://xmlns.com/foaf/0.1/}
\setprefix{\just#stupid@input}{http://xmlns.com/foaf/0.1/}

\begin{document}

\getprefix{foaf}

\getprefix{fuaf}

\getprefix{\just#stupid@input}

\end{document}

In the first argument of \setprefix you're basically limited in using only balanced braces.

3
\documentclass{article}
\newcommand\setprefix[2]{\expandafter\def\csname#1\endcsname{#2}}
\newcommand\getprefix[1]{\csname#1\endcsname}
\begin{document}
\setprefix{foaf}{http://xmlns.com/foaf/0.1/}
\getprefix{foaf}
\end{document}

Note also that you can recall the prefix with \key, in the example \foaf (only as long as the key is alphabetic).

ROLLBACK to original answer, removing caveat.

4
  • The keys do not have to be alphabetic but can be anything: \setprefix{?.3$a}{foo}\useprefix{?.3$a} will work just fine Commented May 16, 2013 at 17:53
  • Why the edit? \expandafter\def\csname ?.3$a\endcsname{foo} and then \csname ?.3$a\endcsname does work without problems! Your initial solution did suffice just fine! (I'd had upvoted but I'm out of votes for today...) Commented May 16, 2013 at 18:17
  • @cgnieder I did not know that I could put strange characters inside a csname. Now if I only knew how to undo an edit... Commented May 16, 2013 at 18:19
  • There should be a rollback button if you look at the edit history Commented May 16, 2013 at 18:20

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.