Subversion Repositories wimsdev

Rev

Rev 8871 | Rev 9093 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
  2.  *
  3.  *  This program is free software; you can redistribute it and/or modify
  4.  *  it under the terms of the GNU General Public License as published by
  5.  *  the Free Software Foundation; either version 2 of the License, or
  6.  *  (at your option) any later version.
  7.  *
  8.  *  This program is distributed in the hope that it will be useful,
  9.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.  *  GNU General Public License for more details.
  12.  *
  13.  *  You should have received a copy of the GNU General Public License
  14.  *  along with this program; if not, write to the Free Software
  15.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16.  */
  17. #include "../Lib/libwims.h"
  18. #include "oef2wims.h"
  19. int prepcnt;
  20. int ex_statement=0, ex_hint=0, ex_help=0, ex_solution=0, ex_latex=0;
  21.  
  22.  
  23. char vbuf_latex[MAX_LINELEN+1];
  24. const size_t MAX_KEY_LEN=128;
  25. char vbuf_statement[MAX_LINELEN+1];
  26. char vbuf_hint[MAX_LINELEN+1];
  27. char vbuf_help[MAX_LINELEN+1];
  28. char vbuf_solution[MAX_LINELEN+1];
  29.  
  30. /* empty processor, template. */
  31. void empty(char *p[MAX_PARM]) {}
  32.  
  33. static void p_keyword(char *p[MAX_PARM], const char *key)
  34. {
  35.     p[0]=find_word_start(p[0]);
  36.     if(strlen(p[0])>MAX_KEY_LEN) p[0][MAX_KEY_LEN]=0;
  37.     fprintf(outf,"%s=%s\n", key, p[0]);
  38. }
  39.  
  40. void p_author(char *p[MAX_PARM]) { p_keyword(p, "author"); }
  41. void p_email(char *p[MAX_PARM]) { p_keyword(p, "email"); }
  42. void p_keywords(char *p[MAX_PARM]) { p_keyword(p, "keywords"); }
  43. void p_title_ca(char *p[MAX_PARM]) { p_keyword(p, "title_ca"); }
  44. void p_title_cn(char *p[MAX_PARM]) { p_keyword(p, "title_cn"); }
  45. void p_title_en(char *p[MAX_PARM]) { p_keyword(p, "title_en"); }
  46. void p_title_es(char *p[MAX_PARM]) { p_keyword(p, "title_es"); }
  47. void p_title_fr(char *p[MAX_PARM]) { p_keyword(p, "title_fr"); }
  48. void p_title_it(char *p[MAX_PARM]) { p_keyword(p, "title_it"); }
  49. void p_title_nl(char *p[MAX_PARM]) { p_keyword(p, "title_nl"); }
  50. void p_title_si(char *p[MAX_PARM]) { p_keyword(p, "title_si"); }
  51.  
  52. void p_computeanswer(char *p[MAX_PARM])
  53. {
  54.     p[0]=find_word_start(p[0]);
  55.     *find_word_end(p[0])=0;
  56.     if(strcasecmp(p[0],"yes"))
  57.       fprintf(outf,"computeanswer=no\n");
  58.     else fprintf(outf,"computeanswer=%s\n",p[0]);
  59. }
  60.  
  61. void p_precision(char *p[MAX_PARM])
  62. {
  63.     int pr;
  64.     pr=atoi(p[0]);
  65.     if(pr<0 || pr>100000000) return;
  66.     fprintf(outf,"precision=%d\n",pr);
  67. }
  68.  
  69. void p_css(char *p[MAX_PARM])
  70. {
  71.     char vbuf_css[MAX_LINELEN+1];
  72.     if(p==NULL) return;
  73.     snprintf(vbuf_css,sizeof(vbuf_css),"%s",p[0]); subst(vbuf_css);
  74.     fprintf(outf,"oefcss=%s\n",vbuf_css);
  75. }
  76.  
  77. void p_credits(char *p[MAX_PARM])
  78. {
  79.     char vbuf_credits[MAX_LINELEN+1];
  80.     if(p==NULL) return;
  81.     snprintf(vbuf_credits,sizeof(vbuf_credits),"%s",p[0]);
  82.     subst(vbuf_credits);
  83.     singlespace(vbuf_credits);
  84.     fprintf(outf,"credits=%s\n\n", vbuf_credits);
  85. }
  86.  
  87. void p_wims(char *p[MAX_PARM])
  88. {
  89.     char vbuf[MAX_LINELEN+1];
  90.     snprintf(vbuf,sizeof(vbuf),"%s",p[0]); subst(vbuf);
  91. /* the second condition could be removed?
  92.  * To be very careful! */
  93.     if(strchr(vbuf,'=')==NULL || strchr(vbuf,'!')!=NULL) return;
  94.     fprintf(outf,"%s\n",vbuf);
  95. }
  96.  
  97. void p_mdef(char *p[MAX_PARM])
  98. {
  99.     char vbuf[MAX_LINELEN+1];
  100.     if(wordchr(mdef,p[0])==NULL) return;
  101.     snprintf(vbuf,sizeof(vbuf),"%s",p[1]); subst(vbuf);
  102. /* the second condition could be removed?
  103.  * To be very careful! */
  104.     if(strchr(vbuf,'!')!=NULL) return;
  105.     fprintf(outf,"m_%s=%s\n",p[0],vbuf);
  106. }
  107.  
  108. void p_range(char *p[MAX_PARM])
  109. {
  110.     double left, right;
  111.     char *pp;
  112.     pp=strstr(p[0],"..");
  113.     if(pp==NULL) return;
  114.     *pp=0;pp+=strlen("..");
  115.     left=atof(p[0]); right=atof(pp);
  116.     if(left>=right-1E-50 || left<-1E50 || right>1E50) return;
  117.     fprintf(outf,"leftrange=%f\nrightrange=%f\n",left,right);
  118. }
  119.  
  120. void p_language(char *p[MAX_PARM])
  121. {
  122.     p[0]=find_word_start(p[0]);
  123.     *find_word_end(p[0])=0;
  124.     if(strlen(p[0])==2) fprintf(outf,"language=%s\n",p[0]);
  125. }
  126.  
  127. void p_statement(char *p[MAX_PARM])
  128. {
  129.     if(ex_statement<0) return;
  130.     if(ex_statement>0 || p==NULL) {
  131.       out_exec(vbuf_statement,"question");
  132.       ex_statement=-1; return;
  133.     }
  134.     if(p==NULL) return;
  135.     snprintf(vbuf_statement,sizeof(vbuf_statement),"%s",p[0]);
  136.     subst(vbuf_statement);
  137.     if(strcmp(format,"html")!=0) {
  138.       fprintf(outf,"question=!nosubst %s\n",vbuf_statement);
  139.       ex_statement=-1;
  140.     }
  141.     else {
  142.       fprintf(outf,"question=%s\n",executed_str);
  143.       ex_statement=1;
  144.     }
  145. }
  146.  
  147. void p_hint(char *p[MAX_PARM])
  148. {
  149.     if(ex_hint<0) return;
  150.     if(ex_hint>0 || p==NULL) {
  151.       out_exec(vbuf_hint,"hint");
  152.       ex_hint=-1; return;
  153.     }
  154.     snprintf(vbuf_hint,sizeof(vbuf_hint),"%s",p[0]); subst(vbuf_hint);
  155.     if(strchr(vbuf_hint,'\\')!=NULL) {
  156.       fprintf(outf,"hint=%s\n",executed_str);
  157.       ex_hint=1;
  158.     }
  159.     else {
  160.       singlespace(vbuf_hint);
  161.       fprintf(outf,"hint=!nosubst %s\n\n", vbuf_hint);
  162.     }
  163. }
  164.  
  165. void p_help(char *p[MAX_PARM])
  166. {
  167.     if(ex_help<0) return;
  168.     if(ex_help>0 || p==NULL) {
  169.       out_exec(vbuf_help,"help");
  170.       ex_help=-1; return;
  171.     }
  172.     snprintf(vbuf_help,sizeof(vbuf_help),"%s",p[0]); subst(vbuf_help);
  173.     if(strchr(vbuf_help,'\\')!=NULL) {
  174.       fprintf(outf,"help=%s\n",executed_str);
  175.       ex_help=1;
  176.     }
  177.     else {
  178.       singlespace(vbuf_help);
  179.       fprintf(outf,"help=!nosubst %s\n\n", vbuf_help);
  180.     }
  181. }
  182.  
  183. void p_solution(char *p[MAX_PARM])
  184. {
  185.     if(ex_solution<0) return;
  186.     if(ex_solution>0 || p==NULL) {
  187.       out_exec(vbuf_solution,"solution");
  188.       ex_solution=-1; return;
  189.     }
  190.     snprintf(vbuf_solution,sizeof(vbuf_solution),"%s",p[0]);
  191.     subst(vbuf_solution);
  192.     if(strchr(vbuf_solution,'\\')!=NULL) {
  193.       fprintf(outf,"solution=%s\n",executed_str);
  194.       ex_solution=1;
  195.     }
  196.     else {
  197.       singlespace(vbuf_solution);
  198.       fprintf(outf,"solution=!nosubst %s\n\n", vbuf_solution);
  199.     }
  200. }
  201.  
  202. void p_latex(char *p[MAX_PARM])
  203. {
  204.     if(ex_latex<0) return;
  205.     if(ex_latex>0 || p==NULL) {
  206.       out_exec(vbuf_latex,"latex");
  207.       ex_latex=-1; return;
  208.     }
  209.     snprintf(vbuf_latex,sizeof(vbuf_latex),"%s",p[0]);
  210.     subst(vbuf_latex);
  211.       singlespace(vbuf_latex);
  212.       fprintf(outf,"latex=!nosubst %s\n\n", vbuf_latex);
  213. }
  214.  
  215. enum {typ_default, typ_num, typ_func, typ_units, typ_text,
  216.       typ_formal,typ_matrix,typ_vector,typ_set,typ_equation,
  217.       typ_case, typ_nocase, typ_atext, typ_wlist, typ_comp,
  218.       typ_algexp, typ_litexp, typ_menu, typ_coord, typ_fill,
  219.       typ_raw, typ_symtext,
  220.       typ_java, typ_src, typ_chem
  221. };
  222.  
  223. struct {
  224.     char *name;
  225.     int  type;
  226.     char *def;
  227. } anstype[]={
  228.       {"algexp", typ_algexp, "algexp"},
  229.       {"aset",  typ_set, "aset"},
  230.       {"atext",  typ_atext, "atext"},
  231.       {"case",  typ_case, "case"},
  232.       {"checkbox", typ_menu, "checkbox"},
  233.       {"chemeq",        typ_chem,       "chemeq"},
  234.       {"chset",  typ_atext, "chset"},
  235.       {"click",  typ_menu, "click"},
  236.       {"clickfill", typ_fill, "clickfill"},
  237.       {"code",  typ_src, "code"},
  238.       {"compose", typ_comp, "compose"},
  239.       {"coord",  typ_coord, "coord"},
  240.       {"coordinates", typ_coord, "coord"},
  241.       {"corresp", typ_comp, "correspond"},
  242.       {"correspond", typ_comp, "correspond"},
  243.       {"default", typ_default, "default"},
  244.       {"dragfill", typ_fill, "dragfill"},
  245.       {"equation", typ_equation, "equation"},
  246.       {"expalg", typ_algexp, "algexp"},
  247.       {"formal", typ_formal, "formal"},
  248.       {"fset",  typ_set, "fset"},
  249.       {"function", typ_func, "function"},
  250.       {"imgcomp", typ_comp, "imgcomp"},
  251.       {"javacurve", typ_java, "javacurve"},
  252.       {"link",  typ_menu, "click"},
  253.       {"litexp", typ_litexp, "litexp"},
  254.       {"mark",  typ_menu, "mark"},
  255.       {"matrix", typ_matrix, "matrix"},
  256.       {"menu",  typ_menu, "menu"},
  257.       {"nocase", typ_nocase, "nocase"},
  258.       {"number", typ_num, "numeric"},
  259.       {"numeric", typ_num, "numeric"},
  260.       {"numexp", typ_algexp, "numexp"},
  261.       {"radio",  typ_menu, "radio"},
  262.       {"range",  typ_func, "range"},
  263.       {"ranges", typ_func, "range"},
  264.       {"raw",  typ_raw, "raw"},
  265.       {"reorder", typ_comp, "reorder"},
  266.       {"select", typ_menu, "menu"},
  267.       {"set",  typ_set, "set"},
  268.       {"sigunits", typ_units, "sigunits"},
  269.       {"symtext", typ_symtext, "symtext"},
  270.       {"text",  typ_text, "case"},
  271.       {"textcomp", typ_comp, "textcomp"},
  272.       {"unit",  typ_units, "units"},
  273.       {"units",  typ_units, "units"},
  274.       {"vector", typ_vector, "vector"},
  275.       {"wlist",  typ_wlist, "wlist"},
  276.       {"wordcomp", typ_comp, "textcomp"}
  277. };
  278.  
  279. #define anstype_no (sizeof(anstype)/sizeof(anstype[0]))
  280.  
  281. void p_answer(char *p[MAX_PARM])
  282. {
  283.     char *pp, vbuf[MAX_LINELEN+1],nbuf[MAX_LINELEN+1];
  284.     int i,j,k,typ;
  285.  
  286. /* look for type definition */
  287.     typ=typ_default;
  288.     for(i=0;i<5;i++) {
  289.       if(p[i]==NULL || p[i][0]==0) continue;
  290.       p[i]=find_word_start(p[i]);
  291.       if(strncasecmp(p[i],"type",strlen("type"))==0) {
  292.           char *tt;
  293.           tt=find_word_start(p[i]+strlen("type"));
  294.           if(*tt=='=') {
  295.             for(j=i;j<6;j++) p[j]=p[j+1]; i--;
  296.             tt=find_word_start(tt+1); *find_word_end(tt)=0;
  297.             k=search_list(anstype,anstype_no,sizeof(anstype[0]),tt);
  298. /* unknown type is now substituted */
  299.             if(k>=0) {
  300.                 fprintf(outf,"replytype%d=%s\n",
  301.                       answercnt,anstype[k].def);
  302.                 typ=anstype[k].type;
  303.             }
  304.             else {
  305.                 snprintf(nbuf,sizeof(nbuf),"%s",tt); subst(nbuf);
  306.                 fprintf(outf,"replytype%d=%s\n\n",answercnt,nbuf);
  307.             }
  308.           }
  309.           continue;
  310.       }
  311.       if(strncasecmp(p[i],"option",strlen("option"))==0) {
  312.           char *tt, *tv;
  313.           tt=p[i]+strlen("option");
  314.           if(*tt=='s' || *tt=='S') tt++;
  315.           tt=find_word_start(tt);
  316.           if(*tt=='=') {
  317.             for(j=i;j<6;j++) p[j]=p[j+1]; i--;
  318.             snprintf(nbuf,sizeof(nbuf),"%s",tt+1); subst(nbuf);
  319.             for(tv=nbuf; *tv; tv++) if(*tv==',' || *tv==';') *tv=' ';
  320.             strip_trailing_spaces(nbuf);
  321.             fprintf(outf,"replyoption%d=%s \n",answercnt,
  322.                   find_word_start(nbuf));
  323.           }
  324.           continue;
  325.       }
  326.       if(strncasecmp(p[i],"weight",strlen("weight"))==0) {
  327.           char *tt;
  328.           tt=p[i]+strlen("weight");
  329.           tt=find_word_start(tt);
  330.           if(*tt=='=') {
  331.             for(j=i;j<6;j++) p[j]=p[j+1]; i--;
  332.             snprintf(nbuf,sizeof(nbuf),"%s",tt+1); subst(nbuf);
  333.             strip_trailing_spaces(nbuf);
  334.             fprintf(outf,"replyweight%d=%s \n",answercnt,
  335.                   find_word_start(nbuf));
  336.           }
  337.           continue;
  338.       }
  339.     }
  340.     p[0]=find_word_start(p[0]);
  341.     strncpy(nbuf,p[0],MAX_LINELEN); nbuf[MAX_LINELEN]=0; subst(nbuf);
  342.     nbuf[MAX_PROMPTLEN]=0;
  343.     strip_trailing_spaces(nbuf); pp=nbuf+strlen(nbuf)-1;
  344.     if(*pp=='=') *pp=0;
  345.     p[1]=find_word_start(p[1]);
  346.     if(*p[1]=='\\' && (isalnum(*(p[1]+1)) || *(p[1]+1)=='_')) {
  347. /* check for analyzed answers */
  348.       int i,n; char *pt;
  349.       strncpy(vbuf,p[1]+1,MAX_LINELEN); vbuf[MAX_LINELEN]=0;
  350.       pt=strchr(vbuf,';'); if(pt!=NULL) *pt=0;
  351.       strip_trailing_spaces(vbuf); n=strlen(vbuf);
  352.       if(n>=MAX_NAMELEN) goto normal;
  353.       for(i=0;i<n && (isalnum(vbuf[i]) || vbuf[i]=='_');i++);
  354.       if(i<n) goto normal;
  355.       for(i=varcnt-1;i>=1 && strcmp(vbuf,param[i].name)!=0;i--);
  356.       if(i<1) { /* unused name; the answer should be analyzed */
  357.           char *pm;
  358.           pm=xmalloc(MAX_NAMELEN+2);
  359.           ovlstrcpy(pm,vbuf); param[varcnt].name=pm;
  360.           if(pt) {
  361.             *pt=';';
  362.             ovlstrcpy(vbuf,pt); subst(vbuf); pt=vbuf;
  363.           }
  364.           else pt="";
  365.           param[varcnt].type=pt_real;
  366.           param[varcnt].save=1;
  367.           fprintf(outf,"replyname%d=%s\nreplygood%d=?analyze %d%s\n",
  368.                 answercnt,nbuf,answercnt,varcnt,pt);
  369.           condans++; answercnt++; varcnt++; return;
  370.       }
  371.     }
  372.     normal:
  373.     strncpy(vbuf,p[1],MAX_LINELEN); vbuf[MAX_LINELEN]=0;
  374.     subst(vbuf);
  375.     switch(typ) {
  376.       default:
  377.       case typ_default: {
  378.           fprintf(outf,"replyname%d=%s\nreplygood%d=%s\n",
  379.                 answercnt,nbuf,answercnt,vbuf);
  380.           break;
  381.       }
  382.       case typ_num: {
  383.           fprintf(outf,"replyname%d=%s\nreplygood%d=$[%s]\n",
  384.                 answercnt,nbuf,answercnt,vbuf);
  385.           break;
  386.       }
  387.       case typ_equation:
  388.       case typ_func: {
  389.           fprintf(outf,"replyname%d=%s\nreplygood%d=!rawmath %s\n",
  390.                 answercnt,nbuf,answercnt,vbuf);
  391.           break;
  392.       }
  393.       case typ_units: {
  394.           fprintf(outf,"replyname%d=%s\nreplygood%d=%s\n",
  395.                 answercnt,nbuf,answercnt,vbuf);
  396.           break;
  397.       }
  398.     }
  399.     answercnt++;
  400. }
  401.  
  402. void p_choice(char *p[MAX_PARM])
  403. {
  404.     int i,j;
  405.     char buf1[MAX_LINELEN+1],buf2[MAX_LINELEN+1],nbuf[MAX_LINELEN+1];
  406.     for(i=0;i<5;i++) {
  407.       if(p[i]==NULL || p[i][0]==0) continue;
  408.       p[i]=find_word_start(p[i]);
  409.       if(strncasecmp(p[i],"option",strlen("option"))==0) {
  410.           char *tt, *tv;
  411.           tt=p[i]+strlen("option");
  412.           if(*tt=='s' || *tt=='S') tt++;
  413.           tt=find_word_start(tt);
  414.           if(*tt=='=') {
  415.             for(j=i;j<6;j++) p[j]=p[j+1]; i--;
  416.             snprintf(nbuf,sizeof(nbuf),"%s",tt+1); subst(nbuf);
  417.             for(tv=nbuf; *tv; tv++) if(*tv==',' || *tv==';') *tv=' ';
  418.             strip_trailing_spaces(nbuf);
  419.             fprintf(outf,"choiceoption%d=%s \n",choicecnt,
  420.                   find_word_start(nbuf));
  421.           }
  422.           continue;
  423.       }
  424.       if(strncasecmp(p[i],"weight",strlen("weight"))==0) {
  425.           char *tt;
  426.           tt=p[i]+strlen("weight");
  427.           tt=find_word_start(tt);
  428.           if(*tt=='=') {
  429.             for(j=i;j<6;j++) p[j]=p[j+1]; i--;
  430.             snprintf(nbuf,sizeof(nbuf),"%s",tt+1); subst(nbuf);
  431.             strip_trailing_spaces(nbuf);
  432.             fprintf(outf,"choiceweight%d=%s \n",choicecnt,
  433.                   find_word_start(nbuf));
  434.           }
  435.           continue;
  436.       }
  437.     }
  438.     p[0]=find_word_start(p[0]);
  439.     snprintf(buf1,sizeof(buf1),"%s",p[1]); subst(buf1);
  440.     snprintf(buf2,sizeof(buf2),"%s",p[2]); subst(buf2);
  441.     snprintf(nbuf,sizeof(nbuf),"%s",p[0]); subst(nbuf);
  442.     nbuf[MAX_PROMPTLEN]=0;
  443.     fprintf(outf,"choicename%d=%s\nchoicegood%d=%s\nchoicebad%d=%s\n",
  444.           choicecnt,nbuf,choicecnt,buf1,choicecnt,buf2);
  445.     choicecnt++;
  446. }
  447.  
  448. void putval(char *p, int n, int ptype)
  449. {
  450.     switch(ptype) {
  451.       case pt_int: {
  452.           fprintf(outf,"val%d=$[rint(%s)]\n",n,p);
  453.           break;
  454.       }
  455.       case pt_real: {
  456.           fprintf(outf,"val%d=$[%s]\n",n,p);
  457.           break;
  458.       }
  459.       case pt_func: {
  460.           fprintf(outf,"val%d=!rawmath %s\n",n,p);
  461.           break;
  462.       }
  463.       case pt_complex: {
  464.           fprintf(outf,"t_=!rawmath %s\nt_=!exec pari print($t_)\n\
  465. val%d=!mathsubst I=i in $t_\n",p,n);
  466.           break;
  467.       }
  468.       case pt_matrix: {
  469.           fprintf(outf,"tmp=!trim %s\n\
  470. val%d=!translate internal $     \\\n$ to ;; in $tmp\n",p,n);
  471.           break;
  472.       }
  473.       case pt_rat: {
  474.           fprintf(outf,"t_=!rawmath %s\n\
  475. val%d=!exec pari print($t_)\n",p,n);
  476.           break;
  477.       }
  478.       default: {
  479.           fprintf(outf,"val%d=%s\n",n,p);
  480.           break;
  481.       }
  482.     }
  483. }
  484.  
  485. void parm(char *p[MAX_PARM], int ptype)
  486. {
  487.     char *pp, *p2;
  488.     char vbuf[MAX_LINELEN+1];
  489.     int i;
  490.  
  491.     p[0]=find_word_start(p[0]);
  492.     if(*p[0]=='\\') p[0]++;
  493. /* bad name */
  494.     if(!isalpha(*p[0])) return;
  495.     strip_trailing_spaces(p[0]);
  496.     for(pp=p[0];*pp;pp++) if(!isalnum(*pp) && *pp!='_') {
  497. /* bad name and security risk */
  498.       if(!isspace(*pp)) return;
  499.       ovlstrcpy(pp,pp+1); pp--;
  500.     }
  501.     for(i=1;i<varcnt && strcmp(p[0],param[i].name)!=0;i++);
  502.     p[1]=find_word_start(p[1]);
  503.     snprintf(vbuf,sizeof(vbuf),"%s",p[1]); subst(vbuf);
  504.     if(deftag) repsubst(vbuf);
  505.     if((pp=strparchr(vbuf,'?'))!=NULL && pp[1]!='?') {
  506.       char buf[MAX_LINELEN+1];
  507.       if(check_compare(vbuf)==0) goto noif;
  508.       p2=strparchr(pp,':'); *pp++=0; if(p2!=NULL) *p2++=0;
  509.       snprintf(buf,sizeof(buf),"%s",vbuf);
  510.       prepcnt=0; parmprep(buf,ptype);
  511.       fprintf(outf,"\n!ifval %s\n",buf);
  512.       snprintf(buf,sizeof(buf),"%s",pp);
  513.       parmprep(buf,ptype); putval(buf,i,ptype);
  514.       if(p2!=NULL) {
  515.           fprintf(outf,"!else\n");
  516.           snprintf(buf,sizeof(buf),"%s",p2);
  517.           parmprep(buf,ptype); putval(buf,i,ptype);
  518.       }
  519.       fprintf(outf,"!endif\n");
  520.     }
  521.     else {
  522. noif:
  523.       prepcnt=0; parmprep(vbuf, ptype);
  524.       putval(vbuf,i,ptype);
  525.     }
  526.     if(i>=varcnt && i<MAX_PARAM) {
  527.       param[varcnt].name=p[0];
  528.       param[varcnt].type=ptype;
  529.       param[varcnt].save=0;
  530.       varcnt++;
  531.     }
  532. }
  533.  
  534. void p_int(char *p[MAX_PARM]) {parm(p,pt_int);}
  535. void p_rational(char *p[MAX_PARM]) {parm(p,pt_rat);}
  536. void p_real(char *p[MAX_PARM]) {parm(p,pt_real);}
  537. void p_complex(char *p[MAX_PARM]) {parm(p,pt_complex);}
  538. void p_func(char *p[MAX_PARM]) {parm(p,pt_func);}
  539. void p_text(char *p[MAX_PARM]) {parm(p,pt_text);}
  540. void p_matrix(char *p[MAX_PARM]) {parm(p,pt_matrix);}
  541.  
  542. void p_parm(char *p[MAX_PARM])
  543. {
  544.     parm(p,pt_real);
  545. }
  546.  
  547. void _p_if(char *p[MAX_PARM], int type)
  548. {
  549.     char vbuf[MAX_LINELEN+1];
  550.     snprintf(vbuf,sizeof(vbuf),"%s",p[0]); subst(vbuf);
  551.     if(deftag) repsubst(vbuf);
  552.     prepcnt=0; parmprep(vbuf, pt_real);
  553.     switch(type) {
  554.           case 0: fprintf(outf,"!if %s \n",vbuf); break;
  555.           case 1: fprintf(outf,"!ifval %s \n",vbuf);
  556.     }
  557. }
  558. void p_if(char *p[MAX_PARM]) { return _p_if(p, 0);}
  559. void p_ifval(char *p[MAX_PARM]) { return _p_if(p, 1);}
  560.  
  561. void p_else(char *p[MAX_PARM])
  562. {
  563.     fprintf(outf,"!else\n");
  564. }
  565.  
  566. void p_endif(char *p[MAX_PARM])
  567. {
  568.     fprintf(outf,"!endif\n");
  569. }
  570.  
  571.  
  572. void p_while(char *p[MAX_PARM])
  573. {
  574.     char vbuf[MAX_LINELEN+1];
  575.     snprintf(vbuf,sizeof(vbuf),"%s",p[0]); subst(vbuf);
  576.     if(deftag) repsubst(vbuf);
  577.     prepcnt=0; parmprep(vbuf, pt_real);
  578.     fprintf(outf,"!while %s \n",vbuf);
  579. }
  580.  
  581. void p_endwhile(char *p[MAX_PARM])
  582. {
  583.     fprintf(outf,"!endwhile\n");
  584. }
  585.  
  586. void p_for(char *p[MAX_PARM])
  587. {
  588.     char *p1, *p2, buf[256];
  589.     char vbuf[MAX_LINELEN+1];
  590.     int i;
  591.  
  592.     p1=find_word_start(p[0]);
  593.     if(!isalpha(*p1)) return;
  594.     for(p2=p1; isalnum(*p2); p2++);
  595.     if(p2-p1>64) return;
  596.     memmove(buf,p1,p2-p1); buf[p2-p1]=0;
  597.     for(i=1;i<varcnt && strcmp(buf,param[i].name)!=0;i++);
  598.     if(i>=varcnt && i<MAX_PARAM) {
  599.       param[varcnt].name=p1;
  600.       param[varcnt].type=pt_real;
  601.       param[varcnt].save=0;
  602.       varcnt++;
  603.     }
  604.     snprintf(vbuf,sizeof(vbuf),"%s",p2); subst(vbuf); *p2=0;
  605.     if(deftag) repsubst(vbuf);
  606.     prepcnt=0; parmprep(vbuf, pt_real);
  607.     fprintf(outf,"!for val%d %s \n", i, vbuf);
  608. }
  609.  
  610. void p_next(char *p[MAX_PARM])
  611. {
  612.     fprintf(outf,"!next\n");
  613. }
  614.  
  615. void p_plot(char *p[MAX_PARM])
  616. {
  617.     int i, f, xr, yr;
  618.     char *pp, *p2;
  619.     char buf[MAX_LINELEN+1];
  620.     f=xr=yr=-1;
  621.     for(i=0;i<3;i++) {
  622.       if(*p[i]==0) continue;
  623.       if((pp=strchr(p[i],'='))==NULL) f=i;
  624.       else {
  625.           *pp=0; pp++;
  626.           p2=find_word_start(p[i]);
  627.           if(*p2=='x' || *p2=='X') xr=i;
  628.           else if (*p2=='y' || *p2=='Y') yr=i;
  629.           ovlstrcpy(p[i],pp);
  630.       }
  631.     }
  632. /*    if(xr>=0 && (pp=strstr(p[xr],".."))!=NULL) {
  633.  
  634.     }
  635. */    if(f<0) return;
  636.     ovlstrcpy(buf, p[f]);
  637.     prepcnt=0; parmprep(buf,pt_func);
  638.     fprintf(outf,"plot_fn=!rawmath %s\n",buf);
  639.  
  640. }
  641.  
  642. void p_condition(char *p[MAX_PARM])
  643. {
  644.     int i,j;
  645.     char buf1[MAX_LINELEN+1],buf2[MAX_LINELEN+1];
  646.     for(i=0;i<5;i++) {
  647.       if(p[i]==NULL || p[i][0]==0) continue;
  648.       p[i]=find_word_start(p[i]);
  649.       if(strncasecmp(p[i],"option",strlen("option"))==0) {
  650.           char *tt, *tv;
  651.           tt=p[i]+strlen("option");
  652.           if(*tt=='s' || *tt=='S') tt++;
  653.           tt=find_word_start(tt);
  654.           if(*tt=='=') {
  655.             for(j=i;j<6;j++) p[j]=p[j+1]; i--;
  656.             snprintf(buf1,sizeof(buf1),"%s",tt+1); subst(buf1);
  657.             for(tv=buf1; *tv; tv++) if(*tv==',' || *tv==';') *tv=' ';
  658.             strip_trailing_spaces(buf1);
  659.             fprintf(outf,"condoption%d=%s \n",conditioncnt,
  660.                   find_word_start(buf1));
  661.           }
  662.           continue;
  663.       }
  664.       if(strncasecmp(p[i],"weight",strlen("weight"))==0) {
  665.           char *tt;
  666.           tt=p[i]+strlen("weight");
  667.           tt=find_word_start(tt);
  668.           if(*tt=='=') {
  669.             for(j=i;j<6;j++) p[j]=p[j+1]; i--;
  670.             snprintf(buf1,sizeof(buf1),"%s",tt+1); subst(buf1);
  671.             strip_trailing_spaces(buf1);
  672.             fprintf(outf,"condweight%d=%s \n",conditioncnt,
  673.                   find_word_start(buf1));
  674.           }
  675.           continue;
  676.       }
  677.     }
  678.     if(p[1][0]==0) {p[1]=p[0]; p[0]="";}
  679.     snprintf(buf1,sizeof(buf1),"%s",p[0]); subst(buf1);
  680.     snprintf(buf2,sizeof(buf2),"%s",p[1]); subst(buf2);
  681.     prepcnt=0; parmprep(buf2, pt_real);
  682.     repsubst(buf2);
  683.     fprintf(outf,"\n!ifval %s\n condtest%d=1\n!else\n condtest%d=0\n!endif\n\
  684. condname%d=%s\n", buf2,conditioncnt,conditioncnt,conditioncnt,buf1);
  685.     conditioncnt++;
  686. }
  687.  
  688. void p_conditions(char *p[MAX_PARM])
  689. {
  690.     char buf[MAX_LINELEN+1];
  691.     snprintf(buf,sizeof(buf),"%s",p[0]); subst(buf);
  692.     prepcnt=0; parmprep(buf, pt_real);
  693.     repsubst(buf);
  694.     fprintf(outf,"\ncondlist=%s\n",buf);
  695. }
  696.  
  697. void p_feedback(char *p[MAX_PARM])
  698. {
  699.     char buf1[MAX_LINELEN+1],buf2[MAX_LINELEN+1];
  700.     char *cmpstr="ifval";
  701.  
  702.     snprintf(buf1,sizeof(buf1),"%s",p[0]); subst(buf1);
  703.     snprintf(buf2,sizeof(buf2),"%s",p[1]); subst(buf2);
  704.     repsubst(buf1); repsubst(buf2);
  705.     if(strstr(buf1,"$m_choice")!=NULL) cmpstr="if";
  706.     prepcnt=0; setpre="!set "; parmprep(buf1, pt_real); setpre="";
  707.     fprintf(outf,"!%s %s\n <div class='oef_feedbacks'>",cmpstr, buf1);
  708.     out_exec(buf2,NULL);
  709.     fprintf(outf,"</div>\n!endif\n");
  710. }
  711.  
  712. /* definition of steps */
  713. void p_steps(char *p[MAX_PARM])
  714. {
  715.     char vbuf[MAX_LINELEN+1];
  716.     char *pp, *p2;
  717.  
  718.     snprintf(vbuf,sizeof(vbuf),"%s",find_word_start(p[0])); subst(vbuf);
  719.     strip_trailing_spaces(vbuf);
  720.     if(vbuf[0]==0) return;
  721.     if((pp=strparchr(vbuf,'?'))!=NULL && pp[1]!='?') {
  722.       char buf[MAX_LINELEN+1];
  723.       if(check_compare(vbuf)==0) goto noif;
  724.       p2=strparchr(pp,':'); *pp++=0; if(p2!=NULL) *p2++=0;
  725.       snprintf(buf,sizeof(buf),"%s",vbuf);
  726.       prepcnt=0; parmprep(buf,pt_text);
  727.       fprintf(outf,"\n!ifval %s \n",buf);
  728.       snprintf(buf,sizeof(buf),"%s",pp);
  729.       parmprep(buf,pt_text);
  730.       fprintf(outf,"oefsteps=%s \n",buf);
  731.       if(p2!=NULL) {
  732.           fprintf(outf,"!else\n");
  733.           snprintf(buf,sizeof(buf),"%s",p2);
  734.           parmprep(buf,pt_text);
  735.           fprintf(outf,"oefsteps=%s \n",buf);
  736.       }
  737.       fprintf(outf,"!endif\n");
  738.     }
  739.     else {
  740. noif:
  741.       prepcnt=0; parmprep(vbuf, pt_text);
  742.       fprintf(outf,"oefsteps=%s \nnextstep=!nosubst %s \n",vbuf,vbuf);
  743.     }
  744.     fprintf(outf,"!readproc oef/steps.proc\n");
  745. }
  746.  
  747. /* dynamic steps */
  748. void p_nextstep(char *p[MAX_PARM])
  749. {
  750.     fprintf(outf,"dynsteps=yes\n");
  751.     p_steps(p);
  752. }
  753.  
  754.