Cannot use textit or url in edef
I'm trying to write a Tex command that automatically prints out attribution information for images I use in my document. I created 2 different commands. The first one is nounattr
(with 3 parameters) which takes the image's name, the author and the link of the image. The second command is printnounattrs
which has no arguments, but should simply print a list of all attributions added before using nounattr
. I was able to implement these commands and get a simple list, but I cannot add any styling to the list whatsoever.
This is what I have at the moment:
NeedsTeXFormat{LaTeX2e}
ProvidesPackage{nounattr}[2018/01/03 The noun project attribution]
RequirePackage{svg}
RequirePackage{url}
newcommandprintnounattrs{}
newcommandnounattr[3]{edefprintnounattrs{printnounattrs#1 pictogram werd ontworpen door #2 van The Noun Project, onder de Creative Commons license (CC BY 3.0). Zie #3. }}
An MWE is the following:
documentclass{report}
usepackage[left=2cm, right=2cm, top=2cm, bottom=2cm]{geometry}
usepackage[parfill]{parskip}
usepackage{nounattr}
begin{document}
nounattr{Protein}{Ben Markoch}{https://thenounproject.com/search/?q=protein&i=54837}
nounattr{Peptides}{Fredrik Edfors}{https://thenounproject.com/search/?q=peptide&i=66903}
printnounattrs
end{document}
Which yields:
I would however like to add some styling into the edef in order for #1 pictogram
to be printed italic and that the url is propely defined as a url using url{#3}
. I changed nounattr
to be:
newcommandnounattr[3]{edefprintnounattrs{printnounattrstextit{#1 pictogram} werd ontworpen door #2 van The Noun Project, onder de Creative Commons license (CC BY 3.0). Zie url{#3}. }}
But this gives me a undefined control sequence
error. I don't understand what's happening and how I can possibly fix this?
macros errors
|
show 4 more comments
I'm trying to write a Tex command that automatically prints out attribution information for images I use in my document. I created 2 different commands. The first one is nounattr
(with 3 parameters) which takes the image's name, the author and the link of the image. The second command is printnounattrs
which has no arguments, but should simply print a list of all attributions added before using nounattr
. I was able to implement these commands and get a simple list, but I cannot add any styling to the list whatsoever.
This is what I have at the moment:
NeedsTeXFormat{LaTeX2e}
ProvidesPackage{nounattr}[2018/01/03 The noun project attribution]
RequirePackage{svg}
RequirePackage{url}
newcommandprintnounattrs{}
newcommandnounattr[3]{edefprintnounattrs{printnounattrs#1 pictogram werd ontworpen door #2 van The Noun Project, onder de Creative Commons license (CC BY 3.0). Zie #3. }}
An MWE is the following:
documentclass{report}
usepackage[left=2cm, right=2cm, top=2cm, bottom=2cm]{geometry}
usepackage[parfill]{parskip}
usepackage{nounattr}
begin{document}
nounattr{Protein}{Ben Markoch}{https://thenounproject.com/search/?q=protein&i=54837}
nounattr{Peptides}{Fredrik Edfors}{https://thenounproject.com/search/?q=peptide&i=66903}
printnounattrs
end{document}
Which yields:
I would however like to add some styling into the edef in order for #1 pictogram
to be printed italic and that the url is propely defined as a url using url{#3}
. I changed nounattr
to be:
newcommandnounattr[3]{edefprintnounattrs{printnounattrstextit{#1 pictogram} werd ontworpen door #2 van The Noun Project, onder de Creative Commons license (CC BY 3.0). Zie url{#3}. }}
But this gives me a undefined control sequence
error. I don't understand what's happening and how I can possibly fix this?
macros errors
1
Indeed some commands liketextit
are not expandable, which means that they can't be used in anedef
context. There are many questions about this concept on this site, for example tex.stackexchange.com/q/35039/35864 and linked questions.
– moewe
yesterday
1
You may want to look into 'list' implementations frometoolbox
orexpl3
instead. I think they can usually deal with these things as they don't go fulledef
on the contents.
– moewe
yesterday
@moewe Thanks for your help so far. I can't usedef
as it causes TeX to go out of memory for some reason. I will take a look at the list implementations you mentioned :)
– Pieter Verschaffelt
yesterday
Yes, I realised that after I had a closer look at what the code was doing. I have removed thedef
suggestion from my comment.
– moewe
yesterday
1
Here's one that should work:expandafterdefexpandafterprintnounattrsexpandafter{printnounattrs
instead ofedefprintnounattrs{printnounattrs
– moewe
yesterday
|
show 4 more comments
I'm trying to write a Tex command that automatically prints out attribution information for images I use in my document. I created 2 different commands. The first one is nounattr
(with 3 parameters) which takes the image's name, the author and the link of the image. The second command is printnounattrs
which has no arguments, but should simply print a list of all attributions added before using nounattr
. I was able to implement these commands and get a simple list, but I cannot add any styling to the list whatsoever.
This is what I have at the moment:
NeedsTeXFormat{LaTeX2e}
ProvidesPackage{nounattr}[2018/01/03 The noun project attribution]
RequirePackage{svg}
RequirePackage{url}
newcommandprintnounattrs{}
newcommandnounattr[3]{edefprintnounattrs{printnounattrs#1 pictogram werd ontworpen door #2 van The Noun Project, onder de Creative Commons license (CC BY 3.0). Zie #3. }}
An MWE is the following:
documentclass{report}
usepackage[left=2cm, right=2cm, top=2cm, bottom=2cm]{geometry}
usepackage[parfill]{parskip}
usepackage{nounattr}
begin{document}
nounattr{Protein}{Ben Markoch}{https://thenounproject.com/search/?q=protein&i=54837}
nounattr{Peptides}{Fredrik Edfors}{https://thenounproject.com/search/?q=peptide&i=66903}
printnounattrs
end{document}
Which yields:
I would however like to add some styling into the edef in order for #1 pictogram
to be printed italic and that the url is propely defined as a url using url{#3}
. I changed nounattr
to be:
newcommandnounattr[3]{edefprintnounattrs{printnounattrstextit{#1 pictogram} werd ontworpen door #2 van The Noun Project, onder de Creative Commons license (CC BY 3.0). Zie url{#3}. }}
But this gives me a undefined control sequence
error. I don't understand what's happening and how I can possibly fix this?
macros errors
I'm trying to write a Tex command that automatically prints out attribution information for images I use in my document. I created 2 different commands. The first one is nounattr
(with 3 parameters) which takes the image's name, the author and the link of the image. The second command is printnounattrs
which has no arguments, but should simply print a list of all attributions added before using nounattr
. I was able to implement these commands and get a simple list, but I cannot add any styling to the list whatsoever.
This is what I have at the moment:
NeedsTeXFormat{LaTeX2e}
ProvidesPackage{nounattr}[2018/01/03 The noun project attribution]
RequirePackage{svg}
RequirePackage{url}
newcommandprintnounattrs{}
newcommandnounattr[3]{edefprintnounattrs{printnounattrs#1 pictogram werd ontworpen door #2 van The Noun Project, onder de Creative Commons license (CC BY 3.0). Zie #3. }}
An MWE is the following:
documentclass{report}
usepackage[left=2cm, right=2cm, top=2cm, bottom=2cm]{geometry}
usepackage[parfill]{parskip}
usepackage{nounattr}
begin{document}
nounattr{Protein}{Ben Markoch}{https://thenounproject.com/search/?q=protein&i=54837}
nounattr{Peptides}{Fredrik Edfors}{https://thenounproject.com/search/?q=peptide&i=66903}
printnounattrs
end{document}
Which yields:
I would however like to add some styling into the edef in order for #1 pictogram
to be printed italic and that the url is propely defined as a url using url{#3}
. I changed nounattr
to be:
newcommandnounattr[3]{edefprintnounattrs{printnounattrstextit{#1 pictogram} werd ontworpen door #2 van The Noun Project, onder de Creative Commons license (CC BY 3.0). Zie url{#3}. }}
But this gives me a undefined control sequence
error. I don't understand what's happening and how I can possibly fix this?
macros errors
macros errors
asked yesterday
Pieter Verschaffelt
1524
1524
1
Indeed some commands liketextit
are not expandable, which means that they can't be used in anedef
context. There are many questions about this concept on this site, for example tex.stackexchange.com/q/35039/35864 and linked questions.
– moewe
yesterday
1
You may want to look into 'list' implementations frometoolbox
orexpl3
instead. I think they can usually deal with these things as they don't go fulledef
on the contents.
– moewe
yesterday
@moewe Thanks for your help so far. I can't usedef
as it causes TeX to go out of memory for some reason. I will take a look at the list implementations you mentioned :)
– Pieter Verschaffelt
yesterday
Yes, I realised that after I had a closer look at what the code was doing. I have removed thedef
suggestion from my comment.
– moewe
yesterday
1
Here's one that should work:expandafterdefexpandafterprintnounattrsexpandafter{printnounattrs
instead ofedefprintnounattrs{printnounattrs
– moewe
yesterday
|
show 4 more comments
1
Indeed some commands liketextit
are not expandable, which means that they can't be used in anedef
context. There are many questions about this concept on this site, for example tex.stackexchange.com/q/35039/35864 and linked questions.
– moewe
yesterday
1
You may want to look into 'list' implementations frometoolbox
orexpl3
instead. I think they can usually deal with these things as they don't go fulledef
on the contents.
– moewe
yesterday
@moewe Thanks for your help so far. I can't usedef
as it causes TeX to go out of memory for some reason. I will take a look at the list implementations you mentioned :)
– Pieter Verschaffelt
yesterday
Yes, I realised that after I had a closer look at what the code was doing. I have removed thedef
suggestion from my comment.
– moewe
yesterday
1
Here's one that should work:expandafterdefexpandafterprintnounattrsexpandafter{printnounattrs
instead ofedefprintnounattrs{printnounattrs
– moewe
yesterday
1
1
Indeed some commands like
textit
are not expandable, which means that they can't be used in an edef
context. There are many questions about this concept on this site, for example tex.stackexchange.com/q/35039/35864 and linked questions.– moewe
yesterday
Indeed some commands like
textit
are not expandable, which means that they can't be used in an edef
context. There are many questions about this concept on this site, for example tex.stackexchange.com/q/35039/35864 and linked questions.– moewe
yesterday
1
1
You may want to look into 'list' implementations from
etoolbox
or expl3
instead. I think they can usually deal with these things as they don't go full edef
on the contents.– moewe
yesterday
You may want to look into 'list' implementations from
etoolbox
or expl3
instead. I think they can usually deal with these things as they don't go full edef
on the contents.– moewe
yesterday
@moewe Thanks for your help so far. I can't use
def
as it causes TeX to go out of memory for some reason. I will take a look at the list implementations you mentioned :)– Pieter Verschaffelt
yesterday
@moewe Thanks for your help so far. I can't use
def
as it causes TeX to go out of memory for some reason. I will take a look at the list implementations you mentioned :)– Pieter Verschaffelt
yesterday
Yes, I realised that after I had a closer look at what the code was doing. I have removed the
def
suggestion from my comment.– moewe
yesterday
Yes, I realised that after I had a closer look at what the code was doing. I have removed the
def
suggestion from my comment.– moewe
yesterday
1
1
Here's one that should work:
expandafterdefexpandafterprintnounattrsexpandafter{printnounattrs
instead of edefprintnounattrs{printnounattrs
– moewe
yesterday
Here's one that should work:
expandafterdefexpandafterprintnounattrsexpandafter{printnounattrs
instead of edefprintnounattrs{printnounattrs
– moewe
yesterday
|
show 4 more comments
2 Answers
2
active
oldest
votes
There is a large group of TeX macros/commands that can't be used (as expected) in an edef
context. Those macros are called not expandable. This aspect of TeX programming is one that creeps up on one sooner or later and is well worth reading up on if one intends to go a bit further in (La)TeX coding. There are a great many questions about issues like this on this site (for example What are the differences between def, edef, gdef and xdef?, When to use edef, noexpand, and expandafter?, ...), but I don't know about a good systematic introduction except for the typical TeX references such as the TeX book or TeX by Topic (see for example What is the best way to learn TeX?, Should I read Donald Knuth's The TeXbook?).
In your particular case textit
and url
are not expandable and will thus break when used in edef
.
If you want to retain the structure of your current approach you can replace the edef
with expandafter
s and a def
documentclass{report}
usepackage[left=2cm, right=2cm, top=2cm, bottom=2cm]{geometry}
usepackage[parfill]{parskip}
RequirePackage{url}
newcommandprintnounattrs{}
newcommandnounattr[3]{%
expandafterdefexpandafterprintnounattrsexpandafter{%
printnounattrs
textit{#1 pictogram} werd ontworpen door #2 van The Noun Project,
onder de Creative Commons license (CC BY 3.0).
Zie url{#3}. }%
}
begin{document}
nounattr{Protein}{Ben Markoch}{https://thenounproject.com/search/?q=protein&i=54837}
nounattr{Peptides}{Fredrik Edfors}{https://thenounproject.com/search/?q=peptide&i=66903}
nounattr{Peptides}{Schmeptides}{https://thenounproject.com/search/?q=peptide&i=123&pq=v_w20w}
printnounattrs
end{document}
While the edef
would try to expand everything in its argument as far as possible, the expandafterdefexpandafterprintnounattrsexpandafter{printnounattrs
expands only the printnounattrs
in the definition exactly once, which means that we can concatenate our list as expected. (The simple defprintnounattrs{printnounattrs...}
would lead to an infinite loop because that would to define the macro printnounattrs
to expand to printnounattrs
.)
Note that with this approach url
suffers from its usual issues that the URL can't contain %
, #
, ^^
or end with since it is used as an argument to a command.
If I were to write a macro for a similar task from scratch I would probably look into using the powerful list macros of etoolbox
or LaTeX3/expl3
.
Here is a naive implementation with etoolbox
documentclass{report}
usepackage{etoolbox}
usepackage{url}
newcommandmylist{}
newcommandnounattr[3]{%
listadd{mylist}{{#1}{#2}{#3}}}
newcommand*{printnounattr}[3]{%
textit{#1 pictogram} werd ontworpen door #2 van The Noun Project,
onder de Creative Commons license (CC BY 3.0).
Zie url{#3}.
}
makeatletter
newcommand*{printnounattr@i}[1]{%
printnounattr#1}
newcommand*{printnounattrs}{%
forlistloop{printnounattr@i}{mylist}}
makeatother
begin{document}
nounattr{Protein}{Ben Markoch}{https://thenounproject.com/search/?q=protein&i=54837}
nounattr{Peptides}{Fredrik Edfors}{https://thenounproject.com/search/?q=peptide&i=66903}
nounattr{Peptides}{Schmeptides}{https://thenounproject.com/search/?q=peptide&i=123&pq=v_w20w}
printnounattrs
end{document}
add a comment |
edef
expands all commands to the fullest. However not all commands can be expanded, like e.g. textit
because it doesn't know what to do with the text when it's not in "printing mode". If you still however want to expand other tokens while leaving e.g. textit
untouched it you could use noexpand
(or unexpanded
if multple tokens) to prevent it from expanding (whilst all the others are):
documentclass{article}
defa{alpha}
edefb{noexpandtextit{a}}
showb
begin{document}
b
end{document}
Shows this in the log:
> b=macro:
->textit {alpha}.
l.4 showb
You can read more about noexpand
(and the related unexpanded
) at this answer
add a comment |
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',
autoActivateHeartbeat: false,
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
});
}
});
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%2f468532%2fcannot-use-textit-or-url-in-edef%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
There is a large group of TeX macros/commands that can't be used (as expected) in an edef
context. Those macros are called not expandable. This aspect of TeX programming is one that creeps up on one sooner or later and is well worth reading up on if one intends to go a bit further in (La)TeX coding. There are a great many questions about issues like this on this site (for example What are the differences between def, edef, gdef and xdef?, When to use edef, noexpand, and expandafter?, ...), but I don't know about a good systematic introduction except for the typical TeX references such as the TeX book or TeX by Topic (see for example What is the best way to learn TeX?, Should I read Donald Knuth's The TeXbook?).
In your particular case textit
and url
are not expandable and will thus break when used in edef
.
If you want to retain the structure of your current approach you can replace the edef
with expandafter
s and a def
documentclass{report}
usepackage[left=2cm, right=2cm, top=2cm, bottom=2cm]{geometry}
usepackage[parfill]{parskip}
RequirePackage{url}
newcommandprintnounattrs{}
newcommandnounattr[3]{%
expandafterdefexpandafterprintnounattrsexpandafter{%
printnounattrs
textit{#1 pictogram} werd ontworpen door #2 van The Noun Project,
onder de Creative Commons license (CC BY 3.0).
Zie url{#3}. }%
}
begin{document}
nounattr{Protein}{Ben Markoch}{https://thenounproject.com/search/?q=protein&i=54837}
nounattr{Peptides}{Fredrik Edfors}{https://thenounproject.com/search/?q=peptide&i=66903}
nounattr{Peptides}{Schmeptides}{https://thenounproject.com/search/?q=peptide&i=123&pq=v_w20w}
printnounattrs
end{document}
While the edef
would try to expand everything in its argument as far as possible, the expandafterdefexpandafterprintnounattrsexpandafter{printnounattrs
expands only the printnounattrs
in the definition exactly once, which means that we can concatenate our list as expected. (The simple defprintnounattrs{printnounattrs...}
would lead to an infinite loop because that would to define the macro printnounattrs
to expand to printnounattrs
.)
Note that with this approach url
suffers from its usual issues that the URL can't contain %
, #
, ^^
or end with since it is used as an argument to a command.
If I were to write a macro for a similar task from scratch I would probably look into using the powerful list macros of etoolbox
or LaTeX3/expl3
.
Here is a naive implementation with etoolbox
documentclass{report}
usepackage{etoolbox}
usepackage{url}
newcommandmylist{}
newcommandnounattr[3]{%
listadd{mylist}{{#1}{#2}{#3}}}
newcommand*{printnounattr}[3]{%
textit{#1 pictogram} werd ontworpen door #2 van The Noun Project,
onder de Creative Commons license (CC BY 3.0).
Zie url{#3}.
}
makeatletter
newcommand*{printnounattr@i}[1]{%
printnounattr#1}
newcommand*{printnounattrs}{%
forlistloop{printnounattr@i}{mylist}}
makeatother
begin{document}
nounattr{Protein}{Ben Markoch}{https://thenounproject.com/search/?q=protein&i=54837}
nounattr{Peptides}{Fredrik Edfors}{https://thenounproject.com/search/?q=peptide&i=66903}
nounattr{Peptides}{Schmeptides}{https://thenounproject.com/search/?q=peptide&i=123&pq=v_w20w}
printnounattrs
end{document}
add a comment |
There is a large group of TeX macros/commands that can't be used (as expected) in an edef
context. Those macros are called not expandable. This aspect of TeX programming is one that creeps up on one sooner or later and is well worth reading up on if one intends to go a bit further in (La)TeX coding. There are a great many questions about issues like this on this site (for example What are the differences between def, edef, gdef and xdef?, When to use edef, noexpand, and expandafter?, ...), but I don't know about a good systematic introduction except for the typical TeX references such as the TeX book or TeX by Topic (see for example What is the best way to learn TeX?, Should I read Donald Knuth's The TeXbook?).
In your particular case textit
and url
are not expandable and will thus break when used in edef
.
If you want to retain the structure of your current approach you can replace the edef
with expandafter
s and a def
documentclass{report}
usepackage[left=2cm, right=2cm, top=2cm, bottom=2cm]{geometry}
usepackage[parfill]{parskip}
RequirePackage{url}
newcommandprintnounattrs{}
newcommandnounattr[3]{%
expandafterdefexpandafterprintnounattrsexpandafter{%
printnounattrs
textit{#1 pictogram} werd ontworpen door #2 van The Noun Project,
onder de Creative Commons license (CC BY 3.0).
Zie url{#3}. }%
}
begin{document}
nounattr{Protein}{Ben Markoch}{https://thenounproject.com/search/?q=protein&i=54837}
nounattr{Peptides}{Fredrik Edfors}{https://thenounproject.com/search/?q=peptide&i=66903}
nounattr{Peptides}{Schmeptides}{https://thenounproject.com/search/?q=peptide&i=123&pq=v_w20w}
printnounattrs
end{document}
While the edef
would try to expand everything in its argument as far as possible, the expandafterdefexpandafterprintnounattrsexpandafter{printnounattrs
expands only the printnounattrs
in the definition exactly once, which means that we can concatenate our list as expected. (The simple defprintnounattrs{printnounattrs...}
would lead to an infinite loop because that would to define the macro printnounattrs
to expand to printnounattrs
.)
Note that with this approach url
suffers from its usual issues that the URL can't contain %
, #
, ^^
or end with since it is used as an argument to a command.
If I were to write a macro for a similar task from scratch I would probably look into using the powerful list macros of etoolbox
or LaTeX3/expl3
.
Here is a naive implementation with etoolbox
documentclass{report}
usepackage{etoolbox}
usepackage{url}
newcommandmylist{}
newcommandnounattr[3]{%
listadd{mylist}{{#1}{#2}{#3}}}
newcommand*{printnounattr}[3]{%
textit{#1 pictogram} werd ontworpen door #2 van The Noun Project,
onder de Creative Commons license (CC BY 3.0).
Zie url{#3}.
}
makeatletter
newcommand*{printnounattr@i}[1]{%
printnounattr#1}
newcommand*{printnounattrs}{%
forlistloop{printnounattr@i}{mylist}}
makeatother
begin{document}
nounattr{Protein}{Ben Markoch}{https://thenounproject.com/search/?q=protein&i=54837}
nounattr{Peptides}{Fredrik Edfors}{https://thenounproject.com/search/?q=peptide&i=66903}
nounattr{Peptides}{Schmeptides}{https://thenounproject.com/search/?q=peptide&i=123&pq=v_w20w}
printnounattrs
end{document}
add a comment |
There is a large group of TeX macros/commands that can't be used (as expected) in an edef
context. Those macros are called not expandable. This aspect of TeX programming is one that creeps up on one sooner or later and is well worth reading up on if one intends to go a bit further in (La)TeX coding. There are a great many questions about issues like this on this site (for example What are the differences between def, edef, gdef and xdef?, When to use edef, noexpand, and expandafter?, ...), but I don't know about a good systematic introduction except for the typical TeX references such as the TeX book or TeX by Topic (see for example What is the best way to learn TeX?, Should I read Donald Knuth's The TeXbook?).
In your particular case textit
and url
are not expandable and will thus break when used in edef
.
If you want to retain the structure of your current approach you can replace the edef
with expandafter
s and a def
documentclass{report}
usepackage[left=2cm, right=2cm, top=2cm, bottom=2cm]{geometry}
usepackage[parfill]{parskip}
RequirePackage{url}
newcommandprintnounattrs{}
newcommandnounattr[3]{%
expandafterdefexpandafterprintnounattrsexpandafter{%
printnounattrs
textit{#1 pictogram} werd ontworpen door #2 van The Noun Project,
onder de Creative Commons license (CC BY 3.0).
Zie url{#3}. }%
}
begin{document}
nounattr{Protein}{Ben Markoch}{https://thenounproject.com/search/?q=protein&i=54837}
nounattr{Peptides}{Fredrik Edfors}{https://thenounproject.com/search/?q=peptide&i=66903}
nounattr{Peptides}{Schmeptides}{https://thenounproject.com/search/?q=peptide&i=123&pq=v_w20w}
printnounattrs
end{document}
While the edef
would try to expand everything in its argument as far as possible, the expandafterdefexpandafterprintnounattrsexpandafter{printnounattrs
expands only the printnounattrs
in the definition exactly once, which means that we can concatenate our list as expected. (The simple defprintnounattrs{printnounattrs...}
would lead to an infinite loop because that would to define the macro printnounattrs
to expand to printnounattrs
.)
Note that with this approach url
suffers from its usual issues that the URL can't contain %
, #
, ^^
or end with since it is used as an argument to a command.
If I were to write a macro for a similar task from scratch I would probably look into using the powerful list macros of etoolbox
or LaTeX3/expl3
.
Here is a naive implementation with etoolbox
documentclass{report}
usepackage{etoolbox}
usepackage{url}
newcommandmylist{}
newcommandnounattr[3]{%
listadd{mylist}{{#1}{#2}{#3}}}
newcommand*{printnounattr}[3]{%
textit{#1 pictogram} werd ontworpen door #2 van The Noun Project,
onder de Creative Commons license (CC BY 3.0).
Zie url{#3}.
}
makeatletter
newcommand*{printnounattr@i}[1]{%
printnounattr#1}
newcommand*{printnounattrs}{%
forlistloop{printnounattr@i}{mylist}}
makeatother
begin{document}
nounattr{Protein}{Ben Markoch}{https://thenounproject.com/search/?q=protein&i=54837}
nounattr{Peptides}{Fredrik Edfors}{https://thenounproject.com/search/?q=peptide&i=66903}
nounattr{Peptides}{Schmeptides}{https://thenounproject.com/search/?q=peptide&i=123&pq=v_w20w}
printnounattrs
end{document}
There is a large group of TeX macros/commands that can't be used (as expected) in an edef
context. Those macros are called not expandable. This aspect of TeX programming is one that creeps up on one sooner or later and is well worth reading up on if one intends to go a bit further in (La)TeX coding. There are a great many questions about issues like this on this site (for example What are the differences between def, edef, gdef and xdef?, When to use edef, noexpand, and expandafter?, ...), but I don't know about a good systematic introduction except for the typical TeX references such as the TeX book or TeX by Topic (see for example What is the best way to learn TeX?, Should I read Donald Knuth's The TeXbook?).
In your particular case textit
and url
are not expandable and will thus break when used in edef
.
If you want to retain the structure of your current approach you can replace the edef
with expandafter
s and a def
documentclass{report}
usepackage[left=2cm, right=2cm, top=2cm, bottom=2cm]{geometry}
usepackage[parfill]{parskip}
RequirePackage{url}
newcommandprintnounattrs{}
newcommandnounattr[3]{%
expandafterdefexpandafterprintnounattrsexpandafter{%
printnounattrs
textit{#1 pictogram} werd ontworpen door #2 van The Noun Project,
onder de Creative Commons license (CC BY 3.0).
Zie url{#3}. }%
}
begin{document}
nounattr{Protein}{Ben Markoch}{https://thenounproject.com/search/?q=protein&i=54837}
nounattr{Peptides}{Fredrik Edfors}{https://thenounproject.com/search/?q=peptide&i=66903}
nounattr{Peptides}{Schmeptides}{https://thenounproject.com/search/?q=peptide&i=123&pq=v_w20w}
printnounattrs
end{document}
While the edef
would try to expand everything in its argument as far as possible, the expandafterdefexpandafterprintnounattrsexpandafter{printnounattrs
expands only the printnounattrs
in the definition exactly once, which means that we can concatenate our list as expected. (The simple defprintnounattrs{printnounattrs...}
would lead to an infinite loop because that would to define the macro printnounattrs
to expand to printnounattrs
.)
Note that with this approach url
suffers from its usual issues that the URL can't contain %
, #
, ^^
or end with since it is used as an argument to a command.
If I were to write a macro for a similar task from scratch I would probably look into using the powerful list macros of etoolbox
or LaTeX3/expl3
.
Here is a naive implementation with etoolbox
documentclass{report}
usepackage{etoolbox}
usepackage{url}
newcommandmylist{}
newcommandnounattr[3]{%
listadd{mylist}{{#1}{#2}{#3}}}
newcommand*{printnounattr}[3]{%
textit{#1 pictogram} werd ontworpen door #2 van The Noun Project,
onder de Creative Commons license (CC BY 3.0).
Zie url{#3}.
}
makeatletter
newcommand*{printnounattr@i}[1]{%
printnounattr#1}
newcommand*{printnounattrs}{%
forlistloop{printnounattr@i}{mylist}}
makeatother
begin{document}
nounattr{Protein}{Ben Markoch}{https://thenounproject.com/search/?q=protein&i=54837}
nounattr{Peptides}{Fredrik Edfors}{https://thenounproject.com/search/?q=peptide&i=66903}
nounattr{Peptides}{Schmeptides}{https://thenounproject.com/search/?q=peptide&i=123&pq=v_w20w}
printnounattrs
end{document}
edited 17 hours ago
answered yesterday
moewe
87k9110333
87k9110333
add a comment |
add a comment |
edef
expands all commands to the fullest. However not all commands can be expanded, like e.g. textit
because it doesn't know what to do with the text when it's not in "printing mode". If you still however want to expand other tokens while leaving e.g. textit
untouched it you could use noexpand
(or unexpanded
if multple tokens) to prevent it from expanding (whilst all the others are):
documentclass{article}
defa{alpha}
edefb{noexpandtextit{a}}
showb
begin{document}
b
end{document}
Shows this in the log:
> b=macro:
->textit {alpha}.
l.4 showb
You can read more about noexpand
(and the related unexpanded
) at this answer
add a comment |
edef
expands all commands to the fullest. However not all commands can be expanded, like e.g. textit
because it doesn't know what to do with the text when it's not in "printing mode". If you still however want to expand other tokens while leaving e.g. textit
untouched it you could use noexpand
(or unexpanded
if multple tokens) to prevent it from expanding (whilst all the others are):
documentclass{article}
defa{alpha}
edefb{noexpandtextit{a}}
showb
begin{document}
b
end{document}
Shows this in the log:
> b=macro:
->textit {alpha}.
l.4 showb
You can read more about noexpand
(and the related unexpanded
) at this answer
add a comment |
edef
expands all commands to the fullest. However not all commands can be expanded, like e.g. textit
because it doesn't know what to do with the text when it's not in "printing mode". If you still however want to expand other tokens while leaving e.g. textit
untouched it you could use noexpand
(or unexpanded
if multple tokens) to prevent it from expanding (whilst all the others are):
documentclass{article}
defa{alpha}
edefb{noexpandtextit{a}}
showb
begin{document}
b
end{document}
Shows this in the log:
> b=macro:
->textit {alpha}.
l.4 showb
You can read more about noexpand
(and the related unexpanded
) at this answer
edef
expands all commands to the fullest. However not all commands can be expanded, like e.g. textit
because it doesn't know what to do with the text when it's not in "printing mode". If you still however want to expand other tokens while leaving e.g. textit
untouched it you could use noexpand
(or unexpanded
if multple tokens) to prevent it from expanding (whilst all the others are):
documentclass{article}
defa{alpha}
edefb{noexpandtextit{a}}
showb
begin{document}
b
end{document}
Shows this in the log:
> b=macro:
->textit {alpha}.
l.4 showb
You can read more about noexpand
(and the related unexpanded
) at this answer
edited yesterday
answered yesterday
Andreas Storvik Strauman
2,503418
2,503418
add a comment |
add a comment |
Thanks for contributing an answer to TeX - LaTeX Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
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%2f468532%2fcannot-use-textit-or-url-in-edef%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
1
Indeed some commands like
textit
are not expandable, which means that they can't be used in anedef
context. There are many questions about this concept on this site, for example tex.stackexchange.com/q/35039/35864 and linked questions.– moewe
yesterday
1
You may want to look into 'list' implementations from
etoolbox
orexpl3
instead. I think they can usually deal with these things as they don't go fulledef
on the contents.– moewe
yesterday
@moewe Thanks for your help so far. I can't use
def
as it causes TeX to go out of memory for some reason. I will take a look at the list implementations you mentioned :)– Pieter Verschaffelt
yesterday
Yes, I realised that after I had a closer look at what the code was doing. I have removed the
def
suggestion from my comment.– moewe
yesterday
1
Here's one that should work:
expandafterdefexpandafterprintnounattrsexpandafter{printnounattrs
instead ofedefprintnounattrs{printnounattrs
– moewe
yesterday