bug-texinfo
[Top][All Lists]
Advanced

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

[PATCH] @quote-args for multiple arguments


From: Sergey Poznyakoff
Subject: [PATCH] @quote-args for multiple arguments
Date: Sun, 02 Jul 2006 02:17:16 +0300

Hello,

Currently the @quote-args command is not much useful: it is allowed only
in macros taking exactly one argument, but for such macros argument
quotation is enabled by default anyway.  The attached patch enables
@quote-args for macros taking multiple arguments as well, so one can
call

 @address@hidden, b}, c}

without escaping commas (see the included testcase). It also updates
the documentation (neither @quote-args nor @allow-recursion were
documented), and fixes a bug in txi-pl.tex that prevented its use with
the latest TeTeX (3.0).

Regards,
Sergey

ChangeLog:

2006-07-02  Sergey Poznyakoff  <address@hidden>

        * doc/txi-pl.tex: Do not use \prefixing and \notprefixing. They
        were defined in PLaTeX, but are no longer global. Use ISO-8859-1
        instead.

        * doc/texinfo.tex (quote-arg, allow-recursion): New macros
        * doc/texinfo.txi: Document @quote-arg and @allow-recursion
        commands.
        * makeinfo/macro.c: Implement @quote-arg for macros taking more
        than 1 argument.
        (add_macro): Initialize argcount
        (get_brace_args): Change argument type to enum quote_type.
        All callers updated.
        Handle @quote-arg for multi-argument macros
        (expand_macro) Use def->argcount instead of re-counting arguments.
        Allow for @quote-arg in multi-argument macros
        * makeinfo/macro.h (MACRO_DEF): New member argcount
        (enum quote_type): New data type.
        (get_brace_args): Change argument type to enum quote_type
        * makeinfo/makeinfo.c (cm_ifeq): Update call to get_brace_args
        * makeinfo/tests/Makefile.am (TESTS): New test quote-args
        (EXTRA_DIST): New file quote-args.txi
        * makeinfo/tests/quote-args: New test
        * makeinfo/tests/quote-args.txi: New file

Index: doc/texinfo.tex
===================================================================
RCS file: /cvsroot/texinfo/texinfo/doc/texinfo.tex,v
retrieving revision 1.216
diff -p -u -r1.216 texinfo.tex
--- doc/texinfo.tex     19 Jun 2006 22:55:33 -0000      1.216
+++ doc/texinfo.tex     1 Jul 2006 22:48:48 -0000
@@ -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{2006-06-19.13}
+\def\texinfoversion{2006-07-02.01}
 %
 % Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
 % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free
@@ -5974,6 +5974,10 @@ where each line of input produces a line
 }
 \expandafter\def\csname macarg.\endcsname{\realbackslash}
 
+\def\quote-arg{}
+  
address@hidden used in \the\macname\space; either use @rmacro, or preprocess 
the document before feeding it to TeX}}
+ 
 \def\macro{\recursivefalse\parsearg\macroxxx}
 \def\rmacro{\recursivetrue\parsearg\macroxxx}
 
Index: doc/texinfo.txi
===================================================================
RCS file: /cvsroot/texinfo/texinfo/doc/texinfo.txi,v
retrieving revision 1.166
diff -p -u -r1.166 texinfo.txi
--- doc/texinfo.txi     24 Jun 2006 22:02:28 -0000      1.166
+++ doc/texinfo.txi     1 Jul 2006 22:49:41 -0000
@@ -13691,6 +13691,7 @@ other whitespace is treated according to
 
 @cindex Recursive macro invocations
 @findex rmacro
address@hidden allow-recursion
 To allow a macro to be used recursively, that is, in an argument to a
 call to itself, you must define it with @samp{@@rmacro}, like this:
 
@@ -13705,6 +13706,93 @@ a\arg\b
 This produces the output `a1atextb2b'.  With @samp{@@macro} instead of
 @samp{@@rmacro}, an error message is given.
 
address@hidden allow-recursion
+You can achieve the same effect by using @samp{@@allow-recursion}
+command within a macro definition.  Using this method, the above
+example will look like:
+
address@hidden
+@@macro mac @address@hidden
+@@allow-recursion
+a\arg\b
+@@end macro
address@hidden example
+
+Both ways of defining recursive macros are completely equivalent as
+far as @code{info} output is concerned.  However,
address@hidden@@allow-recursion} does not work with @TeX{}, so if your
+document uses it, you will need to preprocess it before feeding to
address@hidden (@pxref{Format with texi2dvi}).
+
+If a recursive macro accepts more than one argument, invoking it can
+require escaping comma characters.  Consider, for example, the
+following macro that concatenates its two arguments:
+
address@hidden
address@hidden
+@@rmacro address@hidden,address@hidden
+\a\\b\
+@@end rmacro
address@hidden group
address@hidden example
+
address@hidden quote-arg
+Calling @code{@@address@hidden, address@hidden will produce string
address@hidden  What if you wish to use this macro to concatenate
+three strings?  The straightforward approach would be to concatenate
+two of them and than pass the resulting string as an arument to
+another invocation of @code{@@cat}, e.g.: 
@code{@@address@hidden@@address@hidden, address@hidden,
address@hidden  Unfortunately, in this case extra commas in the macro
+invocation will confuse @command{makeinfo}.  There are two ways to
+cope with this.  First, you can escape the internal comma using
+a backslash character, like that: @code{@@address@hidden@@address@hidden, 
address@hidden,
address@hidden  Secondly, you can define @code{@@cat} with @dfn{argument
+quoting}, using special command @code{@@quote-arg}:
+
address@hidden
address@hidden 
+@@rmacro address@hidden,address@hidden
+@@quote-arg
+\a\\b\
+@@end rmacro
address@hidden group
address@hidden example
+
+Once you rewrite your macro this way, you can use calls to other
+macros as its arguments, @command{makeinfo} will properly quote commas
+occurring within its invocation.
+
+Notice, that @code{@@quote-arg} is set by default for macros that
+accept only one argument.  On one hand it allows to invoke such
+macros with arguments containing commas without worrying about
address@hidden subtleties.  Thus, this example:
+
address@hidden
address@hidden
+@@macro address@hidden@}
+@@address@hidden: address@hidden
+@@end macro
+
+@@address@hidden nice feature, though it can be address@hidden
address@hidden group
address@hidden example
+
address@hidden
+will produce the following output
+
address@hidden
address@hidden: A nice feature, though it can be dangerous.}
address@hidden example
+
+And indeed, it can.  Namely, @command{makeinfo}
+does not control number of arguments passed to one-argument
+macros, so be careful when you invoke them.
+
+The @samp{@@quote-arg} command is a no-op for @TeX{}.
+
+Both @samp{@@quote-arg} and @samp{@@allow-recursion} are allowed only
+within a macro declaration.  Using them elsewhere results in error.
+
 @findex unmacro
 @cindex Macros, undefining
 @cindex Undefining macros
Index: doc/txi-pl.tex
===================================================================
RCS file: /cvsroot/texinfo/texinfo/doc/txi-pl.tex,v
retrieving revision 1.4
diff -p -u -r1.4 txi-pl.tex
--- doc/txi-pl.tex      15 May 2005 00:00:06 -0000      1.4
+++ doc/txi-pl.tex      1 Jul 2006 22:49:42 -0000
@@ -1,7 +1,7 @@
 % txi-pl.tex -- adaptation to Polish for texinfo.tex.
 % $Id: txi-pl.tex,v 1.4 2005/05/15 00:00:06 karl Exp $
 %
-% Copyright (C) 2003 Free Software Foundation.
+% Copyright (C) 2003, 2006 Free Software Foundation.
 %
 % This program is free software; you can redistribute it and/or modify
 % it under the terms of the GNU General Public License as published by
@@ -20,26 +20,25 @@
 % Written by Wojciech Polak <address@hidden> on 29-03-2003.
 % Modified by Staszek Wawrykiewicz <address@hidden> on 01-04-2003.
 %
-\prefixing
 \gdef\putwordAppendix{Suplement}
-\gdef\putwordChapter{Rozdzia/l}
+\gdef\putwordChapter{Rozdzia³}
 \gdef\putwordfile{plik}
 \gdef\putwordin{w}
 \gdef\putwordIndexIsEmpty{(Skorowidz jest pusty)}
 \gdef\putwordIndexNonexistent{(Brak skorowidza)}
 \gdef\putwordInfo{Info}
-\gdef\putwordInstanceVariableof{Przyk/ladowa zmienna}
+\gdef\putwordInstanceVariableof{Przyk³adowa zmienna}
 \gdef\putwordMethodon{Metoda}
-\gdef\putwordNoTitle{Brak tytu/lu}
+\gdef\putwordNoTitle{Brak tytu³u}
 \gdef\putwordof{z}
 \gdef\putwordon{na}
 \gdef\putwordpage{strona}
-\gdef\putwordsection{cz/e/s/c}
-\gdef\putwordSection{Cz/e/s/c}
+\gdef\putwordsection{czê¶æ}
+\gdef\putwordSection{Czê¶æ}
 \gdef\putwordsee{zobacz}
 \gdef\putwordSee{Zobacz}
-\gdef\putwordShortTOC{Kr/otka zawarto/s/c}
-\gdef\putwordTOC{Spis tre/sci}
+\gdef\putwordShortTOC{Krótka zawarto¶æ}
+\gdef\putwordTOC{Spis tre¶ci}
 %
 \gdef\putwordMJan{stycznia}
 \gdef\putwordMFeb{lutego}
@@ -49,17 +48,16 @@
 \gdef\putwordMJun{czerwca}
 \gdef\putwordMJul{lipca}
 \gdef\putwordMAug{sierpnia}
-\gdef\putwordMSep{wrze/snia}
-\gdef\putwordMOct{pa/xdziernika}
+\gdef\putwordMSep{wrze¶nia}
+\gdef\putwordMOct{pa¼dziernika}
 \gdef\putwordMNov{listopada}
 \gdef\putwordMDec{grudnia}
 %
 \gdef\putwordDefmac{Makro}
 \gdef\putwordDefspec{Specjalna forma}
 \gdef\putwordDefvar{Zmienna}
-\gdef\putwordDefopt{Opcja u/zytkownika}
+\gdef\putwordDefopt{Opcja u¿ytkownika}
 \gdef\putwordDeffunc{Funkcja}
-\nonprefixing
 %
 % Produces Day Month Year style of output.
 %
Index: makeinfo/macro.c
===================================================================
RCS file: /cvsroot/texinfo/texinfo/makeinfo/macro.c,v
retrieving revision 1.8
diff -p -u -r1.8 macro.c
--- makeinfo/macro.c    15 May 2005 00:00:07 -0000      1.8
+++ makeinfo/macro.c    1 Jul 2006 22:49:44 -0000
@@ -151,13 +151,14 @@ add_macro (char *name, char **arglist, c
   def->source_lineno = source_lineno;
   def->body = body;
   def->arglist = arglist;
+  def->argcount = array_len (arglist);
   def->inhibited = 0;
   def->flags = flags;
 }
 

 char **
-get_brace_args (int quote_single)
+get_brace_args (enum quote_type quote)
 {
   char **arglist, *word;
   int arglist_index, arglist_size;
@@ -187,8 +188,10 @@ get_brace_args (int quote_single)
           depth++;
           input_text_offset++;
         }
-      else if ((character == ',' && !quote_single) ||
-               ((character == '}') && depth == 1))
+      else if ((character == ','
+               && !(quote == quote_single
+                    || (quote == quote_many && depth > 1)))
+              || ((character == '}') && depth == 1))
         {
           int len = input_text_offset - start;
 
@@ -285,7 +288,9 @@ get_macro_args (MACRO_DEF *def)
             }
         }
     }
-  return get_brace_args (def->flags & ME_QUOTE_ARG);
+  return get_brace_args (def->flags & ME_QUOTE_ARG ?
+                        (def->argcount == 1 ? quote_single : quote_many) :
+                        quote_none);
 }
 
 /* Substitute actual parameters for named parameters in body.
@@ -386,17 +391,13 @@ char *
 expand_macro (MACRO_DEF *def)
 {
   char **arglist;
-  int num_args;
   char *execution_string = NULL;
   int start_line = line_number;
 
-  /* Find out how many arguments this macro definition takes. */
-  num_args = array_len (def->arglist);
-
   /* Gather the arguments present on the line if there are any. */
   arglist = get_macro_args (def);
 
-  if (num_args < array_len (arglist))
+  if (def->argcount < array_len (arglist))
     {
       free_array (arglist);
       line_error (_("Macro `%s' called on line %d with too many args"),
@@ -612,17 +613,12 @@ define_macro (char *mactype, int recursi
           for (i = 10; whitespace (line[i]); i++);
           strcpy (line, line + i);
 
-          if (arglist && arglist[0] && !arglist[1])
-            {
-              flags |= ME_QUOTE_ARG;
-              if (!*line)
-                {
-                  free (line);
-                  continue;
-                }
-            }
-          else
-           line_error (_("@quote-arg only useful for single-argument macros"));
+         flags |= ME_QUOTE_ARG;
+         if (!*line)
+           {
+             free (line);
+             continue;
+           }
         }
 
       if (*line == COMMAND_PREFIX
Index: makeinfo/macro.h
===================================================================
RCS file: /cvsroot/texinfo/texinfo/makeinfo/macro.h,v
retrieving revision 1.3
diff -p -u -r1.3 macro.h
--- makeinfo/macro.h    15 May 2005 00:00:07 -0000      1.3
+++ makeinfo/macro.h    1 Jul 2006 22:49:44 -0000
@@ -37,6 +37,7 @@ typedef struct {
 typedef struct {
   char *name;                   /* Name of the macro. */
   char **arglist;               /* Args to replace when executing. */
+  int argcount;                 /* Number of args in arglist */
   char *body;                   /* Macro body. */
   char *source_file;            /* File where this macro is defined. */
   int source_lineno;            /* Line number within FILENAME. */
@@ -72,6 +73,8 @@ extern void cm_alias (void), cm_definfoe
 
 extern int array_len (char **array);
 extern void free_array (char **array);
-extern char **get_brace_args (int quote_single);
+
+enum quote_type { quote_none, quote_single, quote_many };
+extern char **get_brace_args (enum quote_type type);
 
 #endif /* not MACRO_H */
Index: makeinfo/makeinfo.c
===================================================================
RCS file: /cvsroot/texinfo/texinfo/makeinfo/makeinfo.c,v
retrieving revision 1.87
diff -p -u -r1.87 makeinfo.c
--- makeinfo/makeinfo.c 19 Jun 2006 23:08:57 -0000      1.87
+++ makeinfo/makeinfo.c 1 Jul 2006 22:49:53 -0000
@@ -3640,7 +3640,7 @@ cm_ifeq (void)
 {
   char **arglist;
 
-  arglist = get_brace_args (0);
+  arglist = get_brace_args (quote_none);
 
   if (arglist)
     {
Index: makeinfo/tests/Makefile.am
===================================================================
RCS file: /cvsroot/texinfo/texinfo/makeinfo/tests/Makefile.am,v
retrieving revision 1.5
diff -p -u -r1.5 Makefile.am
--- makeinfo/tests/Makefile.am  11 Apr 2004 17:56:47 -0000      1.5
+++ makeinfo/tests/Makefile.am  1 Jul 2006 22:49:53 -0000
@@ -19,6 +19,7 @@ TESTS = accent accentenc \
   macro-at menu-whitespace \
   no-headers \
   node-expand node-value node-whitespace \
+  quote-args \
   top \
   twofiles
 
@@ -33,4 +34,5 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
   include-value.txi incl-incl.txi \
   macro-at.txi menu-whitespace.txi \
   node-expand.txi node-value.txi node-whitespace.txi \
+  quote-args.txi \
   top.txi # top2.txi
Index: makeinfo/tests/quote-args
--- /dev/null   1994-07-18 02:46:18.000000000 +0300
+++ makeinfo/tests/quote-args   2006-07-02 01:47:26.000000000 +0300
@@ -0,0 +1,19 @@
+#!/bin/sh
+# Test @quote-args facility
+
+: ${srcdir=.}
+
+unset TEXINFO_OUTPUT
+TMP=quote-args.out
+
+cat > quote-args.samp <<EOT
+*FIXME: Many arguments, separated by commas, are processed here*
+natopocotuototam
+
+EOT
+
+../makeinfo --plaintex quote-args.txi | diff - quote-args.samp
+exit_code=$?
+
+rm quote-args.samp
+exit $exit_code
Index: makeinfo/tests/quote-args.txi
--- /dev/null   1994-07-18 02:46:18.000000000 +0300
+++ makeinfo/tests/quote-args.txi       2006-07-02 01:40:30.000000000 +0300
@@ -0,0 +1,22 @@
+\input texinfo 
address@hidden
address@hidden quote-args.info
address@hidden Quote-args facility in macros
+
address@hidden cat{a,b}
address@hidden
+\a\\b\
address@hidden rmacro
+
address@hidden FIXME{a}
address@hidden
address@hidden: \a\}
address@hidden macro
+
address@hidden Top, , (dir), (dir)
+
address@hidden
address@hidden arguments, separated by commas, are processed here}
address@hidden@address@hidden@address@hidden@cat{na, to}, po}, co}, tu}, 
oto},tam}
address@hidden
+
        

reply via email to

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