On 8 August 2015 at 20:31, David Kastrup <[email protected]> wrote: > Gavin Smith <[email protected]> writes: >> The change I've attached to this email works for macros taking a >> single argument only, and allows backslashes to appear on their own in >> braced arguments, while double backslashes are converted into a single >> backslash.
>> I've attached a test file showing use of a @macro and a @rmacro for
>> braced and whole-line arguments. Please have a play around and post if
>> anything breaks.
>
> breaks.
>
> This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2015/dev/Debian)
> (preloaded format=pdfetex)
> restricted \write18 enabled.
> entering extended mode
> (./music-glossary.texi (/usr/local/tmp/lilypond/tex/texinfo.tex
> Loading texinfo [version 2015-08-03.11]: pdf, fonts, markup, glyphs,
> page headings, tables, conditionals, indexing, sectioning, toc, environments,
> defuns, macros, cross references, insertions,
> (/usr/share/texlive/texmf-dist/tex/generic/epsf/epsf.tex
> This is `epsf.tex' v2.7.4 <14 February 2011>
> ) localization, formatting, and turning on texinfo input format.)
> (/usr/local/tmp/lilypond/tex/txi-en.tex) (./macros.texi (./version.texi)
> (./common-macros.texi{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}{/usr/l
> ocal/tmp/lilypond/tex/./out-www/lilypond.map} (./cyrillic.texi)))
> ./music-glossary.texi:39: Missing @endcsname inserted.
> <to be read again>
> @macroargdummy
The attached patch comments out the line that calls the macro that
adds this dummy token. It works with the test file attached.
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.
ref-in-macro.texi
Description: TeXInfo document
Index: doc/texinfo.tex
===================================================================
--- doc/texinfo.tex (revision 6493)
+++ doc/texinfo.tex (working copy)
@@ -7458,9 +7458,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 +7851,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 +7883,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 +7919,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}
