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