A curious dependency between newcommand and curly braces
An example is a bit artificial, but the point is that I do not understand why
{}
influence the outcome of newcommand
in the way described below.
Consider the following definition:
newcommandprintit[1]{#1}
whose outcome is obvious. However, a small alteration:
newcommand{printit[1]}{#1}
and e.g. printit{2}
yields:
I have no idea why. Could you please shed some light on what is going on here?
macros braces grouping
add a comment |
An example is a bit artificial, but the point is that I do not understand why
{}
influence the outcome of newcommand
in the way described below.
Consider the following definition:
newcommandprintit[1]{#1}
whose outcome is obvious. However, a small alteration:
newcommand{printit[1]}{#1}
and e.g. printit{2}
yields:
I have no idea why. Could you please shed some light on what is going on here?
macros braces grouping
1
defnew@command#1{% @testopt{@newcommand#1}0}
from latex.ltx, i.e. LaTeX tests whether there is an optional argument in the first argument ofnewcommand
, i.e.printit[1]
and returns0
, the{2}
in its usage is not regarded as an argument. You could useprintit
without{}
and it will still print0
, use it asprintit[2]
and it will print2
. In fact you have defined a macro with optional arguments in a non-obvious way
– Christian Hupfer
17 hours ago
The correct syntax isnewcommandprintit[1]{#1}
ornewcommand{printit}[1]{#1}
(The number of parameters to be expected is given in square brackets, outside of the{}
). In case people come across this and are confused by the above syntax.
– Peter Grill
17 hours ago
@PeterGrill Yes, I know the correct syntax. But I was curious why grouping printit[1] results in the (rather unexpected) outcome.
– Mad Hatter
15 hours ago
@MadHatter: Yep, I figured that. My comment was intended for others who may come across this and be confused.
– Peter Grill
14 hours ago
add a comment |
An example is a bit artificial, but the point is that I do not understand why
{}
influence the outcome of newcommand
in the way described below.
Consider the following definition:
newcommandprintit[1]{#1}
whose outcome is obvious. However, a small alteration:
newcommand{printit[1]}{#1}
and e.g. printit{2}
yields:
I have no idea why. Could you please shed some light on what is going on here?
macros braces grouping
An example is a bit artificial, but the point is that I do not understand why
{}
influence the outcome of newcommand
in the way described below.
Consider the following definition:
newcommandprintit[1]{#1}
whose outcome is obvious. However, a small alteration:
newcommand{printit[1]}{#1}
and e.g. printit{2}
yields:
I have no idea why. Could you please shed some light on what is going on here?
macros braces grouping
macros braces grouping
edited 5 hours ago
Mad Hatter
asked 17 hours ago
Mad HatterMad Hatter
600420
600420
1
defnew@command#1{% @testopt{@newcommand#1}0}
from latex.ltx, i.e. LaTeX tests whether there is an optional argument in the first argument ofnewcommand
, i.e.printit[1]
and returns0
, the{2}
in its usage is not regarded as an argument. You could useprintit
without{}
and it will still print0
, use it asprintit[2]
and it will print2
. In fact you have defined a macro with optional arguments in a non-obvious way
– Christian Hupfer
17 hours ago
The correct syntax isnewcommandprintit[1]{#1}
ornewcommand{printit}[1]{#1}
(The number of parameters to be expected is given in square brackets, outside of the{}
). In case people come across this and are confused by the above syntax.
– Peter Grill
17 hours ago
@PeterGrill Yes, I know the correct syntax. But I was curious why grouping printit[1] results in the (rather unexpected) outcome.
– Mad Hatter
15 hours ago
@MadHatter: Yep, I figured that. My comment was intended for others who may come across this and be confused.
– Peter Grill
14 hours ago
add a comment |
1
defnew@command#1{% @testopt{@newcommand#1}0}
from latex.ltx, i.e. LaTeX tests whether there is an optional argument in the first argument ofnewcommand
, i.e.printit[1]
and returns0
, the{2}
in its usage is not regarded as an argument. You could useprintit
without{}
and it will still print0
, use it asprintit[2]
and it will print2
. In fact you have defined a macro with optional arguments in a non-obvious way
– Christian Hupfer
17 hours ago
The correct syntax isnewcommandprintit[1]{#1}
ornewcommand{printit}[1]{#1}
(The number of parameters to be expected is given in square brackets, outside of the{}
). In case people come across this and are confused by the above syntax.
– Peter Grill
17 hours ago
@PeterGrill Yes, I know the correct syntax. But I was curious why grouping printit[1] results in the (rather unexpected) outcome.
– Mad Hatter
15 hours ago
@MadHatter: Yep, I figured that. My comment was intended for others who may come across this and be confused.
– Peter Grill
14 hours ago
1
1
defnew@command#1{% @testopt{@newcommand#1}0}
from latex.ltx, i.e. LaTeX tests whether there is an optional argument in the first argument of newcommand
, i.e. printit[1]
and returns 0
, the {2}
in its usage is not regarded as an argument. You could use printit
without {}
and it will still print 0
, use it as printit[2]
and it will print 2
. In fact you have defined a macro with optional arguments in a non-obvious way– Christian Hupfer
17 hours ago
defnew@command#1{% @testopt{@newcommand#1}0}
from latex.ltx, i.e. LaTeX tests whether there is an optional argument in the first argument of newcommand
, i.e. printit[1]
and returns 0
, the {2}
in its usage is not regarded as an argument. You could use printit
without {}
and it will still print 0
, use it as printit[2]
and it will print 2
. In fact you have defined a macro with optional arguments in a non-obvious way– Christian Hupfer
17 hours ago
The correct syntax is
newcommandprintit[1]{#1}
or newcommand{printit}[1]{#1}
(The number of parameters to be expected is given in square brackets, outside of the {}
). In case people come across this and are confused by the above syntax.– Peter Grill
17 hours ago
The correct syntax is
newcommandprintit[1]{#1}
or newcommand{printit}[1]{#1}
(The number of parameters to be expected is given in square brackets, outside of the {}
). In case people come across this and are confused by the above syntax.– Peter Grill
17 hours ago
@PeterGrill Yes, I know the correct syntax. But I was curious why grouping printit[1] results in the (rather unexpected) outcome.
– Mad Hatter
15 hours ago
@PeterGrill Yes, I know the correct syntax. But I was curious why grouping printit[1] results in the (rather unexpected) outcome.
– Mad Hatter
15 hours ago
@MadHatter: Yep, I figured that. My comment was intended for others who may come across this and be confused.
– Peter Grill
14 hours ago
@MadHatter: Yep, I figured that. My comment was intended for others who may come across this and be confused.
– Peter Grill
14 hours ago
add a comment |
1 Answer
1
active
oldest
votes
If LaTeX was being written now,
newcommand{printit[1]}{#1}
would give an error message that printit[1]
was not a single token.
The correct syntax is
newcommand{printit}[1]{#1}
or
newcommandprintit[1]{#1}
LaTeX does nothing special to allow both forms, it is just on the general TeX macro syntax rules that braces can be omitted if a macro argument is a single token.
If you pass two (or in this case, four) tokens to newcommand
then anything that happens is essentially just accidental behaviour, as the system could not really afford the space or time required to catch "unlikely" errors.
As to what happens,
documentclass{article}
begin{document}
newcommand{printit[1]}{#1}
showprintit
expandaftershowcsnamestringprintitendcsname
end{document}
produces the terminal log
> printit=macro:
->@protected@testopt printit \printit {0}.
l.7 showprintit
?
> \printit=long macro:
[#1]->#1.
The command defines printit
to have an optional first argument, although the default value of 0 being supplied was intended as the default value for newcommand
itself.
it is what makes newcommandfoo
the same as newcommandfoo[0]
and define a command with no arguments.
The inner part of the command handling the optional argument is \printit
which just drops the square brackets.
So
printit{2}
is
printit[0]{2}
which is
0{2}
which typesets as 02
Thanks for a thorough explanation!
– Mad Hatter
15 hours ago
What about LaTeX3, which is being written now? ;-)
– Socob
11 hours ago
1
@Socob I hadn't actually checked but addusepackage{xparse}
and replacenewcommand
byNewDocumentCommand
and you get! LaTeX3 Error: First argument of 'NewDocumentCommand' must be a command.
– David Carlisle
5 hours ago
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "85"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f469994%2fa-curious-dependency-between-newcommand-and-curly-braces%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
If LaTeX was being written now,
newcommand{printit[1]}{#1}
would give an error message that printit[1]
was not a single token.
The correct syntax is
newcommand{printit}[1]{#1}
or
newcommandprintit[1]{#1}
LaTeX does nothing special to allow both forms, it is just on the general TeX macro syntax rules that braces can be omitted if a macro argument is a single token.
If you pass two (or in this case, four) tokens to newcommand
then anything that happens is essentially just accidental behaviour, as the system could not really afford the space or time required to catch "unlikely" errors.
As to what happens,
documentclass{article}
begin{document}
newcommand{printit[1]}{#1}
showprintit
expandaftershowcsnamestringprintitendcsname
end{document}
produces the terminal log
> printit=macro:
->@protected@testopt printit \printit {0}.
l.7 showprintit
?
> \printit=long macro:
[#1]->#1.
The command defines printit
to have an optional first argument, although the default value of 0 being supplied was intended as the default value for newcommand
itself.
it is what makes newcommandfoo
the same as newcommandfoo[0]
and define a command with no arguments.
The inner part of the command handling the optional argument is \printit
which just drops the square brackets.
So
printit{2}
is
printit[0]{2}
which is
0{2}
which typesets as 02
Thanks for a thorough explanation!
– Mad Hatter
15 hours ago
What about LaTeX3, which is being written now? ;-)
– Socob
11 hours ago
1
@Socob I hadn't actually checked but addusepackage{xparse}
and replacenewcommand
byNewDocumentCommand
and you get! LaTeX3 Error: First argument of 'NewDocumentCommand' must be a command.
– David Carlisle
5 hours ago
add a comment |
If LaTeX was being written now,
newcommand{printit[1]}{#1}
would give an error message that printit[1]
was not a single token.
The correct syntax is
newcommand{printit}[1]{#1}
or
newcommandprintit[1]{#1}
LaTeX does nothing special to allow both forms, it is just on the general TeX macro syntax rules that braces can be omitted if a macro argument is a single token.
If you pass two (or in this case, four) tokens to newcommand
then anything that happens is essentially just accidental behaviour, as the system could not really afford the space or time required to catch "unlikely" errors.
As to what happens,
documentclass{article}
begin{document}
newcommand{printit[1]}{#1}
showprintit
expandaftershowcsnamestringprintitendcsname
end{document}
produces the terminal log
> printit=macro:
->@protected@testopt printit \printit {0}.
l.7 showprintit
?
> \printit=long macro:
[#1]->#1.
The command defines printit
to have an optional first argument, although the default value of 0 being supplied was intended as the default value for newcommand
itself.
it is what makes newcommandfoo
the same as newcommandfoo[0]
and define a command with no arguments.
The inner part of the command handling the optional argument is \printit
which just drops the square brackets.
So
printit{2}
is
printit[0]{2}
which is
0{2}
which typesets as 02
Thanks for a thorough explanation!
– Mad Hatter
15 hours ago
What about LaTeX3, which is being written now? ;-)
– Socob
11 hours ago
1
@Socob I hadn't actually checked but addusepackage{xparse}
and replacenewcommand
byNewDocumentCommand
and you get! LaTeX3 Error: First argument of 'NewDocumentCommand' must be a command.
– David Carlisle
5 hours ago
add a comment |
If LaTeX was being written now,
newcommand{printit[1]}{#1}
would give an error message that printit[1]
was not a single token.
The correct syntax is
newcommand{printit}[1]{#1}
or
newcommandprintit[1]{#1}
LaTeX does nothing special to allow both forms, it is just on the general TeX macro syntax rules that braces can be omitted if a macro argument is a single token.
If you pass two (or in this case, four) tokens to newcommand
then anything that happens is essentially just accidental behaviour, as the system could not really afford the space or time required to catch "unlikely" errors.
As to what happens,
documentclass{article}
begin{document}
newcommand{printit[1]}{#1}
showprintit
expandaftershowcsnamestringprintitendcsname
end{document}
produces the terminal log
> printit=macro:
->@protected@testopt printit \printit {0}.
l.7 showprintit
?
> \printit=long macro:
[#1]->#1.
The command defines printit
to have an optional first argument, although the default value of 0 being supplied was intended as the default value for newcommand
itself.
it is what makes newcommandfoo
the same as newcommandfoo[0]
and define a command with no arguments.
The inner part of the command handling the optional argument is \printit
which just drops the square brackets.
So
printit{2}
is
printit[0]{2}
which is
0{2}
which typesets as 02
If LaTeX was being written now,
newcommand{printit[1]}{#1}
would give an error message that printit[1]
was not a single token.
The correct syntax is
newcommand{printit}[1]{#1}
or
newcommandprintit[1]{#1}
LaTeX does nothing special to allow both forms, it is just on the general TeX macro syntax rules that braces can be omitted if a macro argument is a single token.
If you pass two (or in this case, four) tokens to newcommand
then anything that happens is essentially just accidental behaviour, as the system could not really afford the space or time required to catch "unlikely" errors.
As to what happens,
documentclass{article}
begin{document}
newcommand{printit[1]}{#1}
showprintit
expandaftershowcsnamestringprintitendcsname
end{document}
produces the terminal log
> printit=macro:
->@protected@testopt printit \printit {0}.
l.7 showprintit
?
> \printit=long macro:
[#1]->#1.
The command defines printit
to have an optional first argument, although the default value of 0 being supplied was intended as the default value for newcommand
itself.
it is what makes newcommandfoo
the same as newcommandfoo[0]
and define a command with no arguments.
The inner part of the command handling the optional argument is \printit
which just drops the square brackets.
So
printit{2}
is
printit[0]{2}
which is
0{2}
which typesets as 02
edited 15 hours ago
answered 16 hours ago
David CarlisleDavid Carlisle
485k4111201863
485k4111201863
Thanks for a thorough explanation!
– Mad Hatter
15 hours ago
What about LaTeX3, which is being written now? ;-)
– Socob
11 hours ago
1
@Socob I hadn't actually checked but addusepackage{xparse}
and replacenewcommand
byNewDocumentCommand
and you get! LaTeX3 Error: First argument of 'NewDocumentCommand' must be a command.
– David Carlisle
5 hours ago
add a comment |
Thanks for a thorough explanation!
– Mad Hatter
15 hours ago
What about LaTeX3, which is being written now? ;-)
– Socob
11 hours ago
1
@Socob I hadn't actually checked but addusepackage{xparse}
and replacenewcommand
byNewDocumentCommand
and you get! LaTeX3 Error: First argument of 'NewDocumentCommand' must be a command.
– David Carlisle
5 hours ago
Thanks for a thorough explanation!
– Mad Hatter
15 hours ago
Thanks for a thorough explanation!
– Mad Hatter
15 hours ago
What about LaTeX3, which is being written now? ;-)
– Socob
11 hours ago
What about LaTeX3, which is being written now? ;-)
– Socob
11 hours ago
1
1
@Socob I hadn't actually checked but add
usepackage{xparse}
and replace newcommand
by NewDocumentCommand
and you get ! LaTeX3 Error: First argument of 'NewDocumentCommand' must be a command.
– David Carlisle
5 hours ago
@Socob I hadn't actually checked but add
usepackage{xparse}
and replace newcommand
by NewDocumentCommand
and you get ! LaTeX3 Error: First argument of 'NewDocumentCommand' must be a command.
– David Carlisle
5 hours ago
add a comment |
Thanks for contributing an answer to TeX - LaTeX Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f469994%2fa-curious-dependency-between-newcommand-and-curly-braces%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
defnew@command#1{% @testopt{@newcommand#1}0}
from latex.ltx, i.e. LaTeX tests whether there is an optional argument in the first argument ofnewcommand
, i.e.printit[1]
and returns0
, the{2}
in its usage is not regarded as an argument. You could useprintit
without{}
and it will still print0
, use it asprintit[2]
and it will print2
. In fact you have defined a macro with optional arguments in a non-obvious way– Christian Hupfer
17 hours ago
The correct syntax is
newcommandprintit[1]{#1}
ornewcommand{printit}[1]{#1}
(The number of parameters to be expected is given in square brackets, outside of the{}
). In case people come across this and are confused by the above syntax.– Peter Grill
17 hours ago
@PeterGrill Yes, I know the correct syntax. But I was curious why grouping printit[1] results in the (rather unexpected) outcome.
– Mad Hatter
15 hours ago
@MadHatter: Yep, I figured that. My comment was intended for others who may come across this and be confused.
– Peter Grill
14 hours ago