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.
    – cgnieder
    Commented May 16, 2013 at 17:47
  • What will your definitions contain? URLs only?
    – Werner
    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}.
    – Werner
    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
    – cgnieder
    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...)
    – cgnieder
    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
    – cgnieder
    Commented May 16, 2013 at 18:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .