Ilya Zakharevich on Tue, 22 Oct 2002 21:21:23 -0700


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

[PATCH CVS] TeX output


This patch:

  a) Introduces a new function Str1(expr,{flag=0}) which is somewhat similar
     to Str(), but

	1) Takes an expression, not a string as the first argument;

	2) Has a different semantic of flags.

     See the first chunk for details.

  b) Fixes output of t_STR values in TeX format (up to some extend?);

  c) Two new functions are available in C (see the last chunk);

  d) Fixes output of variable with underscores; now

	1) The output is a correct TeX;

	2) Differently named variables are output differently.

     Having the output pretty was not a principal aim, but judge by yourselves:

      ? x1_2_3__22_23__32_34
      %6 = x
            1,2,3,[22,23],[32,34]
      ? x_1_2_3__22_23__32_34
      %7 = x
            [1,2,3],[22,23],[32,34]

Enjoy,
Ilya

P.S.	How should we distinguish functions with prototype "s" from functions
	with prototype "G" by their helpstring?  I do not think the distinction
	between Str and Str1 is explained well enough in what I did...

--- ./src/language/helpmsg.c-pre	Tue Oct 15 17:34:04 2002
+++ ./src/language/helpmsg.c	Tue Oct 22 19:05:36 2002
@@ -27,6 +27,7 @@ char *helpmessages_basic[]={
   "Ser(x,{v=x}): convert x (usually a vector) into a power series with variable v, starting with the constant coefficient",
   "Set({x=[]}): convert x into a set, i.e. a row vector with strictly increasing coefficients. Empty set if x is omitted",
   "Str({x=\"\"},{flag=0}): transforms any GEN x into a string. Empty string if x is omitted. If flag is set, perform tilde expansion on string",
+  "Str1(expr,{flag=0}): translates the result of PARI expr to a string.  If flag is 1, the string is the TeX representation of the value; if 2, translates an integer into the corresponding char",
   "Vec({x=[]}): transforms the object x into a vector. Used mainly if x is a polynomial or a power series. Empty vector if x is omitted",
   "Vecsmall({x=[]}): transforms the object x into a VECSMALL. Empty vector if x is omitted",
   "abs(x): absolute value (or modulus) of x",
--- ./src/language/es.c-pre	Thu Oct 17 20:29:42 2002
+++ ./src/language/es.c	Tue Oct 22 21:10:00 2002
@@ -671,6 +671,37 @@ GENtostr0(GEN x, pariout_t *T, void (*do
 char *
 GENtostr(GEN x) { return GENtostr0(x, NULL, &gen_output); }
 
+/* Returns gpmalloc()ed string */
+char *
+GENtoTeXstr(GEN x) {
+  pariout_t T = DFLT_OUTPUT;
+
+  T.prettyp = f_TEX;
+  T.fieldw = 0;
+  return GENtostr0(x, &T, &gen_output);
+}
+
+GEN
+GENtostr2(GEN x, int flag) {
+  long l;
+  unsigned char buf[2];
+
+  if (flag == 0)
+    return strtoGENstr(GENtostr(x), 1);		/* 1: free the argument */
+  if (flag == 1)
+    return strtoGENstr(GENtoTeXstr(x), 1);	/* 1: free the argument */
+  if (flag != 2)
+    err(talker, "Unknown flag in GENtostr2()");
+  if (typ(x) != t_INT)
+    err(talker, "Not an integer in GENtostr2()");
+  l = itos(x);
+  if (l <= 0 || l >= 256)
+    err(talker, "Character overflow in GENtostr2()");
+  buf[0] = l;
+  buf[1] = 0;
+  return strtoGENstr((char*)buf, 0);		/* 0: keep the argument */
+}
+
 /********************************************************************/
 /**                                                                **/
 /**                         WRITE AN INTEGER                       **/
@@ -1105,17 +1136,60 @@ get_var(long v, char *buf)
   sprintf(buf,"#<%d>",(int)v); return buf;
 }
 
+static void
+do_append(char **sp, char c, char *last, int count)
+{
+  if (*sp + count > last)
+    err(talker, "TeX variable name too long");
+  while (count--)
+    *(*sp)++ = c;
+}
+
 static char *
-get_texvar(long v, char *buf)
+get_texvar(long v, char *buf, int len)
 {
   entree *ep = varentries[v];
-  char *s, *t = buf;
+  char *s, *t = buf, *e = buf + len - 1;
 
   if (!ep) err(talker, "this object uses debugging variables");
   s = ep->name;
-  if (strlen(s)>=64) err(talker, "TeX variable name too long");
+  if (strlen(s) >= len) err(talker, "TeX variable name too long");
   while(isalpha((int)*s)) *t++ = *s++;
-  *t = 0; if (isdigit((int)*s) || *s++ == '_') sprintf(t,"_{%s}",s);
+  *t = 0;
+  if (isdigit((int)*s) || *s == '_') {
+    int seen1 = 0, seen = 0;
+
+    /* Skip until the first non-underscore */
+    while (*s == '_') s++, seen++;
+
+    /* Special-case integers and empty subscript */
+    if (*s == 0 || isdigit((unsigned char)*s))
+      seen++;
+
+    do_append(&t, '_', e, 1);
+    do_append(&t, '{', e, 1);
+    do_append(&t, '[', e, seen - 1);
+    while (1) {
+      if (*s == '_')
+        seen1++, s++;
+      else {
+        if (seen1) {
+          do_append(&t, ']', e, (seen >= seen1 ? seen1 : seen) - 1);
+          do_append(&t, ',', e, 1);
+          do_append(&t, '[', e, seen1 - 1);
+          if (seen1 > seen)
+            seen = seen1;
+          seen1 = 0;
+        }
+        if (*s == 0)
+          break;
+        do_append(&t, *s++, e, 1);
+      }
+    }
+    do_append(&t, ']', e, seen - 1);
+    do_append(&t, '}', e, 1);
+    *t = 0;
+  }
   return buf;
 }
 
@@ -1838,7 +1912,7 @@ texi(GEN g, pariout_t *T, int nosign)
       if (!isnull(b)) wr_texnome(T,b,v,1);
       break;
 
-    case t_POL: v = get_texvar(ordvar[varn(g)],buf);
+    case t_POL: v = get_texvar(ordvar[varn(g)], buf, sizeof(buf));
       /* hack: we want g[i] = coeff of degree i. */
       i = degpol(g); g += 2; while (isnull((GEN)g[i])) i--;
       wr_lead_texnome(T,(GEN)g[i],v,i,nosign);
@@ -1849,7 +1923,7 @@ texi(GEN g, pariout_t *T, int nosign)
       }
       break;
 
-    case t_SER: v = get_texvar(ordvar[varn(g)],buf);
+    case t_SER: v = get_texvar(ordvar[varn(g)], buf, sizeof(buf));
       i = valp(g);
       if (signe(g))
       { /* hack: we want g[i] = coeff of degree i. */
@@ -1918,9 +1992,20 @@ texi(GEN g, pariout_t *T, int nosign)
       pariputc('}'); break;
 
     case t_STR:
-      pariputs("\\mbox{"); pariputs(GSTR(g));
+    {
+      char *s;
+  
+      pariputs("\\mbox{");
+      s = GSTR(g);
+      while (*s) {
+	if (strchr("\\{}$_^%#&~", *s))
+	  pariputc('\\');		/* What to do with \\ ? */
+	pariputc(*s);
+	if (strchr("^~", *s++))
+	  pariputs("{}");
+      }
       pariputc('}'); break;
-
+    }
     case t_MAT:
       pariputs("\\pmatrix{\n "); r = lg(g);
       if (r>1)
@@ -3037,7 +3122,7 @@ print0(GEN *g, long flag)
   pariout_t T = GP_DATA? *(GP_DATA->fmt): DFLT_OUTPUT; /* copy */
   T.prettyp = flag;
   for( ; *g; g++)
-    if (typ(*g)==t_STR)
+    if (flag != f_TEX && typ(*g)==t_STR)
       pariputs(GSTR(*g)); /* text surrounded by "" otherwise */
     else
       gen_output(*g, &T);
--- ./src/language/init.c-pre	Tue Oct 15 17:34:06 2002
+++ ./src/language/init.c	Tue Oct 22 18:42:18 2002
@@ -1965,6 +1965,7 @@ entree functions_basic[]={
 {"Ser",14,(void*)gtoser,2,"GDn"},
 {"Set",0,(void*)gtoset,2,"DG"},
 {"Str",0,(void*)strtoGENstr,2,"D\"\",s,D0,L,"},
+{"Str1",99,(void*)GENtostr2,2,"GD0,L,"},
 {"Vec",0,(void*)gtovec,2,"DG"},
 {"Vecsmall",0,(void*)gtovecsmall,2,"DG"},
 {"abs",1,(void*)gabs,3,"Gp"},
--- ./src/headers/paridecl.h-pre	Tue Oct 15 17:34:02 2002
+++ ./src/headers/paridecl.h	Tue Oct 22 18:40:30 2002
@@ -822,6 +822,8 @@ char*   type_name(long t);
 void    voir(GEN x, long nb);
 void    vpariputs(char* format, va_list args);
 void    writebin(char *name, GEN x);
+char *	GENtoTeXstr(GEN x);
+GEN	GENtostr2(GEN x, int flag);
 
 /* galconj.c */