Logo Search packages:      
Sourcecode: jaxe version File versions  Download package

StringMathBuilder.java

/*
Jaxe - Editeur XML en Java

Copyright (C) 2003 Observatoire de Paris-Meudon

Ce programme est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier conformément aux dispositions de la Licence Publique Générale GNU, telle que publiée par la Free Software Foundation ; version 2 de la licence, ou encore (à votre choix) toute version ultérieure.

Ce programme est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE ; sans même la garantie implicite de COMMERCIALISATION ou D'ADAPTATION A UN OBJET PARTICULIER. Pour plus de détail, voir la Licence Publique Générale GNU .

Vous devez avoir reçu un exemplaire de la Licence Publique Générale GNU en même temps que ce programme ; si ce n'est pas le cas, écrivez à la Free Software Foundation Inc., 675 Mass Ave, Cambridge, MA 02139, Etats-Unis.
*/

package jaxe.equations;

import org.apache.log4j.Logger;

import java.util.regex.PatternSyntaxException;
import java.util.Vector;

import jaxe.equations.element.MathElement;
import jaxe.equations.element.MathFrac;
import jaxe.equations.element.MathIdentifier;
import jaxe.equations.element.MathNumber;
import jaxe.equations.element.MathOperator;
import jaxe.equations.element.MathOver;
import jaxe.equations.element.MathRootElement;
import jaxe.equations.element.MathRow;
import jaxe.equations.element.MathSqrt;
import jaxe.equations.element.MathSub;
import jaxe.equations.element.MathSubSup;
import jaxe.equations.element.MathSup;
import jaxe.equations.element.MathTable;
import jaxe.equations.element.MathTableData;
import jaxe.equations.element.MathTableRow;
import jaxe.equations.element.MathText;
import jaxe.equations.element.MathUnder;
import jaxe.equations.element.MathUnderOver;

/**
 * Constructeur pour une expression mathématique linéaire (style maple)
 */
00042 public class StringMathBuilder {
    /**
     * Logger for this class
     */
00046     private static final Logger LOG = Logger.getLogger(StringMathBuilder.class);

    private final MathRootElement rootElement;
    
    // opérateurs remplacés en premier, avant l'analyse de la syntaxe
    private static final String[][] special = {{"<==", "\u21D0"}, {"==>", "\u21D2"}, {"<=>", "\u21D4"},
                                        {"!=", "\u2260"}, {"~=", "\u2248"}, {"<=", "\u2264"},
                                        {">=", "\u2265"}, {"<<", "\u226A"}, {">>", "\u226B"},
                                        //  "->" kepts for backward-compatibility
                                        {"-->", "\u2192"}, {"<->", "\u2194"}, {"->", "\u2192"},
                                        {"<--", "\u2190"},
                                        {"forall", "\u2200"}, {"quelquesoit", "\u2200"},
                                        {"exists", "\u2203"}, {"ilexiste", "\u2203"},
                                        {"part", "\u2202"}, {"drond", "\u2202"},
                                        {"nabla", "\u2207"}, {"prop", "\u221D"},
                                        {"cross", "×"}, {"croix", "×"},
                                        {"plusmn", "±"}, {"plusoumoins", "±"}, {"plusminus", "±"},
                                        {"...", "\u2026"}};
    
    // opérateurs
    private static final String sops = 
            "_^*/\u2207±\u2213-+\u2200\u2203×=\u2260\u2248<>\u2264\u2265\u226A\u226B\u221D" +
            "\u2190\u2192\u2194\u21D0\u21D2\u21D4";
    
    private static final String[][] symbols = {
                    // grec-minuscule
                    {"alpha", "\u03B1"}, {"beta", "\u03B2"}, {"gamma", "\u03B3"},
                    {"delta", "\u03B4"}, {"epsilon", "\u03B5"}, {"zeta", "\u03B6"},
                    {"eta", "\u03B7"}, {"theta", "\u03B8"}, {"iota", "\u03B9"},
                    {"kappa", "\u03BA"}, {"lambda", "\u03BB"}, {"mu", "\u03BC"},
                    {"nu", "\u03BD"}, {"xi", "\u03BE"}, {"omicron", "\u03BF"},
                    {"pi", "\u03C0"}, {"rho", "\u03C1"}, {"sigma", "\u03C3"},
                    {"tau", "\u03C4"}, {"upsilon", "\u03C5"}, {"phi", "\u03C6"},
                    {"chi", "\u03C7"}, {"psi", "\u03C8"}, {"omega", "\u03C9"},
                    // grec-majuscule
                    {"Alpha", "\u0391"}, {"Beta", "\u0392"}, {"Gamma", "\u0393"},
                    {"Delta", "\u0394"}, {"Epsilon", "\u0395"}, {"Zeta", "\u0396"},
                    {"Eta", "\u0397"}, {"Theta", "\u0398"}, {"Iota", "\u0399"},
                    {"Kappa", "\u039A"}, {"Lambda", "\u039B"}, {"Mu", "\u039C"},
                    {"Nu", "\u039D"}, {"Xi", "\u039E"}, {"Omicron", "\u039F"},
                    {"Pi", "\u03A0"}, {"Rho", "\u03A1"}, {"Sigma", "\u03A3"},
                    {"Tau", "\u03A4"}, {"Upsilon", "\u03A5"}, {"Phi", "\u03A6"},
                    {"Chi", "\u03A7"}, {"Psi", "\u03A8"}, {"Omega", "\u03A9"},
                    // autre grec
                    {"thetasym", "\u03D1"}, {"upsih", "\u03D2"}, {"piv", "\u03D6"},
                    // autres caractères
                    {"infin", "\u221E"}, {"infty", "\u221E"}, {"infini", "\u221E"},
                    {"sun", "\u2609"}, {"soleil", "\u2609"},
                    {"star", "\u2605"}, {"étoile", "\u2605"},
                    {"earth", "\u2641"}, {"terre", "\u2641"},
                    {"planck", "\u210F"},
                    {"angstrom", "\u212B"}, {"angström", "\u212B"},
                    {"petitl", "\u2113"},
                    {"asterisk", "*"}, {"astérisque", "*"}, // \uFF0A ?
                    /*{"grandg", "\u1D4A2"},*/
                };
    
    // fonctions qui peuvent se passer de parenthèses quand il n'y a qu'un argument simple
    private static final String[] fctnopar = {"sin", "cos", "tan", "acos", "asin", "atan"};
    
    
    public StringMathBuilder(final String s) {
        rootElement = new MathRootElement();
        final String s2 = ajParentheses(replaceSpecial(s));
        if (!s.equals("")) {
            final MathElement me = parser(s2, false);
            rootElement.addMathElement(me);
        }
    }
    
    /**
     * Return the root  element of a math tree
     *
     * @return Root element
     */
00121     public MathRootElement getMathRootElement()
    {
        return rootElement;
    }
    
    public String replaceSpecial(String s) {
        for (final String[] spec : special) {
            int ind = s.indexOf(spec[0]);
            while (ind != -1) {
                s = s.substring(0, ind) + spec[1] + s.substring(ind + spec[0].length());
                ind = s.indexOf(spec[0]);
            }
        }
        return s;
    }
    
    public static String ajParentheses(String s) {
        // d'abord ajouter des parenthèses pour séparer les éléments des fonctions
        // f(a+1;b;c) -> f((a+1);b;c)
        int indop = s.indexOf(';');
        while (indop != -1) {
            // vers la gauche du ;
            int pp = 0;
            boolean yaop = false;
            char c;
            for (int i=indop-1; i>=0 && pp>=0; i--) {
                c = s.charAt(i);
                if (c == ';' && pp == 0)
                    break; // les parenthèses sont déjà ajoutées
                if (c == '(')
                    pp--;
                else if (c == ')')
                    pp++;
                else if (sops.indexOf(c) != -1)
                    yaop = true;
                if (pp < 0 && yaop) {
                    s = s.substring(0,i) + '(' + s.substring(i,indop) + ')' + s.substring(indop);
                    indop += 2;
                }
            }
            // vers la droite du ;
            pp = 0;
            yaop = false;
            for (int i=indop+1; i<s.length() && pp>=0; i++) {
                c = s.charAt(i);
                if (c == '(')
                    pp++;
                else if (c == ')')
                    pp--;
                else if (sops.indexOf(c) != -1)
                    yaop = true;
                if ((pp < 0 || pp == 0 && c == ';') && yaop)
                    s = s.substring(0,indop+1) + '(' + s.substring(indop+1,i) + ')' + s.substring(i);
                if (c == ';' && pp == 0)
                    break;
            }
            final int indop2 = s.substring(indop+1).indexOf(';');
            if (indop2 == -1)
                indop = indop2;
            else
                indop += indop2 + 1;
        }
        
        // les autres parenthèses
        for (int iops=0; iops<sops.length(); iops++) {
            final char cops = sops.charAt(iops);
            indop = s.indexOf(cops);
            int nindop = indop;
            int im,ip;
            char cm=' ',cp=' ';
            int pp;
            boolean ajp;
            while (nindop != -1) {
                ajp = false;
                im = indop - 1;
                if (im >= 0)
                    cm = s.charAt(im);
                pp = 0;
                while (im >= 0 && (pp != 0 || cm != '(') &&
                    (pp != 0 || sops.indexOf(cm) == -1)) {
                    if (cm == ')')
                        pp++;
                    else if (cm == '(')
                        pp--;
                    im--;
                    if (im >= 0)
                        cm = s.charAt(im);
                }
                if (im < 0 || sops.indexOf(cm) != -1)
                    ajp = true;
                ip = indop + 1;
                if (ip >= 0 && ip <= s.length()-1)
                    cp = s.charAt(ip);
                pp = 0;
                while (ip < s.length() && (pp != 0 || cp != ')') &&
                    (pp != 0 || sops.indexOf(cp) == -1)) {
                    if (cp == '(')
                        pp++;
                    else if (cp == ')')
                        pp--;
                    ip++;
                    if (ip < s.length())
                        cp = s.charAt(ip);
                }
                if (ip >= s.length() || sops.indexOf(cp) != -1)
                    ajp = true;
                if (ajp) {
                    s = s.substring(0, im+1) + "(" + s.substring(im+1, ip) + ")" +
                        s.substring(ip);
                    indop++;
                }
                nindop = s.substring(indop+1).indexOf(cops);
                indop = nindop + indop+1;
            }
        }
        return s;
    }
    
    public MathElement parser(String s, final boolean parentheses) {
        if (s == null || "".equals(s))
            return null;
        
        boolean ajparentheses = false;
        if (s.charAt(0) == '(' && s.charAt(s.length()-1) == ')') {
            int pp = 0;
            for (int i=1; i<s.length()-1; i++) {
                if (s.charAt(i) == '(')
                    pp++;
                else if (s.charAt(i) == ')')
                    pp--;
                if (pp == -1)
                    break;
            }
            if (pp != -1) {
                s = s.substring(1, s.length()-1);
                if (parentheses)
                    ajparentheses = true;
            }
        }
        
        int indop = -1;
        int pp = 0;
        for (int i=0; i<s.length(); i++) {
            if (pp == 0 && sops.indexOf(s.charAt(i)) != -1) {
                indop = i;
                break;
            } else if (s.charAt(i) == '(')
                pp++;
            else if (s.charAt(i) == ')')
                pp--;
        }
        if (indop == -1) {
            boolean nb;
            try {
                nb = s.matches("\\s?([0-9]+([\\.,][0-9]+)?|[\\.,][0-9]+)(E[+-]?[0-9]+)?\\s?");
            } catch (final PatternSyntaxException ex) {
                nb = false;
            }
            if (nb) {
                final MathNumber mn = new MathNumber();
                mn.addText(s);
                return mn;
            }
            final int indf = s.indexOf('(');
            if (indf != -1 && s.charAt(s.length()-1) == ')') {
                // nomfct(p1; p2; ...) ou (nomfctcomplexe)(p1; p2; ...) ?
                // comme (sin^2)(alpha) ou (theta_f)(1)
                // recherche d'une deuxième parenthèse au même niveau que la première
                int indf2 = -1;
                pp = 0;
                for (int i=0; i<s.length(); i++) {
                    final char c = s.charAt(i);
                    if (c == '(' && pp == 0 && i != indf) {
                        indf2 = i;
                        break;
                    } else if (c == '(')
                        pp++;
                    else if (c == ')')
                        pp--;
                }
                String nomfct = null;
                MathElement mfct = null;
                if (indf2 == -1) {
                    nomfct = s.substring(0,indf);
                    s = s.substring(indf+1, s.length()-1);
                } else {
                    mfct = parser(s.substring(0, indf2), false);
                    s = s.substring(indf2+1, s.length()-1);
                }
                // recherche des paramètres
                final Vector<MathElement> vp = new Vector<MathElement>(); // of MathElement
                //indv = s.indexOf(';'); marche pas avec f(g(a;b);c)
                int indv = -1;
                pp = 0;
                for (int i=0; i<s.length(); i++) {
                    final char c = s.charAt(i);
                    if (c == ';' && pp == 0 ) {
                        indv = i;
                        break;
                    } else if (c == '(')
                        pp++;
                    else if (c == ')')
                        pp--;
                }
                if (indv == -1)
                    vp.add(parser(s.trim(), false));
                else
                    while (indv != -1) {
                        vp.add(parser(s.substring(0,indv).trim(), false));
                        s = s.substring(indv+1);
                        indv = -1;
                        pp = 0;
                        for (int i=0; i<s.length(); i++) {
                            final char c = s.charAt(i);
                            if (c == ';' && pp == 0 ) {
                                indv = i;
                                break;
                            } else if (c == '(')
                                pp++;
                            else if (c == ')')
                                pp--;
                        }
                        if (indv == -1)
                            vp.add(parser(s.trim(), false));
                    }
                // transformation en MathML
                MathElement p1, p2, p3, p4;
                if (vp.size() > 0)
                    p1 = vp.get(0);
                else
                    p1 = null;
                if (vp.size() > 1)
                    p2 = vp.get(1);
                else
                    p2 = null;
                if (vp.size() > 2)
                    p3 = vp.get(2);
                else
                    p3 = null;
                if (vp.size() > 3)
                    p4 = vp.get(3);
                else
                    p4 = null;
                MathElement me;
                if ("sqrt".equals(nomfct) || "racine".equals(nomfct)) {
                    me = new MathSqrt();
                    me.addMathElement(p1);
                } else if ("exp".equals(nomfct)) {
                    me = new MathSup();
                    final MathIdentifier mi = new MathIdentifier();
                    mi.addText("e");
                    me.addMathElement(mi);
                    me.addMathElement(p1);
                } else if ("abs".equals(nomfct)) {
                    me = new MathRow();
                    MathOperator mo = new MathOperator();
                    mo.addText("|");
                    me.addMathElement(mo);
                    me.addMathElement(p1);
                    mo = new MathOperator();
                    mo.addText("|");
                    me.addMathElement(mo);
                } else if ("fact".equals(nomfct) || "factorielle".equals(nomfct)
                         || "factorial".equals(nomfct)) {
                    me = new MathRow();
                    MathOperator mo;
                    if (!(p1 instanceof MathIdentifier || p1 instanceof MathNumber)) {
                        mo = new MathOperator();
                        mo.addText("(");
                        me.addMathElement(mo);
                    }
                    me.addMathElement(p1);
                    if (!(p1 instanceof MathIdentifier || p1 instanceof MathNumber)) {
                        mo = new MathOperator();
                        mo.addText(")");
                        me.addMathElement(mo);
                    }
                    mo = new MathOperator();
                    mo.addText("!");
                    me.addMathElement(mo);
                } else if ("int".equals(nomfct) || "intégrale".equals(nomfct)) {
                    me = new MathRow();
                    MathOperator mo = new MathOperator();
                    mo.addText("\u222B");
                    mo.setStretchy(true);
                    if (p3 != null && p4 != null) {
                        final MathUnderOver munderover = new MathUnderOver();
                        munderover.addMathElement(mo);
                        munderover.addMathElement(elemOrQuestion(p3));
                        munderover.addMathElement(elemOrQuestion(p4));
                        me.addMathElement(munderover);
                    } else if (p3 != null) {
                        final MathUnder munder = new MathUnder();
                        munder.addMathElement(mo);
                        munder.addMathElement(elemOrQuestion(p3));
                        me.addMathElement(munder);
                    } else if (p4 != null) {
                        final MathOver mover = new MathOver();
                        mover.addMathElement(mo);
                        mover.addMathElement(elemOrQuestion(p4));
                        me.addMathElement(mover);
                    } else
                        me.addMathElement(mo);
                    final MathRow mrow = new MathRow();
                    mrow.addMathElement(elemOrQuestion(p1));
                    // <mo> &InvisibleTimes; </mo>
                    if (p2 != null) {
                        mo = new MathOperator();
                        mo.addText("d"); // &DifferentialD;
                        mrow.addMathElement(mo);
                        mrow.addMathElement(p2);
                    }
                    me.addMathElement(mrow);
                } else if ("prod".equals(nomfct) || "sum".equals(nomfct) ||
                        "produit".equals(nomfct) || "somme".equals(nomfct)) {
                    me = new MathRow();
                    final MathUnderOver munderover = new MathUnderOver();
                    final MathOperator mo = new MathOperator();
                    if ("prod".equals(nomfct) || "produit".equals(nomfct))
                        mo.addText("\u220F");
                    else if ("sum".equals(nomfct) || "somme".equals(nomfct))
                        mo.addText("\u2211");
                    mo.setStretchy(true);
                    munderover.addMathElement(mo);
                    munderover.addMathElement(elemOrQuestion(p2));
                    munderover.addMathElement(elemOrQuestion(p3));
                    me.addMathElement(munderover);
                    final MathRow mrow = new MathRow();
                    mrow.addMathElement(elemOrQuestion(p1));
                    me.addMathElement(mrow);
                } else if ("over".equals(nomfct) || "dessus".equals(nomfct)) {
                    final MathOver mover = new MathOver();
                    mover.addMathElement(elemOrQuestion(p1));
                    mover.addMathElement(elemOrQuestion(p2));
                    me = mover;
                } else if ("subsup".equals(nomfct)) {
                    final MathSubSup msubsup = new MathSubSup();
                    msubsup.addMathElement(elemOrQuestion(p1));
                    msubsup.addMathElement(elemOrQuestion(p2));
                    msubsup.addMathElement(elemOrQuestion(p3));
                    me = msubsup;
                } else if ("accent".equals(nomfct)) {
                    final MathOver mover = new MathOver();
                    mover.setAccent(true);
                    mover.addMathElement(elemOrQuestion(p1));
                    mover.addMathElement(elemOrQuestion(p2));
                    me = mover;
                } else if ("matrix".equals(nomfct) || "matrice".equals(nomfct)) {
                    me = new MathRow();
                    MathOperator mo = new MathOperator();
                    mo.addText("(");
                    me.addMathElement(mo);
                    final MathTable mtable = new MathTable();
                    for (final MathElement mel : vp)
                        mtable.addMathElement(elemOrQuestion(mel));
                    me.addMathElement(mtable);
                    mo = new MathOperator();
                    mo.addText(")");
                    me.addMathElement(mo);
                } else if ("system".equals(nomfct) || "système".equals(nomfct)) {
                    me = new MathRow();
                    final MathOperator mo = new MathOperator();
                    mo.addText("{");
                    me.addMathElement(mo);
                    final MathTable mtable = new MathTable();
                    for (final MathElement mel : vp) {
                        final MathRow mrow = new MathRow();
                        final MathTableData mtd = new MathTableData();
                        mtd.setColumnAlign("left");
                        mtd.addMathElement(elemOrQuestion(mel));
                        mrow.addMathElement(mtd);
                        mtable.addMathElement(mrow);
                    }
                    me.addMathElement(mtable);
                } else if ("line".equals(nomfct) || "ligne".equals(nomfct)) {
                    me = new MathTableRow();
                    for (final MathElement mel : vp) {
                        final MathTableData mtd = new MathTableData();
                        mtd.addMathElement(elemOrQuestion(mel));
                        me.addMathElement(mtd);
                    }
                } else if ("slash".equals(nomfct)) {
                    me = new MathRow();
                    me.addMathElement(elemOrQuestion(p1));
                    final MathOperator mo = new MathOperator();
                    mo.addText("/"); // could be \u2215
                    me.addMathElement(mo);
                    me.addMathElement(elemOrQuestion(p2));
                } else if ("frac".equals(nomfct) || "fraction".equals(nomfct)) {
                    final MathFrac mfrac = new MathFrac();
                    mfrac.addMathElement(elemOrQuestion(p1));
                    mfrac.addMathElement(elemOrQuestion(p2));
                    me = mfrac;
                } else if ("pscalaire".equals(nomfct) || "scalarp".equals(nomfct)) {
                    final MathRow mrow = new MathRow();
                    mrow.addMathElement(elemOrQuestion(p1));
                    final MathOperator mo = new MathOperator();
                    mo.addText(".");
                    mrow.addMathElement(mo);
                    mrow.addMathElement(elemOrQuestion(p2));
                    return mrow;
                } else if ("dtemps".equals(nomfct) || "timed".equals(nomfct)) {
                    final MathOver mover = new MathOver();
                    mover.setAccent(true);
                    mover.addMathElement(elemOrQuestion(p1));
                    if (p2 instanceof MathNumber) {
                        try {
                            final int n = Integer.parseInt(p2.getText());
                            p2 = new MathText();
                            String spts = "";
                            for (int i=0; i<n; i++)
                                spts = spts + '.';
                            p2.addText(spts);
                        } catch (final NumberFormatException ex) {
                            p2 = null;
                        }
                    } else
                        p2 = null;
                    mover.addMathElement(elemOrQuestion(p2));
                    me = mover;
                } else if ("unité".equals(nomfct) || "unit".equals(nomfct)) {
                    final MathRow mrow = new MathRow();
                    mrow.addMathElement(elemOrQuestion(p1));
                    final MathOperator mo = new MathOperator();
                    mo.addText(" ");
                    mrow.addMathElement(mo);
                    mrow.addMathElement(ident2text(elemOrQuestion(p2))); // les unités ne doivent pas être en italique
                    return mrow;
                } else {
                    me = new MathRow();
                    boolean par = true;
                    if (mfct == null) {
                        mfct = new MathText();
                        for (final String[] element : symbols)
                            if (element[0].equals(nomfct)) {
                                nomfct = element[1];
                                break;
                            }
                        mfct.addText(nomfct);
                        if (p2 == null && p1 instanceof MathIdentifier)
                            for (final String element : fctnopar)
                                if (element.equals(nomfct)) {
                                    par = false;
                                    break;
                                }
                    }
                    me.addMathElement(mfct);
                    if (par) {
                        final MathOperator mo = new MathOperator();
                        mo.addText("("); // \u2061 = &ApplyFunction; serait mieux mais pas reconnu
                        me.addMathElement(mo);
                    }
                    me.addMathElement(p1);
                    for (int i=1; i<vp.size(); i++) { // ATTENTION, LA BOUCLE COMMENCE A 1
                        final MathOperator mo = new MathOperator();
                        mo.addText(";");
                        me.addMathElement(mo);
                        me.addMathElement(vp.get(i));
                    }
                    if (par) {
                        final MathOperator mo = new MathOperator();
                        mo.addText(")");
                        me.addMathElement(mo);
                    } else {
                        final MathText mtext = new MathText();
                        mtext.addText("\u00A0"); // nbsp, mspace serait mieux
                        me.addMathElement(mtext);
                    }
                }
                return me;
            } else if ("hat".equals(s) || "chapeau".equals(s)) {
                final MathOperator mo = new MathOperator();
                mo.setStretchy(true);
                mo.addText("^");
                return mo;
            } else if ("bar".equals(s) || "barre".equals(s)) {
                final MathOperator mo = new MathOperator();
                mo.setStretchy(true);
                mo.addText("\u00AF");
                return mo;
            } else {
                for (final String[] element : symbols)
                    if (element[0].equals(s)) {
                        s = element[1];
                        break;
                    }
                if (s.indexOf(',') != -1 || s.indexOf('.') != -1)
                    s = "?"; // les ',' et les '.' sont interdits dans les noms de variables
                final MathIdentifier mi = new MathIdentifier();
                mi.addText(s);
                return mi;
            }
        }
        final char op = s.charAt(indop);
        if (ajparentheses && "+-".indexOf(op) != -1) {
            final MathRow mrow = new MathRow();
            MathOperator mo = new MathOperator();
            mo.addText("(");
            mrow.addMathElement(mo);
            mrow.addMathElement(parser(s, false));
            mo = new MathOperator();
            mo.addText(")");
            mrow.addMathElement(mo);
            return mrow;
        }
        boolean par1 = false;
        boolean par2 = false;
        if (op == '-')
            par2 = true;
        if (op == '*') {
            par1 = true;
            par2 = true;
        }
        final String s1 = s.substring(0,indop).trim();
        MathElement p1;
        if (s1.equals(""))
            p1 = null;
        else
            p1 = parser(s1, par1);
        final String s2 = s.substring(indop+1).trim();
        MathElement p2;
        if (s2.equals(""))
            p2 = null;
        else
            p2 = parser(s2, par2);
        
        if (op == '/') {
            final MathFrac mfrac = new MathFrac();
            mfrac.addMathElement(elemOrQuestion(p1));
            mfrac.addMathElement(elemOrQuestion(p2));
            return mfrac;
        } else if (op == '^') {
            final MathSup msup = new MathSup();
            if (p1 instanceof MathFrac || p1 instanceof MathRow || p1 instanceof MathSup) {
                final MathRow mrow = new MathRow();
                MathOperator mo = new MathOperator();
                mo.addText("(");
                mrow.addMathElement(mo);
                mrow.addMathElement(p1);
                mo = new MathOperator();
                mo.addText(")");
                mrow.addMathElement(mo);
                p1 = mrow;
            }
            msup.addMathElement(elemOrQuestion(p1));
            msup.addMathElement(elemOrQuestion(p2));
            return msup;
        } else if (op == '_') {
            final MathSub msub = new MathSub();
            msub.addMathElement(elemOrQuestion(p1));
            msub.addMathElement(elemOrQuestion(p2));
            return msub;
        } else if (op == '*') {
            final MathRow mrow = new MathRow();
            mrow.addMathElement(elemOrQuestion(p1));
            
            MathElement dernierDansP1 = p1;
            if (p1 != null)
                while (dernierDansP1.getMathElementCount() > 1)
                    dernierDansP1 = dernierDansP1.getMathElement(
                        dernierDansP1.getMathElementCount()-1);
            final boolean p1nombre = dernierDansP1 instanceof MathNumber;
            MathElement premierDansP2 = p2;
            if (p2 != null)
                while (premierDansP2.getMathElementCount() > 1)
                    premierDansP2 = premierDansP2.getMathElement(0);
            final boolean p2nombre = premierDansP2 instanceof MathNumber;
            if (p1nombre && p2nombre) {
                final MathOperator mo = new MathOperator();
                mo.addText("×");
                mrow.addMathElement(mo);
            } // else <mo> &InvisibleTimes; </mo>
            
            mrow.addMathElement(elemOrQuestion(p2));
            return mrow;
        } else {
            final MathRow mrow = new MathRow();
            if (p1 != null)
                mrow.addMathElement(p1);
            final MathOperator mo = new MathOperator();
            mo.addText(Character.toString(op));
            if ("=\u2260\u2248\u2264\u2265\u226A\u226B".indexOf(op) != -1) {
                // espace autour des opérateurs d'égalité
                mo.setLspace(0.5);
                mo.setRspace(0.5);
            }
            mrow.addMathElement(mo);
            if (p2 != null)
                mrow.addMathElement(p2);
            return mrow;
        }
    }
    
    private static MathElement elemOrQuestion(final MathElement me) {
        if (me != null)
            return me;
        final MathText mtext = new MathText();
        mtext.addText("?");
        return mtext;
    }
    
    private static MathElement ident2text(final MathElement me) {
        if (me instanceof MathIdentifier) {
            final MathText me2 = new MathText();
            me2.addText(me.getText());
            return(me2);
        } else {
            for (int i=0; i<me.getMathElementCount(); i++)
                me.setMathElementAt(ident2text(me.getMathElement(i)), i);
            return(me);
        }
    }
}

Generated by  Doxygen 1.6.0   Back to index