How to define a macro with multiple optional parameters?












4















After I had a macro that worked, I tried to improve it by making some parameters optional.
Unfortunately the macro no longer works. Instead I'm getting errors I do not understand, for example:



LaTeX Warning: Label `####5' multiply defined.
LaTeX Warning: Label `####5' multiply defined.
! LaTeX Error: fLab undefined.
! Illegal parameter number in definition of fLab.
! Illegal parameter number in definition of reserved@a.
! LaTeX Error: fCap undefined.


...and so on.
The last code I tried looked like this:



%% Graphics figure with caption and label
% [1:placement,] 2:relative width, 3:file name[, 4:caption[, 5:label]]
newcommand{figCapLab}[5][htbp]{%
ifthenelse{equal{#5}{}}%
{renewcommand{fLab}{}}%
{renewcommand{fLab}{label{##5}}}%
ifthenelse{equal{#4}{}}%
{renewcommand{fCap}{fLab}}%
{renewcommand{fCap}{caption{fLab{small{}##4}}}}%
begin{figure}[#1]%
centering%
begin{minipage}[t]{#2textwidth}%
includegraphics[width=textwidth]{#3}% is width of surrounding minipage
fCap%
end{minipage}%
end{figure}
}
%% Graphics figure with caption
% [1:placement,] 2:relative width, 3:file name, 4:caption
newcommand{figCap}[4]{%
ifthenelse{equal{#1}{}}%
{figCapLab{#2}{#3}{#4}{}}%
{figCapLab[#1]{#2}{#3}{#4}{}}%
}
%% Graphics figure with label
% [1:placement,] 2:relative width, 3:file name, 4:label
newcommand{figLab}[4]{%
ifthenelse{equal{#1}{}}%
{figCapLab{#2}{#3}{}{#4}}%
{figCapLab[#1]{#2}{#3}{}{#4}}%
}


Who can explain what went wrong?



People who like complete examples should add this prolog:



documentclass[a4paper,twoside]{report}
usepackage{german}
usepackage[latin1]{inputenc}
usepackage{a4}
usepackage{amsmath}
usepackage{url}
usepackage{graphicx}
usepackage{ifthen}


...and this epilog:



begin{document}
See ref{foo}.
figCapLab{0.9}{whatever.pdf}{Caption}{foo}
end{document}









share|improve this question









New contributor




U. Windl is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 4





    Instead of identifying mistakes in your code without much context, can you provide information on what you want to achieve ultimately? Perhaps there are better ways of achieving it.

    – Werner
    4 hours ago











  • please extend your code fragment to complete but small document!

    – Zarko
    4 hours ago











  • @Werner: There are always different ways to reach a goal, but if you change the way too frequently, you'll never make it. So I'd prefer a fix for my "solution" over a completely new attempt (like xparse).

    – U. Windl
    4 hours ago











  • pgfkeys allow you to have multiple keys, which you could call optional arguments.

    – marmot
    3 hours ago
















4















After I had a macro that worked, I tried to improve it by making some parameters optional.
Unfortunately the macro no longer works. Instead I'm getting errors I do not understand, for example:



LaTeX Warning: Label `####5' multiply defined.
LaTeX Warning: Label `####5' multiply defined.
! LaTeX Error: fLab undefined.
! Illegal parameter number in definition of fLab.
! Illegal parameter number in definition of reserved@a.
! LaTeX Error: fCap undefined.


...and so on.
The last code I tried looked like this:



%% Graphics figure with caption and label
% [1:placement,] 2:relative width, 3:file name[, 4:caption[, 5:label]]
newcommand{figCapLab}[5][htbp]{%
ifthenelse{equal{#5}{}}%
{renewcommand{fLab}{}}%
{renewcommand{fLab}{label{##5}}}%
ifthenelse{equal{#4}{}}%
{renewcommand{fCap}{fLab}}%
{renewcommand{fCap}{caption{fLab{small{}##4}}}}%
begin{figure}[#1]%
centering%
begin{minipage}[t]{#2textwidth}%
includegraphics[width=textwidth]{#3}% is width of surrounding minipage
fCap%
end{minipage}%
end{figure}
}
%% Graphics figure with caption
% [1:placement,] 2:relative width, 3:file name, 4:caption
newcommand{figCap}[4]{%
ifthenelse{equal{#1}{}}%
{figCapLab{#2}{#3}{#4}{}}%
{figCapLab[#1]{#2}{#3}{#4}{}}%
}
%% Graphics figure with label
% [1:placement,] 2:relative width, 3:file name, 4:label
newcommand{figLab}[4]{%
ifthenelse{equal{#1}{}}%
{figCapLab{#2}{#3}{}{#4}}%
{figCapLab[#1]{#2}{#3}{}{#4}}%
}


Who can explain what went wrong?



People who like complete examples should add this prolog:



documentclass[a4paper,twoside]{report}
usepackage{german}
usepackage[latin1]{inputenc}
usepackage{a4}
usepackage{amsmath}
usepackage{url}
usepackage{graphicx}
usepackage{ifthen}


...and this epilog:



begin{document}
See ref{foo}.
figCapLab{0.9}{whatever.pdf}{Caption}{foo}
end{document}









share|improve this question









New contributor




U. Windl is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 4





    Instead of identifying mistakes in your code without much context, can you provide information on what you want to achieve ultimately? Perhaps there are better ways of achieving it.

    – Werner
    4 hours ago











  • please extend your code fragment to complete but small document!

    – Zarko
    4 hours ago











  • @Werner: There are always different ways to reach a goal, but if you change the way too frequently, you'll never make it. So I'd prefer a fix for my "solution" over a completely new attempt (like xparse).

    – U. Windl
    4 hours ago











  • pgfkeys allow you to have multiple keys, which you could call optional arguments.

    – marmot
    3 hours ago














4












4








4








After I had a macro that worked, I tried to improve it by making some parameters optional.
Unfortunately the macro no longer works. Instead I'm getting errors I do not understand, for example:



LaTeX Warning: Label `####5' multiply defined.
LaTeX Warning: Label `####5' multiply defined.
! LaTeX Error: fLab undefined.
! Illegal parameter number in definition of fLab.
! Illegal parameter number in definition of reserved@a.
! LaTeX Error: fCap undefined.


...and so on.
The last code I tried looked like this:



%% Graphics figure with caption and label
% [1:placement,] 2:relative width, 3:file name[, 4:caption[, 5:label]]
newcommand{figCapLab}[5][htbp]{%
ifthenelse{equal{#5}{}}%
{renewcommand{fLab}{}}%
{renewcommand{fLab}{label{##5}}}%
ifthenelse{equal{#4}{}}%
{renewcommand{fCap}{fLab}}%
{renewcommand{fCap}{caption{fLab{small{}##4}}}}%
begin{figure}[#1]%
centering%
begin{minipage}[t]{#2textwidth}%
includegraphics[width=textwidth]{#3}% is width of surrounding minipage
fCap%
end{minipage}%
end{figure}
}
%% Graphics figure with caption
% [1:placement,] 2:relative width, 3:file name, 4:caption
newcommand{figCap}[4]{%
ifthenelse{equal{#1}{}}%
{figCapLab{#2}{#3}{#4}{}}%
{figCapLab[#1]{#2}{#3}{#4}{}}%
}
%% Graphics figure with label
% [1:placement,] 2:relative width, 3:file name, 4:label
newcommand{figLab}[4]{%
ifthenelse{equal{#1}{}}%
{figCapLab{#2}{#3}{}{#4}}%
{figCapLab[#1]{#2}{#3}{}{#4}}%
}


Who can explain what went wrong?



People who like complete examples should add this prolog:



documentclass[a4paper,twoside]{report}
usepackage{german}
usepackage[latin1]{inputenc}
usepackage{a4}
usepackage{amsmath}
usepackage{url}
usepackage{graphicx}
usepackage{ifthen}


...and this epilog:



begin{document}
See ref{foo}.
figCapLab{0.9}{whatever.pdf}{Caption}{foo}
end{document}









share|improve this question









New contributor




U. Windl is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












After I had a macro that worked, I tried to improve it by making some parameters optional.
Unfortunately the macro no longer works. Instead I'm getting errors I do not understand, for example:



LaTeX Warning: Label `####5' multiply defined.
LaTeX Warning: Label `####5' multiply defined.
! LaTeX Error: fLab undefined.
! Illegal parameter number in definition of fLab.
! Illegal parameter number in definition of reserved@a.
! LaTeX Error: fCap undefined.


...and so on.
The last code I tried looked like this:



%% Graphics figure with caption and label
% [1:placement,] 2:relative width, 3:file name[, 4:caption[, 5:label]]
newcommand{figCapLab}[5][htbp]{%
ifthenelse{equal{#5}{}}%
{renewcommand{fLab}{}}%
{renewcommand{fLab}{label{##5}}}%
ifthenelse{equal{#4}{}}%
{renewcommand{fCap}{fLab}}%
{renewcommand{fCap}{caption{fLab{small{}##4}}}}%
begin{figure}[#1]%
centering%
begin{minipage}[t]{#2textwidth}%
includegraphics[width=textwidth]{#3}% is width of surrounding minipage
fCap%
end{minipage}%
end{figure}
}
%% Graphics figure with caption
% [1:placement,] 2:relative width, 3:file name, 4:caption
newcommand{figCap}[4]{%
ifthenelse{equal{#1}{}}%
{figCapLab{#2}{#3}{#4}{}}%
{figCapLab[#1]{#2}{#3}{#4}{}}%
}
%% Graphics figure with label
% [1:placement,] 2:relative width, 3:file name, 4:label
newcommand{figLab}[4]{%
ifthenelse{equal{#1}{}}%
{figCapLab{#2}{#3}{}{#4}}%
{figCapLab[#1]{#2}{#3}{}{#4}}%
}


Who can explain what went wrong?



People who like complete examples should add this prolog:



documentclass[a4paper,twoside]{report}
usepackage{german}
usepackage[latin1]{inputenc}
usepackage{a4}
usepackage{amsmath}
usepackage{url}
usepackage{graphicx}
usepackage{ifthen}


...and this epilog:



begin{document}
See ref{foo}.
figCapLab{0.9}{whatever.pdf}{Caption}{foo}
end{document}






macros parameters






share|improve this question









New contributor




U. Windl is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




U. Windl is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 4 hours ago







U. Windl













New contributor




U. Windl is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 4 hours ago









U. WindlU. Windl

1233




1233




New contributor




U. Windl is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





U. Windl is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






U. Windl is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








  • 4





    Instead of identifying mistakes in your code without much context, can you provide information on what you want to achieve ultimately? Perhaps there are better ways of achieving it.

    – Werner
    4 hours ago











  • please extend your code fragment to complete but small document!

    – Zarko
    4 hours ago











  • @Werner: There are always different ways to reach a goal, but if you change the way too frequently, you'll never make it. So I'd prefer a fix for my "solution" over a completely new attempt (like xparse).

    – U. Windl
    4 hours ago











  • pgfkeys allow you to have multiple keys, which you could call optional arguments.

    – marmot
    3 hours ago














  • 4





    Instead of identifying mistakes in your code without much context, can you provide information on what you want to achieve ultimately? Perhaps there are better ways of achieving it.

    – Werner
    4 hours ago











  • please extend your code fragment to complete but small document!

    – Zarko
    4 hours ago











  • @Werner: There are always different ways to reach a goal, but if you change the way too frequently, you'll never make it. So I'd prefer a fix for my "solution" over a completely new attempt (like xparse).

    – U. Windl
    4 hours ago











  • pgfkeys allow you to have multiple keys, which you could call optional arguments.

    – marmot
    3 hours ago








4




4





Instead of identifying mistakes in your code without much context, can you provide information on what you want to achieve ultimately? Perhaps there are better ways of achieving it.

– Werner
4 hours ago





Instead of identifying mistakes in your code without much context, can you provide information on what you want to achieve ultimately? Perhaps there are better ways of achieving it.

– Werner
4 hours ago













please extend your code fragment to complete but small document!

– Zarko
4 hours ago





please extend your code fragment to complete but small document!

– Zarko
4 hours ago













@Werner: There are always different ways to reach a goal, but if you change the way too frequently, you'll never make it. So I'd prefer a fix for my "solution" over a completely new attempt (like xparse).

– U. Windl
4 hours ago





@Werner: There are always different ways to reach a goal, but if you change the way too frequently, you'll never make it. So I'd prefer a fix for my "solution" over a completely new attempt (like xparse).

– U. Windl
4 hours ago













pgfkeys allow you to have multiple keys, which you could call optional arguments.

– marmot
3 hours ago





pgfkeys allow you to have multiple keys, which you could call optional arguments.

– marmot
3 hours ago










2 Answers
2






active

oldest

votes


















5














documentclass{article}
usepackage{graphicx}
newcommandaddtofigtoks[1]{expandafterfigtoksexpandafter
{thefigtoks#1}}
newtoksfigtoks
newcommandfigCapLab[3][htbp]{%
figtoks{begin{figure}[#1]}
addtofigtoks{centering}
addtofigtoks{includegraphics[width=#2textwidth]{#3}}
optcap
}
newcommandoptcap[1][relax]{%
ifxrelax#1relax
addtofigtoks{end{figure}}
thefigtoks
else
addtofigtoks{caption{#1}}%
expandafterlabelopt
fi
}
newcommandlabelopt[1][relax]{%
ifxrelax#1relaxelseaddtofigtoks{label{#1}}fi
addtofigtoks{end{figure}}
thefigtoks
}
begin{document}
figCapLab{.2}{example-image-a}
figCapLab{.2}{example-image-b}[My caption]
figCapLab{.2}{example-image-c}[My caption][fg:label1]
figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

In figures ref{fg:label1} and ref{fg:label2}...
end{document}


enter image description here



Ack-shu-ally, the more I think of it, tokens are not even needed:



documentclass{article}
usepackage{graphicx}
newcommandfigCapLab[3][htbp]{%
begin{figure}[#1]
centering
includegraphics[width=#2textwidth]{#3}
optcap
}
newcommandoptcap[1][relax]{%
ifxrelax#1relax
end{figure}
else
caption{#1}%
expandafterlabelopt
fi
}
newcommandlabelopt[1][relax]{%
ifxrelax#1relaxelselabel{#1}fi
end{figure}
}
begin{document}
figCapLab{.2}{example-image-a}
figCapLab{.2}{example-image-b}[My caption]
figCapLab{.2}{example-image-c}[My caption][fg:label1]
figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

In figures ref{fg:label1} and ref{fg:label2}...
end{document}





share|improve this answer

































    2














    Here is how you can achieve your goal using xparse:



    enter image description here



    documentclass{article}

    usepackage{graphicx,xparse}

    % figCapLab
    % [<float spec>] #1
    % {<width factor>} #2
    % {<image>} #3
    % [<caption>] #4
    % [<label>] #5
    NewDocumentCommand{figCapLab}{ O{htbp} m m o o }{%
    begin{figure}[#1]
    centering
    includegraphics[width=#2linewidth]{#3}% Set image at width
    IfValueT{#4}
    {caption{#4}IfValueT{#5}{label{#5}}}% Set possible caption and label
    end{figure}
    }

    begin{document}

    figCapLab{.2}{example-image-a}
    figCapLab{.2}{example-image-b}[My caption]
    figCapLab{.2}{example-image-c}[My caption][fg:label1]
    figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

    In figures ref{fg:label1} and ref{fg:label2}ldots

    end{document}


    Optional arguments with a default is specified using O{<default>} while optional arguments without a default uses o. Conditioning on whether or not a value is supplied is done using IfValueTF{<parameter>}{<true>}{<false>}. There are also singular conditionals IfValueT and IfValueF, the former of which was used above.



    The above code assumes that an empty caption (blank fourth argument) would not need a label (fifth) argument. If that's needed, move the IfValueT{#5}{label{#5}} out of the <true> branch inside IfValueT{#4}:



    NewDocumentCommand{figCapLab}{ O{htbp} m m o o }{%
    begin{figure}[#1]
    centering
    includegraphics[width=#2textwidth]{#3}% Set image at width
    IfValueT{#4}{caption{#4}}% Possible caption
    IfValueT{#5}{label{#5}}% Possible label
    end{figure}
    }





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


      }
      });






      U. Windl is a new contributor. Be nice, and check out our Code of Conduct.










      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f477627%2fhow-to-define-a-macro-with-multiple-optional-parameters%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









      5














      documentclass{article}
      usepackage{graphicx}
      newcommandaddtofigtoks[1]{expandafterfigtoksexpandafter
      {thefigtoks#1}}
      newtoksfigtoks
      newcommandfigCapLab[3][htbp]{%
      figtoks{begin{figure}[#1]}
      addtofigtoks{centering}
      addtofigtoks{includegraphics[width=#2textwidth]{#3}}
      optcap
      }
      newcommandoptcap[1][relax]{%
      ifxrelax#1relax
      addtofigtoks{end{figure}}
      thefigtoks
      else
      addtofigtoks{caption{#1}}%
      expandafterlabelopt
      fi
      }
      newcommandlabelopt[1][relax]{%
      ifxrelax#1relaxelseaddtofigtoks{label{#1}}fi
      addtofigtoks{end{figure}}
      thefigtoks
      }
      begin{document}
      figCapLab{.2}{example-image-a}
      figCapLab{.2}{example-image-b}[My caption]
      figCapLab{.2}{example-image-c}[My caption][fg:label1]
      figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

      In figures ref{fg:label1} and ref{fg:label2}...
      end{document}


      enter image description here



      Ack-shu-ally, the more I think of it, tokens are not even needed:



      documentclass{article}
      usepackage{graphicx}
      newcommandfigCapLab[3][htbp]{%
      begin{figure}[#1]
      centering
      includegraphics[width=#2textwidth]{#3}
      optcap
      }
      newcommandoptcap[1][relax]{%
      ifxrelax#1relax
      end{figure}
      else
      caption{#1}%
      expandafterlabelopt
      fi
      }
      newcommandlabelopt[1][relax]{%
      ifxrelax#1relaxelselabel{#1}fi
      end{figure}
      }
      begin{document}
      figCapLab{.2}{example-image-a}
      figCapLab{.2}{example-image-b}[My caption]
      figCapLab{.2}{example-image-c}[My caption][fg:label1]
      figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

      In figures ref{fg:label1} and ref{fg:label2}...
      end{document}





      share|improve this answer






























        5














        documentclass{article}
        usepackage{graphicx}
        newcommandaddtofigtoks[1]{expandafterfigtoksexpandafter
        {thefigtoks#1}}
        newtoksfigtoks
        newcommandfigCapLab[3][htbp]{%
        figtoks{begin{figure}[#1]}
        addtofigtoks{centering}
        addtofigtoks{includegraphics[width=#2textwidth]{#3}}
        optcap
        }
        newcommandoptcap[1][relax]{%
        ifxrelax#1relax
        addtofigtoks{end{figure}}
        thefigtoks
        else
        addtofigtoks{caption{#1}}%
        expandafterlabelopt
        fi
        }
        newcommandlabelopt[1][relax]{%
        ifxrelax#1relaxelseaddtofigtoks{label{#1}}fi
        addtofigtoks{end{figure}}
        thefigtoks
        }
        begin{document}
        figCapLab{.2}{example-image-a}
        figCapLab{.2}{example-image-b}[My caption]
        figCapLab{.2}{example-image-c}[My caption][fg:label1]
        figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

        In figures ref{fg:label1} and ref{fg:label2}...
        end{document}


        enter image description here



        Ack-shu-ally, the more I think of it, tokens are not even needed:



        documentclass{article}
        usepackage{graphicx}
        newcommandfigCapLab[3][htbp]{%
        begin{figure}[#1]
        centering
        includegraphics[width=#2textwidth]{#3}
        optcap
        }
        newcommandoptcap[1][relax]{%
        ifxrelax#1relax
        end{figure}
        else
        caption{#1}%
        expandafterlabelopt
        fi
        }
        newcommandlabelopt[1][relax]{%
        ifxrelax#1relaxelselabel{#1}fi
        end{figure}
        }
        begin{document}
        figCapLab{.2}{example-image-a}
        figCapLab{.2}{example-image-b}[My caption]
        figCapLab{.2}{example-image-c}[My caption][fg:label1]
        figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

        In figures ref{fg:label1} and ref{fg:label2}...
        end{document}





        share|improve this answer




























          5












          5








          5







          documentclass{article}
          usepackage{graphicx}
          newcommandaddtofigtoks[1]{expandafterfigtoksexpandafter
          {thefigtoks#1}}
          newtoksfigtoks
          newcommandfigCapLab[3][htbp]{%
          figtoks{begin{figure}[#1]}
          addtofigtoks{centering}
          addtofigtoks{includegraphics[width=#2textwidth]{#3}}
          optcap
          }
          newcommandoptcap[1][relax]{%
          ifxrelax#1relax
          addtofigtoks{end{figure}}
          thefigtoks
          else
          addtofigtoks{caption{#1}}%
          expandafterlabelopt
          fi
          }
          newcommandlabelopt[1][relax]{%
          ifxrelax#1relaxelseaddtofigtoks{label{#1}}fi
          addtofigtoks{end{figure}}
          thefigtoks
          }
          begin{document}
          figCapLab{.2}{example-image-a}
          figCapLab{.2}{example-image-b}[My caption]
          figCapLab{.2}{example-image-c}[My caption][fg:label1]
          figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

          In figures ref{fg:label1} and ref{fg:label2}...
          end{document}


          enter image description here



          Ack-shu-ally, the more I think of it, tokens are not even needed:



          documentclass{article}
          usepackage{graphicx}
          newcommandfigCapLab[3][htbp]{%
          begin{figure}[#1]
          centering
          includegraphics[width=#2textwidth]{#3}
          optcap
          }
          newcommandoptcap[1][relax]{%
          ifxrelax#1relax
          end{figure}
          else
          caption{#1}%
          expandafterlabelopt
          fi
          }
          newcommandlabelopt[1][relax]{%
          ifxrelax#1relaxelselabel{#1}fi
          end{figure}
          }
          begin{document}
          figCapLab{.2}{example-image-a}
          figCapLab{.2}{example-image-b}[My caption]
          figCapLab{.2}{example-image-c}[My caption][fg:label1]
          figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

          In figures ref{fg:label1} and ref{fg:label2}...
          end{document}





          share|improve this answer















          documentclass{article}
          usepackage{graphicx}
          newcommandaddtofigtoks[1]{expandafterfigtoksexpandafter
          {thefigtoks#1}}
          newtoksfigtoks
          newcommandfigCapLab[3][htbp]{%
          figtoks{begin{figure}[#1]}
          addtofigtoks{centering}
          addtofigtoks{includegraphics[width=#2textwidth]{#3}}
          optcap
          }
          newcommandoptcap[1][relax]{%
          ifxrelax#1relax
          addtofigtoks{end{figure}}
          thefigtoks
          else
          addtofigtoks{caption{#1}}%
          expandafterlabelopt
          fi
          }
          newcommandlabelopt[1][relax]{%
          ifxrelax#1relaxelseaddtofigtoks{label{#1}}fi
          addtofigtoks{end{figure}}
          thefigtoks
          }
          begin{document}
          figCapLab{.2}{example-image-a}
          figCapLab{.2}{example-image-b}[My caption]
          figCapLab{.2}{example-image-c}[My caption][fg:label1]
          figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

          In figures ref{fg:label1} and ref{fg:label2}...
          end{document}


          enter image description here



          Ack-shu-ally, the more I think of it, tokens are not even needed:



          documentclass{article}
          usepackage{graphicx}
          newcommandfigCapLab[3][htbp]{%
          begin{figure}[#1]
          centering
          includegraphics[width=#2textwidth]{#3}
          optcap
          }
          newcommandoptcap[1][relax]{%
          ifxrelax#1relax
          end{figure}
          else
          caption{#1}%
          expandafterlabelopt
          fi
          }
          newcommandlabelopt[1][relax]{%
          ifxrelax#1relaxelselabel{#1}fi
          end{figure}
          }
          begin{document}
          figCapLab{.2}{example-image-a}
          figCapLab{.2}{example-image-b}[My caption]
          figCapLab{.2}{example-image-c}[My caption][fg:label1]
          figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

          In figures ref{fg:label1} and ref{fg:label2}...
          end{document}






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 2 hours ago

























          answered 3 hours ago









          Steven B. SegletesSteven B. Segletes

          157k9202411




          157k9202411























              2














              Here is how you can achieve your goal using xparse:



              enter image description here



              documentclass{article}

              usepackage{graphicx,xparse}

              % figCapLab
              % [<float spec>] #1
              % {<width factor>} #2
              % {<image>} #3
              % [<caption>] #4
              % [<label>] #5
              NewDocumentCommand{figCapLab}{ O{htbp} m m o o }{%
              begin{figure}[#1]
              centering
              includegraphics[width=#2linewidth]{#3}% Set image at width
              IfValueT{#4}
              {caption{#4}IfValueT{#5}{label{#5}}}% Set possible caption and label
              end{figure}
              }

              begin{document}

              figCapLab{.2}{example-image-a}
              figCapLab{.2}{example-image-b}[My caption]
              figCapLab{.2}{example-image-c}[My caption][fg:label1]
              figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

              In figures ref{fg:label1} and ref{fg:label2}ldots

              end{document}


              Optional arguments with a default is specified using O{<default>} while optional arguments without a default uses o. Conditioning on whether or not a value is supplied is done using IfValueTF{<parameter>}{<true>}{<false>}. There are also singular conditionals IfValueT and IfValueF, the former of which was used above.



              The above code assumes that an empty caption (blank fourth argument) would not need a label (fifth) argument. If that's needed, move the IfValueT{#5}{label{#5}} out of the <true> branch inside IfValueT{#4}:



              NewDocumentCommand{figCapLab}{ O{htbp} m m o o }{%
              begin{figure}[#1]
              centering
              includegraphics[width=#2textwidth]{#3}% Set image at width
              IfValueT{#4}{caption{#4}}% Possible caption
              IfValueT{#5}{label{#5}}% Possible label
              end{figure}
              }





              share|improve this answer




























                2














                Here is how you can achieve your goal using xparse:



                enter image description here



                documentclass{article}

                usepackage{graphicx,xparse}

                % figCapLab
                % [<float spec>] #1
                % {<width factor>} #2
                % {<image>} #3
                % [<caption>] #4
                % [<label>] #5
                NewDocumentCommand{figCapLab}{ O{htbp} m m o o }{%
                begin{figure}[#1]
                centering
                includegraphics[width=#2linewidth]{#3}% Set image at width
                IfValueT{#4}
                {caption{#4}IfValueT{#5}{label{#5}}}% Set possible caption and label
                end{figure}
                }

                begin{document}

                figCapLab{.2}{example-image-a}
                figCapLab{.2}{example-image-b}[My caption]
                figCapLab{.2}{example-image-c}[My caption][fg:label1]
                figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

                In figures ref{fg:label1} and ref{fg:label2}ldots

                end{document}


                Optional arguments with a default is specified using O{<default>} while optional arguments without a default uses o. Conditioning on whether or not a value is supplied is done using IfValueTF{<parameter>}{<true>}{<false>}. There are also singular conditionals IfValueT and IfValueF, the former of which was used above.



                The above code assumes that an empty caption (blank fourth argument) would not need a label (fifth) argument. If that's needed, move the IfValueT{#5}{label{#5}} out of the <true> branch inside IfValueT{#4}:



                NewDocumentCommand{figCapLab}{ O{htbp} m m o o }{%
                begin{figure}[#1]
                centering
                includegraphics[width=#2textwidth]{#3}% Set image at width
                IfValueT{#4}{caption{#4}}% Possible caption
                IfValueT{#5}{label{#5}}% Possible label
                end{figure}
                }





                share|improve this answer


























                  2












                  2








                  2







                  Here is how you can achieve your goal using xparse:



                  enter image description here



                  documentclass{article}

                  usepackage{graphicx,xparse}

                  % figCapLab
                  % [<float spec>] #1
                  % {<width factor>} #2
                  % {<image>} #3
                  % [<caption>] #4
                  % [<label>] #5
                  NewDocumentCommand{figCapLab}{ O{htbp} m m o o }{%
                  begin{figure}[#1]
                  centering
                  includegraphics[width=#2linewidth]{#3}% Set image at width
                  IfValueT{#4}
                  {caption{#4}IfValueT{#5}{label{#5}}}% Set possible caption and label
                  end{figure}
                  }

                  begin{document}

                  figCapLab{.2}{example-image-a}
                  figCapLab{.2}{example-image-b}[My caption]
                  figCapLab{.2}{example-image-c}[My caption][fg:label1]
                  figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

                  In figures ref{fg:label1} and ref{fg:label2}ldots

                  end{document}


                  Optional arguments with a default is specified using O{<default>} while optional arguments without a default uses o. Conditioning on whether or not a value is supplied is done using IfValueTF{<parameter>}{<true>}{<false>}. There are also singular conditionals IfValueT and IfValueF, the former of which was used above.



                  The above code assumes that an empty caption (blank fourth argument) would not need a label (fifth) argument. If that's needed, move the IfValueT{#5}{label{#5}} out of the <true> branch inside IfValueT{#4}:



                  NewDocumentCommand{figCapLab}{ O{htbp} m m o o }{%
                  begin{figure}[#1]
                  centering
                  includegraphics[width=#2textwidth]{#3}% Set image at width
                  IfValueT{#4}{caption{#4}}% Possible caption
                  IfValueT{#5}{label{#5}}% Possible label
                  end{figure}
                  }





                  share|improve this answer













                  Here is how you can achieve your goal using xparse:



                  enter image description here



                  documentclass{article}

                  usepackage{graphicx,xparse}

                  % figCapLab
                  % [<float spec>] #1
                  % {<width factor>} #2
                  % {<image>} #3
                  % [<caption>] #4
                  % [<label>] #5
                  NewDocumentCommand{figCapLab}{ O{htbp} m m o o }{%
                  begin{figure}[#1]
                  centering
                  includegraphics[width=#2linewidth]{#3}% Set image at width
                  IfValueT{#4}
                  {caption{#4}IfValueT{#5}{label{#5}}}% Set possible caption and label
                  end{figure}
                  }

                  begin{document}

                  figCapLab{.2}{example-image-a}
                  figCapLab{.2}{example-image-b}[My caption]
                  figCapLab{.2}{example-image-c}[My caption][fg:label1]
                  figCapLab[p]{.2}{example-image}[Other caption][fg:label2]

                  In figures ref{fg:label1} and ref{fg:label2}ldots

                  end{document}


                  Optional arguments with a default is specified using O{<default>} while optional arguments without a default uses o. Conditioning on whether or not a value is supplied is done using IfValueTF{<parameter>}{<true>}{<false>}. There are also singular conditionals IfValueT and IfValueF, the former of which was used above.



                  The above code assumes that an empty caption (blank fourth argument) would not need a label (fifth) argument. If that's needed, move the IfValueT{#5}{label{#5}} out of the <true> branch inside IfValueT{#4}:



                  NewDocumentCommand{figCapLab}{ O{htbp} m m o o }{%
                  begin{figure}[#1]
                  centering
                  includegraphics[width=#2textwidth]{#3}% Set image at width
                  IfValueT{#4}{caption{#4}}% Possible caption
                  IfValueT{#5}{label{#5}}% Possible label
                  end{figure}
                  }






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 1 hour ago









                  WernerWerner

                  446k699841691




                  446k699841691






















                      U. Windl is a new contributor. Be nice, and check out our Code of Conduct.










                      draft saved

                      draft discarded


















                      U. Windl is a new contributor. Be nice, and check out our Code of Conduct.













                      U. Windl is a new contributor. Be nice, and check out our Code of Conduct.












                      U. Windl is a new contributor. Be nice, and check out our Code of Conduct.
















                      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.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f477627%2fhow-to-define-a-macro-with-multiple-optional-parameters%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

                      How to make a Squid Proxy server?

                      Is this a new Fibonacci Identity?

                      19世紀