Subversion Repositories wimsdev

Rev

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

  1. /*
  2.     itex2MML  1.3.3
  3.     website : https://golem.ph.utexas.edu/~distler/blog/itex2MML.html
  4.     repository : https://golem.ph.utexas.edu/~distler/code/itexToMML/
  5.  
  6.     renamed to "wims_mathml"
  7.     Slightly modified for WIMS mathml usage 05/2012
  8.     J.M. Evers, B. Perrin-Riou
  9.  
  10. */
  11.  
  12. #include <cstdio>
  13. #include <string>
  14. #include "wims_mathml.h"
  15.  
  16. // these C headers are needed to compile on OpenSuSE Linux (and others?) to use atoi/strlen
  17. #include <string.h>
  18. #include <stdlib.h>
  19. #include <sys/time.h>
  20.  
  21.  
  22. int use_javascript;
  23. char wims_texfontsize[64]; // is set by cmd-line argument "--tex-size" via wims
  24. char wims_mathml_id[64]; // is set by cmd-line argument "--mathml-id" via wims
  25.  
  26. const int set_javascript(){
  27.     if(use_javascript == 1){
  28.         return 1;
  29.     }
  30.     else
  31.     {
  32.         return 0;
  33.     }
  34. }
  35. const char * read_mathml_id(){
  36.     return wims_mathml_id; // wims_mathml.y will use this in first <mstyle id="read_mathml_id()" ...
  37.     // the whole mathml-string will get this "id" ; does not interfere (?) with "maction" tag, which is on "sub math level"
  38. }
  39.  
  40. const char * read_fontsize(){ // declared in wims_mathml.h
  41.     // in not given : mathsize="110%"
  42.     if(strlen(wims_texfontsize) == 0){snprintf(wims_texfontsize,sizeof(wims_texfontsize),"%s","110%");}
  43.     return wims_texfontsize; // wims_mathml.y will use this in first <mstyle mathsize="read_fontsize()" ...
  44. }
  45. // count number of substring occurences
  46. int count_substrings( const std::string & str , const std::string & obj ) {
  47.     int n = 0;
  48.     std::string ::size_type position = 0;
  49.     while( (position = obj.find( str, position )) != std::string::npos ){
  50.         n++;
  51.         position += str.size();
  52.     }
  53.     return n;
  54. }
  55.  
  56. int main (int argc, char ** argv)
  57. {
  58.         bool bPrintItex = false;
  59.         bool bRawFilter = false;
  60.         bool bInline    = false;
  61.         bool bDisplay   = false;
  62.         bool bTexString = false;
  63.         bool bStop = false;
  64.         bool bForbidMarkup = false;
  65.         // wims
  66.         int MAX_MML_SIZE = 8192;
  67.         int i_texstring = 0;
  68.         int insize=0;
  69.         using namespace std;
  70.         std::string itex;
  71.         for (int arg = 1; arg < argc; arg++)
  72.                 {
  73.                         std::string args = argv[arg];
  74.  
  75.                         if (args == "--version" || args == "-v")
  76.                                 {
  77.                                         fputs("wims_mathml version " ITEX2MML_VERSION "\n"
  78.                                               "See https://golem.ph.utexas.edu/~distler/blog/itex2MML.html for more information.\n", stdout);
  79.                                         bStop = true;
  80.                                         break;
  81.                                 }
  82.  
  83.                         if (args == "--help" || args == "-h"){
  84.                             fputs ("usage: wims_mathml [OPTIONS]\n"
  85.                             "\n"
  86.                             "wims_mathml filters an input text stream (e.g., an XHTML web page) converting itex expressions\n"
  87.                             "to MathML. Inline itex expressions are delimited either side by single dollar symbols ($):\n"
  88.                             "\n"
  89.                             "\t<p>The parameters $\\alpha$ and $\\beta$ in the function $f(x)$ are defined below.</p>\n"
  90.                             "\n"
  91.                             "For normal display of equations, etc., itex expressions can be delimited with double dollar\n"
  92.                             "symbols ($$) either side or by \\[ to the left and \\] to the right:\n"
  93.                             "\n"
  94.                             "\t<p class=\"equation\">\\[\n"
  95.                             "\t\tf(x) = \\alpha x + \\frac{\\beta}{1+|x|}\n"
  96.                             "\t\\]</p>\n"
  97.                             "\n"
  98.                             "wims_mathml Options:\n"
  99.                             "\n"
  100.                             "  --raw-filter    filter input stream, converting equations as found to MathML [stops on error]\n"
  101.                             "  --inline        converts a single itex equation, without any $ symbols, to inline MathML\n"
  102.                             "  --display       converts a single itex equation, without any $ symbols, to display-mode MathML\n"
  103.                             "  --forbid-markup forbid markup (more precisely, the '<' and '>' characters) in itex equations\n"
  104.                             "  --print-itex    used in conjuction with --inline or --display: prints the itex string\n"
  105.                             "\n"
  106.                             "WIMS USAGE:"
  107.                             "  --mathml-id      unique random id for every mathml string\n"
  108.                             "  --tex-size       base fontsize of the mathml string\n"
  109.                             "  --max-mml-size   wims maximum stringlength  \n"
  110.                             "  --tex-string     the actual math string\n"
  111.                             "\n"
  112.                             "For further information, see https://golem.ph.utexas.edu/~distler/blog/itex2MML.html\n", stdout);
  113.                             bStop = true;
  114.                             break;
  115.                         }
  116.                         if (args == "--print-itex"){
  117.                             bPrintItex = true;
  118.                             bRawFilter = false;
  119.                             continue;
  120.                         }
  121.                         if (args == "--forbid-markup"){
  122.                             bRawFilter = false;
  123.                             bForbidMarkup = true;
  124.                             continue;
  125.                         }
  126.                         if (args == "--inline"){
  127.                             bRawFilter = false;
  128.                             bInline    = true;
  129.                             bDisplay   = false;
  130.                             continue;
  131.                         }
  132.                         if (args == "--display"){
  133.                             bRawFilter = false;
  134.                             bInline    = false;
  135.                             bDisplay   = true;
  136.                             continue;
  137.                         }
  138.                         if (args == "--raw-filter"){
  139.                             bRawFilter = true;
  140.                             bPrintItex = false;
  141.                             bInline    = false;
  142.                             bDisplay   = false;
  143.                             continue;
  144.                         }
  145.                         // wims
  146.                         if (args == "--use-zoom"){
  147.                             use_javascript = atoi( argv[arg+1] );
  148.                             continue;
  149.                         }
  150.                         if (args == "--tex-size"){
  151.                             snprintf(wims_texfontsize,sizeof(wims_texfontsize),"%s",argv[arg+1]);
  152.                             continue;
  153.                         }
  154.                         if (args == "--max-mml-size"){
  155.                             MAX_MML_SIZE = atoi( argv[arg+1]);
  156.                             continue;
  157.                         }
  158.                         if (args == "--tex-string"){
  159.                             bPrintItex = false;
  160.                             bRawFilter = false;
  161.                             bTexString = true;
  162.                             bDisplay = false;
  163.                             i_texstring = arg+1;
  164.                             break;
  165.                         }
  166.                 }
  167.         if (bStop) return 0;
  168.         /* every mathml-string will have unique id */
  169.         struct timeval tv;
  170.         struct timezone tz;
  171.         struct tm *tm;
  172.         gettimeofday(&tv, &tz);
  173.         tm=localtime(( const time_t * ) &tv.tv_sec);
  174.         snprintf(wims_mathml_id,sizeof(wims_mathml_id),"wims_mathml%ld",long(tv.tv_usec));
  175.  
  176.         if(bTexString){ // WIMS modification: reads a 'latex string' from commandline, if arg="--tex-string"
  177.             char *input;
  178.             int dollarcnt = 0;
  179.             input = argv[i_texstring];
  180.             while(input != NULL){
  181.                  for(int i = 0; i <  strlen(input); i++){
  182.                     switch(input[i]){
  183.                         case '<':itex+= "\\lt ";break; // < \lt
  184.                         case '>':itex+= "\\gt ";break; // < \gt
  185.                         case '$':dollarcnt++;break; // ignore $ we put them directly in itex
  186.                         default:itex+=(char) input[i];
  187.                     }
  188.                 }
  189.                 i_texstring++;// probably never more than 1 ...
  190.                 input = argv[i_texstring];
  191.             }
  192.             // common error to forget \right.
  193.             // this must be done before adding $ around itex
  194.             int left =  count_substrings("\\left\\" ,itex) + count_substrings("\\left[" ,itex) + count_substrings("\\left(" ,itex) + count_substrings("\\left{" ,itex) + count_substrings("\\left." ,itex) + count_substrings("\\left \\" ,itex) + count_substrings("\\left [" ,itex) + count_substrings("\\left (" ,itex) + count_substrings("\\left {" ,itex) + count_substrings("\\left ." ,itex) ;
  195.             int right = count_substrings("\\right\\",itex) + count_substrings("\\right]",itex) + count_substrings("\\right)",itex) + count_substrings("\\right}",itex) + count_substrings("\\right.",itex) + count_substrings("\\right \\",itex) + count_substrings("\\right ]",itex) + count_substrings("\\right )",itex) + count_substrings("\\right }",itex) + count_substrings("\\right .",itex) ;
  196.             if( left != right){
  197.                 if( left > right){
  198.                     for(int i = 0 ; i<left-right;i++){
  199.                         itex+=" \\right.";
  200.                     }
  201.                 }
  202.                 else
  203.                 {
  204.                     for(int i = 0 ; i<right-left;i++){
  205.                         itex="\\left. "+itex;
  206.                     }
  207.                 }
  208.             }
  209.  
  210.             // finish the math mode with appropriate $-signs
  211.             if( dollarcnt > 2 ){
  212.                 bDisplay = true; // use display mode
  213.                 itex="$$" + itex;
  214.                 itex+="$$";
  215.             }
  216.             else
  217.             {
  218.                 bInline = true; // use inline mode
  219.                     itex="$" + itex;
  220.                     itex+="$";
  221.             }
  222.         }
  223.         else // standard syntax echo  "\frac{1}{2}" | wims_mathml --inline > test.xml
  224.         { // nothing changed here...
  225.             #define BUFSIZE 1024
  226.             char buffer[BUFSIZE];
  227.             if (bInline)  itex += "$";
  228.             if (bDisplay) itex += "$$";
  229.             while (fgets (buffer, BUFSIZE, stdin)) itex += buffer;
  230.             if (bInline)  itex += "$";
  231.             if (bDisplay) itex += "$$";
  232.         }
  233.  
  234.         if (bPrintItex)
  235.                 {
  236.                         fputs (itex.c_str (), stdout);
  237.                         fputs ("\n", stdout);
  238.                         fflush (stdout);
  239.                 }
  240.  
  241.         if (!bInline && !bDisplay)
  242.                 {
  243.                         if (bRawFilter)
  244.                                 wims_mathml_filter (itex.c_str(), itex.size());
  245.                         else
  246.                                 if (bForbidMarkup)
  247.                                         wims_mathml_strict_html_filter (itex.c_str(), itex.size());
  248.                                 else
  249.                                         wims_mathml_html_filter (itex.c_str(), itex.size());
  250.                         return 0;
  251.                 }
  252.         char * mathml = wims_mathml_parse (itex.c_str(), itex.size() );
  253.  
  254.         if (mathml)
  255.                 {
  256.                     if(bTexString){ // wims usage
  257.                         if(strlen(mathml) > (MAX_MML_SIZE)){
  258.                             fputs("ERROR",stdout);
  259.                         }
  260.                         else
  261.                         {
  262.                             fputs (mathml, stdout);
  263.                         }
  264.                     }
  265.                     else
  266.                     {
  267.                         fputs (mathml, stdout);
  268.                     }
  269.                     wims_mathml_free_string (mathml);
  270.                     mathml = 0;
  271.                 }
  272.         else
  273.                 {
  274.                     if(bTexString){ // wims usage
  275.                         fprintf(stdout,"ERROR");
  276.                     }
  277.                     else
  278.                     {
  279.                         fputs ("wims_mathml: itex parser failed to generate MathML from itex!\n", stderr);
  280.                     }
  281.                 }
  282.         return 0;
  283. }
  284.