| version 1.14, 2004/03/03 09:25:30 | version 1.22, 2004/03/04 13:19:11 | 
|  |  | 
| * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE, | * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE, | 
| * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE. | * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE. | 
| * | * | 
| * $OpenXM: OpenXM_contrib2/asir2000/builtin/strobj.c,v 1.13 2004/02/26 10:07:55 noro Exp $ | * $OpenXM: OpenXM_contrib2/asir2000/builtin/strobj.c,v 1.21 2004/03/04 13:12:27 noro Exp $ | 
| */ | */ | 
| #include "ca.h" | #include "ca.h" | 
| #include "parse.h" | #include "parse.h" | 
| 
| Line 58  extern jmp_buf environnement; |  | 
| Line 58  extern jmp_buf environnement; |  | 
| #endif | #endif | 
| #include <string.h> | #include <string.h> | 
|  |  | 
|  | struct TeXSymbol { | 
|  | char *text; | 
|  | char *symbol; | 
|  | }; | 
|  |  | 
| extern char *parse_strp; | extern char *parse_strp; | 
|  |  | 
| void Prtostr(), Pstrtov(), Peval_str(); | void Prtostr(), Pstrtov(), Peval_str(); | 
| 
| Line 69  void Pclear_tb(); |  | 
| Line 74  void Pclear_tb(); |  | 
| void Pstring_to_tb(); | void Pstring_to_tb(); | 
| void Pquotetotex_tb(); | void Pquotetotex_tb(); | 
| void Pquotetotex(); | void Pquotetotex(); | 
|  | void Pquotetotex_setenv(); | 
| void fnodetotex_tb(FNODE f,TB tb); | void fnodetotex_tb(FNODE f,TB tb); | 
| char *symbol_name(char *name); | char *symbol_name(char *name); | 
| void tb_to_string(TB tb,STRING *rp); | void tb_to_string(TB tb,STRING *rp); | 
| 
| Line 90  struct ftab str_tab[] = { |  | 
| Line 96  struct ftab str_tab[] = { |  | 
| {"string_to_tb",Pstring_to_tb,1}, | {"string_to_tb",Pstring_to_tb,1}, | 
| {"quotetotex_tb",Pquotetotex_tb,2}, | {"quotetotex_tb",Pquotetotex_tb,2}, | 
| {"quotetotex",Pquotetotex,1}, | {"quotetotex",Pquotetotex,1}, | 
|  | {"quotetotex_setenv",Pquotetotex_setenv,-99999999}, | 
| {0,0,0}, | {0,0,0}, | 
| }; | }; | 
|  |  | 
| 
| Line 103  void write_tb(char *s,TB tb) |  | 
| Line 110  void write_tb(char *s,TB tb) |  | 
| tb->next++; | tb->next++; | 
| } | } | 
|  |  | 
|  | int register_symbol_table(Obj arg); | 
|  | int register_conv_rule(Obj arg); | 
|  | static struct TeXSymbol *user_texsymbol; | 
|  | static char *(*conv_rule)(char *); | 
|  |  | 
|  | static struct { | 
|  | char *name; | 
|  | Obj value; | 
|  | int (*reg)(); | 
|  | } qtot_env[] = { | 
|  | {"symbol_table",0,register_symbol_table}, | 
|  | {"conv_rule",0,register_conv_rule}, | 
|  | {0,0,0}, | 
|  | }; | 
|  |  | 
|  | #define PARTIAL "\\partial" | 
|  | char *conv_rule_d(char *name) | 
|  | { | 
|  | int l,i,j,alpha,start; | 
|  | char *b,*r; | 
|  | l = strlen(name); | 
|  |  | 
|  | if ( name[0] == 'd' ) { | 
|  | /* 3 : _{} */ | 
|  | b = (char *)ALLOCA((2*l+1+strlen(PARTIAL)+3)*sizeof(char)); | 
|  | sprintf(b,"%s_{",PARTIAL); | 
|  | i = 1; | 
|  | j = strlen(b); | 
|  | } else { | 
|  | b = (char *)ALLOCA((2*l+1)*sizeof(char)); | 
|  | i = j = 0; | 
|  | } | 
|  | for ( ; i < l && name[i] == '_'; i++); | 
|  | for ( ; i < l; ) { | 
|  | if ( !isalpha(name[i]) ) | 
|  | break; | 
|  | else | 
|  | b[j++] = name[i++]; | 
|  | } | 
|  | if ( i == l ) | 
|  | if ( name[0] == 'd' ) | 
|  | goto END; | 
|  | else | 
|  | return name; | 
|  | /* we found a digit or '_' */ | 
|  | b[j++] = '_'; b[j++] = '{'; | 
|  | if ( name[i] == '_' ) i++; | 
|  | for ( start = 1; i < l; ) { | 
|  | if ( name[i] == '_' ) { | 
|  | i++; | 
|  | start = 1; | 
|  | b[j++] = ','; | 
|  | } else if ( start ) { | 
|  | alpha = isalpha(name[i])?1:0; | 
|  | b[j++] = name[i++]; | 
|  | start = 0; | 
|  | } else if ( alpha ) { | 
|  | if ( isalpha(name[i]) ) | 
|  | b[j++] = name[i++]; | 
|  | else { | 
|  | alpha = 0; | 
|  | start = 1; | 
|  | b[j++] = ','; | 
|  | } | 
|  | } else { | 
|  | if ( isdigit(name[i]) ) | 
|  | b[j++] = name[i++]; | 
|  | else { | 
|  | alpha = 1; | 
|  | start = 1; | 
|  | b[j++] = ','; | 
|  | } | 
|  | } | 
|  | } | 
|  | b[j++] = '}'; | 
|  | END: | 
|  | if ( name[0] == 'd' ) b[j++] = '}'; | 
|  | b[j++] = 0; | 
|  | r = (char *)MALLOC_ATOMIC((j+1)*sizeof(char)); | 
|  | strcpy(r,b); | 
|  | return r; | 
|  | } | 
|  |  | 
|  | int register_symbol_table(Obj arg) | 
|  | { | 
|  | NODE n,t; | 
|  | Obj b; | 
|  | STRING a0,a1; | 
|  | struct TeXSymbol *uts; | 
|  | int i,len; | 
|  |  | 
|  | /* check */ | 
|  | if ( !arg ) { | 
|  | user_texsymbol = 0; | 
|  | return 1; | 
|  | } | 
|  | if ( OID(arg) != O_LIST ) return 0; | 
|  |  | 
|  | n = BDY((LIST)arg); | 
|  | len = length(n); | 
|  | uts = (struct TeXSymbol *)MALLOC((len+1)*sizeof(struct TeXSymbol)); | 
|  | for ( i = 0; n; n = NEXT(n), i++ ) { | 
|  | b = (Obj)BDY(n); | 
|  | if ( !b || OID(b) != O_LIST ) return 0; | 
|  | t = BDY((LIST)b); | 
|  | if ( !t || !NEXT(t) ) return 0; | 
|  | a0 = (STRING)BDY(t); | 
|  | a1 = (STRING)BDY(NEXT(t)); | 
|  | if ( !a0 || OID(a0) != O_STR ) return 0; | 
|  | if ( !a1 || OID(a1) != O_STR ) return 0; | 
|  | uts[i].text = BDY(a0); | 
|  | uts[i].symbol = BDY(a1); | 
|  | } | 
|  | uts[i].text = 0; | 
|  | uts[i].symbol = 0; | 
|  | user_texsymbol = uts; | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | int register_conv_rule(Obj arg) | 
|  | { | 
|  | if ( INT(arg) ) { | 
|  | switch ( QTOS((Q)arg) ) { | 
|  | case 0: | 
|  | conv_rule = 0; | 
|  | return 1; | 
|  | break; | 
|  | case 1: | 
|  | conv_rule = conv_rule_d; | 
|  | return 1; | 
|  | break; | 
|  | default: | 
|  | return 0; | 
|  | break; | 
|  | } | 
|  | } else return 0; | 
|  | } | 
|  |  | 
|  | void Pquotetotex_setenv(NODE arg,Obj *rp) | 
|  | { | 
|  | int ac,i; | 
|  | char *name; | 
|  | NODE n,n0; | 
|  | STRING s; | 
|  | LIST l; | 
|  |  | 
|  | ac = argc(arg); | 
|  | if ( !ac ) { | 
|  | n0 = 0; | 
|  | for ( i = 0; qtot_env[i].name; i++ ) { | 
|  | NEXTNODE(n0,n); MKSTR(s,qtot_env[i].name); BDY(n) = (pointer)s; | 
|  | NEXTNODE(n0,n); BDY(n) = (Q)qtot_env[i].value; | 
|  | } | 
|  | NEXT(n) = 0; | 
|  | MKLIST(l,n0); | 
|  | *rp = (Obj)l; | 
|  | } else if ( ac == 1 || ac == 2 ) { | 
|  | asir_assert(ARG0(arg),O_STR,"quotetotex_setenv"); | 
|  | name = BDY((STRING)ARG0(arg)); | 
|  | for ( i = 0; qtot_env[i].name; i++ ) | 
|  | if ( !strcmp(qtot_env[i].name,name) ) { | 
|  | if ( ac == 2 ) { | 
|  | if ( (qtot_env[i].reg)((Obj)ARG1(arg)) ) | 
|  | qtot_env[i].value = (Obj)ARG1(arg); | 
|  | else | 
|  | error("quotetotex_setenv : invalid argument"); | 
|  | } | 
|  | *rp = qtot_env[i].value; | 
|  | return; | 
|  | } | 
|  | *rp = 0; | 
|  | } else | 
|  | *rp = 0; | 
|  | } | 
|  |  | 
| void Pwrite_to_tb(NODE arg,Q *rp) | void Pwrite_to_tb(NODE arg,Q *rp) | 
| { | { | 
| int i; | int i; | 
|  | Obj obj; | 
|  | TB tb; | 
|  |  | 
| asir_assert(ARG1(arg),O_TB,"write_to_tb"); | asir_assert(ARG1(arg),O_TB,"write_to_tb"); | 
| write_tb(BDY((STRING)ARG0(arg)),ARG1(arg)); | obj = ARG0(arg); | 
|  | if ( !obj ) | 
|  | write_tb("",ARG1(arg)); | 
|  | else if ( OID(obj) == O_STR ) | 
|  | write_tb(BDY((STRING)obj),ARG1(arg)); | 
|  | else if ( OID(obj) == O_TB ) { | 
|  | tb = (TB)obj; | 
|  | for ( i = 0; i < tb->next; i++ ) | 
|  | write_tb(tb->body[i],ARG1(arg)); | 
|  | } | 
| *rp = 0; | *rp = 0; | 
| } | } | 
|  |  | 
| 
| Line 182  void Pstr_len(arg,rp) |  | 
| Line 375  void Pstr_len(arg,rp) |  | 
| NODE arg; | NODE arg; | 
| Q *rp; | Q *rp; | 
| { | { | 
| STRING str; | Obj obj; | 
| int r; | TB tb; | 
|  | int r,i; | 
|  |  | 
| str = (STRING)ARG0(arg); | obj = (Obj)ARG0(arg); | 
| asir_assert(str,O_STR,"str_chr"); | if ( !obj || (OID(obj) != O_STR && OID(obj) != O_TB) ) | 
| r = strlen(BDY(str)); | error("str_len : invalid argument"); | 
|  | if ( OID(obj) == O_STR) | 
|  | r = strlen(BDY((STRING)obj)); | 
|  | else if ( OID(obj) == O_TB ) { | 
|  | tb = (TB)obj; | 
|  | for ( r = i = 0; i < tb->next; i++ ) | 
|  | r += strlen(tb->body[i]); | 
|  | } | 
| STOQ(r,*rp); | STOQ(r,*rp); | 
| } | } | 
|  |  | 
|  |  | 
| #endif | #endif | 
| } | } | 
|  |  | 
|  | static struct TeXSymbol texsymbol[] = { | 
|  | {"sin","\\sin"}, | 
|  | {"cos","\\cos"}, | 
|  | {"tan","\\tan"}, | 
|  | {"sinh","\\sinh"}, | 
|  | {"cosh","\\cosh"}, | 
|  | {"tanh","\\tanh"}, | 
|  | {"exp","\\exp"}, | 
|  | {"log","\\log"}, | 
|  |  | 
|  | /* Greek Letters (lower case) */ | 
|  | {"alpha","\\alpha"}, | 
|  | {"beta","\\beta"}, | 
|  | {"gamma","\\gamma"}, | 
|  | {"delta","\\delta"}, | 
|  | {"epsilon","\\epsilon"}, | 
|  | {"varepsilon","\\varepsilon"}, | 
|  | {"zeta","\\zeta"}, | 
|  | {"eta","\\eta"}, | 
|  | {"theta","\\theta"}, | 
|  | {"vartheta","\\vartheta"}, | 
|  | {"iota","\\iota"}, | 
|  | {"kappa","\\kappa"}, | 
|  | {"lambda","\\lambda"}, | 
|  | {"mu","\\mu"}, | 
|  | {"nu","\\nu"}, | 
|  | {"xi","\\xi"}, | 
|  | {"pi","\\pi"}, | 
|  | {"varpi","\\varpi"}, | 
|  | {"rho","\\rho"}, | 
|  | {"sigma","\\sigma"}, | 
|  | {"varsigma","\\varsigma"}, | 
|  | {"tau","\\tau"}, | 
|  | {"upsilon","\\upsilon"}, | 
|  | {"phi","\\phi"}, | 
|  | {"varphi","\\varphi"}, | 
|  | {"chi","\\chi"}, | 
|  | {"omega","\\omega"}, | 
|  |  | 
|  | /* Greek Letters, (upper case) */ | 
|  | {"ggamma","\\Gamma"}, | 
|  | {"ddelta","\\Delta"}, | 
|  | {"ttheta","\\Theta"}, | 
|  | {"llambda","\\Lambda"}, | 
|  | {"xxi","\\Xi"}, | 
|  | {"ppi","\\Pi"}, | 
|  | {"ssigma","\\Sigma"}, | 
|  | {"uupsilon","\\Upsilon"}, | 
|  | {"pphi","\\Phi"}, | 
|  | {"ppsi","\\Psi"}, | 
|  | {"oomega","\\Omega"}, | 
|  |  | 
|  | /* Our own mathematical functions */ | 
|  | {"algebra_tensor","\\otimes"}, | 
|  | {"base_where","{\\rm \\ where \\ }"}, | 
|  | /* Mathematical constants */ | 
|  | {"c_pi","\\pi"}, | 
|  | {"c_i","\\sqrt{-1}"}, | 
|  |  | 
|  | /* Temporary  */ | 
|  | {0,0} | 
|  | }; | 
|  |  | 
| char *symbol_name(char *name) | char *symbol_name(char *name) | 
| { | { | 
| /* XXX */ | int i; | 
| return name; |  | 
|  | if ( user_texsymbol ) | 
|  | for ( i = 0; user_texsymbol[i].text; i++ ) | 
|  | if ( !strcmp(user_texsymbol[i].text,name) ) | 
|  | return user_texsymbol[i].symbol; | 
|  | for ( i = 0; texsymbol[i].text; i++ ) | 
|  | if ( !strcmp(texsymbol[i].text,name) ) | 
|  | return texsymbol[i].symbol; | 
|  | if ( conv_rule ) | 
|  | return (*conv_rule)(name); | 
|  | else | 
|  | return name; | 
| } | } | 
|  |  | 
| void fnodetotex_tb(FNODE f,TB tb) | void fnodetotex_tb(FNODE f,TB tb) | 
| 
| Line 371  void fnodetotex_tb(FNODE f,TB tb) |  | 
| Line 646  void fnodetotex_tb(FNODE f,TB tb) |  | 
| char vname[BUFSIZ]; | char vname[BUFSIZ]; | 
| char *opname; | char *opname; | 
| Obj obj; | Obj obj; | 
| int i,len; | int i,len,allzero; | 
|  | FNODE fi,f2; | 
|  |  | 
| write_tb(" ",tb); | write_tb(" ",tb); | 
| if ( !f ) { | if ( !f ) { | 
| 
| Line 420  void fnodetotex_tb(FNODE f,TB tb) |  | 
| Line 696  void fnodetotex_tb(FNODE f,TB tb) |  | 
| } else if ( !strcmp(opname,"*") ) { | } else if ( !strcmp(opname,"*") ) { | 
| fnodetotex_tb((FNODE)FA1(f),tb); | fnodetotex_tb((FNODE)FA1(f),tb); | 
| write_tb(" ",tb); | write_tb(" ",tb); | 
| fnodetotex_tb((FNODE)FA2(f),tb); | /* XXX special care for DP */ | 
|  | f2 = (FNODE)FA2(f); | 
|  | if ( f2->id == I_EV ) { | 
|  | n = (NODE)FA0(f2); | 
|  | for ( i = 0; n; n = NEXT(n), i++ ) { | 
|  | fi = (FNODE)BDY(n); | 
|  | if ( fi->id != I_FORMULA || FA0(fi) ) | 
|  | break; | 
|  | } | 
|  | if ( n ) | 
|  | fnodetotex_tb((FNODE)FA2(f),tb); | 
|  | } else | 
|  | fnodetotex_tb((FNODE)FA2(f),tb); | 
| } else if ( !strcmp(opname,"/") ) { | } else if ( !strcmp(opname,"/") ) { | 
| write_tb("\\frac{",tb); | write_tb("\\frac{",tb); | 
| fnodetotex_tb((FNODE)FA1(f),tb); | fnodetotex_tb((FNODE)FA1(f),tb); | 
| 
| Line 578  void fnodetotex_tb(FNODE f,TB tb) |  | 
| Line 866  void fnodetotex_tb(FNODE f,TB tb) |  | 
| break; | break; | 
| case I_EV: | case I_EV: | 
| n = (NODE)FA0(f); | n = (NODE)FA0(f); | 
|  | allzero = 1; | 
| for ( t0 = 0, i = 0; n; n = NEXT(n), i++ ) { | for ( t0 = 0, i = 0; n; n = NEXT(n), i++ ) { | 
| sprintf(vname,"x_{%d}^{",i); | fi = (FNODE)BDY(n); | 
| write_tb(vname,tb); | if ( fi->id == I_FORMULA && !FA0(fi) ) continue; | 
| fnodetotex_tb((FNODE)BDY(n),tb); | allzero = 0; | 
| write_tb("} ",tb); | if ( fi->id == I_FORMULA && UNIQ(FA0(fi)) ) { | 
|  | sprintf(vname,"x_{%d}",i); | 
|  | len = strlen(vname); | 
|  | opname = MALLOC_ATOMIC(len+1); | 
|  | strcpy(opname,vname); | 
|  | write_tb(opname,tb); | 
|  | } else { | 
|  | sprintf(vname,"x_{%d}^{",i); | 
|  | len = strlen(vname); | 
|  | opname = MALLOC_ATOMIC(len+1); | 
|  | strcpy(opname,vname); | 
|  | write_tb(opname,tb); | 
|  | fnodetotex_tb((FNODE)BDY(n),tb); | 
|  | write_tb("} ",tb); | 
|  | } | 
| } | } | 
|  | /* XXX */ | 
|  | if ( allzero ) | 
|  | write_tb(" 1 ",tb); | 
| break; | break; | 
| } | } | 
| break; | break; |