Empty optional argument or Not giving optional argument at all?When to use LetLtxMacro?xparse bug in optional...

How to not forget my phone in the bathroom?

In a world with multiracial creatures, what word can be used instead of mankind?

Does resurrection consume material components if the target isn’t willing to be resurrected?

Why is Shelob considered evil?

How can guns be countered by melee combat without raw-ability or exceptional explanations?

What does an unprocessed RAW file look like?

How can changes in personality/values of a person who turned into a vampire be explained?

Will linear voltage regulator step up current?

Can a planet be tidally unlocked?

How to know if I am a 'Real Developer'

Why is the meaning of kanji 閑 "leisure"?

Distortion of City -Boundary-Polygons proportional to population size in QGIS?

Why are `&array` and `array` pointing to the same address?

Taking an academic pseudonym?

Why would you use 2 alternate layout buttons instead of 1, when only one can be selected at once

Is layered encryption more secure than long passwords?

Is it possible to detect 100% of SQLi with a simple regex?

Build ASCII Podiums

Almost normal subgroup

Are encryption algorithms with fixed-point free permutations inherently flawed?

Is it ethical to apply for a job on someone's behalf?

Is Screenshot Time-tracking Common?

How can a kingdom keep the secret of a missing monarch from the public?

I hate taking lectures, can I still survive in academia?



Empty optional argument or Not giving optional argument at all?


When to use LetLtxMacro?xparse bug in optional arguments (simply not working)?Optional argument within another optional argument in biblatex citexparse with underscore and optional argumentxparse command with just optional argument failsThree-way optional argument in xparseIn DeclareDocumentCommand signaling first optional argument is missingIs it possible to have optional argument and mandatory one with brace using xparse?Not ignoring spaces before optional argument with xparsexparse gobbles character(s) using an optional argumentIssues with footnotes using wrapping parbox with longtable, threeparttable and tablenotes













3















I learnt that parbox has five arguments, that is: parbox[<align>][<height>][<inner-align>]{<width>}{<text>}. So I constrcut my own myparbox in which I add sloppysetlengthparfillskip{0pt} before #5. But it fails. What's the reason and how to re-define myparbox?



MWE:



documentclass{article}
usepackage{xparse}
NewDocumentCommand{myparbox}{ooomm}{%
parbox[#1][#2][#3]{#4}{sloppysetlengthparfillskip{0pt}#5}
}
begin{document}
AAAfbox{parbox[][][]{4em}{aa bb cc dd ee ff}}AAA\% parbox typesets nothing. why?
BBBfbox{myparbox{4em}{aa bb cc dd ee ff}}BBB% This fails to compile
end{document}


EDIT:



documentclass{article}
usepackage{xparse}
letoldparboxparbox
RenewDocumentCommand{parbox}{sO{c}oO{t}mm}{%
IfBooleanTF{#1}
{%
IfNoValueTF{#3}
{oldparbox[#2]{#5}{sloppysetlengthparfillskip{0pt}#6}}
{oldparbox[#2][#3][#4]{#5}{sloppysetlengthparfillskip{0pt}#6}}
}
{%
IfNoValueTF{#3}
{oldparbox[#2]{#5}{#6}}
{oldparbox[#2][#3][#4]{#5}{#6}}
}
}
begin{document}thefboxsep
AAAfbox{parbox[t]{8em}{aa bb cc dd ee ff gg hh ii}}AAA\% parbox typesets nothing why?.
BBBfbox{parbox*{6em}{aa bb cc dd ee ff}}BBB% This fails to compile
end{document}









share|improve this question




















  • 1





    An empty optional argument [] is not always the same as not giving an optional argument at all. Compare parbox[][]{4em}{aa bb cc dd ee ff} and parbox[]{4em}{aa bb cc dd ee ff}. In the xparse example things get worse because o's #1 becomes the special value -noValue- when no optional argument is given. Naturally parbox can't deal with that.

    – moewe
    1 hour ago













  • I know that the default value of #1 is [c], #3 is [t], but what is the default value of #2 which can be used to define myparbox?

    – lyl
    1 hour ago











  • Instead of worrying about the defaults, it might just be better to run three test cases and run parbox in three different ways. Then you do not need to know about the kernel defaults. Use say IfNoValueTF{#1}{true}{false} and nest several of these.

    – daleif
    33 mins ago











  • According to suggest above , I edited my MWE, but can not pass compile. why?

    – lyl
    26 mins ago
















3















I learnt that parbox has five arguments, that is: parbox[<align>][<height>][<inner-align>]{<width>}{<text>}. So I constrcut my own myparbox in which I add sloppysetlengthparfillskip{0pt} before #5. But it fails. What's the reason and how to re-define myparbox?



MWE:



documentclass{article}
usepackage{xparse}
NewDocumentCommand{myparbox}{ooomm}{%
parbox[#1][#2][#3]{#4}{sloppysetlengthparfillskip{0pt}#5}
}
begin{document}
AAAfbox{parbox[][][]{4em}{aa bb cc dd ee ff}}AAA\% parbox typesets nothing. why?
BBBfbox{myparbox{4em}{aa bb cc dd ee ff}}BBB% This fails to compile
end{document}


EDIT:



documentclass{article}
usepackage{xparse}
letoldparboxparbox
RenewDocumentCommand{parbox}{sO{c}oO{t}mm}{%
IfBooleanTF{#1}
{%
IfNoValueTF{#3}
{oldparbox[#2]{#5}{sloppysetlengthparfillskip{0pt}#6}}
{oldparbox[#2][#3][#4]{#5}{sloppysetlengthparfillskip{0pt}#6}}
}
{%
IfNoValueTF{#3}
{oldparbox[#2]{#5}{#6}}
{oldparbox[#2][#3][#4]{#5}{#6}}
}
}
begin{document}thefboxsep
AAAfbox{parbox[t]{8em}{aa bb cc dd ee ff gg hh ii}}AAA\% parbox typesets nothing why?.
BBBfbox{parbox*{6em}{aa bb cc dd ee ff}}BBB% This fails to compile
end{document}









share|improve this question




















  • 1





    An empty optional argument [] is not always the same as not giving an optional argument at all. Compare parbox[][]{4em}{aa bb cc dd ee ff} and parbox[]{4em}{aa bb cc dd ee ff}. In the xparse example things get worse because o's #1 becomes the special value -noValue- when no optional argument is given. Naturally parbox can't deal with that.

    – moewe
    1 hour ago













  • I know that the default value of #1 is [c], #3 is [t], but what is the default value of #2 which can be used to define myparbox?

    – lyl
    1 hour ago











  • Instead of worrying about the defaults, it might just be better to run three test cases and run parbox in three different ways. Then you do not need to know about the kernel defaults. Use say IfNoValueTF{#1}{true}{false} and nest several of these.

    – daleif
    33 mins ago











  • According to suggest above , I edited my MWE, but can not pass compile. why?

    – lyl
    26 mins ago














3












3








3








I learnt that parbox has five arguments, that is: parbox[<align>][<height>][<inner-align>]{<width>}{<text>}. So I constrcut my own myparbox in which I add sloppysetlengthparfillskip{0pt} before #5. But it fails. What's the reason and how to re-define myparbox?



MWE:



documentclass{article}
usepackage{xparse}
NewDocumentCommand{myparbox}{ooomm}{%
parbox[#1][#2][#3]{#4}{sloppysetlengthparfillskip{0pt}#5}
}
begin{document}
AAAfbox{parbox[][][]{4em}{aa bb cc dd ee ff}}AAA\% parbox typesets nothing. why?
BBBfbox{myparbox{4em}{aa bb cc dd ee ff}}BBB% This fails to compile
end{document}


EDIT:



documentclass{article}
usepackage{xparse}
letoldparboxparbox
RenewDocumentCommand{parbox}{sO{c}oO{t}mm}{%
IfBooleanTF{#1}
{%
IfNoValueTF{#3}
{oldparbox[#2]{#5}{sloppysetlengthparfillskip{0pt}#6}}
{oldparbox[#2][#3][#4]{#5}{sloppysetlengthparfillskip{0pt}#6}}
}
{%
IfNoValueTF{#3}
{oldparbox[#2]{#5}{#6}}
{oldparbox[#2][#3][#4]{#5}{#6}}
}
}
begin{document}thefboxsep
AAAfbox{parbox[t]{8em}{aa bb cc dd ee ff gg hh ii}}AAA\% parbox typesets nothing why?.
BBBfbox{parbox*{6em}{aa bb cc dd ee ff}}BBB% This fails to compile
end{document}









share|improve this question
















I learnt that parbox has five arguments, that is: parbox[<align>][<height>][<inner-align>]{<width>}{<text>}. So I constrcut my own myparbox in which I add sloppysetlengthparfillskip{0pt} before #5. But it fails. What's the reason and how to re-define myparbox?



MWE:



documentclass{article}
usepackage{xparse}
NewDocumentCommand{myparbox}{ooomm}{%
parbox[#1][#2][#3]{#4}{sloppysetlengthparfillskip{0pt}#5}
}
begin{document}
AAAfbox{parbox[][][]{4em}{aa bb cc dd ee ff}}AAA\% parbox typesets nothing. why?
BBBfbox{myparbox{4em}{aa bb cc dd ee ff}}BBB% This fails to compile
end{document}


EDIT:



documentclass{article}
usepackage{xparse}
letoldparboxparbox
RenewDocumentCommand{parbox}{sO{c}oO{t}mm}{%
IfBooleanTF{#1}
{%
IfNoValueTF{#3}
{oldparbox[#2]{#5}{sloppysetlengthparfillskip{0pt}#6}}
{oldparbox[#2][#3][#4]{#5}{sloppysetlengthparfillskip{0pt}#6}}
}
{%
IfNoValueTF{#3}
{oldparbox[#2]{#5}{#6}}
{oldparbox[#2][#3][#4]{#5}{#6}}
}
}
begin{document}thefboxsep
AAAfbox{parbox[t]{8em}{aa bb cc dd ee ff gg hh ii}}AAA\% parbox typesets nothing why?.
BBBfbox{parbox*{6em}{aa bb cc dd ee ff}}BBB% This fails to compile
end{document}






xparse parbox






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 29 mins ago







lyl

















asked 1 hour ago









lyllyl

62328




62328








  • 1





    An empty optional argument [] is not always the same as not giving an optional argument at all. Compare parbox[][]{4em}{aa bb cc dd ee ff} and parbox[]{4em}{aa bb cc dd ee ff}. In the xparse example things get worse because o's #1 becomes the special value -noValue- when no optional argument is given. Naturally parbox can't deal with that.

    – moewe
    1 hour ago













  • I know that the default value of #1 is [c], #3 is [t], but what is the default value of #2 which can be used to define myparbox?

    – lyl
    1 hour ago











  • Instead of worrying about the defaults, it might just be better to run three test cases and run parbox in three different ways. Then you do not need to know about the kernel defaults. Use say IfNoValueTF{#1}{true}{false} and nest several of these.

    – daleif
    33 mins ago











  • According to suggest above , I edited my MWE, but can not pass compile. why?

    – lyl
    26 mins ago














  • 1





    An empty optional argument [] is not always the same as not giving an optional argument at all. Compare parbox[][]{4em}{aa bb cc dd ee ff} and parbox[]{4em}{aa bb cc dd ee ff}. In the xparse example things get worse because o's #1 becomes the special value -noValue- when no optional argument is given. Naturally parbox can't deal with that.

    – moewe
    1 hour ago













  • I know that the default value of #1 is [c], #3 is [t], but what is the default value of #2 which can be used to define myparbox?

    – lyl
    1 hour ago











  • Instead of worrying about the defaults, it might just be better to run three test cases and run parbox in three different ways. Then you do not need to know about the kernel defaults. Use say IfNoValueTF{#1}{true}{false} and nest several of these.

    – daleif
    33 mins ago











  • According to suggest above , I edited my MWE, but can not pass compile. why?

    – lyl
    26 mins ago








1




1





An empty optional argument [] is not always the same as not giving an optional argument at all. Compare parbox[][]{4em}{aa bb cc dd ee ff} and parbox[]{4em}{aa bb cc dd ee ff}. In the xparse example things get worse because o's #1 becomes the special value -noValue- when no optional argument is given. Naturally parbox can't deal with that.

– moewe
1 hour ago







An empty optional argument [] is not always the same as not giving an optional argument at all. Compare parbox[][]{4em}{aa bb cc dd ee ff} and parbox[]{4em}{aa bb cc dd ee ff}. In the xparse example things get worse because o's #1 becomes the special value -noValue- when no optional argument is given. Naturally parbox can't deal with that.

– moewe
1 hour ago















I know that the default value of #1 is [c], #3 is [t], but what is the default value of #2 which can be used to define myparbox?

– lyl
1 hour ago





I know that the default value of #1 is [c], #3 is [t], but what is the default value of #2 which can be used to define myparbox?

– lyl
1 hour ago













Instead of worrying about the defaults, it might just be better to run three test cases and run parbox in three different ways. Then you do not need to know about the kernel defaults. Use say IfNoValueTF{#1}{true}{false} and nest several of these.

– daleif
33 mins ago





Instead of worrying about the defaults, it might just be better to run three test cases and run parbox in three different ways. Then you do not need to know about the kernel defaults. Use say IfNoValueTF{#1}{true}{false} and nest several of these.

– daleif
33 mins ago













According to suggest above , I edited my MWE, but can not pass compile. why?

– lyl
26 mins ago





According to suggest above , I edited my MWE, but can not pass compile. why?

– lyl
26 mins ago










2 Answers
2






active

oldest

votes


















7














As noted in the comments, an empty optional argument [] need not be equivalent to giving no optional argument at all. Whether not giving the argument is equivalent to passing a particular value must be checked with the documentation or implementation of the command.



In the example things get worse because xparse's optional o argument actually contain the special marked value -NoValue- if the corresponding optional argument was not given. You can and should test for presence of a value with IfNoValueTF (as suggested by daleif's comment).



That is a very viable solution when you have only one optional argument to deal with, but it gets messy if the number of arguments increases.



In case of parbox you can find out that the default arguments are c, relax as special marker and s when you look up the definition in sourc2e.pdf.



So you could try



documentclass{article}
usepackage{xparse}
NewDocumentCommand{myparbox}{O{c}O{relax}O{s}mm}{%
parbox[#1][#2][#3]{#4}{sloppysetlengthparfillskip{0pt}#5}%
}
begin{document}
BBBfbox{parbox{4em}{sloppysetlengthparfillskip{0pt}aa bb cc dd ee ff}}BBB

BBBfbox{myparbox{4em}{aa bb cc dd ee ff}}BBB
end{document}


Normally I would try to work around issues like this that require me to know the default optional argument values/behaviour and or need a great number of IfNoValueTF tests to get the arguments right as the first method seems fragile and the second very verbose and repetitive. An approach similar to Marijn's answer might be an alternative, but at least in this case also requires intimate knowledge of the definition of parbox.





edit: I only just saw the new version of the question. let is not enough for robust commands with optional arguments: When to use LetLtxMacro?. I would also strongly suggest not to redefine fundamental commands such as parbox even if the implementation might be backwards compatible. A new name is much safer.






share|improve this answer


























  • I followed your answer and edited my MWE, but failed. Could you please have look at my edited MWE?

    – lyl
    20 mins ago






  • 1





    @lyl That won't work because of the let, see the edit bit of my answer. I could get something working with letltxmacro that compiles, but there is a weird side-effect. Try with usepackage{letltxmacro}LetLtxMacro{oldparbox}{parbox} instead of letoldparboxparbox. It is a really bad idea to redefine such a fundamental command.

    – moewe
    18 mins ago













  • Many thanks!! I'll have a try.

    – lyl
    14 mins ago











  • @lyl Don't! Redefining the original parbox will not end well...

    – moewe
    14 mins ago





















2














Alternatively, you can use xpatch to insert the extra code at the right place in the command, without the need to pass variables around. The parbox command calls the internal @iiiparbox command which processes the actual contents, so this internal command is the one that should be patched. MWE:



documentclass{article}
usepackage{xpatch}
begin{document}
makeatletter
xpatchcmd{@iiiparbox}{#5}{sloppysetlengthparfillskip{0pt}#5}{}{}
makeatother
AAAfbox{parbox{4em}{aa bb cc dd ee ff}}AAA
end{document}


Note that this changes the behavior of all parboxes. If you want a custom command with the justified alignment and also keep the regular command, then you can define the custom command using a copy of the @iiiparbox command and patch the copy instead of the original. MWE:



documentclass{article}
usepackage{xpatch}
begin{document}
makeatletter
defmyparbox{@ifnextchar [@iparbox {myiiiparbox crelax [s]}}
letmyiiiparbox@iiiparbox
xpatchcmd{myiiiparbox}{#5}{sloppysetlengthparfillskip{0pt}#5}{}{}
makeatother
AAAfbox{parbox{4em}{aa bb cc dd ee ff}}AAA

BBBfbox{myparbox{4em}{aa bb cc dd ee ff}}BBB
end{document}


Result:



enter image description here






share|improve this answer
























  • Thank you for your solution with xpatch, I'll be learning this package.

    – lyl
    18 mins ago











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%2f475998%2fempty-optional-argument-or-not-giving-optional-argument-at-all%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














As noted in the comments, an empty optional argument [] need not be equivalent to giving no optional argument at all. Whether not giving the argument is equivalent to passing a particular value must be checked with the documentation or implementation of the command.



In the example things get worse because xparse's optional o argument actually contain the special marked value -NoValue- if the corresponding optional argument was not given. You can and should test for presence of a value with IfNoValueTF (as suggested by daleif's comment).



That is a very viable solution when you have only one optional argument to deal with, but it gets messy if the number of arguments increases.



In case of parbox you can find out that the default arguments are c, relax as special marker and s when you look up the definition in sourc2e.pdf.



So you could try



documentclass{article}
usepackage{xparse}
NewDocumentCommand{myparbox}{O{c}O{relax}O{s}mm}{%
parbox[#1][#2][#3]{#4}{sloppysetlengthparfillskip{0pt}#5}%
}
begin{document}
BBBfbox{parbox{4em}{sloppysetlengthparfillskip{0pt}aa bb cc dd ee ff}}BBB

BBBfbox{myparbox{4em}{aa bb cc dd ee ff}}BBB
end{document}


Normally I would try to work around issues like this that require me to know the default optional argument values/behaviour and or need a great number of IfNoValueTF tests to get the arguments right as the first method seems fragile and the second very verbose and repetitive. An approach similar to Marijn's answer might be an alternative, but at least in this case also requires intimate knowledge of the definition of parbox.





edit: I only just saw the new version of the question. let is not enough for robust commands with optional arguments: When to use LetLtxMacro?. I would also strongly suggest not to redefine fundamental commands such as parbox even if the implementation might be backwards compatible. A new name is much safer.






share|improve this answer


























  • I followed your answer and edited my MWE, but failed. Could you please have look at my edited MWE?

    – lyl
    20 mins ago






  • 1





    @lyl That won't work because of the let, see the edit bit of my answer. I could get something working with letltxmacro that compiles, but there is a weird side-effect. Try with usepackage{letltxmacro}LetLtxMacro{oldparbox}{parbox} instead of letoldparboxparbox. It is a really bad idea to redefine such a fundamental command.

    – moewe
    18 mins ago













  • Many thanks!! I'll have a try.

    – lyl
    14 mins ago











  • @lyl Don't! Redefining the original parbox will not end well...

    – moewe
    14 mins ago


















7














As noted in the comments, an empty optional argument [] need not be equivalent to giving no optional argument at all. Whether not giving the argument is equivalent to passing a particular value must be checked with the documentation or implementation of the command.



In the example things get worse because xparse's optional o argument actually contain the special marked value -NoValue- if the corresponding optional argument was not given. You can and should test for presence of a value with IfNoValueTF (as suggested by daleif's comment).



That is a very viable solution when you have only one optional argument to deal with, but it gets messy if the number of arguments increases.



In case of parbox you can find out that the default arguments are c, relax as special marker and s when you look up the definition in sourc2e.pdf.



So you could try



documentclass{article}
usepackage{xparse}
NewDocumentCommand{myparbox}{O{c}O{relax}O{s}mm}{%
parbox[#1][#2][#3]{#4}{sloppysetlengthparfillskip{0pt}#5}%
}
begin{document}
BBBfbox{parbox{4em}{sloppysetlengthparfillskip{0pt}aa bb cc dd ee ff}}BBB

BBBfbox{myparbox{4em}{aa bb cc dd ee ff}}BBB
end{document}


Normally I would try to work around issues like this that require me to know the default optional argument values/behaviour and or need a great number of IfNoValueTF tests to get the arguments right as the first method seems fragile and the second very verbose and repetitive. An approach similar to Marijn's answer might be an alternative, but at least in this case also requires intimate knowledge of the definition of parbox.





edit: I only just saw the new version of the question. let is not enough for robust commands with optional arguments: When to use LetLtxMacro?. I would also strongly suggest not to redefine fundamental commands such as parbox even if the implementation might be backwards compatible. A new name is much safer.






share|improve this answer


























  • I followed your answer and edited my MWE, but failed. Could you please have look at my edited MWE?

    – lyl
    20 mins ago






  • 1





    @lyl That won't work because of the let, see the edit bit of my answer. I could get something working with letltxmacro that compiles, but there is a weird side-effect. Try with usepackage{letltxmacro}LetLtxMacro{oldparbox}{parbox} instead of letoldparboxparbox. It is a really bad idea to redefine such a fundamental command.

    – moewe
    18 mins ago













  • Many thanks!! I'll have a try.

    – lyl
    14 mins ago











  • @lyl Don't! Redefining the original parbox will not end well...

    – moewe
    14 mins ago
















7












7








7







As noted in the comments, an empty optional argument [] need not be equivalent to giving no optional argument at all. Whether not giving the argument is equivalent to passing a particular value must be checked with the documentation or implementation of the command.



In the example things get worse because xparse's optional o argument actually contain the special marked value -NoValue- if the corresponding optional argument was not given. You can and should test for presence of a value with IfNoValueTF (as suggested by daleif's comment).



That is a very viable solution when you have only one optional argument to deal with, but it gets messy if the number of arguments increases.



In case of parbox you can find out that the default arguments are c, relax as special marker and s when you look up the definition in sourc2e.pdf.



So you could try



documentclass{article}
usepackage{xparse}
NewDocumentCommand{myparbox}{O{c}O{relax}O{s}mm}{%
parbox[#1][#2][#3]{#4}{sloppysetlengthparfillskip{0pt}#5}%
}
begin{document}
BBBfbox{parbox{4em}{sloppysetlengthparfillskip{0pt}aa bb cc dd ee ff}}BBB

BBBfbox{myparbox{4em}{aa bb cc dd ee ff}}BBB
end{document}


Normally I would try to work around issues like this that require me to know the default optional argument values/behaviour and or need a great number of IfNoValueTF tests to get the arguments right as the first method seems fragile and the second very verbose and repetitive. An approach similar to Marijn's answer might be an alternative, but at least in this case also requires intimate knowledge of the definition of parbox.





edit: I only just saw the new version of the question. let is not enough for robust commands with optional arguments: When to use LetLtxMacro?. I would also strongly suggest not to redefine fundamental commands such as parbox even if the implementation might be backwards compatible. A new name is much safer.






share|improve this answer















As noted in the comments, an empty optional argument [] need not be equivalent to giving no optional argument at all. Whether not giving the argument is equivalent to passing a particular value must be checked with the documentation or implementation of the command.



In the example things get worse because xparse's optional o argument actually contain the special marked value -NoValue- if the corresponding optional argument was not given. You can and should test for presence of a value with IfNoValueTF (as suggested by daleif's comment).



That is a very viable solution when you have only one optional argument to deal with, but it gets messy if the number of arguments increases.



In case of parbox you can find out that the default arguments are c, relax as special marker and s when you look up the definition in sourc2e.pdf.



So you could try



documentclass{article}
usepackage{xparse}
NewDocumentCommand{myparbox}{O{c}O{relax}O{s}mm}{%
parbox[#1][#2][#3]{#4}{sloppysetlengthparfillskip{0pt}#5}%
}
begin{document}
BBBfbox{parbox{4em}{sloppysetlengthparfillskip{0pt}aa bb cc dd ee ff}}BBB

BBBfbox{myparbox{4em}{aa bb cc dd ee ff}}BBB
end{document}


Normally I would try to work around issues like this that require me to know the default optional argument values/behaviour and or need a great number of IfNoValueTF tests to get the arguments right as the first method seems fragile and the second very verbose and repetitive. An approach similar to Marijn's answer might be an alternative, but at least in this case also requires intimate knowledge of the definition of parbox.





edit: I only just saw the new version of the question. let is not enough for robust commands with optional arguments: When to use LetLtxMacro?. I would also strongly suggest not to redefine fundamental commands such as parbox even if the implementation might be backwards compatible. A new name is much safer.







share|improve this answer














share|improve this answer



share|improve this answer








edited 15 mins ago

























answered 27 mins ago









moewemoewe

91.5k10114346




91.5k10114346













  • I followed your answer and edited my MWE, but failed. Could you please have look at my edited MWE?

    – lyl
    20 mins ago






  • 1





    @lyl That won't work because of the let, see the edit bit of my answer. I could get something working with letltxmacro that compiles, but there is a weird side-effect. Try with usepackage{letltxmacro}LetLtxMacro{oldparbox}{parbox} instead of letoldparboxparbox. It is a really bad idea to redefine such a fundamental command.

    – moewe
    18 mins ago













  • Many thanks!! I'll have a try.

    – lyl
    14 mins ago











  • @lyl Don't! Redefining the original parbox will not end well...

    – moewe
    14 mins ago





















  • I followed your answer and edited my MWE, but failed. Could you please have look at my edited MWE?

    – lyl
    20 mins ago






  • 1





    @lyl That won't work because of the let, see the edit bit of my answer. I could get something working with letltxmacro that compiles, but there is a weird side-effect. Try with usepackage{letltxmacro}LetLtxMacro{oldparbox}{parbox} instead of letoldparboxparbox. It is a really bad idea to redefine such a fundamental command.

    – moewe
    18 mins ago













  • Many thanks!! I'll have a try.

    – lyl
    14 mins ago











  • @lyl Don't! Redefining the original parbox will not end well...

    – moewe
    14 mins ago



















I followed your answer and edited my MWE, but failed. Could you please have look at my edited MWE?

– lyl
20 mins ago





I followed your answer and edited my MWE, but failed. Could you please have look at my edited MWE?

– lyl
20 mins ago




1




1





@lyl That won't work because of the let, see the edit bit of my answer. I could get something working with letltxmacro that compiles, but there is a weird side-effect. Try with usepackage{letltxmacro}LetLtxMacro{oldparbox}{parbox} instead of letoldparboxparbox. It is a really bad idea to redefine such a fundamental command.

– moewe
18 mins ago







@lyl That won't work because of the let, see the edit bit of my answer. I could get something working with letltxmacro that compiles, but there is a weird side-effect. Try with usepackage{letltxmacro}LetLtxMacro{oldparbox}{parbox} instead of letoldparboxparbox. It is a really bad idea to redefine such a fundamental command.

– moewe
18 mins ago















Many thanks!! I'll have a try.

– lyl
14 mins ago





Many thanks!! I'll have a try.

– lyl
14 mins ago













@lyl Don't! Redefining the original parbox will not end well...

– moewe
14 mins ago







@lyl Don't! Redefining the original parbox will not end well...

– moewe
14 mins ago













2














Alternatively, you can use xpatch to insert the extra code at the right place in the command, without the need to pass variables around. The parbox command calls the internal @iiiparbox command which processes the actual contents, so this internal command is the one that should be patched. MWE:



documentclass{article}
usepackage{xpatch}
begin{document}
makeatletter
xpatchcmd{@iiiparbox}{#5}{sloppysetlengthparfillskip{0pt}#5}{}{}
makeatother
AAAfbox{parbox{4em}{aa bb cc dd ee ff}}AAA
end{document}


Note that this changes the behavior of all parboxes. If you want a custom command with the justified alignment and also keep the regular command, then you can define the custom command using a copy of the @iiiparbox command and patch the copy instead of the original. MWE:



documentclass{article}
usepackage{xpatch}
begin{document}
makeatletter
defmyparbox{@ifnextchar [@iparbox {myiiiparbox crelax [s]}}
letmyiiiparbox@iiiparbox
xpatchcmd{myiiiparbox}{#5}{sloppysetlengthparfillskip{0pt}#5}{}{}
makeatother
AAAfbox{parbox{4em}{aa bb cc dd ee ff}}AAA

BBBfbox{myparbox{4em}{aa bb cc dd ee ff}}BBB
end{document}


Result:



enter image description here






share|improve this answer
























  • Thank you for your solution with xpatch, I'll be learning this package.

    – lyl
    18 mins ago
















2














Alternatively, you can use xpatch to insert the extra code at the right place in the command, without the need to pass variables around. The parbox command calls the internal @iiiparbox command which processes the actual contents, so this internal command is the one that should be patched. MWE:



documentclass{article}
usepackage{xpatch}
begin{document}
makeatletter
xpatchcmd{@iiiparbox}{#5}{sloppysetlengthparfillskip{0pt}#5}{}{}
makeatother
AAAfbox{parbox{4em}{aa bb cc dd ee ff}}AAA
end{document}


Note that this changes the behavior of all parboxes. If you want a custom command with the justified alignment and also keep the regular command, then you can define the custom command using a copy of the @iiiparbox command and patch the copy instead of the original. MWE:



documentclass{article}
usepackage{xpatch}
begin{document}
makeatletter
defmyparbox{@ifnextchar [@iparbox {myiiiparbox crelax [s]}}
letmyiiiparbox@iiiparbox
xpatchcmd{myiiiparbox}{#5}{sloppysetlengthparfillskip{0pt}#5}{}{}
makeatother
AAAfbox{parbox{4em}{aa bb cc dd ee ff}}AAA

BBBfbox{myparbox{4em}{aa bb cc dd ee ff}}BBB
end{document}


Result:



enter image description here






share|improve this answer
























  • Thank you for your solution with xpatch, I'll be learning this package.

    – lyl
    18 mins ago














2












2








2







Alternatively, you can use xpatch to insert the extra code at the right place in the command, without the need to pass variables around. The parbox command calls the internal @iiiparbox command which processes the actual contents, so this internal command is the one that should be patched. MWE:



documentclass{article}
usepackage{xpatch}
begin{document}
makeatletter
xpatchcmd{@iiiparbox}{#5}{sloppysetlengthparfillskip{0pt}#5}{}{}
makeatother
AAAfbox{parbox{4em}{aa bb cc dd ee ff}}AAA
end{document}


Note that this changes the behavior of all parboxes. If you want a custom command with the justified alignment and also keep the regular command, then you can define the custom command using a copy of the @iiiparbox command and patch the copy instead of the original. MWE:



documentclass{article}
usepackage{xpatch}
begin{document}
makeatletter
defmyparbox{@ifnextchar [@iparbox {myiiiparbox crelax [s]}}
letmyiiiparbox@iiiparbox
xpatchcmd{myiiiparbox}{#5}{sloppysetlengthparfillskip{0pt}#5}{}{}
makeatother
AAAfbox{parbox{4em}{aa bb cc dd ee ff}}AAA

BBBfbox{myparbox{4em}{aa bb cc dd ee ff}}BBB
end{document}


Result:



enter image description here






share|improve this answer













Alternatively, you can use xpatch to insert the extra code at the right place in the command, without the need to pass variables around. The parbox command calls the internal @iiiparbox command which processes the actual contents, so this internal command is the one that should be patched. MWE:



documentclass{article}
usepackage{xpatch}
begin{document}
makeatletter
xpatchcmd{@iiiparbox}{#5}{sloppysetlengthparfillskip{0pt}#5}{}{}
makeatother
AAAfbox{parbox{4em}{aa bb cc dd ee ff}}AAA
end{document}


Note that this changes the behavior of all parboxes. If you want a custom command with the justified alignment and also keep the regular command, then you can define the custom command using a copy of the @iiiparbox command and patch the copy instead of the original. MWE:



documentclass{article}
usepackage{xpatch}
begin{document}
makeatletter
defmyparbox{@ifnextchar [@iparbox {myiiiparbox crelax [s]}}
letmyiiiparbox@iiiparbox
xpatchcmd{myiiiparbox}{#5}{sloppysetlengthparfillskip{0pt}#5}{}{}
makeatother
AAAfbox{parbox{4em}{aa bb cc dd ee ff}}AAA

BBBfbox{myparbox{4em}{aa bb cc dd ee ff}}BBB
end{document}


Result:



enter image description here







share|improve this answer












share|improve this answer



share|improve this answer










answered 24 mins ago









MarijnMarijn

7,819636




7,819636













  • Thank you for your solution with xpatch, I'll be learning this package.

    – lyl
    18 mins ago



















  • Thank you for your solution with xpatch, I'll be learning this package.

    – lyl
    18 mins ago

















Thank you for your solution with xpatch, I'll be learning this package.

– lyl
18 mins ago





Thank you for your solution with xpatch, I'll be learning this package.

– lyl
18 mins ago


















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%2f475998%2fempty-optional-argument-or-not-giving-optional-argument-at-all%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

Parapolítica Índice Antecedentes El escándalo Proceso judicial Consecuencias Véase...

How to remove border from elements in the last row?Targeting flex items on the last rowHow to vertically wrap...

Tecnologías entrañables Índice Antecedentes Desarrollo Tecnologías Entrañables en la...