Cannot use textit or url in edef












5














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:
enter image description here



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?










share|improve this question


















  • 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








  • 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










  • @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 of edefprintnounattrs{printnounattrs
    – moewe
    yesterday
















5














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:
enter image description here



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?










share|improve this question


















  • 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








  • 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










  • @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 of edefprintnounattrs{printnounattrs
    – moewe
    yesterday














5












5








5







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:
enter image description here



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?










share|improve this question













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:
enter image description here



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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked yesterday









Pieter Verschaffelt

1524




1524








  • 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








  • 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










  • @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 of edefprintnounattrs{printnounattrs
    – moewe
    yesterday














  • 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








  • 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










  • @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 of edefprintnounattrs{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










2 Answers
2






active

oldest

votes


















8














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 expandafters 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}





share|improve this answer































    7














    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






    share|improve this answer























      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
      });


      }
      });














      draft saved

      draft discarded


















      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









      8














      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 expandafters 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}





      share|improve this answer




























        8














        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 expandafters 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}





        share|improve this answer


























          8












          8








          8






          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 expandafters 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}





          share|improve this answer














          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 expandafters 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}






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 17 hours ago

























          answered yesterday









          moewe

          87k9110333




          87k9110333























              7














              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






              share|improve this answer




























                7














                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






                share|improve this answer


























                  7












                  7








                  7






                  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






                  share|improve 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







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited yesterday

























                  answered yesterday









                  Andreas Storvik Strauman

                  2,503418




                  2,503418






























                      draft saved

                      draft discarded




















































                      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.




                      draft saved


                      draft discarded














                      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





















































                      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

                      An IMO inspired problem

                      Management

                      Has there ever been an instance of an active nuclear power plant within or near a war zone?