On 8 August 2015 at 21:27, Gavin Smith <[email protected]> wrote:
> All I can think of at the moment is not to add the dummy token at the
> end of the argument, and not use the backslash as the last character
> of the argument of the macro. It will work sometimes, depending on
> which token a final backslash absorbs, but there are likely cases when
> this could cause a problem as well.
>
> I'd like to make the @macroargdummy token completely disappear at some
> point, but maybe it isn't possible.
Doing \def\macroargdummy{} in \scanmacro also makes the files I tried
work. It didn't the first time I tried, maybe because I had stale
index files.
Index: doc/texinfo.tex
===================================================================
--- doc/texinfo.tex (revision 6493)
+++ doc/texinfo.tex (working copy)
@@ -7356,6 +7356,7 @@
%
% ... and for \example:
\spaceisspace
+ \def\macroargdummy{}
%
% The \empty here causes a following catcode 5 newline to be eaten as
% part of reading whitespace after a control sequence. It does not
@@ -7458,9 +7459,22 @@
\usembodybackslash
}
+% \macroargbackslash
+% - expand \\ as \, otherwise keep \ as it is.
+{ \catcode`\@=0 @catcode`@\=@active
+@gdef@macroargbackslash#1{%
+% we need noexpand because \ is active
+@if @noexpand \@noexpand #1@normalbackslash%
+@else @normalbackslash #1%
+@fi}
+
+@gdef@usemacroargbackslash{@let\=@macroargbackslash}
+}
+
\def\macroargctxt{% used when scanning invocations
\scanctxt
- \catcode`\\=0
+ \catcode`\\=\active
+ %\catcode`\\=0
}
% why catcode 0 for \ in the above? To recognize \\ \{ \} as "escapes"
% for the single characters \ { }. Thus, we end up with the "commands"
@@ -7838,11 +7852,10 @@
\noexpand\scanmacro{\temp}}%
\or % 1
\expandafter\xdef\csname\the\macname\endcsname{%
- \bgroup
\noexpand\braceorline
\expandafter\noexpand\csname\the\macname xxx\endcsname}%
\expandafter\xdef\csname\the\macname xxx\endcsname##1{%
- \egroup\noexpand\scanmacro{\temp}}%
+ \egroup\noexpand\scanmacro{\temp}\egroup}%
\else
\ifnum\paramno<10\relax % at most 9
\expandafter\xdef\csname\the\macname\endcsname{%
@@ -7871,13 +7884,13 @@
\noexpand\scanmacro{\temp}\egroup}%
\or % 1
\expandafter\xdef\csname\the\macname\endcsname{%
- \bgroup
\noexpand\braceorline
\expandafter\noexpand\csname\the\macname xxx\endcsname}%
\expandafter\xdef\csname\the\macname xxx\endcsname##1{%
\egroup
\noexpand\norecurse{\the\macname}%
- \noexpand\scanmacro{\temp}\egroup}%
+ \noexpand\scanmacro{\temp}\egroup%
+ \egroup}%
\else % at most 9
\ifnum\paramno<10\relax
\expandafter\xdef\csname\the\macname\endcsname{%
@@ -7907,16 +7920,33 @@
\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
+\let\macroargdummy=\relax
+
+% Call #1 with a list of tokens #2, appending an unexpandable token to #2.
+% This allows a trailing active backslash in the argument not to eat the
+% next token.
+\def\callwithterminator#1#2{%
+#1{#2\macroargdummy}%
+}
+
% \braceorline MAC is used for a one-argument macro MAC. It checks
% whether the next non-whitespace character is a {. It sets the context
-% for reading the argument (slightly different in the two cases). Then,
-% to read the argument, in the whole-line case, it then calls the
-% regular \parsearg MAC; in the lbrace case, it just calls MAC itself.
+% for reading the argument (slightly different in the two cases). It
+% opens two groups for this: the inner for reading the argument, the
+% outer for an optional active character definition to remain in place
+% for the macro body.
%
+% To read the argument, in the whole-line case, it then calls the
+% regular \parsearg MAC; in the lbrace case, it calls
+% \callwithterminator MAC.
+%
\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx}
\def\braceorlinexxx{%
- \ifx\nchar\bgroup\macroargctxt
- \else\macrolineargctxt\expandafter\parsearg
+ \ifx\nchar\bgroup
+ \bgroup\usemacroargbackslash\bgroup\macroargctxt
+ \expandafter\callwithterminator
+ \else
+ \bgroup\bgroup\macrolineargctxt\expandafter\parsearg
\fi \macnamexxx}