Subversion Repositories wimsdev

Rev

Rev 11132 | Rev 16241 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 11132 Rev 12237
Line 329... Line 329...
329
}
329
}
330
 
330
 
331
/* sort according to type */
331
/* sort according to type */
332
int fsort(const void *p1, const void *p2)
332
int fsort(const void *p1, const void *p2)
333
{
333
{
334
    struct afactor *t1, *t2;
334
  struct afactor *t1, *t2;
335
    int i1,i2;
335
  int i1,i2;
336
 
336
 
337
    t1=*(struct afactor **) p1; t2=*(struct afactor **) p2;
337
  t1=*(struct afactor **) p1; t2=*(struct afactor **) p2;
338
    i1=t1->type; i2=t2->type;
338
  i1=t1->type; i2=t2->type;
339
    if(i1>type_var) i1=type_var;
339
  if(i1>type_var) i1=type_var;
340
    if(i2>type_var) i2=type_var;
340
  if(i2>type_var) i2=type_var;
341
    return i1-i2;
341
  return i1-i2;
342
}
342
}
343
 
343
 
344
void t_oneterm(char *p, int num)
344
void t_oneterm(char *p, int num)
345
{
345
{
346
    int sign, fcnt, s, i, dentype, rel;
346
  int sign, fcnt, s, i, dentype, rel;
347
    char *pp, *pe, *pt;
347
  char *pp, *pe, *pt;
348
    struct afactor factors[MAX_FACTORS];
348
  struct afactor factors[MAX_FACTORS];
349
    struct afactor *numerator[MAX_FACTORS],
349
  struct afactor *numerator[MAX_FACTORS],
350
      *denominator[MAX_FACTORS],
350
    *denominator[MAX_FACTORS],
351
      *neutral[MAX_FACTORS];
351
    *neutral[MAX_FACTORS];
352
    int numcnt,dencnt,neucnt;
352
  int numcnt,dencnt,neucnt;
353
/* interpret some arrows */
353
/* interpret some arrows */
-
 
354
  rel=0;
354
    rel=0; switch(*p) {
355
  switch(*p) {
355
      case '<': {
356
    case '<': {
356
        rel++; p++; if(*p!='=') {tprint(" < "); break;} // <
357
      rel++; p++; if(*p!='=') {tprint(" < "); break;} // <
357
        do p++; while(*p=='=');
358
      do p++; while(*p=='=');
358
        if(*p!='>') {tprint("\\le ");break;} // <= , <===
359
      if(*p!='>') {tprint("\\le ");break;} // <= , <===
359
        else {tprint("\\iff ");p++; break;} // <==>
360
      else {tprint("\\iff ");p++; break;} // <==>
360
      }
361
    }
361
      case '>': {
362
    case '>': {
362
        rel++; p++; if(*p!='=') {tprint(" > "); rel=1; break;} // >
363
      rel++; p++; if(*p!='=') {tprint(" > "); rel=1; break;} // >
363
        while(*p=='=') p++;
364
      while(*p=='=') p++;
364
        tprint("\\ge "); // >=
365
        tprint("\\ge "); // >=
365
        break;
366
        break;
366
      }
367
    }
367
      case '-': {
368
    case '-': {
368
        for(pp=p;*pp=='-';pp++);
369
      for(pp=p;*pp=='-';pp++);
369
        if(*pp!='>') break;
370
      if(*pp!='>') break;
370
        rel++; tprint("\\to "); p=++pp; //->
371
      rel++; tprint("\\to "); p=++pp; //->
371
        break;
372
      break;
372
      }
373
    }
373
     case '=': {
374
    case '=': {
374
        rel++; for(pp=p;*pp=='=';pp++);
375
        rel++; for(pp=p;*pp=='=';pp++);
375
        if(*pp!='>') break;
376
        if(*pp!='>') break;
376
        tprint("\\Rightarrow "); p=++pp; // =>
377
        tprint("\\Rightarrow "); p=++pp; // =>
377
        break;
378
        break;
378
      }
379
    }
379
    }
380
  }
380
    if(*p==',' || *p==';' || *p=='=') {tprint("%c",*p); p++; num=0;}
381
  if(*p==',' || *p==';' || *p=='=') {tprint("%c",*p); p++; num=0;}
381
    sign=1; while(*p=='+' || *p=='-') {
382
    sign=1; while(*p=='+' || *p=='-') {
382
      if(*p=='-') sign*=-1;
383
      if(*p=='-') sign*=-1;
383
      p++;
384
      p++;
384
    }
385
  }
385
    for(fcnt=0, pp=p; fcnt<MAX_FACTORS && *pp; fcnt++, pp=pe) {
386
  for(fcnt=0, pp=p; fcnt<MAX_FACTORS && *pp; fcnt++, pp=pe) {
386
      s=1;
387
    s=1;
387
      while(*pp=='*' || *pp=='/') {
388
    while(*pp=='*' || *pp=='/') {
388
        if(*pp=='/') s=-1;
389
      if(*pp=='/') s=-1;
389
        pp++;
390
      pp++;
390
      }
391
    }
391
      factors[fcnt].side=s;
392
    factors[fcnt].side=s;
392
      while(*pp=='+' || *pp=='-') {
393
    while(*pp=='+' || *pp=='-') {
393
        if(*pp=='-') sign*=-1;
394
      if(*pp=='-') sign*=-1;
394
        pp++;
395
      pp++;
395
      }
396
    }
396
      pe=find_factor_end(pp); if(pe<=pp) break;
397
    pe=find_factor_end(pp); if(pe<=pp) break;
397
      factors[fcnt].beg=pp; factors[fcnt].end=pe;
398
    factors[fcnt].beg=pp; factors[fcnt].end=pe;
398
      if(pe-pp==1 && *pp=='1') fcnt--;
399
    if(pe-pp==1 && *pp=='1') fcnt--;
399
      if(*pp=='(') {
400
    if(*pp=='(') {
400
        char *pt, *pe2, buf[MAX_LINELEN+1];
401
      char *pt, *pe2, buf[MAX_LINELEN+1];
401
        int ss;
402
      int ss;
402
        pp++; pt=find_matching(pp,')');
403
      pp++; pt=find_matching(pp,')');
403
        if(pt>=pe-1) {
404
      if(pt>=pe-1) {
404
          memmove(buf,pp,pt-pp); buf[pt-pp]=0;
405
        memmove(buf,pp,pt-pp); buf[pt-pp]=0;
405
          i=term_cnt(buf);
406
        i=term_cnt(buf);
406
          if(i==1) { /* remove parentheses */
407
        if(i==1) { /* remove parentheses */
407
              for(;pp<pt && fcnt<MAX_FACTORS;pp=pe2,fcnt++) {
408
          for(;pp<pt && fcnt<MAX_FACTORS;pp=pe2,fcnt++) {
-
 
409
            ss=s;
408
                ss=s; while(*pp=='*' || *pp=='/') {
410
            while(*pp=='*' || *pp=='/') {
409
                    if(*pp=='/') ss=-s;
411
              if(*pp=='/') ss=-s;
410
                    pp++;
412
              pp++;
411
                }
413
            }
412
                factors[fcnt].side=ss;
414
            factors[fcnt].side=ss;
413
                while(*pp=='+' || *pp=='-') {
415
            while(*pp=='+' || *pp=='-') {
414
                    if(*pp=='-') sign*=-1;
416
              if(*pp=='-') sign*=-1;
415
                    pp++;
417
              pp++;
416
                }
418
            }
417
                pe2=find_factor_end(pp);
419
            pe2=find_factor_end(pp);
418
                if(pe2<=pp) goto bailout;
420
            if(pe2<=pp) goto bailout;
419
                factors[fcnt].beg=pp; factors[fcnt].end=pe2;
421
            factors[fcnt].beg=pp; factors[fcnt].end=pe2;
420
                if(pe2-pp==1 && *pp=='1') fcnt--;
422
            if(pe2-pp==1 && *pp=='1') fcnt--;
421
              }
-
 
422
              fcnt--;
-
 
423
          }
423
          }
-
 
424
          fcnt--;
424
        }
425
        }
425
      }
426
      }
426
    }
427
    }
-
 
428
  }
427
    bailout:
429
  bailout:
428
/* decide if the factor is of type numeric, integer, poly, transcend or variable
430
/* decide if the factor is of type numeric, integer, poly, transcend or variable
429
*  (see priorities)
431
*  (see priorities)
430
*/
432
*/
431
    for(i=0;i<fcnt;i++) {
433
  for(i=0;i<fcnt;i++) {
432
      pp=factors[i].beg; pe=factors[i].end;
434
    pp=factors[i].beg; pe=factors[i].end;
433
      if(myisdigit(*pp) || *pp=='.') {
435
    if(myisdigit(*pp) || *pp=='.') {
434
        for(pt=pp;pt<pe && myisdigit(*pt);pt++);
436
      for(pt=pp;pt<pe && myisdigit(*pt);pt++);
435
        if(pt<pe) factors[i].type=type_numeric; // digits with a point
437
      if(pt<pe) factors[i].type=type_numeric; // digits with a point
436
        else factors[i].type=type_integer;  // digits without point
438
      else factors[i].type=type_integer;  // digits without point
437
        continue;
439
      continue;
438
      }
440
    }
439
      if(*pp=='(') {
441
    if(*pp=='(') {
440
        factors[i].type=type_poly; continue; //there exists a parenthesis
442
      factors[i].type=type_poly; continue; //there exists a parenthesis
441
      }
443
    }
442
      pt=strchr(pp,'(');
444
    pt=strchr(pp,'(');
443
      if(pt!=NULL && pt<pe) factors[i].type=type_transcend; //??
445
    if(pt!=NULL && pt<pe) factors[i].type=type_transcend; //??
444
      else factors[i].type=type_var;  // variable in other cases
446
    else factors[i].type=type_var;  // variable in other cases
445
    }
447
  }
446
    dentype=-1;
448
  dentype=-1;
447
    for(i=0;i<fcnt;i++) if(factors[i].side<0 && factors[i].type>dentype)
449
  for(i=0;i<fcnt;i++) if(factors[i].side<0 && factors[i].type>dentype)
448
      dentype=factors[i].type; // denominator type will be compared to the type of the factors
450
    dentype=factors[i].type; // denominator type will be compared to the type of the factors
449
    dencnt=numcnt=neucnt=0;
451
  dencnt=numcnt=neucnt=0;
450
    for(i=0;i<fcnt;i++) {
452
  for(i=0;i<fcnt;i++) {
451
      if(factors[i].type>dentype) neutral[neucnt++]=factors+i;
453
    if(factors[i].type>dentype) neutral[neucnt++]=factors+i;
452
      else {
454
    else {
453
        if(factors[i].side>0) numerator[numcnt++]=factors+i;
455
      if(factors[i].side>0) numerator[numcnt++]=factors+i;
454
        else denominator[dencnt++]=factors+i;
456
      else denominator[dencnt++]=factors+i;
-
 
457
    }
-
 
458
  }
-
 
459
  if(dencnt>0) qsort(denominator,dencnt,sizeof(denominator[0]),fsort);
-
 
460
  if(numcnt>0) qsort(numerator,numcnt,sizeof(numerator[0]),fsort);
-
 
461
  if(neucnt>0) qsort(neutral,neucnt,sizeof(neutral[0]),fsort);
-
 
462
  if(sign>0 && num>0 && rel==0) tprint(" +");
-
 
463
  if(sign<0) tprint(" -");
-
 
464
  if(fcnt<1) tprint("1 "); // no factors why 1 - don't remove the 1 if [1,2;3,4], the 1 is useful?
-
 
465
  if(dencnt>0) {
-
 
466
    tprint(" {");
-
 
467
    if(numcnt==0) tprint(" 1"); // no numerator ? will write {1 over denominator}
-
 
468
    else {/* numerator */
-
 
469
      if(numcnt==1 && *numerator[0]->beg=='(' &&
-
 
470
          find_matching(numerator[0]->beg+1,')')==(numerator[0]->end)-1) {
-
 
471
        *(numerator[0]->end-1)=0;
-
 
472
        t_onestring(numerator[0]->beg+1);
-
 
473
        *(numerator[0]->end-1)=')';
455
      }
474
      }
-
 
475
      else for(i=0; i<numcnt; i++) {t_onefactor(numerator[i],i);
-
 
476
      if(i<numcnt-1) tprint(" ");} /* add space between factors */
456
    }
477
    }
457
    if(dencnt>0) qsort(denominator,dencnt,sizeof(denominator[0]),fsort);
-
 
458
    if(numcnt>0) qsort(numerator,numcnt,sizeof(numerator[0]),fsort);
-
 
459
    if(neucnt>0) qsort(neutral,neucnt,sizeof(neutral[0]),fsort);
-
 
460
    if(sign>0 && num>0 && rel==0) tprint(" +");
-
 
461
    if(sign<0) tprint(" -");
-
 
462
    if(fcnt<1) tprint("1 "); // no factors why 1 - don't remove the 1 if [1,2;3,4], the 1 is useful?
-
 
463
    if(dencnt>0) {
-
 
464
      tprint(" {");
-
 
465
      if(numcnt==0) tprint(" 1"); // no numerator ? will write {1 over denominator}
-
 
466
      else {/* numerator */
-
 
467
        if(numcnt==1 && *numerator[0]->beg=='(' &&
-
 
468
           find_matching(numerator[0]->beg+1,')')==(numerator[0]->end)-1) {
-
 
469
          *(numerator[0]->end-1)=0;
-
 
470
          t_onestring(numerator[0]->beg+1);
-
 
471
          *(numerator[0]->end-1)=')';
-
 
472
        }
-
 
473
        else for(i=0; i<numcnt; i++) {t_onefactor(numerator[i],i);
-
 
474
                if(i<numcnt-1) tprint(" ");} /* add space between factors */
-
 
475
      }
-
 
476
      tprint(" \\over ");      /* Now denominator */
478
    tprint(" \\over ");      /* Now denominator */
477
      if(dencnt==1 && *denominator[0]->beg=='(' &&
479
    if(dencnt==1 && *denominator[0]->beg=='(' &&
478
        find_matching(denominator[0]->beg+1,')')==(denominator[0]->end)-1) {
480
      find_matching(denominator[0]->beg+1,')')==(denominator[0]->end)-1) {
479
         *(denominator[0]->end-1)=0;
481
       *(denominator[0]->end-1)=0;
480
         t_onestring(denominator[0]->beg+1);
482
       t_onestring(denominator[0]->beg+1);
481
         *(denominator[0]->end-1)=')';
483
       *(denominator[0]->end-1)=')';
482
      }
-
 
483
      else for(i=0;i<dencnt;i++) {t_onefactor(denominator[i],i);
-
 
484
                        if(i<dencnt-1) tprint(" ");} /* add space between factors */
-
 
485
      tprint("} ");
-
 
486
    }
484
    }
-
 
485
    else for(i=0;i<dencnt;i++) {t_onefactor(denominator[i],i);
-
 
486
    if(i<dencnt-1) tprint(" ");} /* add space between factors */
-
 
487
    tprint("} ");
-
 
488
  }
487
    for(i=0;i<neucnt;i++) {t_onefactor(neutral[i],i+dencnt);
489
  for(i=0;i<neucnt;i++) {t_onefactor(neutral[i],i+dencnt);
488
                if(i<neucnt-1) tprint(" ");} /* add space between factors */
490
  if(i<neucnt-1) tprint(" ");} /* add space between factors */
489
}
491
}
490
 
492
 
491
/* put exponential */
493
/* put exponential */
492
void t_exponential(char *pp)
494
void t_exponential(char *pp)
493
{
495
{
494
    char *pe, *pt;
496
  char *pe, *pt;
495
    int t=0;
497
  int t=0;
496
 
498
 
497
    while(*pp && strchr("!'\"",*pp)!=NULL) {
499
  while(*pp && strchr("!'\"",*pp)!=NULL) {
498
      tprint("%c",*pp); pp++;
500
    tprint("%c",*pp); pp++;
499
    }
501
  }
500
    if(*pp=='^') pp++; else return;
502
  if(*pp=='^') pp++; else return;
501
    if(*pp=='(') {
503
  if(*pp=='(') {
502
      pe=find_matching(pp+1,')');
504
    pe=find_matching(pp+1,')');
503
      if(*(pe+1)==0) {
505
    if(*(pe+1)==0) {
504
        pp++;*pe=0;
506
      pp++;*pe=0;
505
        for(pt=pp;*pt && (isalnum(*pt) || *pt=='.');pt++);
507
      for(pt=pp;*pt && (isalnum(*pt) || *pt=='.');pt++);
506
        if(*pt==0) t=1;
508
      if(*pt==0) t=1;
507
      }
-
 
508
    }
-
 
509
    if(strlen(pp)==1 && t==0) tprint("^%s ",pp);
-
 
510
    else {
-
 
511
      tprint(" ^{"); if(t) tprint("(");
-
 
512
      t_onestring(pp);
-
 
513
      if(t) tprint(")");
-
 
514
      tprint("} ");
-
 
515
    }
509
    }
-
 
510
  }
-
 
511
  if(strlen(pp)==1 && t==0) tprint("^%s ",pp);
-
 
512
  else {
-
 
513
    tprint(" ^{"); if(t) tprint("(");
-
 
514
    t_onestring(pp);
-
 
515
    if(t) tprint(")");
-
 
516
    tprint("} ");
-
 
517
  }
516
}
518
}
517
 
519
 
518
void t_onefactor(struct afactor *fb, int num)
520
void t_onefactor(struct afactor *fb, int num)
519
{
521
{
520
    char *p, *pe, lp, *rp, rp2, rpbuf[128];
522
  char *p, *pe, lp, *rp, rp2, rpbuf[128];
521
    char fbuf[MAX_LINELEN+1], pbuf[MAX_LINELEN+1];
523
  char fbuf[MAX_LINELEN+1], pbuf[MAX_LINELEN+1];
522
    int i;
524
  int i;
523
 
525
 
524
    memmove(pbuf,fb->beg,fb->end-fb->beg);
526
  memmove(pbuf,fb->beg,fb->end-fb->beg);
525
    pbuf[fb->end-fb->beg]=0;
527
  pbuf[fb->end-fb->beg]=0;
526
    if(num>0 && (myisdigit(pbuf[0]) || pbuf[0]=='.'))
528
  if(num>0 && (myisdigit(pbuf[0]) || pbuf[0]=='.'))
527
      tprint("\\times ");
529
    tprint("\\times ");
528
    rp2=')'; p=pbuf;
530
  rp2=')'; p=pbuf;
529
    if(strchr("({[",*p)!=NULL) {
531
  if(strchr("({[",*p)!=NULL) {
530
    lp=*p; switch(lp) {
532
  lp=*p; switch(lp) {
531
        case '(': rp2=')';  break;
533
    case '(': rp2=')';  break;
532
        case '[': { /* verify for matrices */
534
    case '[': { /* verify for matrices */
533
          char *pt;
535
      char *pt;
534
          pe=find_matching(p+1,']');
536
      pe=find_matching(p+1,']');
535
          for(pt=p+1;pt<pe;pt++) {
537
      for(pt=p+1;pt<pe;pt++) {
536
              switch(*pt) {
538
        switch(*pt) {
537
                case '(': pt=find_matching(pt+1,')'); break;
539
          case '(': pt=find_matching(pt+1,')'); break;
538
                case '[': pt=find_matching(pt+1,']'); break;
540
          case '[': pt=find_matching(pt+1,']'); break;
539
                case '{': pt=find_matching(pt+1,'}'); break;
541
          case '{': pt=find_matching(pt+1,'}'); break;
540
                case '|': pt=find_matching(pt+1,'|'); break;
542
          case '|': pt=find_matching(pt+1,'|'); break;
541
 
543
 
542
                case ',':
544
          case ',':
543
                case ';': goto out;
545
          case ';': goto out;
544
              }
546
        }
545
          }
547
      }
546
          out: if(*pt==';' || *pt==',') { /* is matrix of the form [ 1,2;5,6] */
548
      out: if(*pt==';' || *pt==',') { /* is matrix of the form [ 1,2;5,6] */
547
              char mbuf[MAX_LINELEN+1];
549
        char mbuf[MAX_LINELEN+1];
548
              char *pp, *pt;
550
        char *pp, *pt;
549
 
551
 
550
              p++; if(*pe) *pe++=0;
552
        p++; if(*pe) *pe++=0;
551
              tprint(" \\begin{pmatrix}");
553
        tprint(" \\begin{pmatrix}");
552
              for(pp=p,i=0;*pp;pp=pt,i++) {
554
        for(pp=p,i=0;*pp;pp=pt,i++) {
553
                pt=find_term_end(pp);
555
          pt=find_term_end(pp);
554
                memmove(mbuf,pp,pt-pp); mbuf[pt-pp]=0;
556
          memmove(mbuf,pp,pt-pp); mbuf[pt-pp]=0;
555
                t_oneterm(mbuf,i);
557
          t_oneterm(mbuf,i);
556
                if(*pt==',') {
558
          if(*pt==',') {
557
                    tprint(" &"); pt++; i=-1;
559
            tprint(" &"); pt++; i=-1;
558
                }
560
          }
559
                if(*pt==';') {
561
          if(*pt==';') {
560
                    tprint("\\cr "); pt++; i=-1;
562
            tprint("\\cr "); pt++; i=-1;
561
                }
-
 
562
              }
-
 
563
              tprint(" \\end{pmatrix}"); goto expon;
-
 
564
          }
563
          }
565
          rp2=']'; break;
-
 
566
        }
564
        }
567
        case '{': { /* protected */
-
 
568
          pe=find_matching(p+1,'}');
-
 
569
          *pe=0;tprint(" %s} ",p);
-
 
570
          goto expon;
565
        tprint(" \\end{pmatrix}"); goto expon;
571
        }
566
      }
572
    }
-
 
573
    tprint(" \\left%c",lp);
567
      rp2=']'; break;
574
    snprintf(rpbuf,sizeof(rpbuf),"\\right%c ",rp2); rp=rpbuf;
-
 
575
    paren: p++;pe=find_matching(p,rp2); *pe=0;
-
 
576
    t_onestring(p); tprint(rp); pe++; goto expon;
-
 
577
    }
568
    }
-
 
569
    case '{': { /* protected */
-
 
570
      pe=find_matching(p+1,'}');
-
 
571
      *pe=0;tprint(" %s} ",p);
-
 
572
      goto expon;
-
 
573
    }
-
 
574
  }
-
 
575
  tprint(" \\left%c",lp);
-
 
576
  snprintf(rpbuf,sizeof(rpbuf),"\\right%c ",rp2); rp=rpbuf;
-
 
577
  paren: p++;pe=find_matching(p,rp2); *pe=0;
-
 
578
  t_onestring(p); tprint(rp); pe++; goto expon;
-
 
579
  }
578
    pe=find_mathvar_end(p); while(*pe && strchr("'\"!",*pe)!=NULL) pe++;
580
  pe=find_mathvar_end(p); while(*pe && strchr("'\"!",*pe)!=NULL) pe++;
579
    memmove(fbuf,p,pe-p); fbuf[pe-p]=0;
581
  memmove(fbuf,p,pe-p); fbuf[pe-p]=0;
580
    if(myisdigit(*p) || *p=='.') putnumber(fbuf);
582
  if(myisdigit(*p) || *p=='.') putnumber(fbuf);
581
    if(isalpha(*p)) {
583
  if(isalpha(*p)) {
582
    pe=find_mathvar_end(p); while(*pe && strchr("'\"!",*pe)!=NULL) pe++;
584
    pe=find_mathvar_end(p); while(*pe && strchr("'\"!",*pe)!=NULL) pe++;
583
    if(*pe=='(') {
585
    if(*pe=='(') {
584
        p=pe;
586
      p=pe;
585
/* search in list of math functions*/
587
/* search in list of math functions*/
586
        i=search_list(tmathfn, tmathfn_no, sizeof(tmathfn[0]), fbuf);
588
      i=search_list(tmathfn, tmathfn_no, sizeof(tmathfn[0]), fbuf);
587
        if(i>=0) {
589
      if(i>=0) {
588
          switch(tmathfn[i].expind) {
590
        switch(tmathfn[i].expind) {
589
              case 0: {
591
          case 0: {
590
                tprint(" %s",tmathfn[i].left);
592
            tprint(" %s",tmathfn[i].left);
591
                rp=tmathfn[i].right; break;
593
            rp=tmathfn[i].right; break;
592
              }
-
 
593
              case 1: {
-
 
594
                tprint(" %s",tmathfn[i].left);
-
 
595
                pe=find_matching(pe+1,')')+1;
-
 
596
                if(*pe && strchr("^'\"!",*pe)!=NULL) {
-
 
597
                    t_exponential(pe); *pe=0;
-
 
598
                }
-
 
599
                tprint(" \\left("); rp=tmathfn[i].right;
-
 
600
                break;
-
 
601
              }
-
 
602
              case 2: {  /* routine */
-
 
603
                p++;pe=find_matching(p,rp2); *pe=0;
-
 
604
                tmathfn[i].routine(p);
-
 
605
                pe++; goto expon;
-
 
606
              }
-
 
607
              default: rp=""; break;
-
 
608
          }
594
          }
-
 
595
          case 1: {
-
 
596
            tprint(" %s",tmathfn[i].left);
-
 
597
            pe=find_matching(pe+1,')')+1;
-
 
598
            if(*pe && strchr("^'\"!",*pe)!=NULL) {
-
 
599
              t_exponential(pe); *pe=0;
609
        }
600
            }
-
 
601
            tprint(" \\left("); rp=tmathfn[i].right;
-
 
602
            break;
610
        else {
603
          }
-
 
604
          case 2: {  /* routine */
-
 
605
            p++;pe=find_matching(p,rp2); *pe=0;
611
          putvar(fbuf);
606
            tmathfn[i].routine(p);
612
          rp="\\right) "; tprint(" \\left(");
607
            pe++; goto expon;
613
        }
608
          }
614
        rp2=')'; goto paren;
609
          default: rp=""; break;
-
 
610
        }
615
    }
611
      }
616
    else {
612
      else {
617
        putvar(fbuf);
613
        putvar(fbuf);
-
 
614
        rp="\\right) "; tprint(" \\left(");
-
 
615
      }
-
 
616
      rp2=')'; goto paren;
-
 
617
    }
-
 
618
    else {
-
 
619
      putvar(fbuf);
618
        if(*pe=='_') {
620
      if(*pe=='_') {
619
          char *ptt, buff[256];
621
        char *ptt, buff[256];
620
          tprint("_"); pe++;
622
        tprint("_"); pe++;
-
 
623
        if(*pe=='(') {
-
 
624
          ptt=find_matching(pe+1,')'); if(ptt) ptt++;
-
 
625
        }
-
 
626
        else {
621
          if(*pe=='(') {
627
          if(*pe=='{') {
622
              ptt=find_matching(pe+1,')'); if(ptt) ptt++;
628
            ptt=find_matching(pe+1,'}'); if(ptt) ptt++;
623
          }
629
          }
624
          else {
-
 
625
              if(*pe=='{') {
-
 
626
                ptt=find_matching(pe+1,'}'); if(ptt) ptt++;
-
 
627
              }
-
 
628
              else ptt=find_mathvar_end(pe);
630
          else ptt=find_mathvar_end(pe);
629
          }
-
 
630
          if(ptt==NULL || ptt-pe>128) goto expon;
-
 
631
          memmove(buff,pe,ptt-pe); buff[ptt-pe]=0; pe=ptt;
-
 
632
          strip_enclosing_par(buff);
-
 
633
          tprint("{%s}",buff);
-
 
634
        }
631
        }
-
 
632
        if(ptt==NULL || ptt-pe>128) goto expon;
-
 
633
        memmove(buff,pe,ptt-pe); buff[ptt-pe]=0; pe=ptt;
-
 
634
        strip_enclosing_par(buff);
-
 
635
        tprint("{%s}",buff);
-
 
636
      }
635
    }
637
    }
636
    }
638
  }
637
    /* exponential */
639
    /* exponential */
638
    expon: if(*pe && strchr("^'\"!",*pe)!=NULL) t_exponential(pe);
640
  expon: if(*pe && strchr("^'\"!",*pe)!=NULL) t_exponential(pe);
639
}
641
}
640
 
642
 
641
void t_onestring(char *p)
643
void t_onestring(char *p)
642
{
644
{
643
    char termbuf[MAX_LINELEN+1];
645
  char termbuf[MAX_LINELEN+1];
644
    char *pp, *pe;
646
  char *pp, *pe;
645
    int i;
647
  int i;
646
 
648
 
647
    for(pp=p,i=0;*pp;pp=pe,i++) {
649
  for(pp=p,i=0;*pp;pp=pe,i++) {
648
    pe=find_term_end(pp);
650
  pe=find_term_end(pp);
649
    memmove(termbuf,pp,pe-pp); termbuf[pe-pp]=0;
651
  memmove(termbuf,pp,pe-pp); termbuf[pe-pp]=0;
650
    t_oneterm(termbuf,i);
652
  t_oneterm(termbuf,i);
651
    }
653
  }
652
}
654
}
653
/* replace \pmatrix{  } by latex syntax \begin{pmatrix} .. \end{pmatrix} */
655
/* replace \pmatrix{  } by latex syntax \begin{pmatrix} .. \end{pmatrix} */
654
 
656
 
655
void _replace_matrix ( char *p , char *s_mat1, char *s_mat2 )
657
void _replace_matrix ( char *p , char *s_mat1, char *s_mat2 )
-
 
658
{
656
{ char pbuf[MAX_LINELEN];
659
  char pbuf[MAX_LINELEN];
657
  while ( (p = strstr(p,s_mat1)) )
660
  while ( (p = strstr(p,s_mat1)) ){
658
  { char *p2 = find_matching(p+strlen(s_mat1),'}');
661
    char *p2 = find_matching(p+strlen(s_mat1),'}');
659
    long len = p2-p-strlen(s_mat1);
662
    long len = p2-p-strlen(s_mat1);
660
    if (!p2) { module_error("unmatched_parentheses"); return; }
663
    if (!p2) { module_error("unmatched_parentheses"); return; }
661
    memcpy(pbuf, p+strlen(s_mat1), len); pbuf[len]= 0;
664
    memcpy(pbuf, p+strlen(s_mat1), len); pbuf[len]= 0;
662
    p2 ++ ;
665
    p2 ++ ;
663
    string_modify(p, p, p2, "\\begin{%s}%s\\end{%s}",s_mat2,pbuf,s_mat2);
666
    string_modify(p, p, p2, "\\begin{%s}%s\\end{%s}",s_mat2,pbuf,s_mat2);
Line 665... Line 668...
665
}
668
}
666
 
669
 
667
/* translate raw math expression into TeX source */
670
/* translate raw math expression into TeX source */
668
void texmath(char *p)
671
void texmath(char *p)
669
{
672
{
670
    char *pp;
673
  char *pp;
671
    _replace_matrix (p,"\\matrix{","matrix");
674
  _replace_matrix (p,"\\matrix{","matrix");
672
    _replace_matrix (p,"\\pmatrix{","pmatrix");
675
  _replace_matrix (p,"\\pmatrix{","pmatrix");
673
    if(strpbrk(p,"{}\\")!=NULL) return;
676
  if(strpbrk(p,"{}\\")!=NULL) return;
674
    for(pp=strstr(p,"!="); pp; pp=strstr(pp+1,"!=")) {
677
  for(pp=strstr(p,"!="); pp; pp=strstr(pp+1,"!=")) {
675
      if(pp>p && !isspace(*(pp-1))) continue;
678
    if(pp>p && !isspace(*(pp-1))) continue;
676
      string_modify(p,pp,pp+2,"*neq*");
679
    string_modify(p,pp,pp+2,"*neq*");
677
    }
680
  }
678
/* remove spaces */
681
/* remove spaces */
679
    for(pp=p; *pp; pp++) {
682
  for(pp=p; *pp; pp++) {
680
    if(isspace(*pp)) {ovlstrcpy(pp,pp+1); pp--;}
683
  if(isspace(*pp)) {ovlstrcpy(pp,pp+1); pp--;}
681
    }
684
  }
682
/* replace ** by ^  see __replace_badchar(p,"**", "^");*/
685
/* replace ** by ^  see __replace_badchar(p,"**", "^");*/
683
    for(pp=strstr(p,"**"); pp!=NULL; pp=strstr(pp,"**")) {
686
  for(pp=strstr(p,"**"); pp!=NULL; pp=strstr(pp,"**")) {
684
      *pp='^'; ovlstrcpy(pp+1,pp+2);
687
    *pp='^'; ovlstrcpy(pp+1,pp+2);
685
    }
688
  }
686
    if(check_parentheses(p,1)!=0) module_error("unmatched_parentheses");
689
  if(check_parentheses(p,1)!=0) module_error("unmatched_parentheses");
687
    texmathbuf[0]=0; t_onestring(p);
690
  texmathbuf[0]=0; t_onestring(p);
688
    singlespace(texmathbuf);strip_trailing_spaces(texmathbuf);
691
  singlespace(texmathbuf);strip_trailing_spaces(texmathbuf);
689
    mystrncpy(p,texmathbuf,MAX_LINELEN);
692
  mystrncpy(p,texmathbuf,MAX_LINELEN);
690
}
693
}