Saving arguments of commands to be used later











up vote
4
down vote

favorite












I'd like to create a command to print some contacts inserted with same 3 commands: name{},work{},email{}.



Every time we use those 3 commands, a new contact is collected and then all of them is printed as below.



I suspect that I need some kind of array of list, to save the contacts, but I have no idea how to search for this.



MWE



documentclass{article}

makeatletter
deflistcontacts{%
noindenttextbf{@name}par
noindenttextit{@work}par
noindenttexttt{@email}par

vskip 1in % to start a new block of contact
}

newcommand{name}[1]{def@name{#1}}
newcommand{work}[1]{def@work{#1}}
newcommand{email}[1]{def@email{#1}}

newcommand{information}[3]{%
name{#1}
work{#2}
email{#3}
}
makeatother

information{Faa Foo}{Univ. Blah}{goo@goo.com}


%% I'd like to insert a new one with same commands
%name{Faa Foo}
%work{Univ. Blah}
%email{goo@goo.com}


% and repeat the process with different number of blocks,
%that is, could be any finite number of contacts.

begin{document}
listcontacts
end{document}









share|improve this question


























    up vote
    4
    down vote

    favorite












    I'd like to create a command to print some contacts inserted with same 3 commands: name{},work{},email{}.



    Every time we use those 3 commands, a new contact is collected and then all of them is printed as below.



    I suspect that I need some kind of array of list, to save the contacts, but I have no idea how to search for this.



    MWE



    documentclass{article}

    makeatletter
    deflistcontacts{%
    noindenttextbf{@name}par
    noindenttextit{@work}par
    noindenttexttt{@email}par

    vskip 1in % to start a new block of contact
    }

    newcommand{name}[1]{def@name{#1}}
    newcommand{work}[1]{def@work{#1}}
    newcommand{email}[1]{def@email{#1}}

    newcommand{information}[3]{%
    name{#1}
    work{#2}
    email{#3}
    }
    makeatother

    information{Faa Foo}{Univ. Blah}{goo@goo.com}


    %% I'd like to insert a new one with same commands
    %name{Faa Foo}
    %work{Univ. Blah}
    %email{goo@goo.com}


    % and repeat the process with different number of blocks,
    %that is, could be any finite number of contacts.

    begin{document}
    listcontacts
    end{document}









    share|improve this question
























      up vote
      4
      down vote

      favorite









      up vote
      4
      down vote

      favorite











      I'd like to create a command to print some contacts inserted with same 3 commands: name{},work{},email{}.



      Every time we use those 3 commands, a new contact is collected and then all of them is printed as below.



      I suspect that I need some kind of array of list, to save the contacts, but I have no idea how to search for this.



      MWE



      documentclass{article}

      makeatletter
      deflistcontacts{%
      noindenttextbf{@name}par
      noindenttextit{@work}par
      noindenttexttt{@email}par

      vskip 1in % to start a new block of contact
      }

      newcommand{name}[1]{def@name{#1}}
      newcommand{work}[1]{def@work{#1}}
      newcommand{email}[1]{def@email{#1}}

      newcommand{information}[3]{%
      name{#1}
      work{#2}
      email{#3}
      }
      makeatother

      information{Faa Foo}{Univ. Blah}{goo@goo.com}


      %% I'd like to insert a new one with same commands
      %name{Faa Foo}
      %work{Univ. Blah}
      %email{goo@goo.com}


      % and repeat the process with different number of blocks,
      %that is, could be any finite number of contacts.

      begin{document}
      listcontacts
      end{document}









      share|improve this question













      I'd like to create a command to print some contacts inserted with same 3 commands: name{},work{},email{}.



      Every time we use those 3 commands, a new contact is collected and then all of them is printed as below.



      I suspect that I need some kind of array of list, to save the contacts, but I have no idea how to search for this.



      MWE



      documentclass{article}

      makeatletter
      deflistcontacts{%
      noindenttextbf{@name}par
      noindenttextit{@work}par
      noindenttexttt{@email}par

      vskip 1in % to start a new block of contact
      }

      newcommand{name}[1]{def@name{#1}}
      newcommand{work}[1]{def@work{#1}}
      newcommand{email}[1]{def@email{#1}}

      newcommand{information}[3]{%
      name{#1}
      work{#2}
      email{#3}
      }
      makeatother

      information{Faa Foo}{Univ. Blah}{goo@goo.com}


      %% I'd like to insert a new one with same commands
      %name{Faa Foo}
      %work{Univ. Blah}
      %email{goo@goo.com}


      % and repeat the process with different number of blocks,
      %that is, could be any finite number of contacts.

      begin{document}
      listcontacts
      end{document}






      macros






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 20 hours ago









      Sigur

      22.7k353134




      22.7k353134






















          3 Answers
          3






          active

          oldest

          votes

















          up vote
          3
          down vote













          I have made it so that @name[<index>] @work[<index>], and @email[<index>] are arrays, where the index is stepped with every call to information{}{}{}.



          listcontact{<index>} will provide the contact info for the one specified index. In the MWE, I loop through all indices.



          documentclass{article}
          usepackage{pgffor}
          makeatletter
          newcounter{infocnt}
          newcommand{name}[1]{%
          expandafterdefcsname @name[theinfocnt]endcsname{#1}}
          newcommand{work}[1]{%
          expandafterdefcsname @work[theinfocnt]endcsname{#1}}
          newcommand{email}[1]{%
          expandafterdefcsname @email[theinfocnt]endcsname{#1}}
          newcommand{information}[3]{%
          stepcounter{infocnt}%
          name{#1}%
          work{#2}%
          email{#3}%
          }
          newcommandlistcontact[1]{noindent%
          NAME: textbf{csname @name[#1]endcsname}\
          WORK: textbf{csname @work[#1]endcsname}\
          EMAIL: textbf{csname @email[#1]endcsname}par
          vskip 1in
          }
          makeatother
          information{Faa Foo}{Univ. Blah}{goo@goo.com}
          information{XXX}{YYY}{ZZZ@goo.com}
          begin{document}
          foreachx in {1,2,...,theinfocnt}{listcontact{x}}
          end{document}


          enter image description here



          If I had my 'druthers, though, I would input the list all at once, quite simply, with the same output. The listofitems package immediately stores the list as an accessible array:



          documentclass{article}
          usepackage{listofitems}
          newcommandlistcontact[1]{noindent%
          NAME: textbf{contacts[#1,1]}\
          WORK: textbf{contacts[#1,2]}\
          EMAIL: textbf{contacts[#1,3]}par
          vskip 1in
          }
          setsepchar{\/&}
          begin{document}
          readlist*contacts{
          Faa Foo & Univ. Blah & goo@goo.com\
          XXX & YYY & ZZZ@goo.com}
          foreachitemxincontacts{listcontact{xcnt}}

          Here is the email of contact 2: contacts[2,3].
          end{document}


          enter image description here



          With a small supplement from the readarray package, the list of contacts could even be stored in an external file.






          share|improve this answer























          • Very nice, specially since tikz is needed only for the loop.
            – Sigur
            20 hours ago










          • @Sigur Oops. I redefined it (didn't see it defined earlier).
            – Steven B. Segletes
            20 hours ago












          • No problem, I observed that. Thanks a lot
            – Sigur
            20 hours ago










          • Do you know another way to print all without using tikz? Maybe using the value of the counter only? I'm going to share the file and tikz could be not available.
            – Sigur
            20 hours ago






          • 1




            @Sigur I changed it to pgffor. However, I also added technique #2, which is far simpler, if you can add all names at once.
            – Steven B. Segletes
            20 hours ago


















          up vote
          2
          down vote













          This is “property lists” playground. Here I define newcontact for defining a contact with a key-value interface.



          With newcontactscheme one defines different ways to print the data; default is used by listcontact if no optional argument is supplied. In the definition, use getcontact{<key>}{#1} to print the value corresponding to <key> for the current contact, represented by #1.



          documentclass{article}
          usepackage{xparse}

          ExplSyntaxOn

          NewDocumentCommand{newcontact}{mm}
          {% #1 = contact label, #2 = data
          prop_new:c { g_sigur_contact_#1_prop }
          prop_gset_from_keyval:cn { g_sigur_contact_#1_prop } { #2 }
          }
          NewDocumentCommand{listcontact}{O{default}m}
          {
          cs_set_eq:Nc __sigur_contact_list:n { sigur_contact_list_#1:n }
          __sigur_contact_list:n { #2 }
          }
          NewDocumentCommand{getcontact}{mm}
          {
          sigur_contact_print:nn { #1 } { #2 }
          }
          NewDocumentCommand{newcontactscheme}{m+m}
          {% #1 = scheme name, #2 = definition
          cs_new_protected:cn { sigur_contact_list_#1:n } { #2 }
          }
          cs_new_protected:Nn sigur_contact_print:nn
          {
          prop_item:cn { g_sigur_contact_#2_prop } { #1 }
          }
          ExplSyntaxOff

          newcontactscheme{default}{%
          parnoindent
          getcontact{name}{#1}\
          getcontact{work}{#1}\
          getcontact{email}{#1}par
          }
          newcontactscheme{short}{%
          getcontact{name}{#1}, getcontact{email}{#1}%
          }
          newcontactscheme{alternate}{%
          begin{tabular}[t]{@{}l@{ }l@{}}
          Name: & getcontact{name}{#1} \
          Work: & getcontact{work}{#1} \
          Email: & texttt{getcontact{email}{#1}}
          end{tabular}%
          }

          newcontact{foo}{
          name=Faa Foo,
          work=Univ. Blah,
          email=goo@goo.com
          }
          newcontact{xxx}{
          name=XXX,
          work=YYY,
          email=ZZZ@goo.com
          }

          begin{document}

          listcontact{foo}

          medskip

          listcontact{xxx}

          medskip

          Short: listcontact[short]{xxx}

          medskip

          Alternate: listcontact[alternate]{foo}

          end{document}


          enter image description here



          A version that also defines listallcontacts (the optional argument is one of the defined schemes).



          documentclass{article}
          usepackage{xparse}

          ExplSyntaxOn

          NewDocumentCommand{newcontact}{mm}
          {% #1 = contact label, #2 = data
          prop_new:c { g_sigur_contact_#1_prop }
          prop_gset_from_keyval:cn { g_sigur_contact_#1_prop } { #2 }
          seq_gput_right:Nn g_sigur_contact_seq { #1 }
          }
          NewDocumentCommand{listcontact}{O{default}m}
          {
          cs_set_eq:Nc __sigur_contact_list:n { sigur_contact_list_#1:n }
          __sigur_contact_list:n { #2 }
          }
          NewDocumentCommand{listallcontacts}{O{default}}
          {
          cs_set_eq:Nc __sigur_contact_list:n { sigur_contact_list_#1:n }
          seq_map_inline:Nn g_sigur_contact_seq
          {
          __sigur_contact_list:n { ##1 } par
          }
          }
          NewDocumentCommand{getcontact}{mm}
          {
          sigur_contact_print:nn { #1 } { #2 }
          }
          NewDocumentCommand{newcontactscheme}{m+m}
          {% #1 = scheme name, #2 = definition
          cs_new_protected:cn { sigur_contact_list_#1:n } { #2 }
          }

          seq_new:N g_sigur_contact_seq

          cs_new_protected:Nn sigur_contact_print:nn
          {
          prop_item:cn { g_sigur_contact_#2_prop } { #1 }
          }
          ExplSyntaxOff

          newcontactscheme{default}{%
          parnoindent
          getcontact{name}{#1}\
          getcontact{work}{#1}\
          getcontact{email}{#1}par
          }
          newcontactscheme{short}{%
          getcontact{name}{#1}, getcontact{email}{#1}%
          }
          newcontactscheme{alternate}{%
          begin{tabular}[t]{@{}l@{ }l@{}}
          Name: & getcontact{name}{#1} \
          Work: & getcontact{work}{#1} \
          Email: & texttt{getcontact{email}{#1}}
          end{tabular}%
          }

          newcontact{foo}{
          name=Faa Foo,
          work=Univ. Blah,
          email=goo@goo.com
          }
          newcontact{xxx}{
          name=XXX,
          work=YYY,
          email=ZZZ@goo.com
          }

          begin{document}

          listcontact{foo}

          medskip

          listcontact{xxx}

          medskip

          Short: listcontact[short]{xxx}

          medskip

          Alternate: listcontact[alternate]{foo}

          medskip

          listallcontacts

          medskip

          listallcontacts[short]

          end{document}





          share|improve this answer























          • I never studied or tried to learn xparse. The result is amazing. Nice!
            – Sigur
            17 hours ago


















          up vote
          2
          down vote













          This is similar to Steven Seglets solution with slightly different packaging. You can show a single contact with ShowContact{} or list all the contact with listcontacts



          enter image description here



          Notes:




          • The values are stored based on #1 which is used as the key to access the contacts. An attempt to reuse the same key is now flagged as an error.

          • This has now been updated to add a medskip between entries when the entire list is printed. The medskip is not added before the first entry, nor after the last as shown in the figure.


          Code:



          documentclass{article}
          usepackage{etoolbox}

          makeatletter

          newtoggle{@IsFirstEntryInList}

          newcommand*{@ShowContact}[1]{%
          iftoggle{@IsFirstEntryInList}{%
          globaltogglefalse{@IsFirstEntryInList}%
          }{%
          medskip% <-- separator between entries
          }%
          ShowContact{#1}%
          }
          newcommand*{ShowContact}[1]{%
          parnoindenttextbf{csuse{name #1}}%
          parnoindenttextit{csuse{work #1}}%
          parnoindenttexttt{csuse{email #1}}%
          }%

          %% https://tex.stackexchange.com/a/14394/4301
          newcommand*{listcontacts}{% Initialize
          globaltoggletrue{@IsFirstEntryInList}%
          }
          newcommand{AddToListOfContacts}[1]{%
          g@addto@macrolistcontacts{{#1}}%
          }


          newcommand{information}[3]{%
          ifcsdef{name #1}{%
          PackageError{jobname}{Multiple uses of the key: '#1'}{}%
          }{%
          csdef{name #1}{#1}%
          csdef{work #1}{#2}%
          csdef{email #1}{#3}%
          AddToListOfContacts{unexpanded{@ShowContact{#1}}}%
          }%
          }
          makeatother

          information{Faa Foo}{Univ. Blah}{goo@goo.com}
          information{Harvard}{Harvard University}{me@harvard.com}
          %information{Harvard}{xxx University}{me@harvard.com}% <-- Triggers an error

          begin{document}
          noindent
          To show one contact:

          ShowContact{Harvard}

          medskipnoindent
          To show all contacts:

          listcontacts
          parnoindent
          Text following to check that there is no extra space at end...
          end{document}





          share|improve this answer























          • Interesting. In this case, the contacts are accessed via argument value, not via a number, right?
            – Sigur
            20 hours ago










          • @Sigur: Yes, the first parameter is used as the key to access the information. This is really helpful if you have a large number of contacts.
            – Peter Grill
            20 hours ago










          • Since I'm going to share this file, do you know if etoolbox comes with a basic installation? Because I know that tikz does not.
            – Sigur
            20 hours ago










          • Yes, etoolbox is in the standard distribution. But, so is tikz so not sure why you think otherwise. Also, have added error checking in the updated version.
            – Peter Grill
            20 hours ago








          • 1




            @Sigur: As requested, I have updated it inserts a medskip only between entries. You can replace the medskip with the symbol you desire.
            – Peter Grill
            8 hours ago











          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "85"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














           

          draft saved


          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f460175%2fsaving-arguments-of-commands-to-be-used-later%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          3 Answers
          3






          active

          oldest

          votes








          3 Answers
          3






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          3
          down vote













          I have made it so that @name[<index>] @work[<index>], and @email[<index>] are arrays, where the index is stepped with every call to information{}{}{}.



          listcontact{<index>} will provide the contact info for the one specified index. In the MWE, I loop through all indices.



          documentclass{article}
          usepackage{pgffor}
          makeatletter
          newcounter{infocnt}
          newcommand{name}[1]{%
          expandafterdefcsname @name[theinfocnt]endcsname{#1}}
          newcommand{work}[1]{%
          expandafterdefcsname @work[theinfocnt]endcsname{#1}}
          newcommand{email}[1]{%
          expandafterdefcsname @email[theinfocnt]endcsname{#1}}
          newcommand{information}[3]{%
          stepcounter{infocnt}%
          name{#1}%
          work{#2}%
          email{#3}%
          }
          newcommandlistcontact[1]{noindent%
          NAME: textbf{csname @name[#1]endcsname}\
          WORK: textbf{csname @work[#1]endcsname}\
          EMAIL: textbf{csname @email[#1]endcsname}par
          vskip 1in
          }
          makeatother
          information{Faa Foo}{Univ. Blah}{goo@goo.com}
          information{XXX}{YYY}{ZZZ@goo.com}
          begin{document}
          foreachx in {1,2,...,theinfocnt}{listcontact{x}}
          end{document}


          enter image description here



          If I had my 'druthers, though, I would input the list all at once, quite simply, with the same output. The listofitems package immediately stores the list as an accessible array:



          documentclass{article}
          usepackage{listofitems}
          newcommandlistcontact[1]{noindent%
          NAME: textbf{contacts[#1,1]}\
          WORK: textbf{contacts[#1,2]}\
          EMAIL: textbf{contacts[#1,3]}par
          vskip 1in
          }
          setsepchar{\/&}
          begin{document}
          readlist*contacts{
          Faa Foo & Univ. Blah & goo@goo.com\
          XXX & YYY & ZZZ@goo.com}
          foreachitemxincontacts{listcontact{xcnt}}

          Here is the email of contact 2: contacts[2,3].
          end{document}


          enter image description here



          With a small supplement from the readarray package, the list of contacts could even be stored in an external file.






          share|improve this answer























          • Very nice, specially since tikz is needed only for the loop.
            – Sigur
            20 hours ago










          • @Sigur Oops. I redefined it (didn't see it defined earlier).
            – Steven B. Segletes
            20 hours ago












          • No problem, I observed that. Thanks a lot
            – Sigur
            20 hours ago










          • Do you know another way to print all without using tikz? Maybe using the value of the counter only? I'm going to share the file and tikz could be not available.
            – Sigur
            20 hours ago






          • 1




            @Sigur I changed it to pgffor. However, I also added technique #2, which is far simpler, if you can add all names at once.
            – Steven B. Segletes
            20 hours ago















          up vote
          3
          down vote













          I have made it so that @name[<index>] @work[<index>], and @email[<index>] are arrays, where the index is stepped with every call to information{}{}{}.



          listcontact{<index>} will provide the contact info for the one specified index. In the MWE, I loop through all indices.



          documentclass{article}
          usepackage{pgffor}
          makeatletter
          newcounter{infocnt}
          newcommand{name}[1]{%
          expandafterdefcsname @name[theinfocnt]endcsname{#1}}
          newcommand{work}[1]{%
          expandafterdefcsname @work[theinfocnt]endcsname{#1}}
          newcommand{email}[1]{%
          expandafterdefcsname @email[theinfocnt]endcsname{#1}}
          newcommand{information}[3]{%
          stepcounter{infocnt}%
          name{#1}%
          work{#2}%
          email{#3}%
          }
          newcommandlistcontact[1]{noindent%
          NAME: textbf{csname @name[#1]endcsname}\
          WORK: textbf{csname @work[#1]endcsname}\
          EMAIL: textbf{csname @email[#1]endcsname}par
          vskip 1in
          }
          makeatother
          information{Faa Foo}{Univ. Blah}{goo@goo.com}
          information{XXX}{YYY}{ZZZ@goo.com}
          begin{document}
          foreachx in {1,2,...,theinfocnt}{listcontact{x}}
          end{document}


          enter image description here



          If I had my 'druthers, though, I would input the list all at once, quite simply, with the same output. The listofitems package immediately stores the list as an accessible array:



          documentclass{article}
          usepackage{listofitems}
          newcommandlistcontact[1]{noindent%
          NAME: textbf{contacts[#1,1]}\
          WORK: textbf{contacts[#1,2]}\
          EMAIL: textbf{contacts[#1,3]}par
          vskip 1in
          }
          setsepchar{\/&}
          begin{document}
          readlist*contacts{
          Faa Foo & Univ. Blah & goo@goo.com\
          XXX & YYY & ZZZ@goo.com}
          foreachitemxincontacts{listcontact{xcnt}}

          Here is the email of contact 2: contacts[2,3].
          end{document}


          enter image description here



          With a small supplement from the readarray package, the list of contacts could even be stored in an external file.






          share|improve this answer























          • Very nice, specially since tikz is needed only for the loop.
            – Sigur
            20 hours ago










          • @Sigur Oops. I redefined it (didn't see it defined earlier).
            – Steven B. Segletes
            20 hours ago












          • No problem, I observed that. Thanks a lot
            – Sigur
            20 hours ago










          • Do you know another way to print all without using tikz? Maybe using the value of the counter only? I'm going to share the file and tikz could be not available.
            – Sigur
            20 hours ago






          • 1




            @Sigur I changed it to pgffor. However, I also added technique #2, which is far simpler, if you can add all names at once.
            – Steven B. Segletes
            20 hours ago













          up vote
          3
          down vote










          up vote
          3
          down vote









          I have made it so that @name[<index>] @work[<index>], and @email[<index>] are arrays, where the index is stepped with every call to information{}{}{}.



          listcontact{<index>} will provide the contact info for the one specified index. In the MWE, I loop through all indices.



          documentclass{article}
          usepackage{pgffor}
          makeatletter
          newcounter{infocnt}
          newcommand{name}[1]{%
          expandafterdefcsname @name[theinfocnt]endcsname{#1}}
          newcommand{work}[1]{%
          expandafterdefcsname @work[theinfocnt]endcsname{#1}}
          newcommand{email}[1]{%
          expandafterdefcsname @email[theinfocnt]endcsname{#1}}
          newcommand{information}[3]{%
          stepcounter{infocnt}%
          name{#1}%
          work{#2}%
          email{#3}%
          }
          newcommandlistcontact[1]{noindent%
          NAME: textbf{csname @name[#1]endcsname}\
          WORK: textbf{csname @work[#1]endcsname}\
          EMAIL: textbf{csname @email[#1]endcsname}par
          vskip 1in
          }
          makeatother
          information{Faa Foo}{Univ. Blah}{goo@goo.com}
          information{XXX}{YYY}{ZZZ@goo.com}
          begin{document}
          foreachx in {1,2,...,theinfocnt}{listcontact{x}}
          end{document}


          enter image description here



          If I had my 'druthers, though, I would input the list all at once, quite simply, with the same output. The listofitems package immediately stores the list as an accessible array:



          documentclass{article}
          usepackage{listofitems}
          newcommandlistcontact[1]{noindent%
          NAME: textbf{contacts[#1,1]}\
          WORK: textbf{contacts[#1,2]}\
          EMAIL: textbf{contacts[#1,3]}par
          vskip 1in
          }
          setsepchar{\/&}
          begin{document}
          readlist*contacts{
          Faa Foo & Univ. Blah & goo@goo.com\
          XXX & YYY & ZZZ@goo.com}
          foreachitemxincontacts{listcontact{xcnt}}

          Here is the email of contact 2: contacts[2,3].
          end{document}


          enter image description here



          With a small supplement from the readarray package, the list of contacts could even be stored in an external file.






          share|improve this answer














          I have made it so that @name[<index>] @work[<index>], and @email[<index>] are arrays, where the index is stepped with every call to information{}{}{}.



          listcontact{<index>} will provide the contact info for the one specified index. In the MWE, I loop through all indices.



          documentclass{article}
          usepackage{pgffor}
          makeatletter
          newcounter{infocnt}
          newcommand{name}[1]{%
          expandafterdefcsname @name[theinfocnt]endcsname{#1}}
          newcommand{work}[1]{%
          expandafterdefcsname @work[theinfocnt]endcsname{#1}}
          newcommand{email}[1]{%
          expandafterdefcsname @email[theinfocnt]endcsname{#1}}
          newcommand{information}[3]{%
          stepcounter{infocnt}%
          name{#1}%
          work{#2}%
          email{#3}%
          }
          newcommandlistcontact[1]{noindent%
          NAME: textbf{csname @name[#1]endcsname}\
          WORK: textbf{csname @work[#1]endcsname}\
          EMAIL: textbf{csname @email[#1]endcsname}par
          vskip 1in
          }
          makeatother
          information{Faa Foo}{Univ. Blah}{goo@goo.com}
          information{XXX}{YYY}{ZZZ@goo.com}
          begin{document}
          foreachx in {1,2,...,theinfocnt}{listcontact{x}}
          end{document}


          enter image description here



          If I had my 'druthers, though, I would input the list all at once, quite simply, with the same output. The listofitems package immediately stores the list as an accessible array:



          documentclass{article}
          usepackage{listofitems}
          newcommandlistcontact[1]{noindent%
          NAME: textbf{contacts[#1,1]}\
          WORK: textbf{contacts[#1,2]}\
          EMAIL: textbf{contacts[#1,3]}par
          vskip 1in
          }
          setsepchar{\/&}
          begin{document}
          readlist*contacts{
          Faa Foo & Univ. Blah & goo@goo.com\
          XXX & YYY & ZZZ@goo.com}
          foreachitemxincontacts{listcontact{xcnt}}

          Here is the email of contact 2: contacts[2,3].
          end{document}


          enter image description here



          With a small supplement from the readarray package, the list of contacts could even be stored in an external file.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 20 hours ago

























          answered 20 hours ago









          Steven B. Segletes

          151k9189397




          151k9189397












          • Very nice, specially since tikz is needed only for the loop.
            – Sigur
            20 hours ago










          • @Sigur Oops. I redefined it (didn't see it defined earlier).
            – Steven B. Segletes
            20 hours ago












          • No problem, I observed that. Thanks a lot
            – Sigur
            20 hours ago










          • Do you know another way to print all without using tikz? Maybe using the value of the counter only? I'm going to share the file and tikz could be not available.
            – Sigur
            20 hours ago






          • 1




            @Sigur I changed it to pgffor. However, I also added technique #2, which is far simpler, if you can add all names at once.
            – Steven B. Segletes
            20 hours ago


















          • Very nice, specially since tikz is needed only for the loop.
            – Sigur
            20 hours ago










          • @Sigur Oops. I redefined it (didn't see it defined earlier).
            – Steven B. Segletes
            20 hours ago












          • No problem, I observed that. Thanks a lot
            – Sigur
            20 hours ago










          • Do you know another way to print all without using tikz? Maybe using the value of the counter only? I'm going to share the file and tikz could be not available.
            – Sigur
            20 hours ago






          • 1




            @Sigur I changed it to pgffor. However, I also added technique #2, which is far simpler, if you can add all names at once.
            – Steven B. Segletes
            20 hours ago
















          Very nice, specially since tikz is needed only for the loop.
          – Sigur
          20 hours ago




          Very nice, specially since tikz is needed only for the loop.
          – Sigur
          20 hours ago












          @Sigur Oops. I redefined it (didn't see it defined earlier).
          – Steven B. Segletes
          20 hours ago






          @Sigur Oops. I redefined it (didn't see it defined earlier).
          – Steven B. Segletes
          20 hours ago














          No problem, I observed that. Thanks a lot
          – Sigur
          20 hours ago




          No problem, I observed that. Thanks a lot
          – Sigur
          20 hours ago












          Do you know another way to print all without using tikz? Maybe using the value of the counter only? I'm going to share the file and tikz could be not available.
          – Sigur
          20 hours ago




          Do you know another way to print all without using tikz? Maybe using the value of the counter only? I'm going to share the file and tikz could be not available.
          – Sigur
          20 hours ago




          1




          1




          @Sigur I changed it to pgffor. However, I also added technique #2, which is far simpler, if you can add all names at once.
          – Steven B. Segletes
          20 hours ago




          @Sigur I changed it to pgffor. However, I also added technique #2, which is far simpler, if you can add all names at once.
          – Steven B. Segletes
          20 hours ago










          up vote
          2
          down vote













          This is “property lists” playground. Here I define newcontact for defining a contact with a key-value interface.



          With newcontactscheme one defines different ways to print the data; default is used by listcontact if no optional argument is supplied. In the definition, use getcontact{<key>}{#1} to print the value corresponding to <key> for the current contact, represented by #1.



          documentclass{article}
          usepackage{xparse}

          ExplSyntaxOn

          NewDocumentCommand{newcontact}{mm}
          {% #1 = contact label, #2 = data
          prop_new:c { g_sigur_contact_#1_prop }
          prop_gset_from_keyval:cn { g_sigur_contact_#1_prop } { #2 }
          }
          NewDocumentCommand{listcontact}{O{default}m}
          {
          cs_set_eq:Nc __sigur_contact_list:n { sigur_contact_list_#1:n }
          __sigur_contact_list:n { #2 }
          }
          NewDocumentCommand{getcontact}{mm}
          {
          sigur_contact_print:nn { #1 } { #2 }
          }
          NewDocumentCommand{newcontactscheme}{m+m}
          {% #1 = scheme name, #2 = definition
          cs_new_protected:cn { sigur_contact_list_#1:n } { #2 }
          }
          cs_new_protected:Nn sigur_contact_print:nn
          {
          prop_item:cn { g_sigur_contact_#2_prop } { #1 }
          }
          ExplSyntaxOff

          newcontactscheme{default}{%
          parnoindent
          getcontact{name}{#1}\
          getcontact{work}{#1}\
          getcontact{email}{#1}par
          }
          newcontactscheme{short}{%
          getcontact{name}{#1}, getcontact{email}{#1}%
          }
          newcontactscheme{alternate}{%
          begin{tabular}[t]{@{}l@{ }l@{}}
          Name: & getcontact{name}{#1} \
          Work: & getcontact{work}{#1} \
          Email: & texttt{getcontact{email}{#1}}
          end{tabular}%
          }

          newcontact{foo}{
          name=Faa Foo,
          work=Univ. Blah,
          email=goo@goo.com
          }
          newcontact{xxx}{
          name=XXX,
          work=YYY,
          email=ZZZ@goo.com
          }

          begin{document}

          listcontact{foo}

          medskip

          listcontact{xxx}

          medskip

          Short: listcontact[short]{xxx}

          medskip

          Alternate: listcontact[alternate]{foo}

          end{document}


          enter image description here



          A version that also defines listallcontacts (the optional argument is one of the defined schemes).



          documentclass{article}
          usepackage{xparse}

          ExplSyntaxOn

          NewDocumentCommand{newcontact}{mm}
          {% #1 = contact label, #2 = data
          prop_new:c { g_sigur_contact_#1_prop }
          prop_gset_from_keyval:cn { g_sigur_contact_#1_prop } { #2 }
          seq_gput_right:Nn g_sigur_contact_seq { #1 }
          }
          NewDocumentCommand{listcontact}{O{default}m}
          {
          cs_set_eq:Nc __sigur_contact_list:n { sigur_contact_list_#1:n }
          __sigur_contact_list:n { #2 }
          }
          NewDocumentCommand{listallcontacts}{O{default}}
          {
          cs_set_eq:Nc __sigur_contact_list:n { sigur_contact_list_#1:n }
          seq_map_inline:Nn g_sigur_contact_seq
          {
          __sigur_contact_list:n { ##1 } par
          }
          }
          NewDocumentCommand{getcontact}{mm}
          {
          sigur_contact_print:nn { #1 } { #2 }
          }
          NewDocumentCommand{newcontactscheme}{m+m}
          {% #1 = scheme name, #2 = definition
          cs_new_protected:cn { sigur_contact_list_#1:n } { #2 }
          }

          seq_new:N g_sigur_contact_seq

          cs_new_protected:Nn sigur_contact_print:nn
          {
          prop_item:cn { g_sigur_contact_#2_prop } { #1 }
          }
          ExplSyntaxOff

          newcontactscheme{default}{%
          parnoindent
          getcontact{name}{#1}\
          getcontact{work}{#1}\
          getcontact{email}{#1}par
          }
          newcontactscheme{short}{%
          getcontact{name}{#1}, getcontact{email}{#1}%
          }
          newcontactscheme{alternate}{%
          begin{tabular}[t]{@{}l@{ }l@{}}
          Name: & getcontact{name}{#1} \
          Work: & getcontact{work}{#1} \
          Email: & texttt{getcontact{email}{#1}}
          end{tabular}%
          }

          newcontact{foo}{
          name=Faa Foo,
          work=Univ. Blah,
          email=goo@goo.com
          }
          newcontact{xxx}{
          name=XXX,
          work=YYY,
          email=ZZZ@goo.com
          }

          begin{document}

          listcontact{foo}

          medskip

          listcontact{xxx}

          medskip

          Short: listcontact[short]{xxx}

          medskip

          Alternate: listcontact[alternate]{foo}

          medskip

          listallcontacts

          medskip

          listallcontacts[short]

          end{document}





          share|improve this answer























          • I never studied or tried to learn xparse. The result is amazing. Nice!
            – Sigur
            17 hours ago















          up vote
          2
          down vote













          This is “property lists” playground. Here I define newcontact for defining a contact with a key-value interface.



          With newcontactscheme one defines different ways to print the data; default is used by listcontact if no optional argument is supplied. In the definition, use getcontact{<key>}{#1} to print the value corresponding to <key> for the current contact, represented by #1.



          documentclass{article}
          usepackage{xparse}

          ExplSyntaxOn

          NewDocumentCommand{newcontact}{mm}
          {% #1 = contact label, #2 = data
          prop_new:c { g_sigur_contact_#1_prop }
          prop_gset_from_keyval:cn { g_sigur_contact_#1_prop } { #2 }
          }
          NewDocumentCommand{listcontact}{O{default}m}
          {
          cs_set_eq:Nc __sigur_contact_list:n { sigur_contact_list_#1:n }
          __sigur_contact_list:n { #2 }
          }
          NewDocumentCommand{getcontact}{mm}
          {
          sigur_contact_print:nn { #1 } { #2 }
          }
          NewDocumentCommand{newcontactscheme}{m+m}
          {% #1 = scheme name, #2 = definition
          cs_new_protected:cn { sigur_contact_list_#1:n } { #2 }
          }
          cs_new_protected:Nn sigur_contact_print:nn
          {
          prop_item:cn { g_sigur_contact_#2_prop } { #1 }
          }
          ExplSyntaxOff

          newcontactscheme{default}{%
          parnoindent
          getcontact{name}{#1}\
          getcontact{work}{#1}\
          getcontact{email}{#1}par
          }
          newcontactscheme{short}{%
          getcontact{name}{#1}, getcontact{email}{#1}%
          }
          newcontactscheme{alternate}{%
          begin{tabular}[t]{@{}l@{ }l@{}}
          Name: & getcontact{name}{#1} \
          Work: & getcontact{work}{#1} \
          Email: & texttt{getcontact{email}{#1}}
          end{tabular}%
          }

          newcontact{foo}{
          name=Faa Foo,
          work=Univ. Blah,
          email=goo@goo.com
          }
          newcontact{xxx}{
          name=XXX,
          work=YYY,
          email=ZZZ@goo.com
          }

          begin{document}

          listcontact{foo}

          medskip

          listcontact{xxx}

          medskip

          Short: listcontact[short]{xxx}

          medskip

          Alternate: listcontact[alternate]{foo}

          end{document}


          enter image description here



          A version that also defines listallcontacts (the optional argument is one of the defined schemes).



          documentclass{article}
          usepackage{xparse}

          ExplSyntaxOn

          NewDocumentCommand{newcontact}{mm}
          {% #1 = contact label, #2 = data
          prop_new:c { g_sigur_contact_#1_prop }
          prop_gset_from_keyval:cn { g_sigur_contact_#1_prop } { #2 }
          seq_gput_right:Nn g_sigur_contact_seq { #1 }
          }
          NewDocumentCommand{listcontact}{O{default}m}
          {
          cs_set_eq:Nc __sigur_contact_list:n { sigur_contact_list_#1:n }
          __sigur_contact_list:n { #2 }
          }
          NewDocumentCommand{listallcontacts}{O{default}}
          {
          cs_set_eq:Nc __sigur_contact_list:n { sigur_contact_list_#1:n }
          seq_map_inline:Nn g_sigur_contact_seq
          {
          __sigur_contact_list:n { ##1 } par
          }
          }
          NewDocumentCommand{getcontact}{mm}
          {
          sigur_contact_print:nn { #1 } { #2 }
          }
          NewDocumentCommand{newcontactscheme}{m+m}
          {% #1 = scheme name, #2 = definition
          cs_new_protected:cn { sigur_contact_list_#1:n } { #2 }
          }

          seq_new:N g_sigur_contact_seq

          cs_new_protected:Nn sigur_contact_print:nn
          {
          prop_item:cn { g_sigur_contact_#2_prop } { #1 }
          }
          ExplSyntaxOff

          newcontactscheme{default}{%
          parnoindent
          getcontact{name}{#1}\
          getcontact{work}{#1}\
          getcontact{email}{#1}par
          }
          newcontactscheme{short}{%
          getcontact{name}{#1}, getcontact{email}{#1}%
          }
          newcontactscheme{alternate}{%
          begin{tabular}[t]{@{}l@{ }l@{}}
          Name: & getcontact{name}{#1} \
          Work: & getcontact{work}{#1} \
          Email: & texttt{getcontact{email}{#1}}
          end{tabular}%
          }

          newcontact{foo}{
          name=Faa Foo,
          work=Univ. Blah,
          email=goo@goo.com
          }
          newcontact{xxx}{
          name=XXX,
          work=YYY,
          email=ZZZ@goo.com
          }

          begin{document}

          listcontact{foo}

          medskip

          listcontact{xxx}

          medskip

          Short: listcontact[short]{xxx}

          medskip

          Alternate: listcontact[alternate]{foo}

          medskip

          listallcontacts

          medskip

          listallcontacts[short]

          end{document}





          share|improve this answer























          • I never studied or tried to learn xparse. The result is amazing. Nice!
            – Sigur
            17 hours ago













          up vote
          2
          down vote










          up vote
          2
          down vote









          This is “property lists” playground. Here I define newcontact for defining a contact with a key-value interface.



          With newcontactscheme one defines different ways to print the data; default is used by listcontact if no optional argument is supplied. In the definition, use getcontact{<key>}{#1} to print the value corresponding to <key> for the current contact, represented by #1.



          documentclass{article}
          usepackage{xparse}

          ExplSyntaxOn

          NewDocumentCommand{newcontact}{mm}
          {% #1 = contact label, #2 = data
          prop_new:c { g_sigur_contact_#1_prop }
          prop_gset_from_keyval:cn { g_sigur_contact_#1_prop } { #2 }
          }
          NewDocumentCommand{listcontact}{O{default}m}
          {
          cs_set_eq:Nc __sigur_contact_list:n { sigur_contact_list_#1:n }
          __sigur_contact_list:n { #2 }
          }
          NewDocumentCommand{getcontact}{mm}
          {
          sigur_contact_print:nn { #1 } { #2 }
          }
          NewDocumentCommand{newcontactscheme}{m+m}
          {% #1 = scheme name, #2 = definition
          cs_new_protected:cn { sigur_contact_list_#1:n } { #2 }
          }
          cs_new_protected:Nn sigur_contact_print:nn
          {
          prop_item:cn { g_sigur_contact_#2_prop } { #1 }
          }
          ExplSyntaxOff

          newcontactscheme{default}{%
          parnoindent
          getcontact{name}{#1}\
          getcontact{work}{#1}\
          getcontact{email}{#1}par
          }
          newcontactscheme{short}{%
          getcontact{name}{#1}, getcontact{email}{#1}%
          }
          newcontactscheme{alternate}{%
          begin{tabular}[t]{@{}l@{ }l@{}}
          Name: & getcontact{name}{#1} \
          Work: & getcontact{work}{#1} \
          Email: & texttt{getcontact{email}{#1}}
          end{tabular}%
          }

          newcontact{foo}{
          name=Faa Foo,
          work=Univ. Blah,
          email=goo@goo.com
          }
          newcontact{xxx}{
          name=XXX,
          work=YYY,
          email=ZZZ@goo.com
          }

          begin{document}

          listcontact{foo}

          medskip

          listcontact{xxx}

          medskip

          Short: listcontact[short]{xxx}

          medskip

          Alternate: listcontact[alternate]{foo}

          end{document}


          enter image description here



          A version that also defines listallcontacts (the optional argument is one of the defined schemes).



          documentclass{article}
          usepackage{xparse}

          ExplSyntaxOn

          NewDocumentCommand{newcontact}{mm}
          {% #1 = contact label, #2 = data
          prop_new:c { g_sigur_contact_#1_prop }
          prop_gset_from_keyval:cn { g_sigur_contact_#1_prop } { #2 }
          seq_gput_right:Nn g_sigur_contact_seq { #1 }
          }
          NewDocumentCommand{listcontact}{O{default}m}
          {
          cs_set_eq:Nc __sigur_contact_list:n { sigur_contact_list_#1:n }
          __sigur_contact_list:n { #2 }
          }
          NewDocumentCommand{listallcontacts}{O{default}}
          {
          cs_set_eq:Nc __sigur_contact_list:n { sigur_contact_list_#1:n }
          seq_map_inline:Nn g_sigur_contact_seq
          {
          __sigur_contact_list:n { ##1 } par
          }
          }
          NewDocumentCommand{getcontact}{mm}
          {
          sigur_contact_print:nn { #1 } { #2 }
          }
          NewDocumentCommand{newcontactscheme}{m+m}
          {% #1 = scheme name, #2 = definition
          cs_new_protected:cn { sigur_contact_list_#1:n } { #2 }
          }

          seq_new:N g_sigur_contact_seq

          cs_new_protected:Nn sigur_contact_print:nn
          {
          prop_item:cn { g_sigur_contact_#2_prop } { #1 }
          }
          ExplSyntaxOff

          newcontactscheme{default}{%
          parnoindent
          getcontact{name}{#1}\
          getcontact{work}{#1}\
          getcontact{email}{#1}par
          }
          newcontactscheme{short}{%
          getcontact{name}{#1}, getcontact{email}{#1}%
          }
          newcontactscheme{alternate}{%
          begin{tabular}[t]{@{}l@{ }l@{}}
          Name: & getcontact{name}{#1} \
          Work: & getcontact{work}{#1} \
          Email: & texttt{getcontact{email}{#1}}
          end{tabular}%
          }

          newcontact{foo}{
          name=Faa Foo,
          work=Univ. Blah,
          email=goo@goo.com
          }
          newcontact{xxx}{
          name=XXX,
          work=YYY,
          email=ZZZ@goo.com
          }

          begin{document}

          listcontact{foo}

          medskip

          listcontact{xxx}

          medskip

          Short: listcontact[short]{xxx}

          medskip

          Alternate: listcontact[alternate]{foo}

          medskip

          listallcontacts

          medskip

          listallcontacts[short]

          end{document}





          share|improve this answer














          This is “property lists” playground. Here I define newcontact for defining a contact with a key-value interface.



          With newcontactscheme one defines different ways to print the data; default is used by listcontact if no optional argument is supplied. In the definition, use getcontact{<key>}{#1} to print the value corresponding to <key> for the current contact, represented by #1.



          documentclass{article}
          usepackage{xparse}

          ExplSyntaxOn

          NewDocumentCommand{newcontact}{mm}
          {% #1 = contact label, #2 = data
          prop_new:c { g_sigur_contact_#1_prop }
          prop_gset_from_keyval:cn { g_sigur_contact_#1_prop } { #2 }
          }
          NewDocumentCommand{listcontact}{O{default}m}
          {
          cs_set_eq:Nc __sigur_contact_list:n { sigur_contact_list_#1:n }
          __sigur_contact_list:n { #2 }
          }
          NewDocumentCommand{getcontact}{mm}
          {
          sigur_contact_print:nn { #1 } { #2 }
          }
          NewDocumentCommand{newcontactscheme}{m+m}
          {% #1 = scheme name, #2 = definition
          cs_new_protected:cn { sigur_contact_list_#1:n } { #2 }
          }
          cs_new_protected:Nn sigur_contact_print:nn
          {
          prop_item:cn { g_sigur_contact_#2_prop } { #1 }
          }
          ExplSyntaxOff

          newcontactscheme{default}{%
          parnoindent
          getcontact{name}{#1}\
          getcontact{work}{#1}\
          getcontact{email}{#1}par
          }
          newcontactscheme{short}{%
          getcontact{name}{#1}, getcontact{email}{#1}%
          }
          newcontactscheme{alternate}{%
          begin{tabular}[t]{@{}l@{ }l@{}}
          Name: & getcontact{name}{#1} \
          Work: & getcontact{work}{#1} \
          Email: & texttt{getcontact{email}{#1}}
          end{tabular}%
          }

          newcontact{foo}{
          name=Faa Foo,
          work=Univ. Blah,
          email=goo@goo.com
          }
          newcontact{xxx}{
          name=XXX,
          work=YYY,
          email=ZZZ@goo.com
          }

          begin{document}

          listcontact{foo}

          medskip

          listcontact{xxx}

          medskip

          Short: listcontact[short]{xxx}

          medskip

          Alternate: listcontact[alternate]{foo}

          end{document}


          enter image description here



          A version that also defines listallcontacts (the optional argument is one of the defined schemes).



          documentclass{article}
          usepackage{xparse}

          ExplSyntaxOn

          NewDocumentCommand{newcontact}{mm}
          {% #1 = contact label, #2 = data
          prop_new:c { g_sigur_contact_#1_prop }
          prop_gset_from_keyval:cn { g_sigur_contact_#1_prop } { #2 }
          seq_gput_right:Nn g_sigur_contact_seq { #1 }
          }
          NewDocumentCommand{listcontact}{O{default}m}
          {
          cs_set_eq:Nc __sigur_contact_list:n { sigur_contact_list_#1:n }
          __sigur_contact_list:n { #2 }
          }
          NewDocumentCommand{listallcontacts}{O{default}}
          {
          cs_set_eq:Nc __sigur_contact_list:n { sigur_contact_list_#1:n }
          seq_map_inline:Nn g_sigur_contact_seq
          {
          __sigur_contact_list:n { ##1 } par
          }
          }
          NewDocumentCommand{getcontact}{mm}
          {
          sigur_contact_print:nn { #1 } { #2 }
          }
          NewDocumentCommand{newcontactscheme}{m+m}
          {% #1 = scheme name, #2 = definition
          cs_new_protected:cn { sigur_contact_list_#1:n } { #2 }
          }

          seq_new:N g_sigur_contact_seq

          cs_new_protected:Nn sigur_contact_print:nn
          {
          prop_item:cn { g_sigur_contact_#2_prop } { #1 }
          }
          ExplSyntaxOff

          newcontactscheme{default}{%
          parnoindent
          getcontact{name}{#1}\
          getcontact{work}{#1}\
          getcontact{email}{#1}par
          }
          newcontactscheme{short}{%
          getcontact{name}{#1}, getcontact{email}{#1}%
          }
          newcontactscheme{alternate}{%
          begin{tabular}[t]{@{}l@{ }l@{}}
          Name: & getcontact{name}{#1} \
          Work: & getcontact{work}{#1} \
          Email: & texttt{getcontact{email}{#1}}
          end{tabular}%
          }

          newcontact{foo}{
          name=Faa Foo,
          work=Univ. Blah,
          email=goo@goo.com
          }
          newcontact{xxx}{
          name=XXX,
          work=YYY,
          email=ZZZ@goo.com
          }

          begin{document}

          listcontact{foo}

          medskip

          listcontact{xxx}

          medskip

          Short: listcontact[short]{xxx}

          medskip

          Alternate: listcontact[alternate]{foo}

          medskip

          listallcontacts

          medskip

          listallcontacts[short]

          end{document}






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 17 hours ago

























          answered 17 hours ago









          egreg

          697k8518513118




          697k8518513118












          • I never studied or tried to learn xparse. The result is amazing. Nice!
            – Sigur
            17 hours ago


















          • I never studied or tried to learn xparse. The result is amazing. Nice!
            – Sigur
            17 hours ago
















          I never studied or tried to learn xparse. The result is amazing. Nice!
          – Sigur
          17 hours ago




          I never studied or tried to learn xparse. The result is amazing. Nice!
          – Sigur
          17 hours ago










          up vote
          2
          down vote













          This is similar to Steven Seglets solution with slightly different packaging. You can show a single contact with ShowContact{} or list all the contact with listcontacts



          enter image description here



          Notes:




          • The values are stored based on #1 which is used as the key to access the contacts. An attempt to reuse the same key is now flagged as an error.

          • This has now been updated to add a medskip between entries when the entire list is printed. The medskip is not added before the first entry, nor after the last as shown in the figure.


          Code:



          documentclass{article}
          usepackage{etoolbox}

          makeatletter

          newtoggle{@IsFirstEntryInList}

          newcommand*{@ShowContact}[1]{%
          iftoggle{@IsFirstEntryInList}{%
          globaltogglefalse{@IsFirstEntryInList}%
          }{%
          medskip% <-- separator between entries
          }%
          ShowContact{#1}%
          }
          newcommand*{ShowContact}[1]{%
          parnoindenttextbf{csuse{name #1}}%
          parnoindenttextit{csuse{work #1}}%
          parnoindenttexttt{csuse{email #1}}%
          }%

          %% https://tex.stackexchange.com/a/14394/4301
          newcommand*{listcontacts}{% Initialize
          globaltoggletrue{@IsFirstEntryInList}%
          }
          newcommand{AddToListOfContacts}[1]{%
          g@addto@macrolistcontacts{{#1}}%
          }


          newcommand{information}[3]{%
          ifcsdef{name #1}{%
          PackageError{jobname}{Multiple uses of the key: '#1'}{}%
          }{%
          csdef{name #1}{#1}%
          csdef{work #1}{#2}%
          csdef{email #1}{#3}%
          AddToListOfContacts{unexpanded{@ShowContact{#1}}}%
          }%
          }
          makeatother

          information{Faa Foo}{Univ. Blah}{goo@goo.com}
          information{Harvard}{Harvard University}{me@harvard.com}
          %information{Harvard}{xxx University}{me@harvard.com}% <-- Triggers an error

          begin{document}
          noindent
          To show one contact:

          ShowContact{Harvard}

          medskipnoindent
          To show all contacts:

          listcontacts
          parnoindent
          Text following to check that there is no extra space at end...
          end{document}





          share|improve this answer























          • Interesting. In this case, the contacts are accessed via argument value, not via a number, right?
            – Sigur
            20 hours ago










          • @Sigur: Yes, the first parameter is used as the key to access the information. This is really helpful if you have a large number of contacts.
            – Peter Grill
            20 hours ago










          • Since I'm going to share this file, do you know if etoolbox comes with a basic installation? Because I know that tikz does not.
            – Sigur
            20 hours ago










          • Yes, etoolbox is in the standard distribution. But, so is tikz so not sure why you think otherwise. Also, have added error checking in the updated version.
            – Peter Grill
            20 hours ago








          • 1




            @Sigur: As requested, I have updated it inserts a medskip only between entries. You can replace the medskip with the symbol you desire.
            – Peter Grill
            8 hours ago















          up vote
          2
          down vote













          This is similar to Steven Seglets solution with slightly different packaging. You can show a single contact with ShowContact{} or list all the contact with listcontacts



          enter image description here



          Notes:




          • The values are stored based on #1 which is used as the key to access the contacts. An attempt to reuse the same key is now flagged as an error.

          • This has now been updated to add a medskip between entries when the entire list is printed. The medskip is not added before the first entry, nor after the last as shown in the figure.


          Code:



          documentclass{article}
          usepackage{etoolbox}

          makeatletter

          newtoggle{@IsFirstEntryInList}

          newcommand*{@ShowContact}[1]{%
          iftoggle{@IsFirstEntryInList}{%
          globaltogglefalse{@IsFirstEntryInList}%
          }{%
          medskip% <-- separator between entries
          }%
          ShowContact{#1}%
          }
          newcommand*{ShowContact}[1]{%
          parnoindenttextbf{csuse{name #1}}%
          parnoindenttextit{csuse{work #1}}%
          parnoindenttexttt{csuse{email #1}}%
          }%

          %% https://tex.stackexchange.com/a/14394/4301
          newcommand*{listcontacts}{% Initialize
          globaltoggletrue{@IsFirstEntryInList}%
          }
          newcommand{AddToListOfContacts}[1]{%
          g@addto@macrolistcontacts{{#1}}%
          }


          newcommand{information}[3]{%
          ifcsdef{name #1}{%
          PackageError{jobname}{Multiple uses of the key: '#1'}{}%
          }{%
          csdef{name #1}{#1}%
          csdef{work #1}{#2}%
          csdef{email #1}{#3}%
          AddToListOfContacts{unexpanded{@ShowContact{#1}}}%
          }%
          }
          makeatother

          information{Faa Foo}{Univ. Blah}{goo@goo.com}
          information{Harvard}{Harvard University}{me@harvard.com}
          %information{Harvard}{xxx University}{me@harvard.com}% <-- Triggers an error

          begin{document}
          noindent
          To show one contact:

          ShowContact{Harvard}

          medskipnoindent
          To show all contacts:

          listcontacts
          parnoindent
          Text following to check that there is no extra space at end...
          end{document}





          share|improve this answer























          • Interesting. In this case, the contacts are accessed via argument value, not via a number, right?
            – Sigur
            20 hours ago










          • @Sigur: Yes, the first parameter is used as the key to access the information. This is really helpful if you have a large number of contacts.
            – Peter Grill
            20 hours ago










          • Since I'm going to share this file, do you know if etoolbox comes with a basic installation? Because I know that tikz does not.
            – Sigur
            20 hours ago










          • Yes, etoolbox is in the standard distribution. But, so is tikz so not sure why you think otherwise. Also, have added error checking in the updated version.
            – Peter Grill
            20 hours ago








          • 1




            @Sigur: As requested, I have updated it inserts a medskip only between entries. You can replace the medskip with the symbol you desire.
            – Peter Grill
            8 hours ago













          up vote
          2
          down vote










          up vote
          2
          down vote









          This is similar to Steven Seglets solution with slightly different packaging. You can show a single contact with ShowContact{} or list all the contact with listcontacts



          enter image description here



          Notes:




          • The values are stored based on #1 which is used as the key to access the contacts. An attempt to reuse the same key is now flagged as an error.

          • This has now been updated to add a medskip between entries when the entire list is printed. The medskip is not added before the first entry, nor after the last as shown in the figure.


          Code:



          documentclass{article}
          usepackage{etoolbox}

          makeatletter

          newtoggle{@IsFirstEntryInList}

          newcommand*{@ShowContact}[1]{%
          iftoggle{@IsFirstEntryInList}{%
          globaltogglefalse{@IsFirstEntryInList}%
          }{%
          medskip% <-- separator between entries
          }%
          ShowContact{#1}%
          }
          newcommand*{ShowContact}[1]{%
          parnoindenttextbf{csuse{name #1}}%
          parnoindenttextit{csuse{work #1}}%
          parnoindenttexttt{csuse{email #1}}%
          }%

          %% https://tex.stackexchange.com/a/14394/4301
          newcommand*{listcontacts}{% Initialize
          globaltoggletrue{@IsFirstEntryInList}%
          }
          newcommand{AddToListOfContacts}[1]{%
          g@addto@macrolistcontacts{{#1}}%
          }


          newcommand{information}[3]{%
          ifcsdef{name #1}{%
          PackageError{jobname}{Multiple uses of the key: '#1'}{}%
          }{%
          csdef{name #1}{#1}%
          csdef{work #1}{#2}%
          csdef{email #1}{#3}%
          AddToListOfContacts{unexpanded{@ShowContact{#1}}}%
          }%
          }
          makeatother

          information{Faa Foo}{Univ. Blah}{goo@goo.com}
          information{Harvard}{Harvard University}{me@harvard.com}
          %information{Harvard}{xxx University}{me@harvard.com}% <-- Triggers an error

          begin{document}
          noindent
          To show one contact:

          ShowContact{Harvard}

          medskipnoindent
          To show all contacts:

          listcontacts
          parnoindent
          Text following to check that there is no extra space at end...
          end{document}





          share|improve this answer














          This is similar to Steven Seglets solution with slightly different packaging. You can show a single contact with ShowContact{} or list all the contact with listcontacts



          enter image description here



          Notes:




          • The values are stored based on #1 which is used as the key to access the contacts. An attempt to reuse the same key is now flagged as an error.

          • This has now been updated to add a medskip between entries when the entire list is printed. The medskip is not added before the first entry, nor after the last as shown in the figure.


          Code:



          documentclass{article}
          usepackage{etoolbox}

          makeatletter

          newtoggle{@IsFirstEntryInList}

          newcommand*{@ShowContact}[1]{%
          iftoggle{@IsFirstEntryInList}{%
          globaltogglefalse{@IsFirstEntryInList}%
          }{%
          medskip% <-- separator between entries
          }%
          ShowContact{#1}%
          }
          newcommand*{ShowContact}[1]{%
          parnoindenttextbf{csuse{name #1}}%
          parnoindenttextit{csuse{work #1}}%
          parnoindenttexttt{csuse{email #1}}%
          }%

          %% https://tex.stackexchange.com/a/14394/4301
          newcommand*{listcontacts}{% Initialize
          globaltoggletrue{@IsFirstEntryInList}%
          }
          newcommand{AddToListOfContacts}[1]{%
          g@addto@macrolistcontacts{{#1}}%
          }


          newcommand{information}[3]{%
          ifcsdef{name #1}{%
          PackageError{jobname}{Multiple uses of the key: '#1'}{}%
          }{%
          csdef{name #1}{#1}%
          csdef{work #1}{#2}%
          csdef{email #1}{#3}%
          AddToListOfContacts{unexpanded{@ShowContact{#1}}}%
          }%
          }
          makeatother

          information{Faa Foo}{Univ. Blah}{goo@goo.com}
          information{Harvard}{Harvard University}{me@harvard.com}
          %information{Harvard}{xxx University}{me@harvard.com}% <-- Triggers an error

          begin{document}
          noindent
          To show one contact:

          ShowContact{Harvard}

          medskipnoindent
          To show all contacts:

          listcontacts
          parnoindent
          Text following to check that there is no extra space at end...
          end{document}






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 8 hours ago

























          answered 20 hours ago









          Peter Grill

          163k24432740




          163k24432740












          • Interesting. In this case, the contacts are accessed via argument value, not via a number, right?
            – Sigur
            20 hours ago










          • @Sigur: Yes, the first parameter is used as the key to access the information. This is really helpful if you have a large number of contacts.
            – Peter Grill
            20 hours ago










          • Since I'm going to share this file, do you know if etoolbox comes with a basic installation? Because I know that tikz does not.
            – Sigur
            20 hours ago










          • Yes, etoolbox is in the standard distribution. But, so is tikz so not sure why you think otherwise. Also, have added error checking in the updated version.
            – Peter Grill
            20 hours ago








          • 1




            @Sigur: As requested, I have updated it inserts a medskip only between entries. You can replace the medskip with the symbol you desire.
            – Peter Grill
            8 hours ago


















          • Interesting. In this case, the contacts are accessed via argument value, not via a number, right?
            – Sigur
            20 hours ago










          • @Sigur: Yes, the first parameter is used as the key to access the information. This is really helpful if you have a large number of contacts.
            – Peter Grill
            20 hours ago










          • Since I'm going to share this file, do you know if etoolbox comes with a basic installation? Because I know that tikz does not.
            – Sigur
            20 hours ago










          • Yes, etoolbox is in the standard distribution. But, so is tikz so not sure why you think otherwise. Also, have added error checking in the updated version.
            – Peter Grill
            20 hours ago








          • 1




            @Sigur: As requested, I have updated it inserts a medskip only between entries. You can replace the medskip with the symbol you desire.
            – Peter Grill
            8 hours ago
















          Interesting. In this case, the contacts are accessed via argument value, not via a number, right?
          – Sigur
          20 hours ago




          Interesting. In this case, the contacts are accessed via argument value, not via a number, right?
          – Sigur
          20 hours ago












          @Sigur: Yes, the first parameter is used as the key to access the information. This is really helpful if you have a large number of contacts.
          – Peter Grill
          20 hours ago




          @Sigur: Yes, the first parameter is used as the key to access the information. This is really helpful if you have a large number of contacts.
          – Peter Grill
          20 hours ago












          Since I'm going to share this file, do you know if etoolbox comes with a basic installation? Because I know that tikz does not.
          – Sigur
          20 hours ago




          Since I'm going to share this file, do you know if etoolbox comes with a basic installation? Because I know that tikz does not.
          – Sigur
          20 hours ago












          Yes, etoolbox is in the standard distribution. But, so is tikz so not sure why you think otherwise. Also, have added error checking in the updated version.
          – Peter Grill
          20 hours ago






          Yes, etoolbox is in the standard distribution. But, so is tikz so not sure why you think otherwise. Also, have added error checking in the updated version.
          – Peter Grill
          20 hours ago






          1




          1




          @Sigur: As requested, I have updated it inserts a medskip only between entries. You can replace the medskip with the symbol you desire.
          – Peter Grill
          8 hours ago




          @Sigur: As requested, I have updated it inserts a medskip only between entries. You can replace the medskip with the symbol you desire.
          – Peter Grill
          8 hours ago


















           

          draft saved


          draft discarded



















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f460175%2fsaving-arguments-of-commands-to-be-used-later%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          サソリ

          広島県道265号伴広島線

          Accessing regular linux commands in Huawei's Dopra Linux