| 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 */