/*
 
    itex2MML  1.3.3
 
    renamed to "wims_mathml"
 
    Slightly modified for WIMS mathml usage 05/2012
 
    J.M. Evers, B. Perrin-Riou
 
 
 
*/
 
 
 
#include <cstdio>
 
#include <string>
 
#include "wims_mathml.h"
 
 
 
// these C headers are needed to compile on OpenSuSE Linux (and others?) to use atoi/strlen
 
#include <string.h>
 
#include <stdlib.h>
 
#include <sys/time.h>
 
 
 
 
 
int use_javascript;
 
char wims_texfontsize[64]; // is set by cmd-line argument "--tex-size" via wims
 
char wims_mathml_id[64]; // is set by cmd-line argument "--mathml-id" via wims
 
 
 
const int set_javascript(){
 
    if(use_javascript == 1){
 
        return 1;
 
    }
 
    else
 
    {
 
        return 0;
 
    }
 
}
 
const char * read_mathml_id(){
 
    return wims_mathml_id; // wims_mathml.y will use this in first <mstyle id="read_mathml_id()" ...
 
    // the whole mathml-string will get this "id" ; does not interfere (?) with "maction" tag, which is on "sub math level"
 
}
 
 
 
const char * read_fontsize(){ // declared in wims_mathml.h
 
    // in not given : mathsize="110%"
 
    if(strlen(wims_texfontsize) == 0){snprintf(wims_texfontsize,sizeof(wims_texfontsize),"%s","110%");}
 
    return wims_texfontsize; // wims_mathml.y will use this in first <mstyle mathsize="read_fontsize()" ...
 
}
 
// count number of substring occurences
 
int count_substrings( const std::string & str , const std::string & obj ) {
 
    int n = 0;
 
    std::string ::size_type position = 0;
 
    while( (position = obj.find( str, position )) != std::string::npos ){
 
        n++;
 
        position += str.size();
 
    }
 
    return n;
 
}
 
 
 
int main (int argc, char ** argv)
 
{
 
        bool bPrintItex = false;
 
        bool bRawFilter = false;
 
        bool bInline    = false;
 
        bool bDisplay   = false;
 
        bool bTexString = false;
 
        bool bStop = false;
 
        bool bForbidMarkup = false;
 
        // wims
 
        int MAX_MML_SIZE = 8192;
 
        int i_texstring = 0;
 
        int insize=0;
 
        using namespace std;
 
        std::string itex;
 
        for (int arg = 1; arg < argc; arg++)
 
                {
 
                        std::string args = argv[arg];
 
 
 
                        if (args == "--version" || args == "-v")
 
                                {
 
                                        fputs("wims_mathml version " ITEX2MML_VERSION "\n"
 
                                              "See http://golem.ph.utexas.edu/~distler/blog/wims_mathml.html for more information.\n", stdout);
 
                                        bStop = true;
 
                                        break;
 
                                }
 
 
 
                        if (args == "--help" || args == "-h"){
 
                            fputs ("usage: wims_mathml [OPTIONS]\n"
 
                            "\n"
 
                            "wims_mathml filters an input text stream (e.g., an XHTML web page) converting itex expressions\n"
 
                            "to MathML. Inline itex expressions are delimited either side by single dollar symbols ($):\n"
 
                            "\n"
 
                            "\t<p>The parameters $\\alpha$ and $\\beta$ in the function $f(x)$ are defined below.</p>\n"
 
                            "\n"
 
                            "For normal display of equations, etc., itex expressions can be delimited with double dollar\n"
 
                            "symbols ($$) either side or by \\[ to the left and \\] to the right:\n"
 
                            "\n"
 
                            "\t<p class=\"equation\">\\[\n"
 
                            "\t\tf(x) = \\alpha x + \\frac{\\beta}{1+|x|}\n"
 
                            "\t\\]</p>\n"
 
                            "\n"
 
                            "wims_mathml Options:\n"
 
                            "\n"
 
                            "  --raw-filter    filter input stream, converting equations as found to MathML [stops on error]\n"
 
                            "  --inline        converts a single itex equation, without any $ symbols, to inline MathML\n"
 
                            "  --display       converts a single itex equation, without any $ symbols, to display-mode MathML\n"
 
                            "  --forbid-markup forbid markup (more precisely, the '<' and '>' characters) in itex equations\n"
 
                            "  --print-itex    used in conjuction with --inline or --display: prints the itex string\n"
 
                            "\n"
 
                            "WIMS USAGE:"
 
                            "  --mathml-id      unique random id for every mathml string\n"
 
                            "  --tex-size       base fontsize of the mathml string\n"
 
                            "  --max-mml-size   wims maximum stringlength  \n"
 
                            "  --tex-string     the actual math string\n"
 
                            "\n"
 
                            "For further information, see http://golem.ph.utexas.edu/~distler/blog/wims_mathml.html\n", stdout);
 
                            bStop = true;
 
                            break;
 
                        }
 
                        if (args == "--print-itex"){
 
                            bPrintItex = true;
 
                            bRawFilter = false;
 
                            continue;
 
                        }
 
                        if (args == "--forbid-markup"){
 
                            bRawFilter = false;
 
                            bForbidMarkup = true;
 
                            continue;
 
                        }
 
                        if (args == "--inline"){
 
                            bRawFilter = false;
 
                            bInline    = true;
 
                            bDisplay   = false;
 
                            continue;
 
                        }
 
                        if (args == "--display"){
 
                            bRawFilter = false;
 
                            bInline    = false;
 
                            bDisplay   = true;
 
                            continue;
 
                        }
 
                        if (args == "--raw-filter"){
 
                            bRawFilter = true;
 
                            bPrintItex = false;
 
                            bInline    = false;
 
                            bDisplay   = false;
 
                            continue;
 
                        }
 
                        // wims
 
                        if (args == "--use-zoom"){
 
                            use_javascript = atoi( argv[arg+1] );
 
                            continue;
 
                        }
 
                        if (args == "--tex-size"){
 
                            snprintf(wims_texfontsize,sizeof(wims_texfontsize),"%s",argv[arg+1]);
 
                            continue;
 
                        }
 
                        if (args == "--max-mml-size"){
 
                            MAX_MML_SIZE = atoi( argv[arg+1]);
 
                            continue;
 
                        }
 
                        if (args == "--tex-string"){
 
                            bPrintItex = false;
 
                            bRawFilter = false;
 
                            bTexString = true;
 
                            bDisplay = false;
 
                            i_texstring = arg+1;
 
                            break;
 
                        }
 
                }
 
        if (bStop) return 0;
 
        /* every mathml-string will have unique id */
 
        struct timeval tv;
 
        struct timezone tz;
 
        struct tm *tm;
 
        gettimeofday(&tv, &tz);
 
        tm=localtime(( const time_t * ) &tv.tv_sec);
 
        snprintf(wims_mathml_id,sizeof(wims_mathml_id),"wims_mathml%ld",long(tv.tv_usec));
 
 
 
        if(bTexString){ // WIMS modification: reads a 'latex string' from commandline, if arg="--tex-string"
 
            char *input;
 
            int dollarcnt = 0;
 
            input = argv[i_texstring];
 
            while(input != NULL){
 
                 for(int i = 0; i <  strlen(input); i++){
 
                    switch(input[i]){
 
                        case '<':itex+= "\\lt ";break; // < \lt
 
                        case '>':itex+= "\\gt ";break; // < \gt
 
                        case '$':dollarcnt++;break; // ignore $ we put them directly in itex
 
                        default:itex+=(char) input[i];
 
                    }
 
                }
 
                i_texstring++;// probably never more than 1 ...
 
                input = argv[i_texstring];
 
            }
 
            // common error to forget \right.
 
            // this must be done before adding $ around itex
 
            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) ;
 
            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) ;
 
            if( left != right){
 
                if( left > right){
 
                    for(int i = 0 ; i<left-right;i++){
 
                        itex+=" \\right.";
 
                    }
 
                }
 
                else
 
                {
 
                    for(int i = 0 ; i<right-left;i++){
 
                        itex="\\left. "+itex;
 
                    }
 
                }
 
            }
 
 
 
            // finish the math mode with appropriate $-signs
 
            if( dollarcnt > 2 ){
 
                bDisplay = true; // use display mode
 
                itex="$$" + itex;
 
                itex+="$$";
 
            }
 
            else
 
            {
 
                bInline = true; // use inline mode
 
                    itex="$" + itex;
 
                    itex+="$";
 
            }
 
        }
 
        else // standard syntax echo  "\frac{1}{2}" | wims_mathml --inline > test.xml
 
        { // nothing changed here...
 
            #define BUFSIZE 1024
 
            char buffer[BUFSIZE];
 
            if (bInline)  itex += "$";
 
            if (bDisplay) itex += "$$";
 
            while (fgets (buffer, BUFSIZE, stdin)) itex += buffer;
 
            if (bInline)  itex += "$";
 
            if (bDisplay) itex += "$$";
 
        }
 
 
 
        if (bPrintItex)
 
                {
 
                        fputs (itex.c_str (), stdout);
 
                        fputs ("\n", stdout);
 
                        fflush (stdout);
 
                }
 
 
 
        if (!bInline && !bDisplay)
 
                {
 
                        if (bRawFilter)
 
                                wims_mathml_filter (itex.c_str(), itex.size());
 
                        else
 
                                if (bForbidMarkup)
 
                                        wims_mathml_strict_html_filter (itex.c_str(), itex.size());
 
                                else
 
                                        wims_mathml_html_filter (itex.c_str(), itex.size());
 
                        return 0;
 
                }
 
        char * mathml = wims_mathml_parse (itex.c_str(), itex.size() );
 
 
 
        if (mathml)
 
                {
 
                    if(bTexString){ // wims usage
 
                        if(strlen(mathml) > (MAX_MML_SIZE)){
 
                            fputs("ERROR",stdout);
 
                        }
 
                        else
 
                        {
 
                            fputs (mathml, stdout);
 
                        }
 
                    }
 
                    else
 
                    {
 
                        fputs (mathml, stdout);
 
                    }
 
                    wims_mathml_free_string (mathml);
 
                    mathml = 0;
 
                }
 
        else
 
                {
 
                    if(bTexString){ // wims usage
 
                        fprintf(stdout,"ERROR");
 
                    }
 
                    else
 
                    {
 
                        fputs ("wims_mathml: itex parser failed to generate MathML from itex!\n", stderr);
 
                    }
 
                }
 
        return 0;
 
}