What is “# Notation”? How does the # syntax work?
Closely Related: How to implement expandbefore, similarly to expandafter?
In the related question, a reference is made to the "# Notation"
. How does the syntax work?
From an answer on the other question:
makeatletter
%
newcommandname{}%
longdefname#1#{UD@innername{#1}}%
%
newcommandUD@innername[2]{%
expandafterUD@exchangeexpandafter{csname#2endcsname}{#1}%
}%
%
newcommandUD@exchange[2]{#2#1}%
%
makeatother
How does the parameter syntax, (without a number), actually work? deftest#1#{csname test#1endcsname}? What are good use cases to use this pattern?
macros syntax primitives
|
show 7 more comments
Closely Related: How to implement expandbefore, similarly to expandafter?
In the related question, a reference is made to the "# Notation"
. How does the syntax work?
From an answer on the other question:
makeatletter
%
newcommandname{}%
longdefname#1#{UD@innername{#1}}%
%
newcommandUD@innername[2]{%
expandafterUD@exchangeexpandafter{csname#2endcsname}{#1}%
}%
%
newcommandUD@exchange[2]{#2#1}%
%
makeatother
How does the parameter syntax, (without a number), actually work? deftest#1#{csname test#1endcsname}? What are good use cases to use this pattern?
macros syntax primitives
2
#1
,#2
, etc. are the arguments. For example, if you havenewcommand{mycommand}[2]{#1 and #2}
andmycommand{Hello}{world}
you will get "Hello and world".
– JouleV
13 hours ago
Could you highlight what you want to know?
– TeXnician
13 hours ago
In absence of the TeXbook you could have a look at §11.5.6 Brace delimiting in TeX by Topic, though the passage is not very long.
– moewe
13 hours ago
1
The#1#
is a nice bracing trick but definitely not fundamental syntax (the usualdef
s work without the second#
). That's why I asked what exactly your question is.
– TeXnician
13 hours ago
1
See tex.stackexchange.com/a/474903/2388 for an explanation about the #1# syntax.
– Ulrike Fischer
12 hours ago
|
show 7 more comments
Closely Related: How to implement expandbefore, similarly to expandafter?
In the related question, a reference is made to the "# Notation"
. How does the syntax work?
From an answer on the other question:
makeatletter
%
newcommandname{}%
longdefname#1#{UD@innername{#1}}%
%
newcommandUD@innername[2]{%
expandafterUD@exchangeexpandafter{csname#2endcsname}{#1}%
}%
%
newcommandUD@exchange[2]{#2#1}%
%
makeatother
How does the parameter syntax, (without a number), actually work? deftest#1#{csname test#1endcsname}? What are good use cases to use this pattern?
macros syntax primitives
Closely Related: How to implement expandbefore, similarly to expandafter?
In the related question, a reference is made to the "# Notation"
. How does the syntax work?
From an answer on the other question:
makeatletter
%
newcommandname{}%
longdefname#1#{UD@innername{#1}}%
%
newcommandUD@innername[2]{%
expandafterUD@exchangeexpandafter{csname#2endcsname}{#1}%
}%
%
newcommandUD@exchange[2]{#2#1}%
%
makeatother
How does the parameter syntax, (without a number), actually work? deftest#1#{csname test#1endcsname}? What are good use cases to use this pattern?
macros syntax primitives
macros syntax primitives
edited 13 hours ago
elika kohen
asked 13 hours ago
elika kohenelika kohen
1376
1376
2
#1
,#2
, etc. are the arguments. For example, if you havenewcommand{mycommand}[2]{#1 and #2}
andmycommand{Hello}{world}
you will get "Hello and world".
– JouleV
13 hours ago
Could you highlight what you want to know?
– TeXnician
13 hours ago
In absence of the TeXbook you could have a look at §11.5.6 Brace delimiting in TeX by Topic, though the passage is not very long.
– moewe
13 hours ago
1
The#1#
is a nice bracing trick but definitely not fundamental syntax (the usualdef
s work without the second#
). That's why I asked what exactly your question is.
– TeXnician
13 hours ago
1
See tex.stackexchange.com/a/474903/2388 for an explanation about the #1# syntax.
– Ulrike Fischer
12 hours ago
|
show 7 more comments
2
#1
,#2
, etc. are the arguments. For example, if you havenewcommand{mycommand}[2]{#1 and #2}
andmycommand{Hello}{world}
you will get "Hello and world".
– JouleV
13 hours ago
Could you highlight what you want to know?
– TeXnician
13 hours ago
In absence of the TeXbook you could have a look at §11.5.6 Brace delimiting in TeX by Topic, though the passage is not very long.
– moewe
13 hours ago
1
The#1#
is a nice bracing trick but definitely not fundamental syntax (the usualdef
s work without the second#
). That's why I asked what exactly your question is.
– TeXnician
13 hours ago
1
See tex.stackexchange.com/a/474903/2388 for an explanation about the #1# syntax.
– Ulrike Fischer
12 hours ago
2
2
#1
, #2
, etc. are the arguments. For example, if you have newcommand{mycommand}[2]{#1 and #2}
and mycommand{Hello}{world}
you will get "Hello and world".– JouleV
13 hours ago
#1
, #2
, etc. are the arguments. For example, if you have newcommand{mycommand}[2]{#1 and #2}
and mycommand{Hello}{world}
you will get "Hello and world".– JouleV
13 hours ago
Could you highlight what you want to know?
– TeXnician
13 hours ago
Could you highlight what you want to know?
– TeXnician
13 hours ago
In absence of the TeXbook you could have a look at §11.5.6 Brace delimiting in TeX by Topic, though the passage is not very long.
– moewe
13 hours ago
In absence of the TeXbook you could have a look at §11.5.6 Brace delimiting in TeX by Topic, though the passage is not very long.
– moewe
13 hours ago
1
1
The
#1#
is a nice bracing trick but definitely not fundamental syntax (the usual def
s work without the second #
). That's why I asked what exactly your question is.– TeXnician
13 hours ago
The
#1#
is a nice bracing trick but definitely not fundamental syntax (the usual def
s work without the second #
). That's why I asked what exactly your question is.– TeXnician
13 hours ago
1
1
See tex.stackexchange.com/a/474903/2388 for an explanation about the #1# syntax.
– Ulrike Fischer
12 hours ago
See tex.stackexchange.com/a/474903/2388 for an explanation about the #1# syntax.
– Ulrike Fischer
12 hours ago
|
show 7 more comments
1 Answer
1
active
oldest
votes
The gist of name
is:
With
name⟨stuff without braces before the left-brace⟩{⟨stuff within braces⟩}
TeX shall as first argument fetch ⟨stuff without braces before the left-brace⟩
and as second argument process ⟨stuff within braces⟩
:
The ⟨stuff within braces⟩
is taken for the name of a control-sequence-token which can be obtained via wrapping ⟨stuff within braces⟩
into csname..endcsname
and carrying out the resulting csname..endcsname
-expression.
Instead of {⟨stuff within braces⟩}
that control-sequence-token will be behind ⟨stuff without braces before the left-brace⟩
.
When macros with delimited arguments get carried out, (La)TeX gathers the tokens forming the arguments from the token-stream and hereby in the token-stream searches the argument-delimiters as the argument-delimiters are taken for markers for ending the process of gathering tokens for the argument in question.
What delimiters are to be searched is to be denoted in the ⟨parameter text⟩ of the definition.
You can denote that (La)TeX shall search as delimiter for the last argument, e.g., a relax
by writing relax
as the last thing of the ⟨parameter text⟩.
You can denote that as delimiter for the last argument (La)TeX shall search a left-brace by writing #
as the last thing of the ⟨parameter text⟩.
In (almost ;-) ) any case the ⟨parameter text⟩ of a macro-definition is followed by the ⟨replacement text⟩, nested in braces.
Thus in any case the ⟨parameter text⟩ of a macro-definition will be trailed by the left-brace of the pair of braces that surrounds the ⟨replacement text⟩.
Thus when the last token of the ⟨parameter text⟩ is a #
, it will be trailed by a {
.
That's why this thingie for denoting that (La)TeX shall search for a left-brace as the delimiter when gathering the last argument for the macro, is also called #{
-notation.
The subtle difference with the searching for relax
and the searching for an opening-brace is:
When (La)TeX as delimiter for an argument of a macro, e.g., searches the relax
and finds it, it does not only stop gathering tokens for the argument, but it does also remove the delimiter/the relax
-token.
When (La)TeX as delimiter for the last argument of a macro searches the left-brace and finds it, it does stop gathering tokens for the last argument and it leaves that delimiter/that brace in place and puts the macro's ⟨replacement text⟩ before it.
Quotes from Prof. Donald Ervin Knuth's TeXbook, Chapter 20: Definitions (also called Macros)— Prof. Donald Ervin Knuth, professor emeritus of the art of computer programming at Stanford University, is the inventor of TeX:
Now that we have seen a number of examples, let’s look at the precise
rules that govern TeX macros. Definitions have the general form
def⟨control sequence⟩⟨parameter
text⟩{⟨replacement text⟩}
where the ⟨parameter text⟩ contains
no braces, and where all occurrences of { and
} in the ⟨replacement
text⟩ are properly nested. Furthermore the
# symbol has a special significance: In the
⟨parameter text⟩, the first
appearance of # must be followed by 1, the
next by 2, and so on; up to nine #’s are
allowed. In the ⟨replacement text⟩
each # must be followed by a digit that appeared after
# in the ⟨parameter
text⟩, or else the # should be followed
by another #. The latter case stands for a single
# token when the macro is expanded; the former case
stands for insertion of the corresponding argument.
[...]
A special extension is allowed to these rules: If the very last
character of the ⟨parameter text⟩ is
#, so that this # is immediately followed by
{, TeX will behave as if the { had been
inserted at the right end of both the parameter text and the
replacement text. For example, if you say ‘defa#1#{hbox
to #1}’, the subsequent text
‘a3pt{x}’ will expand to ‘hbox
to 3pt{x}’, because the argument of a is delimited
by a left brace.
In other words:
If you saydefa#1#{hbox to #1}
, the subsequent text a3pt{x}
will be processed as follows:
As argument for the macro a
TeX will from the subsequent text gather an argument which is delimited by a left-brace: It will gather the phrase 3pt
.
The left-brace (and everything behind it) will be left in place while replacing a
and its argument by the ⟨replacement text⟩ yields: hbox to 3pt
so that the entire thing will be: hbox to 3pt{x}
.
In short: #{
-notation (note the left-brace!) means that the last parameter of the macro in question is delimited by a left-brace (of category code 1 (begin group) ) which will be left in place when (La)TeX does gather from the token-stream the last argument for that macro.
The fact that in this special case the delimiter, i.e., the left-brace, will be left in place is noteworthy as this is the only situation where an argument-delimiter will not be removed from the token stream during the process of gathering an argument.
I.e., if the argument-delimiter would, e.g., be a relax
-token as in
defmymacro#1relax{The Argument#1 was delimited by relax. }
, the relax
-token serving as delimiter would be removed when gathering the argument from the token-stream: With
mymacro , which is nonsense,relax...
as argument for mymacro
(La)TeX would gather from the token-stream the sequence , which is nonsense,
and then it would find the token relax
and would take that relax
-token for the delimiter of the argument, and therefore (La)TeX would stop gathering tokens for the argument and it would remove the delimiter. (Then it would start gathering the other arguments of mymacro
if according to the ⟨parameter text⟩ of its definition there were any. But there are none.) Then it would deliver the ⟨replacement text⟩:
The Argument, which is nonsense, was delimited by relax.
This ⟨replacement text⟩ would be trailed by the three dots and therefore now the token-stream would contain:
The Argument, which is nonsense, was delimited by relax. ...
But if the definition is:
defmymacro#1#{The Argument#1 was delimited by a left-brace. }
and you say
mymacro , which is nonsense,{...
, you will get
The Argument, which is nonsense, was delimited by a left-brace. {...
because unlike with the former case, where the relax
which delimits the argument gets removed, in this case, the left-brace which delimits the argument will not be removed.
The phrase
If the very last
character of the ⟨parameter text⟩ is
#, so that this # is immediately followed by
{, TeX will behave as if the { had been
inserted at the right end of both the parameter text and the
replacement text.
means:
A definition usually is of pattern
def⟨control sequence⟩⟨parameter
text⟩{⟨replacement text⟩}
Assume, you wish to define a macro macro
which processes two arguments whereof the first argument is undelimited and whereof the second argument is delimited by the sequence foobar
and which just "spits out" the arguments.
In this case you create an expression like:
defmacro#1#2foobar{argument 1: #1 argument 2: #2}
.
⟨control sequence⟩ = macro
.
⟨parameter text⟩ = #1#2foobar
⟨replacement text⟩ = argument 1: #1 argument 2: #2
When you look at the expression, you see that at the right end of the ⟨parameter text⟩, there will be the tokens that form the delimiter of the last argument, i.e., the tokens foobar
. They belong to the tokens which form the ⟨parameter text⟩. Right behind them you can see the left-brace from that pair of braces that surrounds the ⟨replacement text⟩.
Thus in this case at the right end of the ⟨parameter text⟩ you find the tokens that delimit the last argument and you find the left-brace of the pair of braces that surrounds the ⟨replacement text⟩.
The sequence
macro{A}Bfoobar
yields:
argument 1: A argument 2: B
As you can see, the delimiting tokens foobar
were removed while gathering the tokens that belong to the arguments.
If instead you define:
defmacro#1#2foobar{argument 1: #1 argument 2: #2foobar}
.
⟨control sequence⟩ = macro
.
⟨parameter text⟩ = #1#2foobar
⟨replacement text⟩ = argument 1: #1 argument 2: #2foobar
, i.e., if you insert the delimiter foobar
at the right end of the ⟨replacement text⟩ also, the sequence
macro{A}Bfoobar
yields
argument 1: A argument 2: Bfoobar
as if with the previous definition the delimiter had been left in place.
What if you wish to define such a thing but the delimiter not being a sequence foobar
but being a left-brace?
The definition should still be of pattern
defmacro#1#2⟨delimiter⟩{argument 1: #1 argument 2: #2⟨delimiter⟩}
but for several reasons you cannot take {
as ⟨delimiter⟩ and write
defmacro#1#2{{argument 1: #1 argument 2: #2{}
and hereby take #1#2{
for the ⟨parameter text⟩ and argument 1: #1 argument 2: #2{
for the ⟨replacement text⟩:
In many situations one cannot easily insert single left-braces without getting errors due to braces being unbalanced.
The situation would be ambiguous because (La)TeX would have to guess whether an opening brace near/at the right end of the ⟨parameter text⟩ is an argument-delimiter or whether it belongs to that pair of braces that surrounds the ⟨replacement text⟩.
(La)TeX would also have to guess whether the right-brace should just match the left-brace at the end of the ⟨replacement text⟩ or whether it should denote the end of the ⟨replacement text⟩.
Therefore as a syntactic workaround #{
-notation was invented:
With
defmacro#1#2#{argument 1: #1 argument 2: #2}
⟨control sequence⟩ = macro
.
⟨parameter text⟩ = #1#2#
⟨replacement text⟩ = argument 1: #1 argument 2: #2
, the ⟨parameter text⟩ does not end with a token {
that shall delimit the last argument but it does end with #
.
That #
is used for denoting that (La)TeX shall search a left-brace as argument-delimiter when during the process of expanding macro
gathering the tokens of the last argument of macro
from the token stream. That #
also denotes that the left-brace found as delimiter shall be left in place so that the ⟨replacement text⟩ of macro
goes before it.
In other words:
That #
causes (La)TeX to behave as if as last token that is to delimit the last argument a left-brace was found in the ⟨parameter text⟩.
It also causes (La)TeX to behave as if the last token given in the definition's ⟨replacement text⟩ was a left-brace.
To your comment:
Umm. I don't suppose you could make something up? A best guess at what
is going on? Let me rephrase, in your other example if you even have
cat code 1 characters floating about in all of this. Is it right to
infer that this "primitive behavior" is occurring during the input
phase of reading the file? (Sorry, I am making up terminology as I go
... I am speaking of theprocess_input_buffer
event handler.
The very first stage of processing in LaTeX is reading the input (from file or from console) and taking it for a set of instructions for putting tokens into the token-stream. (Character-tokens/control-sequence-tokens). In subsequent stages the tokens in the token-stream get processed. In an earlier one of these stages, expandable tokens, e.g., macros, get expanded. I.e., they get replaced by those tokens that form the replacement-texts of their definitions. In this stage gathering tokens for macro-arguments takes place. Thus the behavior does not take place when reading the file but does take place after reading and tokenizing, in the stage of expanding expandable tokens and hereby gathering other tokens as their arguments.
I tried to elaborate in detail on how (La)TeX does gather and process macro arguments in my answer to the question How does TeX look for delimited arguments?
I tried to elaborate in detail on expandafter
and on ways of avoiding it in my answer to the question How can I know the number of expandafters when appending to a csname macro?
I tried to elaborate in detail on the macro name
in my answer to the question Define a control sequence after that a space matters
So therefore, theFirst { Brace
is being inserted IMMEDIATELY BEFORE the parameter text,3
in the case explained in the text. (Letters can't be delimiters, apparently). TheSecond { Brace
is being inserted IMMEDIATELY before theLast } Brace
of the replacement text. defa#1#{hbox to #1} a3pt{x} ... I have no idea why the book's explanation says something very different. Anyway, could you put those locations in your answer, so I can accept it? Thank you very much for your help!
– elika kohen
9 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%2f477537%2fwhat-is-notation-how-does-the-syntax-work%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
The gist of name
is:
With
name⟨stuff without braces before the left-brace⟩{⟨stuff within braces⟩}
TeX shall as first argument fetch ⟨stuff without braces before the left-brace⟩
and as second argument process ⟨stuff within braces⟩
:
The ⟨stuff within braces⟩
is taken for the name of a control-sequence-token which can be obtained via wrapping ⟨stuff within braces⟩
into csname..endcsname
and carrying out the resulting csname..endcsname
-expression.
Instead of {⟨stuff within braces⟩}
that control-sequence-token will be behind ⟨stuff without braces before the left-brace⟩
.
When macros with delimited arguments get carried out, (La)TeX gathers the tokens forming the arguments from the token-stream and hereby in the token-stream searches the argument-delimiters as the argument-delimiters are taken for markers for ending the process of gathering tokens for the argument in question.
What delimiters are to be searched is to be denoted in the ⟨parameter text⟩ of the definition.
You can denote that (La)TeX shall search as delimiter for the last argument, e.g., a relax
by writing relax
as the last thing of the ⟨parameter text⟩.
You can denote that as delimiter for the last argument (La)TeX shall search a left-brace by writing #
as the last thing of the ⟨parameter text⟩.
In (almost ;-) ) any case the ⟨parameter text⟩ of a macro-definition is followed by the ⟨replacement text⟩, nested in braces.
Thus in any case the ⟨parameter text⟩ of a macro-definition will be trailed by the left-brace of the pair of braces that surrounds the ⟨replacement text⟩.
Thus when the last token of the ⟨parameter text⟩ is a #
, it will be trailed by a {
.
That's why this thingie for denoting that (La)TeX shall search for a left-brace as the delimiter when gathering the last argument for the macro, is also called #{
-notation.
The subtle difference with the searching for relax
and the searching for an opening-brace is:
When (La)TeX as delimiter for an argument of a macro, e.g., searches the relax
and finds it, it does not only stop gathering tokens for the argument, but it does also remove the delimiter/the relax
-token.
When (La)TeX as delimiter for the last argument of a macro searches the left-brace and finds it, it does stop gathering tokens for the last argument and it leaves that delimiter/that brace in place and puts the macro's ⟨replacement text⟩ before it.
Quotes from Prof. Donald Ervin Knuth's TeXbook, Chapter 20: Definitions (also called Macros)— Prof. Donald Ervin Knuth, professor emeritus of the art of computer programming at Stanford University, is the inventor of TeX:
Now that we have seen a number of examples, let’s look at the precise
rules that govern TeX macros. Definitions have the general form
def⟨control sequence⟩⟨parameter
text⟩{⟨replacement text⟩}
where the ⟨parameter text⟩ contains
no braces, and where all occurrences of { and
} in the ⟨replacement
text⟩ are properly nested. Furthermore the
# symbol has a special significance: In the
⟨parameter text⟩, the first
appearance of # must be followed by 1, the
next by 2, and so on; up to nine #’s are
allowed. In the ⟨replacement text⟩
each # must be followed by a digit that appeared after
# in the ⟨parameter
text⟩, or else the # should be followed
by another #. The latter case stands for a single
# token when the macro is expanded; the former case
stands for insertion of the corresponding argument.
[...]
A special extension is allowed to these rules: If the very last
character of the ⟨parameter text⟩ is
#, so that this # is immediately followed by
{, TeX will behave as if the { had been
inserted at the right end of both the parameter text and the
replacement text. For example, if you say ‘defa#1#{hbox
to #1}’, the subsequent text
‘a3pt{x}’ will expand to ‘hbox
to 3pt{x}’, because the argument of a is delimited
by a left brace.
In other words:
If you saydefa#1#{hbox to #1}
, the subsequent text a3pt{x}
will be processed as follows:
As argument for the macro a
TeX will from the subsequent text gather an argument which is delimited by a left-brace: It will gather the phrase 3pt
.
The left-brace (and everything behind it) will be left in place while replacing a
and its argument by the ⟨replacement text⟩ yields: hbox to 3pt
so that the entire thing will be: hbox to 3pt{x}
.
In short: #{
-notation (note the left-brace!) means that the last parameter of the macro in question is delimited by a left-brace (of category code 1 (begin group) ) which will be left in place when (La)TeX does gather from the token-stream the last argument for that macro.
The fact that in this special case the delimiter, i.e., the left-brace, will be left in place is noteworthy as this is the only situation where an argument-delimiter will not be removed from the token stream during the process of gathering an argument.
I.e., if the argument-delimiter would, e.g., be a relax
-token as in
defmymacro#1relax{The Argument#1 was delimited by relax. }
, the relax
-token serving as delimiter would be removed when gathering the argument from the token-stream: With
mymacro , which is nonsense,relax...
as argument for mymacro
(La)TeX would gather from the token-stream the sequence , which is nonsense,
and then it would find the token relax
and would take that relax
-token for the delimiter of the argument, and therefore (La)TeX would stop gathering tokens for the argument and it would remove the delimiter. (Then it would start gathering the other arguments of mymacro
if according to the ⟨parameter text⟩ of its definition there were any. But there are none.) Then it would deliver the ⟨replacement text⟩:
The Argument, which is nonsense, was delimited by relax.
This ⟨replacement text⟩ would be trailed by the three dots and therefore now the token-stream would contain:
The Argument, which is nonsense, was delimited by relax. ...
But if the definition is:
defmymacro#1#{The Argument#1 was delimited by a left-brace. }
and you say
mymacro , which is nonsense,{...
, you will get
The Argument, which is nonsense, was delimited by a left-brace. {...
because unlike with the former case, where the relax
which delimits the argument gets removed, in this case, the left-brace which delimits the argument will not be removed.
The phrase
If the very last
character of the ⟨parameter text⟩ is
#, so that this # is immediately followed by
{, TeX will behave as if the { had been
inserted at the right end of both the parameter text and the
replacement text.
means:
A definition usually is of pattern
def⟨control sequence⟩⟨parameter
text⟩{⟨replacement text⟩}
Assume, you wish to define a macro macro
which processes two arguments whereof the first argument is undelimited and whereof the second argument is delimited by the sequence foobar
and which just "spits out" the arguments.
In this case you create an expression like:
defmacro#1#2foobar{argument 1: #1 argument 2: #2}
.
⟨control sequence⟩ = macro
.
⟨parameter text⟩ = #1#2foobar
⟨replacement text⟩ = argument 1: #1 argument 2: #2
When you look at the expression, you see that at the right end of the ⟨parameter text⟩, there will be the tokens that form the delimiter of the last argument, i.e., the tokens foobar
. They belong to the tokens which form the ⟨parameter text⟩. Right behind them you can see the left-brace from that pair of braces that surrounds the ⟨replacement text⟩.
Thus in this case at the right end of the ⟨parameter text⟩ you find the tokens that delimit the last argument and you find the left-brace of the pair of braces that surrounds the ⟨replacement text⟩.
The sequence
macro{A}Bfoobar
yields:
argument 1: A argument 2: B
As you can see, the delimiting tokens foobar
were removed while gathering the tokens that belong to the arguments.
If instead you define:
defmacro#1#2foobar{argument 1: #1 argument 2: #2foobar}
.
⟨control sequence⟩ = macro
.
⟨parameter text⟩ = #1#2foobar
⟨replacement text⟩ = argument 1: #1 argument 2: #2foobar
, i.e., if you insert the delimiter foobar
at the right end of the ⟨replacement text⟩ also, the sequence
macro{A}Bfoobar
yields
argument 1: A argument 2: Bfoobar
as if with the previous definition the delimiter had been left in place.
What if you wish to define such a thing but the delimiter not being a sequence foobar
but being a left-brace?
The definition should still be of pattern
defmacro#1#2⟨delimiter⟩{argument 1: #1 argument 2: #2⟨delimiter⟩}
but for several reasons you cannot take {
as ⟨delimiter⟩ and write
defmacro#1#2{{argument 1: #1 argument 2: #2{}
and hereby take #1#2{
for the ⟨parameter text⟩ and argument 1: #1 argument 2: #2{
for the ⟨replacement text⟩:
In many situations one cannot easily insert single left-braces without getting errors due to braces being unbalanced.
The situation would be ambiguous because (La)TeX would have to guess whether an opening brace near/at the right end of the ⟨parameter text⟩ is an argument-delimiter or whether it belongs to that pair of braces that surrounds the ⟨replacement text⟩.
(La)TeX would also have to guess whether the right-brace should just match the left-brace at the end of the ⟨replacement text⟩ or whether it should denote the end of the ⟨replacement text⟩.
Therefore as a syntactic workaround #{
-notation was invented:
With
defmacro#1#2#{argument 1: #1 argument 2: #2}
⟨control sequence⟩ = macro
.
⟨parameter text⟩ = #1#2#
⟨replacement text⟩ = argument 1: #1 argument 2: #2
, the ⟨parameter text⟩ does not end with a token {
that shall delimit the last argument but it does end with #
.
That #
is used for denoting that (La)TeX shall search a left-brace as argument-delimiter when during the process of expanding macro
gathering the tokens of the last argument of macro
from the token stream. That #
also denotes that the left-brace found as delimiter shall be left in place so that the ⟨replacement text⟩ of macro
goes before it.
In other words:
That #
causes (La)TeX to behave as if as last token that is to delimit the last argument a left-brace was found in the ⟨parameter text⟩.
It also causes (La)TeX to behave as if the last token given in the definition's ⟨replacement text⟩ was a left-brace.
To your comment:
Umm. I don't suppose you could make something up? A best guess at what
is going on? Let me rephrase, in your other example if you even have
cat code 1 characters floating about in all of this. Is it right to
infer that this "primitive behavior" is occurring during the input
phase of reading the file? (Sorry, I am making up terminology as I go
... I am speaking of theprocess_input_buffer
event handler.
The very first stage of processing in LaTeX is reading the input (from file or from console) and taking it for a set of instructions for putting tokens into the token-stream. (Character-tokens/control-sequence-tokens). In subsequent stages the tokens in the token-stream get processed. In an earlier one of these stages, expandable tokens, e.g., macros, get expanded. I.e., they get replaced by those tokens that form the replacement-texts of their definitions. In this stage gathering tokens for macro-arguments takes place. Thus the behavior does not take place when reading the file but does take place after reading and tokenizing, in the stage of expanding expandable tokens and hereby gathering other tokens as their arguments.
I tried to elaborate in detail on how (La)TeX does gather and process macro arguments in my answer to the question How does TeX look for delimited arguments?
I tried to elaborate in detail on expandafter
and on ways of avoiding it in my answer to the question How can I know the number of expandafters when appending to a csname macro?
I tried to elaborate in detail on the macro name
in my answer to the question Define a control sequence after that a space matters
So therefore, theFirst { Brace
is being inserted IMMEDIATELY BEFORE the parameter text,3
in the case explained in the text. (Letters can't be delimiters, apparently). TheSecond { Brace
is being inserted IMMEDIATELY before theLast } Brace
of the replacement text. defa#1#{hbox to #1} a3pt{x} ... I have no idea why the book's explanation says something very different. Anyway, could you put those locations in your answer, so I can accept it? Thank you very much for your help!
– elika kohen
9 hours ago
add a comment |
The gist of name
is:
With
name⟨stuff without braces before the left-brace⟩{⟨stuff within braces⟩}
TeX shall as first argument fetch ⟨stuff without braces before the left-brace⟩
and as second argument process ⟨stuff within braces⟩
:
The ⟨stuff within braces⟩
is taken for the name of a control-sequence-token which can be obtained via wrapping ⟨stuff within braces⟩
into csname..endcsname
and carrying out the resulting csname..endcsname
-expression.
Instead of {⟨stuff within braces⟩}
that control-sequence-token will be behind ⟨stuff without braces before the left-brace⟩
.
When macros with delimited arguments get carried out, (La)TeX gathers the tokens forming the arguments from the token-stream and hereby in the token-stream searches the argument-delimiters as the argument-delimiters are taken for markers for ending the process of gathering tokens for the argument in question.
What delimiters are to be searched is to be denoted in the ⟨parameter text⟩ of the definition.
You can denote that (La)TeX shall search as delimiter for the last argument, e.g., a relax
by writing relax
as the last thing of the ⟨parameter text⟩.
You can denote that as delimiter for the last argument (La)TeX shall search a left-brace by writing #
as the last thing of the ⟨parameter text⟩.
In (almost ;-) ) any case the ⟨parameter text⟩ of a macro-definition is followed by the ⟨replacement text⟩, nested in braces.
Thus in any case the ⟨parameter text⟩ of a macro-definition will be trailed by the left-brace of the pair of braces that surrounds the ⟨replacement text⟩.
Thus when the last token of the ⟨parameter text⟩ is a #
, it will be trailed by a {
.
That's why this thingie for denoting that (La)TeX shall search for a left-brace as the delimiter when gathering the last argument for the macro, is also called #{
-notation.
The subtle difference with the searching for relax
and the searching for an opening-brace is:
When (La)TeX as delimiter for an argument of a macro, e.g., searches the relax
and finds it, it does not only stop gathering tokens for the argument, but it does also remove the delimiter/the relax
-token.
When (La)TeX as delimiter for the last argument of a macro searches the left-brace and finds it, it does stop gathering tokens for the last argument and it leaves that delimiter/that brace in place and puts the macro's ⟨replacement text⟩ before it.
Quotes from Prof. Donald Ervin Knuth's TeXbook, Chapter 20: Definitions (also called Macros)— Prof. Donald Ervin Knuth, professor emeritus of the art of computer programming at Stanford University, is the inventor of TeX:
Now that we have seen a number of examples, let’s look at the precise
rules that govern TeX macros. Definitions have the general form
def⟨control sequence⟩⟨parameter
text⟩{⟨replacement text⟩}
where the ⟨parameter text⟩ contains
no braces, and where all occurrences of { and
} in the ⟨replacement
text⟩ are properly nested. Furthermore the
# symbol has a special significance: In the
⟨parameter text⟩, the first
appearance of # must be followed by 1, the
next by 2, and so on; up to nine #’s are
allowed. In the ⟨replacement text⟩
each # must be followed by a digit that appeared after
# in the ⟨parameter
text⟩, or else the # should be followed
by another #. The latter case stands for a single
# token when the macro is expanded; the former case
stands for insertion of the corresponding argument.
[...]
A special extension is allowed to these rules: If the very last
character of the ⟨parameter text⟩ is
#, so that this # is immediately followed by
{, TeX will behave as if the { had been
inserted at the right end of both the parameter text and the
replacement text. For example, if you say ‘defa#1#{hbox
to #1}’, the subsequent text
‘a3pt{x}’ will expand to ‘hbox
to 3pt{x}’, because the argument of a is delimited
by a left brace.
In other words:
If you saydefa#1#{hbox to #1}
, the subsequent text a3pt{x}
will be processed as follows:
As argument for the macro a
TeX will from the subsequent text gather an argument which is delimited by a left-brace: It will gather the phrase 3pt
.
The left-brace (and everything behind it) will be left in place while replacing a
and its argument by the ⟨replacement text⟩ yields: hbox to 3pt
so that the entire thing will be: hbox to 3pt{x}
.
In short: #{
-notation (note the left-brace!) means that the last parameter of the macro in question is delimited by a left-brace (of category code 1 (begin group) ) which will be left in place when (La)TeX does gather from the token-stream the last argument for that macro.
The fact that in this special case the delimiter, i.e., the left-brace, will be left in place is noteworthy as this is the only situation where an argument-delimiter will not be removed from the token stream during the process of gathering an argument.
I.e., if the argument-delimiter would, e.g., be a relax
-token as in
defmymacro#1relax{The Argument#1 was delimited by relax. }
, the relax
-token serving as delimiter would be removed when gathering the argument from the token-stream: With
mymacro , which is nonsense,relax...
as argument for mymacro
(La)TeX would gather from the token-stream the sequence , which is nonsense,
and then it would find the token relax
and would take that relax
-token for the delimiter of the argument, and therefore (La)TeX would stop gathering tokens for the argument and it would remove the delimiter. (Then it would start gathering the other arguments of mymacro
if according to the ⟨parameter text⟩ of its definition there were any. But there are none.) Then it would deliver the ⟨replacement text⟩:
The Argument, which is nonsense, was delimited by relax.
This ⟨replacement text⟩ would be trailed by the three dots and therefore now the token-stream would contain:
The Argument, which is nonsense, was delimited by relax. ...
But if the definition is:
defmymacro#1#{The Argument#1 was delimited by a left-brace. }
and you say
mymacro , which is nonsense,{...
, you will get
The Argument, which is nonsense, was delimited by a left-brace. {...
because unlike with the former case, where the relax
which delimits the argument gets removed, in this case, the left-brace which delimits the argument will not be removed.
The phrase
If the very last
character of the ⟨parameter text⟩ is
#, so that this # is immediately followed by
{, TeX will behave as if the { had been
inserted at the right end of both the parameter text and the
replacement text.
means:
A definition usually is of pattern
def⟨control sequence⟩⟨parameter
text⟩{⟨replacement text⟩}
Assume, you wish to define a macro macro
which processes two arguments whereof the first argument is undelimited and whereof the second argument is delimited by the sequence foobar
and which just "spits out" the arguments.
In this case you create an expression like:
defmacro#1#2foobar{argument 1: #1 argument 2: #2}
.
⟨control sequence⟩ = macro
.
⟨parameter text⟩ = #1#2foobar
⟨replacement text⟩ = argument 1: #1 argument 2: #2
When you look at the expression, you see that at the right end of the ⟨parameter text⟩, there will be the tokens that form the delimiter of the last argument, i.e., the tokens foobar
. They belong to the tokens which form the ⟨parameter text⟩. Right behind them you can see the left-brace from that pair of braces that surrounds the ⟨replacement text⟩.
Thus in this case at the right end of the ⟨parameter text⟩ you find the tokens that delimit the last argument and you find the left-brace of the pair of braces that surrounds the ⟨replacement text⟩.
The sequence
macro{A}Bfoobar
yields:
argument 1: A argument 2: B
As you can see, the delimiting tokens foobar
were removed while gathering the tokens that belong to the arguments.
If instead you define:
defmacro#1#2foobar{argument 1: #1 argument 2: #2foobar}
.
⟨control sequence⟩ = macro
.
⟨parameter text⟩ = #1#2foobar
⟨replacement text⟩ = argument 1: #1 argument 2: #2foobar
, i.e., if you insert the delimiter foobar
at the right end of the ⟨replacement text⟩ also, the sequence
macro{A}Bfoobar
yields
argument 1: A argument 2: Bfoobar
as if with the previous definition the delimiter had been left in place.
What if you wish to define such a thing but the delimiter not being a sequence foobar
but being a left-brace?
The definition should still be of pattern
defmacro#1#2⟨delimiter⟩{argument 1: #1 argument 2: #2⟨delimiter⟩}
but for several reasons you cannot take {
as ⟨delimiter⟩ and write
defmacro#1#2{{argument 1: #1 argument 2: #2{}
and hereby take #1#2{
for the ⟨parameter text⟩ and argument 1: #1 argument 2: #2{
for the ⟨replacement text⟩:
In many situations one cannot easily insert single left-braces without getting errors due to braces being unbalanced.
The situation would be ambiguous because (La)TeX would have to guess whether an opening brace near/at the right end of the ⟨parameter text⟩ is an argument-delimiter or whether it belongs to that pair of braces that surrounds the ⟨replacement text⟩.
(La)TeX would also have to guess whether the right-brace should just match the left-brace at the end of the ⟨replacement text⟩ or whether it should denote the end of the ⟨replacement text⟩.
Therefore as a syntactic workaround #{
-notation was invented:
With
defmacro#1#2#{argument 1: #1 argument 2: #2}
⟨control sequence⟩ = macro
.
⟨parameter text⟩ = #1#2#
⟨replacement text⟩ = argument 1: #1 argument 2: #2
, the ⟨parameter text⟩ does not end with a token {
that shall delimit the last argument but it does end with #
.
That #
is used for denoting that (La)TeX shall search a left-brace as argument-delimiter when during the process of expanding macro
gathering the tokens of the last argument of macro
from the token stream. That #
also denotes that the left-brace found as delimiter shall be left in place so that the ⟨replacement text⟩ of macro
goes before it.
In other words:
That #
causes (La)TeX to behave as if as last token that is to delimit the last argument a left-brace was found in the ⟨parameter text⟩.
It also causes (La)TeX to behave as if the last token given in the definition's ⟨replacement text⟩ was a left-brace.
To your comment:
Umm. I don't suppose you could make something up? A best guess at what
is going on? Let me rephrase, in your other example if you even have
cat code 1 characters floating about in all of this. Is it right to
infer that this "primitive behavior" is occurring during the input
phase of reading the file? (Sorry, I am making up terminology as I go
... I am speaking of theprocess_input_buffer
event handler.
The very first stage of processing in LaTeX is reading the input (from file or from console) and taking it for a set of instructions for putting tokens into the token-stream. (Character-tokens/control-sequence-tokens). In subsequent stages the tokens in the token-stream get processed. In an earlier one of these stages, expandable tokens, e.g., macros, get expanded. I.e., they get replaced by those tokens that form the replacement-texts of their definitions. In this stage gathering tokens for macro-arguments takes place. Thus the behavior does not take place when reading the file but does take place after reading and tokenizing, in the stage of expanding expandable tokens and hereby gathering other tokens as their arguments.
I tried to elaborate in detail on how (La)TeX does gather and process macro arguments in my answer to the question How does TeX look for delimited arguments?
I tried to elaborate in detail on expandafter
and on ways of avoiding it in my answer to the question How can I know the number of expandafters when appending to a csname macro?
I tried to elaborate in detail on the macro name
in my answer to the question Define a control sequence after that a space matters
So therefore, theFirst { Brace
is being inserted IMMEDIATELY BEFORE the parameter text,3
in the case explained in the text. (Letters can't be delimiters, apparently). TheSecond { Brace
is being inserted IMMEDIATELY before theLast } Brace
of the replacement text. defa#1#{hbox to #1} a3pt{x} ... I have no idea why the book's explanation says something very different. Anyway, could you put those locations in your answer, so I can accept it? Thank you very much for your help!
– elika kohen
9 hours ago
add a comment |
The gist of name
is:
With
name⟨stuff without braces before the left-brace⟩{⟨stuff within braces⟩}
TeX shall as first argument fetch ⟨stuff without braces before the left-brace⟩
and as second argument process ⟨stuff within braces⟩
:
The ⟨stuff within braces⟩
is taken for the name of a control-sequence-token which can be obtained via wrapping ⟨stuff within braces⟩
into csname..endcsname
and carrying out the resulting csname..endcsname
-expression.
Instead of {⟨stuff within braces⟩}
that control-sequence-token will be behind ⟨stuff without braces before the left-brace⟩
.
When macros with delimited arguments get carried out, (La)TeX gathers the tokens forming the arguments from the token-stream and hereby in the token-stream searches the argument-delimiters as the argument-delimiters are taken for markers for ending the process of gathering tokens for the argument in question.
What delimiters are to be searched is to be denoted in the ⟨parameter text⟩ of the definition.
You can denote that (La)TeX shall search as delimiter for the last argument, e.g., a relax
by writing relax
as the last thing of the ⟨parameter text⟩.
You can denote that as delimiter for the last argument (La)TeX shall search a left-brace by writing #
as the last thing of the ⟨parameter text⟩.
In (almost ;-) ) any case the ⟨parameter text⟩ of a macro-definition is followed by the ⟨replacement text⟩, nested in braces.
Thus in any case the ⟨parameter text⟩ of a macro-definition will be trailed by the left-brace of the pair of braces that surrounds the ⟨replacement text⟩.
Thus when the last token of the ⟨parameter text⟩ is a #
, it will be trailed by a {
.
That's why this thingie for denoting that (La)TeX shall search for a left-brace as the delimiter when gathering the last argument for the macro, is also called #{
-notation.
The subtle difference with the searching for relax
and the searching for an opening-brace is:
When (La)TeX as delimiter for an argument of a macro, e.g., searches the relax
and finds it, it does not only stop gathering tokens for the argument, but it does also remove the delimiter/the relax
-token.
When (La)TeX as delimiter for the last argument of a macro searches the left-brace and finds it, it does stop gathering tokens for the last argument and it leaves that delimiter/that brace in place and puts the macro's ⟨replacement text⟩ before it.
Quotes from Prof. Donald Ervin Knuth's TeXbook, Chapter 20: Definitions (also called Macros)— Prof. Donald Ervin Knuth, professor emeritus of the art of computer programming at Stanford University, is the inventor of TeX:
Now that we have seen a number of examples, let’s look at the precise
rules that govern TeX macros. Definitions have the general form
def⟨control sequence⟩⟨parameter
text⟩{⟨replacement text⟩}
where the ⟨parameter text⟩ contains
no braces, and where all occurrences of { and
} in the ⟨replacement
text⟩ are properly nested. Furthermore the
# symbol has a special significance: In the
⟨parameter text⟩, the first
appearance of # must be followed by 1, the
next by 2, and so on; up to nine #’s are
allowed. In the ⟨replacement text⟩
each # must be followed by a digit that appeared after
# in the ⟨parameter
text⟩, or else the # should be followed
by another #. The latter case stands for a single
# token when the macro is expanded; the former case
stands for insertion of the corresponding argument.
[...]
A special extension is allowed to these rules: If the very last
character of the ⟨parameter text⟩ is
#, so that this # is immediately followed by
{, TeX will behave as if the { had been
inserted at the right end of both the parameter text and the
replacement text. For example, if you say ‘defa#1#{hbox
to #1}’, the subsequent text
‘a3pt{x}’ will expand to ‘hbox
to 3pt{x}’, because the argument of a is delimited
by a left brace.
In other words:
If you saydefa#1#{hbox to #1}
, the subsequent text a3pt{x}
will be processed as follows:
As argument for the macro a
TeX will from the subsequent text gather an argument which is delimited by a left-brace: It will gather the phrase 3pt
.
The left-brace (and everything behind it) will be left in place while replacing a
and its argument by the ⟨replacement text⟩ yields: hbox to 3pt
so that the entire thing will be: hbox to 3pt{x}
.
In short: #{
-notation (note the left-brace!) means that the last parameter of the macro in question is delimited by a left-brace (of category code 1 (begin group) ) which will be left in place when (La)TeX does gather from the token-stream the last argument for that macro.
The fact that in this special case the delimiter, i.e., the left-brace, will be left in place is noteworthy as this is the only situation where an argument-delimiter will not be removed from the token stream during the process of gathering an argument.
I.e., if the argument-delimiter would, e.g., be a relax
-token as in
defmymacro#1relax{The Argument#1 was delimited by relax. }
, the relax
-token serving as delimiter would be removed when gathering the argument from the token-stream: With
mymacro , which is nonsense,relax...
as argument for mymacro
(La)TeX would gather from the token-stream the sequence , which is nonsense,
and then it would find the token relax
and would take that relax
-token for the delimiter of the argument, and therefore (La)TeX would stop gathering tokens for the argument and it would remove the delimiter. (Then it would start gathering the other arguments of mymacro
if according to the ⟨parameter text⟩ of its definition there were any. But there are none.) Then it would deliver the ⟨replacement text⟩:
The Argument, which is nonsense, was delimited by relax.
This ⟨replacement text⟩ would be trailed by the three dots and therefore now the token-stream would contain:
The Argument, which is nonsense, was delimited by relax. ...
But if the definition is:
defmymacro#1#{The Argument#1 was delimited by a left-brace. }
and you say
mymacro , which is nonsense,{...
, you will get
The Argument, which is nonsense, was delimited by a left-brace. {...
because unlike with the former case, where the relax
which delimits the argument gets removed, in this case, the left-brace which delimits the argument will not be removed.
The phrase
If the very last
character of the ⟨parameter text⟩ is
#, so that this # is immediately followed by
{, TeX will behave as if the { had been
inserted at the right end of both the parameter text and the
replacement text.
means:
A definition usually is of pattern
def⟨control sequence⟩⟨parameter
text⟩{⟨replacement text⟩}
Assume, you wish to define a macro macro
which processes two arguments whereof the first argument is undelimited and whereof the second argument is delimited by the sequence foobar
and which just "spits out" the arguments.
In this case you create an expression like:
defmacro#1#2foobar{argument 1: #1 argument 2: #2}
.
⟨control sequence⟩ = macro
.
⟨parameter text⟩ = #1#2foobar
⟨replacement text⟩ = argument 1: #1 argument 2: #2
When you look at the expression, you see that at the right end of the ⟨parameter text⟩, there will be the tokens that form the delimiter of the last argument, i.e., the tokens foobar
. They belong to the tokens which form the ⟨parameter text⟩. Right behind them you can see the left-brace from that pair of braces that surrounds the ⟨replacement text⟩.
Thus in this case at the right end of the ⟨parameter text⟩ you find the tokens that delimit the last argument and you find the left-brace of the pair of braces that surrounds the ⟨replacement text⟩.
The sequence
macro{A}Bfoobar
yields:
argument 1: A argument 2: B
As you can see, the delimiting tokens foobar
were removed while gathering the tokens that belong to the arguments.
If instead you define:
defmacro#1#2foobar{argument 1: #1 argument 2: #2foobar}
.
⟨control sequence⟩ = macro
.
⟨parameter text⟩ = #1#2foobar
⟨replacement text⟩ = argument 1: #1 argument 2: #2foobar
, i.e., if you insert the delimiter foobar
at the right end of the ⟨replacement text⟩ also, the sequence
macro{A}Bfoobar
yields
argument 1: A argument 2: Bfoobar
as if with the previous definition the delimiter had been left in place.
What if you wish to define such a thing but the delimiter not being a sequence foobar
but being a left-brace?
The definition should still be of pattern
defmacro#1#2⟨delimiter⟩{argument 1: #1 argument 2: #2⟨delimiter⟩}
but for several reasons you cannot take {
as ⟨delimiter⟩ and write
defmacro#1#2{{argument 1: #1 argument 2: #2{}
and hereby take #1#2{
for the ⟨parameter text⟩ and argument 1: #1 argument 2: #2{
for the ⟨replacement text⟩:
In many situations one cannot easily insert single left-braces without getting errors due to braces being unbalanced.
The situation would be ambiguous because (La)TeX would have to guess whether an opening brace near/at the right end of the ⟨parameter text⟩ is an argument-delimiter or whether it belongs to that pair of braces that surrounds the ⟨replacement text⟩.
(La)TeX would also have to guess whether the right-brace should just match the left-brace at the end of the ⟨replacement text⟩ or whether it should denote the end of the ⟨replacement text⟩.
Therefore as a syntactic workaround #{
-notation was invented:
With
defmacro#1#2#{argument 1: #1 argument 2: #2}
⟨control sequence⟩ = macro
.
⟨parameter text⟩ = #1#2#
⟨replacement text⟩ = argument 1: #1 argument 2: #2
, the ⟨parameter text⟩ does not end with a token {
that shall delimit the last argument but it does end with #
.
That #
is used for denoting that (La)TeX shall search a left-brace as argument-delimiter when during the process of expanding macro
gathering the tokens of the last argument of macro
from the token stream. That #
also denotes that the left-brace found as delimiter shall be left in place so that the ⟨replacement text⟩ of macro
goes before it.
In other words:
That #
causes (La)TeX to behave as if as last token that is to delimit the last argument a left-brace was found in the ⟨parameter text⟩.
It also causes (La)TeX to behave as if the last token given in the definition's ⟨replacement text⟩ was a left-brace.
To your comment:
Umm. I don't suppose you could make something up? A best guess at what
is going on? Let me rephrase, in your other example if you even have
cat code 1 characters floating about in all of this. Is it right to
infer that this "primitive behavior" is occurring during the input
phase of reading the file? (Sorry, I am making up terminology as I go
... I am speaking of theprocess_input_buffer
event handler.
The very first stage of processing in LaTeX is reading the input (from file or from console) and taking it for a set of instructions for putting tokens into the token-stream. (Character-tokens/control-sequence-tokens). In subsequent stages the tokens in the token-stream get processed. In an earlier one of these stages, expandable tokens, e.g., macros, get expanded. I.e., they get replaced by those tokens that form the replacement-texts of their definitions. In this stage gathering tokens for macro-arguments takes place. Thus the behavior does not take place when reading the file but does take place after reading and tokenizing, in the stage of expanding expandable tokens and hereby gathering other tokens as their arguments.
I tried to elaborate in detail on how (La)TeX does gather and process macro arguments in my answer to the question How does TeX look for delimited arguments?
I tried to elaborate in detail on expandafter
and on ways of avoiding it in my answer to the question How can I know the number of expandafters when appending to a csname macro?
I tried to elaborate in detail on the macro name
in my answer to the question Define a control sequence after that a space matters
The gist of name
is:
With
name⟨stuff without braces before the left-brace⟩{⟨stuff within braces⟩}
TeX shall as first argument fetch ⟨stuff without braces before the left-brace⟩
and as second argument process ⟨stuff within braces⟩
:
The ⟨stuff within braces⟩
is taken for the name of a control-sequence-token which can be obtained via wrapping ⟨stuff within braces⟩
into csname..endcsname
and carrying out the resulting csname..endcsname
-expression.
Instead of {⟨stuff within braces⟩}
that control-sequence-token will be behind ⟨stuff without braces before the left-brace⟩
.
When macros with delimited arguments get carried out, (La)TeX gathers the tokens forming the arguments from the token-stream and hereby in the token-stream searches the argument-delimiters as the argument-delimiters are taken for markers for ending the process of gathering tokens for the argument in question.
What delimiters are to be searched is to be denoted in the ⟨parameter text⟩ of the definition.
You can denote that (La)TeX shall search as delimiter for the last argument, e.g., a relax
by writing relax
as the last thing of the ⟨parameter text⟩.
You can denote that as delimiter for the last argument (La)TeX shall search a left-brace by writing #
as the last thing of the ⟨parameter text⟩.
In (almost ;-) ) any case the ⟨parameter text⟩ of a macro-definition is followed by the ⟨replacement text⟩, nested in braces.
Thus in any case the ⟨parameter text⟩ of a macro-definition will be trailed by the left-brace of the pair of braces that surrounds the ⟨replacement text⟩.
Thus when the last token of the ⟨parameter text⟩ is a #
, it will be trailed by a {
.
That's why this thingie for denoting that (La)TeX shall search for a left-brace as the delimiter when gathering the last argument for the macro, is also called #{
-notation.
The subtle difference with the searching for relax
and the searching for an opening-brace is:
When (La)TeX as delimiter for an argument of a macro, e.g., searches the relax
and finds it, it does not only stop gathering tokens for the argument, but it does also remove the delimiter/the relax
-token.
When (La)TeX as delimiter for the last argument of a macro searches the left-brace and finds it, it does stop gathering tokens for the last argument and it leaves that delimiter/that brace in place and puts the macro's ⟨replacement text⟩ before it.
Quotes from Prof. Donald Ervin Knuth's TeXbook, Chapter 20: Definitions (also called Macros)— Prof. Donald Ervin Knuth, professor emeritus of the art of computer programming at Stanford University, is the inventor of TeX:
Now that we have seen a number of examples, let’s look at the precise
rules that govern TeX macros. Definitions have the general form
def⟨control sequence⟩⟨parameter
text⟩{⟨replacement text⟩}
where the ⟨parameter text⟩ contains
no braces, and where all occurrences of { and
} in the ⟨replacement
text⟩ are properly nested. Furthermore the
# symbol has a special significance: In the
⟨parameter text⟩, the first
appearance of # must be followed by 1, the
next by 2, and so on; up to nine #’s are
allowed. In the ⟨replacement text⟩
each # must be followed by a digit that appeared after
# in the ⟨parameter
text⟩, or else the # should be followed
by another #. The latter case stands for a single
# token when the macro is expanded; the former case
stands for insertion of the corresponding argument.
[...]
A special extension is allowed to these rules: If the very last
character of the ⟨parameter text⟩ is
#, so that this # is immediately followed by
{, TeX will behave as if the { had been
inserted at the right end of both the parameter text and the
replacement text. For example, if you say ‘defa#1#{hbox
to #1}’, the subsequent text
‘a3pt{x}’ will expand to ‘hbox
to 3pt{x}’, because the argument of a is delimited
by a left brace.
In other words:
If you saydefa#1#{hbox to #1}
, the subsequent text a3pt{x}
will be processed as follows:
As argument for the macro a
TeX will from the subsequent text gather an argument which is delimited by a left-brace: It will gather the phrase 3pt
.
The left-brace (and everything behind it) will be left in place while replacing a
and its argument by the ⟨replacement text⟩ yields: hbox to 3pt
so that the entire thing will be: hbox to 3pt{x}
.
In short: #{
-notation (note the left-brace!) means that the last parameter of the macro in question is delimited by a left-brace (of category code 1 (begin group) ) which will be left in place when (La)TeX does gather from the token-stream the last argument for that macro.
The fact that in this special case the delimiter, i.e., the left-brace, will be left in place is noteworthy as this is the only situation where an argument-delimiter will not be removed from the token stream during the process of gathering an argument.
I.e., if the argument-delimiter would, e.g., be a relax
-token as in
defmymacro#1relax{The Argument#1 was delimited by relax. }
, the relax
-token serving as delimiter would be removed when gathering the argument from the token-stream: With
mymacro , which is nonsense,relax...
as argument for mymacro
(La)TeX would gather from the token-stream the sequence , which is nonsense,
and then it would find the token relax
and would take that relax
-token for the delimiter of the argument, and therefore (La)TeX would stop gathering tokens for the argument and it would remove the delimiter. (Then it would start gathering the other arguments of mymacro
if according to the ⟨parameter text⟩ of its definition there were any. But there are none.) Then it would deliver the ⟨replacement text⟩:
The Argument, which is nonsense, was delimited by relax.
This ⟨replacement text⟩ would be trailed by the three dots and therefore now the token-stream would contain:
The Argument, which is nonsense, was delimited by relax. ...
But if the definition is:
defmymacro#1#{The Argument#1 was delimited by a left-brace. }
and you say
mymacro , which is nonsense,{...
, you will get
The Argument, which is nonsense, was delimited by a left-brace. {...
because unlike with the former case, where the relax
which delimits the argument gets removed, in this case, the left-brace which delimits the argument will not be removed.
The phrase
If the very last
character of the ⟨parameter text⟩ is
#, so that this # is immediately followed by
{, TeX will behave as if the { had been
inserted at the right end of both the parameter text and the
replacement text.
means:
A definition usually is of pattern
def⟨control sequence⟩⟨parameter
text⟩{⟨replacement text⟩}
Assume, you wish to define a macro macro
which processes two arguments whereof the first argument is undelimited and whereof the second argument is delimited by the sequence foobar
and which just "spits out" the arguments.
In this case you create an expression like:
defmacro#1#2foobar{argument 1: #1 argument 2: #2}
.
⟨control sequence⟩ = macro
.
⟨parameter text⟩ = #1#2foobar
⟨replacement text⟩ = argument 1: #1 argument 2: #2
When you look at the expression, you see that at the right end of the ⟨parameter text⟩, there will be the tokens that form the delimiter of the last argument, i.e., the tokens foobar
. They belong to the tokens which form the ⟨parameter text⟩. Right behind them you can see the left-brace from that pair of braces that surrounds the ⟨replacement text⟩.
Thus in this case at the right end of the ⟨parameter text⟩ you find the tokens that delimit the last argument and you find the left-brace of the pair of braces that surrounds the ⟨replacement text⟩.
The sequence
macro{A}Bfoobar
yields:
argument 1: A argument 2: B
As you can see, the delimiting tokens foobar
were removed while gathering the tokens that belong to the arguments.
If instead you define:
defmacro#1#2foobar{argument 1: #1 argument 2: #2foobar}
.
⟨control sequence⟩ = macro
.
⟨parameter text⟩ = #1#2foobar
⟨replacement text⟩ = argument 1: #1 argument 2: #2foobar
, i.e., if you insert the delimiter foobar
at the right end of the ⟨replacement text⟩ also, the sequence
macro{A}Bfoobar
yields
argument 1: A argument 2: Bfoobar
as if with the previous definition the delimiter had been left in place.
What if you wish to define such a thing but the delimiter not being a sequence foobar
but being a left-brace?
The definition should still be of pattern
defmacro#1#2⟨delimiter⟩{argument 1: #1 argument 2: #2⟨delimiter⟩}
but for several reasons you cannot take {
as ⟨delimiter⟩ and write
defmacro#1#2{{argument 1: #1 argument 2: #2{}
and hereby take #1#2{
for the ⟨parameter text⟩ and argument 1: #1 argument 2: #2{
for the ⟨replacement text⟩:
In many situations one cannot easily insert single left-braces without getting errors due to braces being unbalanced.
The situation would be ambiguous because (La)TeX would have to guess whether an opening brace near/at the right end of the ⟨parameter text⟩ is an argument-delimiter or whether it belongs to that pair of braces that surrounds the ⟨replacement text⟩.
(La)TeX would also have to guess whether the right-brace should just match the left-brace at the end of the ⟨replacement text⟩ or whether it should denote the end of the ⟨replacement text⟩.
Therefore as a syntactic workaround #{
-notation was invented:
With
defmacro#1#2#{argument 1: #1 argument 2: #2}
⟨control sequence⟩ = macro
.
⟨parameter text⟩ = #1#2#
⟨replacement text⟩ = argument 1: #1 argument 2: #2
, the ⟨parameter text⟩ does not end with a token {
that shall delimit the last argument but it does end with #
.
That #
is used for denoting that (La)TeX shall search a left-brace as argument-delimiter when during the process of expanding macro
gathering the tokens of the last argument of macro
from the token stream. That #
also denotes that the left-brace found as delimiter shall be left in place so that the ⟨replacement text⟩ of macro
goes before it.
In other words:
That #
causes (La)TeX to behave as if as last token that is to delimit the last argument a left-brace was found in the ⟨parameter text⟩.
It also causes (La)TeX to behave as if the last token given in the definition's ⟨replacement text⟩ was a left-brace.
To your comment:
Umm. I don't suppose you could make something up? A best guess at what
is going on? Let me rephrase, in your other example if you even have
cat code 1 characters floating about in all of this. Is it right to
infer that this "primitive behavior" is occurring during the input
phase of reading the file? (Sorry, I am making up terminology as I go
... I am speaking of theprocess_input_buffer
event handler.
The very first stage of processing in LaTeX is reading the input (from file or from console) and taking it for a set of instructions for putting tokens into the token-stream. (Character-tokens/control-sequence-tokens). In subsequent stages the tokens in the token-stream get processed. In an earlier one of these stages, expandable tokens, e.g., macros, get expanded. I.e., they get replaced by those tokens that form the replacement-texts of their definitions. In this stage gathering tokens for macro-arguments takes place. Thus the behavior does not take place when reading the file but does take place after reading and tokenizing, in the stage of expanding expandable tokens and hereby gathering other tokens as their arguments.
I tried to elaborate in detail on how (La)TeX does gather and process macro arguments in my answer to the question How does TeX look for delimited arguments?
I tried to elaborate in detail on expandafter
and on ways of avoiding it in my answer to the question How can I know the number of expandafters when appending to a csname macro?
I tried to elaborate in detail on the macro name
in my answer to the question Define a control sequence after that a space matters
edited 6 hours ago
answered 11 hours ago
Ulrich DiezUlrich Diez
5,105618
5,105618
So therefore, theFirst { Brace
is being inserted IMMEDIATELY BEFORE the parameter text,3
in the case explained in the text. (Letters can't be delimiters, apparently). TheSecond { Brace
is being inserted IMMEDIATELY before theLast } Brace
of the replacement text. defa#1#{hbox to #1} a3pt{x} ... I have no idea why the book's explanation says something very different. Anyway, could you put those locations in your answer, so I can accept it? Thank you very much for your help!
– elika kohen
9 hours ago
add a comment |
So therefore, theFirst { Brace
is being inserted IMMEDIATELY BEFORE the parameter text,3
in the case explained in the text. (Letters can't be delimiters, apparently). TheSecond { Brace
is being inserted IMMEDIATELY before theLast } Brace
of the replacement text. defa#1#{hbox to #1} a3pt{x} ... I have no idea why the book's explanation says something very different. Anyway, could you put those locations in your answer, so I can accept it? Thank you very much for your help!
– elika kohen
9 hours ago
So therefore, the
First { Brace
is being inserted IMMEDIATELY BEFORE the parameter text, 3
in the case explained in the text. (Letters can't be delimiters, apparently). The Second { Brace
is being inserted IMMEDIATELY before the Last } Brace
of the replacement text. defa#1#{hbox to #1} a3pt{x} ... I have no idea why the book's explanation says something very different. Anyway, could you put those locations in your answer, so I can accept it? Thank you very much for your help!– elika kohen
9 hours ago
So therefore, the
First { Brace
is being inserted IMMEDIATELY BEFORE the parameter text, 3
in the case explained in the text. (Letters can't be delimiters, apparently). The Second { Brace
is being inserted IMMEDIATELY before the Last } Brace
of the replacement text. defa#1#{hbox to #1} a3pt{x} ... I have no idea why the book's explanation says something very different. Anyway, could you put those locations in your answer, so I can accept it? Thank you very much for your help!– elika kohen
9 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%2f477537%2fwhat-is-notation-how-does-the-syntax-work%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
2
#1
,#2
, etc. are the arguments. For example, if you havenewcommand{mycommand}[2]{#1 and #2}
andmycommand{Hello}{world}
you will get "Hello and world".– JouleV
13 hours ago
Could you highlight what you want to know?
– TeXnician
13 hours ago
In absence of the TeXbook you could have a look at §11.5.6 Brace delimiting in TeX by Topic, though the passage is not very long.
– moewe
13 hours ago
1
The
#1#
is a nice bracing trick but definitely not fundamental syntax (the usualdef
s work without the second#
). That's why I asked what exactly your question is.– TeXnician
13 hours ago
1
See tex.stackexchange.com/a/474903/2388 for an explanation about the #1# syntax.
– Ulrike Fischer
12 hours ago