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.

Imagine I have a macro \createcontact that accepts three parameters. Now, instead of using these during the expansion, I would like to save them separately for later use and retrieval. The above macro is used in the following context:

\newcommand{\myfirstauthor}{\createcontact{Alice}{Munich}{Germany}}
\newcommand{\mysecondauthor}{\createcontact{Bob}{London}{United Kingdom}}
% and so forth

How do I implement \createcontact so that I can extract the individual parameters that have been passed to it from \myfirstauthor, \mysecondauthor etc.? How would then the code for the extraction look like? In other words, how do I need to define \createcontact and, say, a macro \extractsecond so that \extractsecond\myfirstauthor expands to Munich?

EDIT: Note that only the definition of \createcontact can be adapted, not that of \myfirstauthor, \mysecondauthor etc.. That is, the usage pattern above must remain "as is".

The reason of this exercise is that the above pattern is used in users' documents all over the place. I would like to do more complex processing of the \createcontact parameters than simply using them once in a macro. (For example, I want to use Munich in one context, and Germany in another.)

As per Peter's request, here comes a "compilable" example that has placeholders instead of the commands I'm interested in:

\documentclass{article}

% HOW TO IMPLEMENT THIS?
\newcommand{\createcontact}[3]{...}
\newcommand{\extractfirst}[1]{...}
\newcommand{\extractsecond}[1]{...}
\newcommand{\extractthird}[1]{...}
% HOW TO IMPLEMENT THIS?

% DO NOT CHANGE OR MOVE THIS
\newcommand{\myfirstauthor}{\createcontact{Alice}{Munich}{Germany}}
\newcommand{\mysecondauthor}{\createcontact{Bob}{London}{United Kingdom}}
% DO NOT CHANGE OR MOVE THIS

\begin{document}
  \extractfirst{\myfirstauthor} lives in \extractsecond{\myfirstauthor}
  which is located in \extractthird{\myfirstauthor};
  this may or may not be true for \extractfirst{\mysecondauthor}.
\end{document}
share|improve this question
    
I think what you want is to use different definitions for \createcontact depending on the context. This aim might be achievable by doing \renewcommand{\createcontact}[3]{#2} for instance to have \myfirstauthor typeset Munich, and replacing #2 by #3 would make \myfirstauthor typeset Germany`. Please clarify when you want each behaviour, and what should trigger the change in behaviour. –  Bruno Le Floch Mar 22 '12 at 2:38
    
Can the \newcommand{\myfirstauthor} be moved to the preamble? –  Peter Grill Mar 22 '12 at 2:38
    
@PeterGrill: Yes, it could. I have edited accordingly. But it cannot come before the definitions of \create... and \extract.... –  krlmlr Mar 22 '12 at 2:41
    
@BrunoLeFloch: Thank you for the hint, I think I can implement it in the way you suggested: (Re)define \createcontact only in the \extract... macros. Do you want to convert this to an answer? –  krlmlr Mar 22 '12 at 2:47
    
Is the content between the two % DO NOT CHANGE THIS coming from a separate file? It would be easier to add code after the definitions of \myfirstauthor and before \begin{document}, but can work around this if really needed. Also, is it ok to change \extractfirst{\myfirstauthor} to \extractfirst{myfirstauthor} (slash removed)? –  Peter Grill Mar 22 '12 at 2:49
show 5 more comments

3 Answers

up vote 3 down vote accepted

Using lambda lists:

\documentclass{minimal}
\usepackage{lambda} % http://www.ctan.org/pkg/lambda-lists
%
\def\createcontact#1#2#3{\Listize[#1,#2,#3]}
\let\extractfirst\Head
\def\extractsecond#1{\extractfirst{\Tail{#1}}}
\def\extractthird#1{\extractsecond{\Tail{#1}}}
%
\newcommand{\myfirstauthor}{\createcontact{Alice}{Munich}{Germany}}
\newcommand{\mysecondauthor}{\createcontact{Bob}{London}{United Kingdom}}
%
\begin{document}
  \extractfirst{\myfirstauthor} lives in \extractsecond{\myfirstauthor}
  which is located in \extractthird{\myfirstauthor};
  (or \Head{\Tail{\Tail{\myfirstauthor}}},
  or \Head{\Reverse{\myfirstauthor}})
  this may or may not be true for \extractfirst{\mysecondauthor}.
\end{document}
share|improve this answer
    
That's nice code using one of the less widely known packages. Is it possible to code an accessor that accepts a number, see tex.stackexchange.com/questions/48938/…? –  krlmlr Mar 23 '12 at 23:57
    
@user946850: I was actually thinking about that; something like a \nth macro. But then I realized all assignments happen in TeX's stomach (functional bell ringing?). So then I thought how to do Church numerals in TeX's mouth, and realized you could use e-TeX extensions for the number. Then all that is left is to build the list so, that it includes an index. I haven't done any of this, I'm merely thinking out loud here. –  morbusg Mar 24 '12 at 7:38
add comment

Basic Solution:

Without more details it is difficult to know if something as simple as this will work for you: You call \myfirstauthor{Kenobi}{General}{1138}, and then to access each member you simply refer to \myfirstauthorName, \myfirstauthorRank, and \myfirstauthorSerialNum:

enter image description here

\documentclass{article}

\newcommand{\myfirstauthor}[3]{%
    \newcommand{\myfirstauthorName}{#1}%
    \newcommand{\myfirstauthorRank}{#2}%
    \newcommand{\myfirstauthorSerialNum}{#3}%
}

\begin{document}
\myfirstauthor{Kenobi}{General}{1138}

The details of the first author are:

\medskip
\begin{tabular}{rl}
Name: & \myfirstauthorName\\
Rank: & \myfirstauthorRank\\
Serial Number: & \myfirstauthorSerialNum
\end{tabular}
\end{document}

Alternate Solution:

Instead of creating a list of separate macors \myfirstauthor, \mysecondauthor, etc you could specify the differentiation between them as the first parameter to the \myauthor macro. This yields a more flexible solution as you can create the macros on the fly. So with this solution yo can use \myauthor[first]{Kenobi}{General}{1138} (or leave out the first as that is the default), but others can simply be defined by \myauthor[second]{Dooku}{Count}{66}, and accessed as in the above case to yield:

enter image description here

To create another one you just use \myauthor[third]{}{}{}, etc...

\documentclass{article}

\newcommand{\myauthor}[4][first]{%
    \expandafter\newcommand\csname my#1authorName\endcsname{#2}%
    \expandafter\newcommand\csname my#1authorRank\endcsname{#3}%
    \expandafter\newcommand\csname my#1authorSerialNum\endcsname{#4}%
}

\begin{document}
\myauthor{Kenobi}{General}{1138}
\myauthor[second]{Dooku}{Count}{66}

The details of the first two authors are:

\medskip
\begin{tabular}{rll}
Name: & \myfirstauthorName & \mysecondauthorName\\
Rank: & \myfirstauthorRank & \mysecondauthorRank\\
Serial Number: & \myfirstauthorSerialNum & \mysecondauthorSerialNum
\end{tabular}
\end{document}

Solution Based on given MWE:

With the revised restrictions, you can use \AtBeginDocument to change the definition of \createcontact based on if \myfirstauthor or \mysecondauthor is called:

enter image description here

\documentclass{article}

% HOW TO IMPLEMENT THIS?
\newcommand{\createcontact}[3]{}
\newcommand{\extractfirst}[1]{\csname #1Name\endcsname}
\newcommand{\extractsecond}[1]{\csname #1City\endcsname}
\newcommand{\extractthird}[1]{\csname #1Country\endcsname}

\newcommand{\myfirstauthorName}{}%
\newcommand{\myfirstauthorCity}{}%
\newcommand{\myfirstauthorCountry}{}%
\newcommand{\CreateFirstContact}[3]{%
    \renewcommand{\myfirstauthorName}{#1}%
    \renewcommand{\myfirstauthorCity}{#2}%
    \renewcommand{\myfirstauthorCountry}{#3}%
}
\newcommand{\mysecondauthorName}{}%
\newcommand{\mysecondauthorCity}{}%
\newcommand{\mysecondauthorCountry}{}%
\newcommand{\CreateSecondContact}[3]{%
    \renewcommand{\mysecondauthorName}{#1}%
    \renewcommand{\mysecondauthorCity}{#2}%
    \renewcommand{\mysecondauthorCountry}{#3}%
}


\AtBeginDocument{%
    \let\OldFirstAuthor\myfirstauthor
    \let\OldSecondAuthor\mysecondauthor
    \renewcommand{\myfirstauthor}{\let\createcontact\CreateFirstContact\OldFirstAuthor}
    \renewcommand{\mysecondauthor}{\let\createcontact\CreateSecondContact\OldSecondAuthor}
    \myfirstauthor
    \mysecondauthor
}
% HOW TO IMPLEMENT THIS?

% DO NOT CHANGE THIS
\newcommand{\myfirstauthor}{\createcontact{Alice}{Munich}{Germany}}
\newcommand{\mysecondauthor}{\createcontact{Bob}{London}{United Kingdom}}

\begin{document}
\noindent
  \extractfirst{myfirstauthor} lives in \extractsecond{myfirstauthor}
  which is located in \extractthird{myfirstauthor};
  this may or may not be true for \extractfirst{mysecondauthor}.
\end{document}
share|improve this answer
    
Thank you for the effort, but this is not what I meant. The "API" is given -- I can only alter the definition of \createcontact, but I cannot do anything about how \myfirstauthor, \mysecondauthor etc. are defined. –  krlmlr Mar 22 '12 at 2:19
    
@user946850: Can you please compose a compilable example that illustrates exactly what you want. Commands can be redefined and changed. But without more details it is is difficult to guess what would work for you. –  Peter Grill Mar 22 '12 at 2:28
    
I cannot produce a compilable example because I don't know how to define the commands I need in the first place. I have edited the question, and I hope it is somewhat clearer now. –  krlmlr Mar 22 '12 at 2:30
1  
@user946850: Sorry it is not clear. Can you mock up a compilable example. I know it is obvious to you, but won't be to others who are not dealing exactly with your problem. –  Peter Grill Mar 22 '12 at 2:30
    
@user946850: Pretend the commands exist, and show me how you want to access them and tell me what the expected output should be. For example how do you want to access Munich? You can comment that portion out it out to make it compilable. –  Peter Grill Mar 22 '12 at 2:34
show 2 more comments

With credit to Bruno Le Floch for the idea, here is what I would consider "working for me":

\documentclass{standalone}
% ONE POSSIBLE SOLUTION
\newcommand{\createcontact}[3]{}
\newcommand{\extractfirst}[1]{\renewcommand{\createcontact}[3]{##1}#1}
\newcommand{\extractsecond}[1]{\renewcommand{\createcontact}[3]{##2}#1}
\newcommand{\extractthird}[1]{\renewcommand{\createcontact}[3]{##3}#1}
% ONE POSSIBLE SOLUTION

% DO NOT CHANGE THIS
\newcommand{\myfirstauthor}{\createcontact{Alice}{Munich}{Germany}}
\newcommand{\mysecondauthor}{\createcontact{Bob}{London}{United Kingdom}}
% DO NOT CHANGE THIS
\begin{document}

  \extractfirst{\myfirstauthor} lives in \extractsecond{\myfirstauthor}
  which is located in \extractthird{\myfirstauthor};
  this may or may not true for \extractfirst{\mysecondauthor}.
\end{document}

Result of compilation

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.