texinfo-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[6785] macro argument backslash implementation with expansion stage


From: Gavin D. Smith
Subject: [6785] macro argument backslash implementation with expansion stage
Date: Mon, 16 Nov 2015 18:21:22 +0000

Revision: 6785
          http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=6785
Author:   gavin
Date:     2015-11-16 18:21:21 +0000 (Mon, 16 Nov 2015)
Log Message:
-----------
macro argument backslash implementation with expansion stage

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/doc/texinfo.tex

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog     2015-11-15 14:45:20 UTC (rev 6784)
+++ trunk/ChangeLog     2015-11-16 18:21:21 UTC (rev 6785)
@@ -1,3 +1,15 @@
+2015-11-16  Gavin Smith  <address@hidden>
+
+       * doc/texinfo.tex (\passargtomacro): Rewrite to operate purely 
+       at TeX's expansion stage.
+       (\defmacro): Use \passargtomacro for macros of more than one 
+       argument.
+       (\macroargctxt): Change catcode of space.
+       (\scanmacro): Don't call \passargtomacro because macro arguments 
+       have already been processed.
+       (\pdfurl, \commondummiesnofonts): Remove definition of 
+       \xprocessmacroarg.
+
 2015-11-15  Gavin Smith  <address@hidden>
 
        * doc/texinfo-text-test.texi: Add examples of spaces in macro 

Modified: trunk/doc/texinfo.tex
===================================================================
--- trunk/doc/texinfo.tex       2015-11-15 14:45:20 UTC (rev 6784)
+++ trunk/doc/texinfo.tex       2015-11-16 18:21:21 UTC (rev 6785)
@@ -3,7 +3,7 @@
 % Load plain if necessary, i.e., if running under initex.
 \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
 %
-\def\texinfoversion{2015-10-29.16}
+\def\texinfoversion{2015-11-16.18}
 %
 % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
 % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
@@ -1416,7 +1416,6 @@
       \normalturnoffactive
       address@hidden@}%
       \let\/=\empty
-      \let\xprocessmacroarg=\eatspaces % in case we are in a macro expansion
       \makevalueexpandable
       % do we want to go so far as to use \indexnofonts instead of just
       % special-casing \var here?
@@ -4676,16 +4675,6 @@
   \definedummyword\verb
   \definedummyword\w
   \definedummyword\xref
-  %
-  % Consider:
-  %   @macro mkind{arg1,arg2}
-  %   @cindex \arg2\
-  %   @end macro
-  %   @mkind{foo, bar}
-  % The space after the comma will end up in the temporary definition
-  % that we make for arg2 (see \parsemargdef ff.).  We want all this to be
-  % expanded for the sake of the index, so we end up just seeing "bar".
-  \let\xprocessmacroarg\eatspaces
 }
 
 % For testing: output @{ and @} in index sort strings as \{ and \}.
@@ -7612,8 +7601,7 @@
 % Argument is macro body with arguments substituted
 \def\scanmacro#1{%
   \newlinechar`\^^M
-  % Reduce doubled backslashes to one
-  \def\xprocessmacroarg{\passargtomacro\eatspaces}%
+  \def\xprocessmacroarg{\eatspaces}%
   %
   % Process the macro body under the current catcode regime.
   \scantokens{#1\texinfoc}\aftermacro%
@@ -7733,6 +7721,7 @@
 % an argument to another Texinfo command.
 \def\macroargctxt{%
   \scanctxt
+  \catcode`\ =\active
   \catcode`\^^M=\other
   \catcode`\\=\active
 }
@@ -8127,16 +8116,23 @@
          \egroup\noexpand\scanmacro{\macrobody}}%
     \else
       \ifnum\paramno<10\relax % at most 9
+        % See non-recursive section below for comments
         \expandafter\xdef\csname\the\macname\endcsname{%
-           \bgroup\noexpand\macroargctxt
-           \noexpand\csname\the\macname @@\endcsname}%
+          \bgroup
+          \noexpand\expandafter
+          \noexpand\macroargctxt
+          \noexpand\expandafter
+          \expandafter\noexpand\csname\the\macname @@\endcsname}%
         \expandafter\xdef\csname\the\macname @@\endcsname##1{%
-            \expandafter\noexpand\csname\the\macname @@@\endcsname ##1,}%
+            \noexpand\passargtomacro
+            \expandafter\noexpand\csname\the\macname @@@\endcsname{##1,}}%
+        \expandafter\xdef\csname\the\macname @@@\endcsname##1{%
+            \expandafter\noexpand\csname\the\macname @@@@\endcsname ##1}%
         \expandafter\expandafter
         \expandafter\xdef
         \expandafter\expandafter
-          \csname\the\macname @@@\endcsname
-            \paramlist{\egroup\noexpand\scanmacro{\macrobody}}%
+          \csname\the\macname @@@@\endcsname\paramlist{%
+            \egroup\noexpand\scanmacro{\macrobody}}%
       \else % 10 or more
         \expandafter\xdef\csname\the\macname\endcsname{%
           address@hidden
@@ -8166,19 +8162,27 @@
         }%
     \else % at most 9
       \ifnum\paramno<10\relax
+        % @MACNAME sets the context for reading the macro argument
+        % @MACNAME@@ gets the argument, processes backslashes and appends a 
+        % comma.
+        % @MACNAME@@@ removes braces surrounding the argument list.
+        % @MACNAME@@@@ scans the macro body with arguments substituted.
         \expandafter\xdef\csname\the\macname\endcsname{%
-           \bgroup\noexpand\macroargctxt
-           \expandafter\noexpand\csname\the\macname @@\endcsname}%
+          \bgroup
+          \noexpand\expandafter  % This \expandafter skip any spaces after the
+          \noexpand\macroargctxt % macro before we change the catcode of space.
+          \noexpand\expandafter
+          \expandafter\noexpand\csname\the\macname @@\endcsname}%
         \expandafter\xdef\csname\the\macname @@\endcsname##1{%
-            \expandafter\noexpand\csname\the\macname @@@\endcsname ##1,}%
+            \noexpand\passargtomacro
+            \expandafter\noexpand\csname\the\macname @@@\endcsname{##1,}}%
+        \expandafter\xdef\csname\the\macname @@@\endcsname##1{%
+            \expandafter\noexpand\csname\the\macname @@@@\endcsname ##1}%
         \expandafter\expandafter
         \expandafter\xdef
         \expandafter\expandafter
-        \csname\the\macname @@@\endcsname
-        \paramlist{%
-            \egroup
-            \noexpand\scanmacro{\macrobody}%
-            }%
+          \csname\the\macname @@@@\endcsname\paramlist{%
+            \egroup\noexpand\scanmacro{\macrobody}}%
       \else % 10 or more:
         \expandafter\xdef\csname\the\macname\endcsname{%
           address@hidden
@@ -8194,71 +8198,96 @@
 \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
 
 
address@hidden \catcode`\\=13
address@hidden@_=11
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
address@hidden \catcode`\\=13  % We need to manipulate \ so use @ as escape
address@hidden@_=11  % private names
address@hidden@!=11  % used as argument separator
 
+% \passargtomacro#1#2 -
 % Call #1 with a list of tokens #2, with any doubled backslashes in #2
 % compressed to one.
+%
+% This implementation works by expansion, and not execution (so we cannot use 
+% \def or similar).  This reduces the risk of this failing in contexts where 
+% complete expansion is done with no execution (for example, in writing out to 
+% an auxiliary file for an index entry).
+% 
+% State is kept in the input stream: the argument passed to
+% @look_ahead, @gobble_and_check_finish and @add_segment is
+%
+% THE_MACRO ARG_RESULT ! {PENDING_BS} NEXT_TOKEN  (... rest of input)
+%
+% where:
+% THE_MACRO - name of the macro we want to call
+% ARG_RESULT - argument list we build to pass to that macro
+% PENDING_BS - either a backslash or nothing
+% NEXT_TOKEN - used to look ahead in the input stream to see what's coming next
+
 @address@hidden
-  @address@hidden
-  @address@hidden
-  @address@hidden@finish}%
-  @address@hidden
-  @address@hidden@relax
-  @address@hidden
+  @add_segment address@hidden@_finish\%
 }
address@hidden@address@hidden @address@hidden@address@hidden
 
-% Input stream is just after a backslash.  If the next token is not a
-% backslash, process the rest of the argument; otherwise, remove the next
-% token.
address@hidden@look_ahead{%
-  @address@hidden@look_aheadzzz}
address@hidden@look_aheadzzz{%
-  @address@hidden
-   @address@hidden@gobble_and_check_finish 
+% #1 - THE_MACRO ARG_RESULT
+% #2 - PENDING_BS
+% #3 - NEXT_TOKEN
+% #4 used to look ahead
+%
+% If the next token is not a backslash, process the rest of the argument; 
+% otherwise, remove the next token.
address@hidden@look_ahead#1!#2#3#4{%
+  @ifx#4\%
+   @address@hidden 
   @else
-   @address@hidden@add_segment
-  @address@hidden
+   @address@hidden
+  @fi#1!{#2}#4#4%
 }
 
-% Double backslash found.  Add a single backslash here.
address@hidden@gobble_and_check_finish#1{%
-  @add_the_backslash
-  @address@hidden
-  @address@hidden@add_segment
+% #1 - THE_MACRO ARG_RESULT
+% #2 - PENDING_BS
+% #3 - NEXT_TOKEN
+% #4 should be a backslash, which is gobbled.
+% #5 looks ahead
+%
+% Double backslash found.  Add a single backslash, and look ahead.
address@hidden@gobble_and_check_finish#1!#2#3#4#5{%
+  @add_segment#1\!{}#5#5%
 }
 
-% append a backslash to \arg_result
address@hidden@add_the_backslash{%
-  @address@hidden@address@hidden@address@hidden
-}
address@hidden@address@hidden
 
+% #1 - THE_MACRO ARG_RESULT
+% #2 - PENDING_BS
+% #3 - NEXT_TOKEN
+% #4 is input stream until next backslash
+%
 % Input stream is either at the start of the argument, or just after a 
 % backslash sequence, either a lone backslash, or a doubled backslash.  
-% \next_token contains the first token in the input stream: if it is \finish, 
-% finish; otherwise, append to \arg_result the segment of the argument up until
-% the next backslash.  \pending_backslash contains a backslash to represent
+% NEXT_TOKEN contains the first token in the input stream: if it is \finish, 
+% finish; otherwise, append to ARG_RESULT the segment of the argument up until
+% the next backslash.  PENDING_BACKSLASH contains a backslash to represent
 % a backslash just before the start of the input stream that has not been
-% added to \arg_result.
address@hidden@add_segment#1\{%
address@hidden@address@hidden
-  @address@hidden@call_the_macro%
+% added to ARG_RESULT.
address@hidden@add_segment#1!#2#3#4\{%
address@hidden@_finish
+  @call_the_macro#1!%
 @else
-  @address@hidden@look_ahead
-  %
-  % append to @arg_result
-  % token list registers might be better
-  @address@hidden@address@hidden
-  @address@hidden@address@hidden
-  @address@hidden@expandafter{%
-  @address@hidden
-  @pending_backslash#1}%
-  @address@hidden
address@hidden@next}
+  % append the pending backslash to the result, followed by the next segment
+  @address@hidden@address@hidden
+  % this @fi is discarded by @look_ahead.
+  % we can't get rid of it with \expandafter because we don't know how 
+  % long #4 is.
+}
 
address@hidden@address@hidden@address@hidden@arg_result}}
+% #1 - THE_MACRO
+% #2 - ARG_RESULT
+% #3 discards the res of the conditional in @add_segment, and @is_fi ends the 
+% conditional.
address@hidden@address@hidden@is_fi #1{#2}}
 
 }
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 % \braceorline MAC is used for a one-argument macro MAC.  It checks
 % whether the next non-whitespace character is a {.  It sets the context




reply via email to

[Prev in Thread] Current Thread [Next in Thread]