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}
macros
add a comment |
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}
macros
add a comment |
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}
macros
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
macros
asked 20 hours ago
Sigur
22.7k353134
22.7k353134
add a comment |
add a comment |
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}
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}
With a small supplement from the readarray
package, the list of contacts could even be stored in an external file.
Very nice, specially sincetikz
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 usingtikz
? Maybe using the value of the counter only? I'm going to share the file andtikz
could be not available.
– Sigur
20 hours ago
1
@Sigur I changed it topgffor
. However, I also added technique #2, which is far simpler, if you can add all names at once.
– Steven B. Segletes
20 hours ago
add a comment |
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}
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}
I never studied or tried to learnxparse
. The result is amazing. Nice!
– Sigur
17 hours ago
add a comment |
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
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. Themedskip
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}
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 ifetoolbox
comes with a basic installation? Because I know thattikz
does not.
– Sigur
20 hours ago
Yes,etoolbox
is in the standard distribution. But, so istikz
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 amedskip
only between entries. You can replace themedskip
with the symbol you desire.
– Peter Grill
8 hours ago
|
show 7 more comments
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}
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}
With a small supplement from the readarray
package, the list of contacts could even be stored in an external file.
Very nice, specially sincetikz
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 usingtikz
? Maybe using the value of the counter only? I'm going to share the file andtikz
could be not available.
– Sigur
20 hours ago
1
@Sigur I changed it topgffor
. However, I also added technique #2, which is far simpler, if you can add all names at once.
– Steven B. Segletes
20 hours ago
add a comment |
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}
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}
With a small supplement from the readarray
package, the list of contacts could even be stored in an external file.
Very nice, specially sincetikz
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 usingtikz
? Maybe using the value of the counter only? I'm going to share the file andtikz
could be not available.
– Sigur
20 hours ago
1
@Sigur I changed it topgffor
. However, I also added technique #2, which is far simpler, if you can add all names at once.
– Steven B. Segletes
20 hours ago
add a comment |
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}
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}
With a small supplement from the readarray
package, the list of contacts could even be stored in an external file.
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}
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}
With a small supplement from the readarray
package, the list of contacts could even be stored in an external file.
edited 20 hours ago
answered 20 hours ago
Steven B. Segletes
151k9189397
151k9189397
Very nice, specially sincetikz
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 usingtikz
? Maybe using the value of the counter only? I'm going to share the file andtikz
could be not available.
– Sigur
20 hours ago
1
@Sigur I changed it topgffor
. However, I also added technique #2, which is far simpler, if you can add all names at once.
– Steven B. Segletes
20 hours ago
add a comment |
Very nice, specially sincetikz
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 usingtikz
? Maybe using the value of the counter only? I'm going to share the file andtikz
could be not available.
– Sigur
20 hours ago
1
@Sigur I changed it topgffor
. 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
add a comment |
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}
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}
I never studied or tried to learnxparse
. The result is amazing. Nice!
– Sigur
17 hours ago
add a comment |
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}
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}
I never studied or tried to learnxparse
. The result is amazing. Nice!
– Sigur
17 hours ago
add a comment |
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}
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}
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}
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}
edited 17 hours ago
answered 17 hours ago
egreg
697k8518513118
697k8518513118
I never studied or tried to learnxparse
. The result is amazing. Nice!
– Sigur
17 hours ago
add a comment |
I never studied or tried to learnxparse
. 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
add a comment |
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
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. Themedskip
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}
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 ifetoolbox
comes with a basic installation? Because I know thattikz
does not.
– Sigur
20 hours ago
Yes,etoolbox
is in the standard distribution. But, so istikz
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 amedskip
only between entries. You can replace themedskip
with the symbol you desire.
– Peter Grill
8 hours ago
|
show 7 more comments
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
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. Themedskip
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}
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 ifetoolbox
comes with a basic installation? Because I know thattikz
does not.
– Sigur
20 hours ago
Yes,etoolbox
is in the standard distribution. But, so istikz
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 amedskip
only between entries. You can replace themedskip
with the symbol you desire.
– Peter Grill
8 hours ago
|
show 7 more comments
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
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. Themedskip
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}
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
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. Themedskip
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}
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 ifetoolbox
comes with a basic installation? Because I know thattikz
does not.
– Sigur
20 hours ago
Yes,etoolbox
is in the standard distribution. But, so istikz
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 amedskip
only between entries. You can replace themedskip
with the symbol you desire.
– Peter Grill
8 hours ago
|
show 7 more comments
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 ifetoolbox
comes with a basic installation? Because I know thattikz
does not.
– Sigur
20 hours ago
Yes,etoolbox
is in the standard distribution. But, so istikz
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 amedskip
only between entries. You can replace themedskip
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
|
show 7 more comments
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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