> Allow me to post my work so far. I seem to have something working for
> backslashes. I haven't got { and } to work yet.
>
> My test file is "macro-backslash.texi", attached. I've tested macro
> invocations both with and without braces, to check that I am not
> messing anything up for the case with braces. To test this, try
> replacing one of the instances of "\\yesbrace" with "\yesbrace", in
> order to get an error message about an undefined control sequence. As
> you can see from the output dvi file, both "\\" and "\" effect a "\"
> in the output for a line argument.
A month or so ago I made more progress on this. If I remember
correctly, previous changes I posted had the flaw that the definition
of backslash would be permanently changed for the rest of the
document. I managed to fix this flaw, and went on to try to get \, to
work as an escape for a comma for macros taking multiple arguments.
This was more complicated though, and I never finished it.
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'm sure it's possible to get it to work for macros of multiple
arguments as well, but I expect that that use case isn't as common; so
I figured it's better just to put out what I've got so far, instead of
holding out for a perfect solution that I may never finish.
\} and \{ aren't important to support: they would only be needed in
cases when a macro argument contains unbalanced braces.
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.
Index: ChangeLog =================================================================== --- ChangeLog (revision 6513) +++ ChangeLog (working copy) @@ -1,5 +1,21 @@ 2015-08-08 Gavin Smith <[email protected]> + * doc/texinfo.tex (\macroargctxt): Make catcode of backslash + active, instead of escape. + (\usemacroargbackslash): New macro to set an active definition + of backslash. + (\callwithterminator): New macro. + (\macroargdummy): New unexpandable control sequence. + (\braceorline): Open two groups, the outer possibly with a + changed active definition for backslash, the inner just for + getting the argument. For a braced argument, call macro via + \callwithterminator. + (\defmacro) <1 arg recursive, 1 arg not recursive>: End the + extra group opened in \braceorline, and rely on \braceorline to + open all groups for us. + +2015-08-08 Gavin Smith <[email protected]> + * info/session.c (_scroll_forward, _scroll_backward): Set point at beginning (resp. end) of node if going backwards (resp. forwards) failed. If we did go backwards, put the cursor at the Index: doc/texinfo.tex =================================================================== --- doc/texinfo.tex (revision 6493) +++ doc/texinfo.tex (working copy) @@ -7458,9 +7458,22 @@ end \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 @@ end \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 @@ end \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 @@ end \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}
bsbsbs.texi
Description: TeXInfo document
