Subversion Repositories wimsdev

Rev

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

  1. /*    Copyright (C) 2012 WIMSDEV
  2.  *    This file is part of the WIMS package.
  3.  *
  4.  *  This program is free software; you can redistribute it and/or modify
  5.  *  it under the terms of the GNU General Public License as published by
  6.  *  the Free Software Foundation; either version 2 of the License, or
  7.  *  (at your option) any later version.
  8.  *
  9.  *  This program is distributed in the hope that it will be useful,
  10.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *  GNU General Public License for more details.
  13.  *
  14.  *  You should have received a copy of the GNU General Public License
  15.  *  along with this program; if not, write to the Free Software
  16.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  */
  18. #include "wims.h"
  19. int disable_mathml;
  20. int mathml(char *p, int option ){
  21.     if (strlen(p)==0) return 1 ;
  22.     if( mathalign_base <= 1){
  23.       internal_error(" why is wims trying mathml()?\n");
  24.       return 0; // go to insmath with gifs
  25.     }
  26.     if( disable_mathml==1 || atoi(getvar("disable_mathml"))==1) return 0;
  27.     if(strlen(p) > MAX_LINELEN ){ // too big ? probably too big for gifs as well ; but error signalling is better in gif-methods
  28.       mathalign_base = 1;// 0 or 1 position of tex_gifs
  29.       return 0; // go to insmath with gifs
  30.     }
  31.     //singlespace(p); // needed for check unbalanced \left\right in wims_mathml.cc --> insmath.c
  32.     singlespace(p);
  33.     int my_pipe[2];
  34.     pid_t pid;
  35.     if(pipe(my_pipe)){// pipe could not be opened...
  36.       internal_error("mathml(): pipe() failure.\n");
  37.       mathalign_base = 1;
  38.       return 0; // go to insmath with gifs
  39.     }
  40.     else
  41.     {
  42.       pid = fork();
  43.       if (pid == (pid_t) 0){
  44.           // this buffer should probably be set to 0.5 * MAX_LINELEN : mathml is very big !
  45.           // if output mathml string larger ;ERROR will be signaled by wims_mathml.
  46.           char mml_buffer[MAX_LINELEN+1];
  47.           sprintf(mml_buffer, "%d", MAX_LINELEN);// int --> char
  48.           // setting --tex-size argument to wims_mathml.cc
  49.           char mathml_tex_size[64];//this should be a string like "250%"
  50.           int texsize_list[]={20,30,50,70,90,100,120,130,150,180,220,300};
  51.           // analogue to  mathfonts.c but now we talk %  and we could make any amount of changes
  52.           // not limited by font-size !!
  53.           // when math_with_gifs is removed from wims, we can rethink / improve this
  54.           int idx = 6;
  55.           int use_js_zoom = 0; // default js-zoom in mathml if disabled
  56.           // enable via adm/light
  57.           // next code is stolen from wims.c
  58.           if(getvar("useropts") != NULL || getvar("wims_useropts") != NULL){
  59.             char *u;
  60.             u = getvar("useropts"); // set via adm/light or via cookie?
  61.             if(u == NULL || *u == 0){ u=getvar("wims_useropts");} // wims_user? look into def file
  62.             if(u != NULL && *u != 0){
  63.                 if(myisdigit(u[0])){ //2 digit code : 12,22,32,...,92  [tex_size mathalignbase]
  64.                   idx = u[0] - '0';
  65.                   if(idx < 0 || idx > 11){ idx = 6; } // the default value 120%
  66.                 }
  67.                 if(myisdigit(u[2]) && u[2]!=0){ // suppose we add 0 or 1 to useropts for using js-zoom on mathml?
  68.                 // 3 digitcode:  621 == fontsize idx=6 & use mathml & use zoom
  69.                   use_js_zoom = u[2] - '0';
  70.                   if(use_js_zoom > 1 || use_js_zoom < 0){
  71.                       use_js_zoom = 0; //disable js-zooming of mathml
  72.                   }
  73.                 }
  74.             }
  75.           }
  76.           else
  77.           { // we take the default setting from adm/management config
  78.             idx = atoi(getvar("wims_texbasesize")) ;
  79.             if(idx < 0 || idx > 11){ idx = 6; } // the default value 120%
  80.           }
  81.           // check is a module wants to disable zooming (eg drag&drop or others )
  82.           // !set disable_zoom=yes
  83.           // if not set: disable_zoom="no"; see config.c
  84.           if( strcmp( getvar("disable_zoom") , "yes" ) == 0 ){
  85.              use_js_zoom = 0;
  86.           }
  87.           // now write the "char" 200% into variable "mathml_tex_size"
  88.           snprintf(mathml_tex_size,sizeof(mathml_tex_size),"%d%%",texsize_list[idx]);
  89.           // int --> char : added % sign (needed for mathml) [%% = escaped %]
  90.           if(strlen(mathml_tex_size) == 0 ){ // this should not happen
  91.             sprintf(mathml_tex_size,"%s","120%");
  92.             // if it goes wrong we set 120%
  93.             // default in itex2MML was 110% : but we thought it was too small... ?
  94.           }
  95.           char zoom[2];
  96.           snprintf(zoom, 2 ,"%d",use_js_zoom);// int --> char : "0" or "1"
  97.           char *argv[]={"wims_mathml","--use-zoom",zoom,"--tex-size",mathml_tex_size,"--max-mml-size",mml_buffer,"--tex-string",p,NULL};
  98. /* This is the child process. Close other end first. */
  99.           close(my_pipe[0]);
  100.           dup2(my_pipe[1], 1);  // send stdout to the pipe
  101.           dup2(my_pipe[1], 2);  // send stderr to the pipe
  102.           close(my_pipe[1]);
  103.           execv("../bin/wims_mathml",argv);
  104.           internal_error("could not execute wims_mathml\n");
  105.           mathalign_base = 1;
  106.           return 0; // go to insmath with gifs
  107.       }
  108.       else
  109.       {
  110.           if (pid < (pid_t) 0){
  111.             close(my_pipe[0]);  // close the read end of the pipe in the parent
  112.             close(my_pipe[1]);  // close the write end of the pipe in the parent
  113.             internal_error("mathml(): fork() failure.\n");
  114.             mathalign_base = 1;
  115.             return 0; // go to insmath with gifs
  116.           }
  117.           else
  118.           {
  119.              int status;
  120.             FILE *stream;
  121.             close(my_pipe[1]);  // close the write end of the pipe in the parent
  122.             stream = fdopen (my_pipe[0], "r");
  123.             char buffer[MAX_LINELEN+1];
  124.             // make buffer filled with 'zero/null'
  125.             memset(buffer,'\0',MAX_LINELEN);//bzero(buffer,maxsize);
  126. /* read output from program line by line */
  127.             if (option == 1) {
  128.                 *p=0;
  129.                 while ( fgets(buffer, MAX_LINELEN, stream) != NULL ){
  130.                      if(strcmp(buffer,"ERROR") != 0){
  131.                       mystrncpy(p, buffer, MAX_LINELEN-1);
  132.                      }
  133.                     else /* ERROR close stream; close pipe; wait for clean exit */
  134.                     {
  135.                   fclose (stream); /* do not know if this is really needed... but it won't hurt ? */
  136.                   close(my_pipe[0]);
  137.                   waitpid(pid, &status, 0);
  138.                      mathalign_base=1; /* go to insmath with gifs */
  139.                      return 0;
  140.                     }
  141.                 }
  142.             }
  143.             else /* this will probably not used ? remove it ? */
  144.             {
  145.              while ( fgets(buffer, MAX_LINELEN, stream) != NULL ){
  146.                  if(strcmp(buffer,"ERROR") != 0){
  147.                   output("%s", buffer);
  148.                  }
  149.                     else
  150.                     {
  151.                      mathalign_base=1;
  152.                      return 0;
  153.                     }
  154.                 }
  155.             }
  156.             fclose (stream);
  157.             close(my_pipe[0]);
  158.             waitpid(pid, &status, 0);
  159.           }
  160.        }
  161.     }
  162.     return 1;
  163. }
  164.