newcommand: Combine (optional) star and optional parameter












5















How may I define a new command that admits starred and non-starred variants, and that also admits an optional argument?



I tried the following:



documentclass{minimal}
makeatletter
newcommandMyCommand[1][1]{%
@ifstar{%
The starred variant with parameter: #1%
}{%
The non-starred variant with parameter: #1%
}
}
makeatother
begin{document}
MyCommand \
MyCommand* \
MyCommand[2] \
MyCommand*[2]
end{document}


But this gives:




The non-starred variant with parameter: 1

The starred variant with parameter: 1

The non-starred variant with parameter: 2

The starred variant with parameter: 1[2]




Yet, one can write MyCommand[2]* to obtain "The starred variant with parameter: 2" but somehow I'd like the above version to work.










share|improve this question




















  • 2





    Please, avoid using the minimal class; it is not meant for minimal examples.

    – egreg
    Mar 15 at 13:52











  • I learned many things with this question, including the fact that the minimal class is not made for minimal examples!

    – Bruno
    Mar 15 at 14:27
















5















How may I define a new command that admits starred and non-starred variants, and that also admits an optional argument?



I tried the following:



documentclass{minimal}
makeatletter
newcommandMyCommand[1][1]{%
@ifstar{%
The starred variant with parameter: #1%
}{%
The non-starred variant with parameter: #1%
}
}
makeatother
begin{document}
MyCommand \
MyCommand* \
MyCommand[2] \
MyCommand*[2]
end{document}


But this gives:




The non-starred variant with parameter: 1

The starred variant with parameter: 1

The non-starred variant with parameter: 2

The starred variant with parameter: 1[2]




Yet, one can write MyCommand[2]* to obtain "The starred variant with parameter: 2" but somehow I'd like the above version to work.










share|improve this question




















  • 2





    Please, avoid using the minimal class; it is not meant for minimal examples.

    – egreg
    Mar 15 at 13:52











  • I learned many things with this question, including the fact that the minimal class is not made for minimal examples!

    – Bruno
    Mar 15 at 14:27














5












5








5








How may I define a new command that admits starred and non-starred variants, and that also admits an optional argument?



I tried the following:



documentclass{minimal}
makeatletter
newcommandMyCommand[1][1]{%
@ifstar{%
The starred variant with parameter: #1%
}{%
The non-starred variant with parameter: #1%
}
}
makeatother
begin{document}
MyCommand \
MyCommand* \
MyCommand[2] \
MyCommand*[2]
end{document}


But this gives:




The non-starred variant with parameter: 1

The starred variant with parameter: 1

The non-starred variant with parameter: 2

The starred variant with parameter: 1[2]




Yet, one can write MyCommand[2]* to obtain "The starred variant with parameter: 2" but somehow I'd like the above version to work.










share|improve this question
















How may I define a new command that admits starred and non-starred variants, and that also admits an optional argument?



I tried the following:



documentclass{minimal}
makeatletter
newcommandMyCommand[1][1]{%
@ifstar{%
The starred variant with parameter: #1%
}{%
The non-starred variant with parameter: #1%
}
}
makeatother
begin{document}
MyCommand \
MyCommand* \
MyCommand[2] \
MyCommand*[2]
end{document}


But this gives:




The non-starred variant with parameter: 1

The starred variant with parameter: 1

The non-starred variant with parameter: 2

The starred variant with parameter: 1[2]




Yet, one can write MyCommand[2]* to obtain "The starred variant with parameter: 2" but somehow I'd like the above version to work.







macros






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 15 at 13:45







Bruno

















asked Mar 15 at 13:40









BrunoBruno

1,0921822




1,0921822








  • 2





    Please, avoid using the minimal class; it is not meant for minimal examples.

    – egreg
    Mar 15 at 13:52











  • I learned many things with this question, including the fact that the minimal class is not made for minimal examples!

    – Bruno
    Mar 15 at 14:27














  • 2





    Please, avoid using the minimal class; it is not meant for minimal examples.

    – egreg
    Mar 15 at 13:52











  • I learned many things with this question, including the fact that the minimal class is not made for minimal examples!

    – Bruno
    Mar 15 at 14:27








2




2





Please, avoid using the minimal class; it is not meant for minimal examples.

– egreg
Mar 15 at 13:52





Please, avoid using the minimal class; it is not meant for minimal examples.

– egreg
Mar 15 at 13:52













I learned many things with this question, including the fact that the minimal class is not made for minimal examples!

– Bruno
Mar 15 at 14:27





I learned many things with this question, including the fact that the minimal class is not made for minimal examples!

– Bruno
Mar 15 at 14:27










2 Answers
2






active

oldest

votes


















7














With xparse it's very easy to play around with optional arguments and starred variants:



documentclass{article}
usepackage{xparse}
NewDocumentCommandMyCommand
{
s % optional *
O{1} % first optional argument (default = 1)
}
{%
IfBooleanTF{#1}
{The starred variant with parameter: #2}
{The non-starred variant with parameter: #2}
}
begin{document}
noindent
MyCommand \
MyCommand* \
MyCommand[2]\
MyCommand*[2]
end{document}


With LaTeX's newcommand it a little trickier. The @ifstar macro looks at the next token after the macro is expanded and has absorbed its arguments, so you need to first check for the * and only then look for the optional argument:



documentclass{article}
makeatletter
newcommandMyCommand
{%
@ifstar
{MyCommand@star}
{MyCommand@nostar}%
}
newcommandMyCommand@star[1][1]{%
The starred variant with parameter: #1%
}
newcommandMyCommand@nostar[1][1]{%
The non-starred variant with parameter: #1%
}
makeatother
begin{document}
noindent
MyCommand \
MyCommand* \
MyCommand[2]\
MyCommand*[2]
end{document}


Both versions print:




enter image description here




Your code works, but not as you expect it to. The MyCommand[1][1] looks for an optional argument “while expanding” MyCommand, which then gives you:



@ifstar{%
The starred variant with parameter: <optional argument or default>%
}{%
The non-starred variant with parameter: <optional argument or default>%
}


and only after that the @ifstar test will be expanded to look for the optional * and choose the text accordingly, so the actual syntax for the command you defined is:



MyCommand[optional argument]<optional star>





share|improve this answer

































    3














    Make MyCommand take no parameters, but just figure out the star. Then fork from there.



    documentclass{minimal}
    makeatletter
    newcommandMyCommand{%
    @ifstar{mycommandstar}{mycommandnostar}
    }
    newcommandmycommandstar[1][1]{The starred variant with parameter: #1}
    newcommandmycommandnostar[1][1]{The non-starred variant with parameter: #1}
    makeatother
    begin{document}
    MyCommand \
    MyCommand* \
    MyCommand[2] \
    MyCommand*[2]
    end{document}


    enter image description here






    share|improve this answer



















    • 2





      I'd add a % at the end of the definition of MyCommand. It works without that because the definition of @ifstar ignores space tokens by design, but... :)

      – Phelype Oleinik
      Mar 15 at 14:20











    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%2f479632%2fnewcommand-combine-optional-star-and-optional-parameter%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









    7














    With xparse it's very easy to play around with optional arguments and starred variants:



    documentclass{article}
    usepackage{xparse}
    NewDocumentCommandMyCommand
    {
    s % optional *
    O{1} % first optional argument (default = 1)
    }
    {%
    IfBooleanTF{#1}
    {The starred variant with parameter: #2}
    {The non-starred variant with parameter: #2}
    }
    begin{document}
    noindent
    MyCommand \
    MyCommand* \
    MyCommand[2]\
    MyCommand*[2]
    end{document}


    With LaTeX's newcommand it a little trickier. The @ifstar macro looks at the next token after the macro is expanded and has absorbed its arguments, so you need to first check for the * and only then look for the optional argument:



    documentclass{article}
    makeatletter
    newcommandMyCommand
    {%
    @ifstar
    {MyCommand@star}
    {MyCommand@nostar}%
    }
    newcommandMyCommand@star[1][1]{%
    The starred variant with parameter: #1%
    }
    newcommandMyCommand@nostar[1][1]{%
    The non-starred variant with parameter: #1%
    }
    makeatother
    begin{document}
    noindent
    MyCommand \
    MyCommand* \
    MyCommand[2]\
    MyCommand*[2]
    end{document}


    Both versions print:




    enter image description here




    Your code works, but not as you expect it to. The MyCommand[1][1] looks for an optional argument “while expanding” MyCommand, which then gives you:



    @ifstar{%
    The starred variant with parameter: <optional argument or default>%
    }{%
    The non-starred variant with parameter: <optional argument or default>%
    }


    and only after that the @ifstar test will be expanded to look for the optional * and choose the text accordingly, so the actual syntax for the command you defined is:



    MyCommand[optional argument]<optional star>





    share|improve this answer






























      7














      With xparse it's very easy to play around with optional arguments and starred variants:



      documentclass{article}
      usepackage{xparse}
      NewDocumentCommandMyCommand
      {
      s % optional *
      O{1} % first optional argument (default = 1)
      }
      {%
      IfBooleanTF{#1}
      {The starred variant with parameter: #2}
      {The non-starred variant with parameter: #2}
      }
      begin{document}
      noindent
      MyCommand \
      MyCommand* \
      MyCommand[2]\
      MyCommand*[2]
      end{document}


      With LaTeX's newcommand it a little trickier. The @ifstar macro looks at the next token after the macro is expanded and has absorbed its arguments, so you need to first check for the * and only then look for the optional argument:



      documentclass{article}
      makeatletter
      newcommandMyCommand
      {%
      @ifstar
      {MyCommand@star}
      {MyCommand@nostar}%
      }
      newcommandMyCommand@star[1][1]{%
      The starred variant with parameter: #1%
      }
      newcommandMyCommand@nostar[1][1]{%
      The non-starred variant with parameter: #1%
      }
      makeatother
      begin{document}
      noindent
      MyCommand \
      MyCommand* \
      MyCommand[2]\
      MyCommand*[2]
      end{document}


      Both versions print:




      enter image description here




      Your code works, but not as you expect it to. The MyCommand[1][1] looks for an optional argument “while expanding” MyCommand, which then gives you:



      @ifstar{%
      The starred variant with parameter: <optional argument or default>%
      }{%
      The non-starred variant with parameter: <optional argument or default>%
      }


      and only after that the @ifstar test will be expanded to look for the optional * and choose the text accordingly, so the actual syntax for the command you defined is:



      MyCommand[optional argument]<optional star>





      share|improve this answer




























        7












        7








        7







        With xparse it's very easy to play around with optional arguments and starred variants:



        documentclass{article}
        usepackage{xparse}
        NewDocumentCommandMyCommand
        {
        s % optional *
        O{1} % first optional argument (default = 1)
        }
        {%
        IfBooleanTF{#1}
        {The starred variant with parameter: #2}
        {The non-starred variant with parameter: #2}
        }
        begin{document}
        noindent
        MyCommand \
        MyCommand* \
        MyCommand[2]\
        MyCommand*[2]
        end{document}


        With LaTeX's newcommand it a little trickier. The @ifstar macro looks at the next token after the macro is expanded and has absorbed its arguments, so you need to first check for the * and only then look for the optional argument:



        documentclass{article}
        makeatletter
        newcommandMyCommand
        {%
        @ifstar
        {MyCommand@star}
        {MyCommand@nostar}%
        }
        newcommandMyCommand@star[1][1]{%
        The starred variant with parameter: #1%
        }
        newcommandMyCommand@nostar[1][1]{%
        The non-starred variant with parameter: #1%
        }
        makeatother
        begin{document}
        noindent
        MyCommand \
        MyCommand* \
        MyCommand[2]\
        MyCommand*[2]
        end{document}


        Both versions print:




        enter image description here




        Your code works, but not as you expect it to. The MyCommand[1][1] looks for an optional argument “while expanding” MyCommand, which then gives you:



        @ifstar{%
        The starred variant with parameter: <optional argument or default>%
        }{%
        The non-starred variant with parameter: <optional argument or default>%
        }


        and only after that the @ifstar test will be expanded to look for the optional * and choose the text accordingly, so the actual syntax for the command you defined is:



        MyCommand[optional argument]<optional star>





        share|improve this answer















        With xparse it's very easy to play around with optional arguments and starred variants:



        documentclass{article}
        usepackage{xparse}
        NewDocumentCommandMyCommand
        {
        s % optional *
        O{1} % first optional argument (default = 1)
        }
        {%
        IfBooleanTF{#1}
        {The starred variant with parameter: #2}
        {The non-starred variant with parameter: #2}
        }
        begin{document}
        noindent
        MyCommand \
        MyCommand* \
        MyCommand[2]\
        MyCommand*[2]
        end{document}


        With LaTeX's newcommand it a little trickier. The @ifstar macro looks at the next token after the macro is expanded and has absorbed its arguments, so you need to first check for the * and only then look for the optional argument:



        documentclass{article}
        makeatletter
        newcommandMyCommand
        {%
        @ifstar
        {MyCommand@star}
        {MyCommand@nostar}%
        }
        newcommandMyCommand@star[1][1]{%
        The starred variant with parameter: #1%
        }
        newcommandMyCommand@nostar[1][1]{%
        The non-starred variant with parameter: #1%
        }
        makeatother
        begin{document}
        noindent
        MyCommand \
        MyCommand* \
        MyCommand[2]\
        MyCommand*[2]
        end{document}


        Both versions print:




        enter image description here




        Your code works, but not as you expect it to. The MyCommand[1][1] looks for an optional argument “while expanding” MyCommand, which then gives you:



        @ifstar{%
        The starred variant with parameter: <optional argument or default>%
        }{%
        The non-starred variant with parameter: <optional argument or default>%
        }


        and only after that the @ifstar test will be expanded to look for the optional * and choose the text accordingly, so the actual syntax for the command you defined is:



        MyCommand[optional argument]<optional star>






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 15 at 13:58

























        answered Mar 15 at 13:49









        Phelype OleinikPhelype Oleinik

        24.6k54688




        24.6k54688























            3














            Make MyCommand take no parameters, but just figure out the star. Then fork from there.



            documentclass{minimal}
            makeatletter
            newcommandMyCommand{%
            @ifstar{mycommandstar}{mycommandnostar}
            }
            newcommandmycommandstar[1][1]{The starred variant with parameter: #1}
            newcommandmycommandnostar[1][1]{The non-starred variant with parameter: #1}
            makeatother
            begin{document}
            MyCommand \
            MyCommand* \
            MyCommand[2] \
            MyCommand*[2]
            end{document}


            enter image description here






            share|improve this answer



















            • 2





              I'd add a % at the end of the definition of MyCommand. It works without that because the definition of @ifstar ignores space tokens by design, but... :)

              – Phelype Oleinik
              Mar 15 at 14:20
















            3














            Make MyCommand take no parameters, but just figure out the star. Then fork from there.



            documentclass{minimal}
            makeatletter
            newcommandMyCommand{%
            @ifstar{mycommandstar}{mycommandnostar}
            }
            newcommandmycommandstar[1][1]{The starred variant with parameter: #1}
            newcommandmycommandnostar[1][1]{The non-starred variant with parameter: #1}
            makeatother
            begin{document}
            MyCommand \
            MyCommand* \
            MyCommand[2] \
            MyCommand*[2]
            end{document}


            enter image description here






            share|improve this answer



















            • 2





              I'd add a % at the end of the definition of MyCommand. It works without that because the definition of @ifstar ignores space tokens by design, but... :)

              – Phelype Oleinik
              Mar 15 at 14:20














            3












            3








            3







            Make MyCommand take no parameters, but just figure out the star. Then fork from there.



            documentclass{minimal}
            makeatletter
            newcommandMyCommand{%
            @ifstar{mycommandstar}{mycommandnostar}
            }
            newcommandmycommandstar[1][1]{The starred variant with parameter: #1}
            newcommandmycommandnostar[1][1]{The non-starred variant with parameter: #1}
            makeatother
            begin{document}
            MyCommand \
            MyCommand* \
            MyCommand[2] \
            MyCommand*[2]
            end{document}


            enter image description here






            share|improve this answer













            Make MyCommand take no parameters, but just figure out the star. Then fork from there.



            documentclass{minimal}
            makeatletter
            newcommandMyCommand{%
            @ifstar{mycommandstar}{mycommandnostar}
            }
            newcommandmycommandstar[1][1]{The starred variant with parameter: #1}
            newcommandmycommandnostar[1][1]{The non-starred variant with parameter: #1}
            makeatother
            begin{document}
            MyCommand \
            MyCommand* \
            MyCommand[2] \
            MyCommand*[2]
            end{document}


            enter image description here







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Mar 15 at 13:48









            Steven B. SegletesSteven B. Segletes

            159k9204412




            159k9204412








            • 2





              I'd add a % at the end of the definition of MyCommand. It works without that because the definition of @ifstar ignores space tokens by design, but... :)

              – Phelype Oleinik
              Mar 15 at 14:20














            • 2





              I'd add a % at the end of the definition of MyCommand. It works without that because the definition of @ifstar ignores space tokens by design, but... :)

              – Phelype Oleinik
              Mar 15 at 14:20








            2




            2





            I'd add a % at the end of the definition of MyCommand. It works without that because the definition of @ifstar ignores space tokens by design, but... :)

            – Phelype Oleinik
            Mar 15 at 14:20





            I'd add a % at the end of the definition of MyCommand. It works without that because the definition of @ifstar ignores space tokens by design, but... :)

            – Phelype Oleinik
            Mar 15 at 14:20


















            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.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f479632%2fnewcommand-combine-optional-star-and-optional-parameter%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

            Identifying “long and narrow” polygons in with PostGISlength and width of polygonWhy postgis st_overlaps reports Qgis' “avoid intersections” generated polygon as overlapping with others?Adjusting polygons to boundary and filling holesDrawing polygons with fixed area?How to remove spikes in Polygons with PostGISDeleting sliver polygons after difference operation in QGIS?Snapping boundaries in PostGISSplit polygon into parts adding attributes based on underlying polygon in QGISSplitting overlap between polygons and assign to nearest polygon using PostGIS?Expanding polygons and clipping at midpoint?Removing Intersection of Buffers in Same Layers

            Masuk log Menu navigasi

            อาณาจักร (ชีววิทยา) ดูเพิ่ม อ้างอิง รายการเลือกการนำทาง10.1086/39456810.5962/bhl.title.447410.1126/science.163.3863.150576276010.1007/BF01796092408502"Phylogenetic structure of the prokaryotic domain: the primary kingdoms"10.1073/pnas.74.11.5088432104270744"Towards a natural system of organisms: proposal for the domains Archaea, Bacteria, and Eucarya"1990PNAS...87.4576W10.1073/pnas.87.12.4576541592112744PubMedJump the queueexpand by handPubMedJump the queueexpand by handPubMedJump the queueexpand by hand"A revised six-kingdom system of life"10.1111/j.1469-185X.1998.tb00030.x9809012"Only six kingdoms of life"10.1098/rspb.2004.2705169172415306349"Kingdoms Protozoa and Chromista and the eozoan root of the eukaryotic tree"10.1098/rsbl.2009.0948288006020031978เพิ่มข้อมูล