> 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}
 
 

Attachment: bsbsbs.texi
Description: TeXInfo document

Reply via email to