On 10 August 2015 at 18:07, David Kastrup <[email protected]> wrote:
>> Here's a change that I think's nicer, which does the expansion of the
>> active backslash earlier as an extra stage of expansion.
>
> Well, this is an interesting one...
>
> \entry{Tiny examples}{90}{\code {Tiny examples}}
> ] [91]
> /usr/local/tmp/lilypond/Documentation/contributor/issues.itexi:275: Undefined 
> c
> ontrol sequence.
> <argument> @empty Simple@unhbox @voidb
>                                        @x @penalty @tiepenalty @ 
> tasks@unhbo...
>

> l.275 @qq{Simple tasks -- Documentation}
>                                          on:
> ?
> /usr/local/tmp/lilypond/Documentation/contributor/issues.itexi:275: Emergency 
> s
> top.

> With the definition
>
> @macro qq{TEXT}
> @quotedblleft{}\TEXT\@quotedblright{}
> @end macro

I didn't reproduce this at first. I had downloaded the LilyPond
sources a couple of days ago, although couldn't build the
documentation because of numerous missing dependencies. I thought I'd
have a look at the source and found that the macro use was in an
@example environment. Trying this, I got the same error.

Tracing the macros gives this:

@arg ->Simple t@macroargdummy

 ->@leavevmode @penalty @tiepenalty @

The space itself is being expanded. Since space was \let equal to \tie
with \sepspaces when \example was opened, the space is expanding to
the definition of \tie.

Adding an extra line

\catcode`\ =\other

eliminates this expansion.
Index: texinfo.tex
===================================================================
--- texinfo.tex (revision 6493)
+++ texinfo.tex (working copy)
@@ -7460,7 +7460,9 @@
 
 \def\macroargctxt{% used when scanning invocations
   \scanctxt
-  \catcode`\\=0
+  \catcode`\ =\other
+  \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"
@@ -7907,16 +7909,52 @@
 
 \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
 
+% Call #1 with a list of tokens #2, with any doubled backslashes in #2
+% compressed to one.
+\def\passargtomacro#1#2{%
+% Append an unexpandable token to #2, to allows a trailing
+% active backslash in the argument not to eat the next token.
+\let\macroargdummy=\relax
+\def\arg{#2\macroargdummy}%
+%
+% Expand the arg list.  There won't be unwanted expansion of control sequences 
+% in the argument because the arg was read with the catcode of @ as \other.
+\let\resultingbackslash=\relax % prevent expansion
+\usemacroargbackslash
+\macroargctxt
+\def\macroargdummy{}%
+\edef\arg{\arg}%
+\expandafter#1\expandafter{\arg}%
+}
+
+% use active definition of backslash at time of expansion
+\def\resultingbackslash{\activebackslash}
+
+% \macroargbackslash
+% - expand \\ and single \ as \resultingbackslash
+{ \catcode`\@=0 @catcode`@\=@active
+@gdef@macroargbackslash#1{%
+% we need noexpand because \ is active
+@if @noexpand \@noexpand #1@resultingbackslash%
+@else @resultingbackslash #1%
+@fi}
+
+@gdef@usemacroargbackslash{@let\=@macroargbackslash}
+}
+
+
 % \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.
+% to read the argument, in the whole-line case, it then calls the regular
+% \parsearg MAC; in the lbrace case, it calls \passargtomacro MAC.
 % 
 \def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx}
 \def\braceorlinexxx{%
-  \ifx\nchar\bgroup\macroargctxt
-  \else\macrolineargctxt\expandafter\parsearg
+  \ifx\nchar\bgroup
+    \macroargctxt\expandafter\passargtomacro
+  \else
+    \macrolineargctxt\expandafter\parsearg
   \fi \macnamexxx}
 
 
@@ -10292,7 +10330,10 @@
 % catcode other.  We switch back and forth between these.
 @gdef@rawbackslash{@let\=@backslashcurfont}
 @gdef@otherbackslash{@let\=@realbackslash}
+@gdef@usenormalbackslash{@let\=@normalbackslash}
 
+{@catcode`@\=@active @gdef@activebackslash{\}}
+
 @gdef@usemathbackslash{@def@backslashcurfont{@math{@backslash}}}
 
 % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of

Attachment: quotedblleft.texi
Description: TeXInfo document

Reply via email to