Subversion Repositories wimsdev

Rev

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