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

share|improve this question
    
This is more or less exactly what LaTeX's \@namedef and \@nameuse do. Or etoolbox' \csdef and \csuse. –  cgnieder May 16 '13 at 17:47
    
What will your definitions contain? URLs only? –  Werner May 16 '13 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. –  white_gecko May 16 '13 at 20:31
    
@white_gecko: Then you can include the url package and change #2 in David's answer to \url{#2}. –  Werner May 16 '13 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 –  white_gecko May 16 '13 at 21:10
add comment

3 Answers

up vote 6 down vote accepted
\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.

share|improve this answer
add comment

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.

share|improve this answer
add comment
\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.

share|improve this answer
    
The keys do not have to be alphabetic but can be anything: \setprefix{?.3$a}{foo}\useprefix{?.3$a} will work just fine –  cgnieder May 16 '13 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 May 16 '13 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... –  Steven B. Segletes May 16 '13 at 18:19
    
There should be a rollback button if you look at the edit history –  cgnieder May 16 '13 at 18:20
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.