/*
* This file is part of Herschel Common Science System (HCSS).
* Copyright 2001-2010 Herschel Science Ground Segment Consortium
*
* HCSS is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* HCSS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with HCSS.
* If not, see .
*/
/*
*
*/
package org.jplot2d.tex;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* This Class contains the simplified model of MathML. The complete model is
* described in: Document
* Object Model for MathML
*
* The corresponding MathML DOM Interface is MathMLMathElement
*
* @author Jingjing Li
*
*/
public abstract class MathElement {
public enum MathVariant {
NORMAL, BOLD, ITALIC; // bold_italic,
// double_struck, bold_fraktur, script, bold_script, fraktur,
// SANS_SERIF,
// bold_sans_serif, sans_serif_italic, sans_serif_bold_italic,
// MONOSPACE
public String mathCommand() {
switch (this) {
case NORMAL:
return "\\mathrm";
case BOLD:
return "\\mathbf";
case ITALIC:
return "\\mathit";
}
return null;
}
public String textCommand() {
switch (this) {
case NORMAL:
return "\\textrm";
case BOLD:
return "\\textbf";
case ITALIC:
return "\\textit";
}
return null;
}
}
/**
* The Null MathElement is a special MathElement which represent a empty
* element.
*/
public static final MathElement EMPTY = new MathElement() {
public String toMathML() {
return " ";
}
public void fillTeXString(TeXStringBuilder sb) {
sb.append("{}");
}
};
public abstract String toMathML();
public abstract void fillTeXString(TeXStringBuilder sb);
protected String toTeXString() {
TeXStringBuilder sb = new TeXStringBuilder();
this.fillTeXString(sb);
if (sb.isMathMode()) {
sb.append('$');
}
return sb.toString();
}
private String str;
public String toString() {
if (str == null) {
str = toTeXString();
}
return str;
}
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof MathElement) {
return this.toString().equals(((MathElement) anObject).toString());
}
return false;
}
public int hashCode() {
return toString().hashCode();
}
/**
* MathML DOM Interface: MathMLPresentationElement
*/
public static abstract class PElement extends MathElement {
}
/**
* MathML DOM Interface: MathMLPresentationContainer
*/
public static abstract class PContainer extends PElement {
protected final List pl = new ArrayList();
public int size() {
return pl.size();
}
public List getElementList() {
return pl;
}
public PElement get(int index) {
return pl.get(index);
}
protected void fillMathML(StringBuilder sb) {
if (pl.size() == 0) {
return;
} else {
for (Iterator itr = pl.iterator(); itr.hasNext();) {
PElement p = itr.next();
sb.append(p.toMathML());
}
}
}
public void fillTeXString(TeXStringBuilder sb) {
if (pl.size() == 0) {
return;
} else {
for (Iterator itr = pl.iterator(); itr.hasNext();) {
PElement p = itr.next();
p.fillTeXString(sb);
}
}
}
/**
* Check if a Mtext child exist in this Mstyle, recursing into mrow.
*
* @return
*/
protected boolean isMtextChildExist() {
for (Iterator itr = pl.iterator(); itr.hasNext();) {
PElement p = itr.next();
if (p instanceof Mtext) {
return true;
}
if (p instanceof Mrow) {
if (((Mrow) p).isMtextChildExist()) {
return true;
}
}
}
return false;
}
}
/**
* Horizontally Group Sub-Expressions
*/
public static class Mrow extends PContainer {
public Mrow() {
}
public Mrow(List mes) {
pl.addAll(mes);
}
public String toMathML() {
StringBuilder sb = new StringBuilder();
sb.append("");
fillMathML(sb);
sb.append(" ");
return sb.toString();
}
public void fillTeXString(TeXStringBuilder sb) {
sb.append("{");
super.fillTeXString(sb);
sb.append("}");
}
/**
* As a top level container, the toString not contains the pair of {}
*/
protected String toTeXString() {
TeXStringBuilder sb = new TeXStringBuilder();
super.fillTeXString(sb);
if (sb.isMathMode()) {
sb.append('$');
}
return sb.toString();
}
}
public static class Mstyle extends PContainer {
protected final MathVariant _mathvariant;
public Mstyle(MathVariant mathvariant, PElement pe) {
_mathvariant = mathvariant;
if (pe instanceof Mrow) {
pl.addAll(((Mrow) pe).pl);
} else {
pl.add(pe);
}
}
public MathVariant getMathVariant() {
return _mathvariant;
}
public String toMathML() {
StringBuilder sb = new StringBuilder();
sb.append("");
fillMathML(sb);
sb.append(" ");
return sb.toString();
}
public void fillTeXString(TeXStringBuilder sb) {
if (sb.isTextMode()) {
sb.append(_mathvariant.textCommand());
sb.append('{');
super.fillTeXString(sb);
sb.append('}');
} else {
if (isMtextChildExist()) {
sb.append(_mathvariant.textCommand());
sb.append('{');
sb.goTextMode();
super.fillTeXString(sb);
sb.goMathMode();
sb.append('}');
} else {
sb.append(_mathvariant.mathCommand());
sb.append('{');
super.fillTeXString(sb);
sb.append('}');
}
}
}
}
/**
* Extends of Math, multiple lines of MathElement
*/
public static class XLines extends MathElement {
private final List mel = new ArrayList();
public XLines(List xlines) {
mel.addAll(xlines);
}
public int size() {
return mel.size();
}
public MathElement[] getElements() {
MathElement[] pa = new MathElement[mel.size()];
return mel.toArray(pa);
}
public MathElement get(int index) {
return mel.get(index);
}
public String toMathML() {
StringBuilder sb = new StringBuilder();
sb.append("");
for (Iterator itr = mel.iterator(); itr.hasNext();) {
MathElement p = itr.next();
sb.append(p.toMathML());
}
sb.append(" ");
return sb.toString();
}
public void fillTeXString(TeXStringBuilder sb) {
if (sb.isMathMode()) {
throw new IllegalStateException();
}
Iterator itr = mel.iterator();
MathElement p = itr.next();
p.fillTeXString(sb);
while (itr.hasNext()) {
if (sb.isMathMode()) {
sb.append('$');
sb.goTextMode();
}
sb.append("\\n");
p = itr.next();
p.fillTeXString(sb);
}
}
}
/**
* Presentation Token
*/
public static abstract class PToken extends PElement {
protected String _string;
public void fillTeXString(TeXStringBuilder sb) {
if (sb.isTextMode()) {
sb.goMathMode();
sb.append('$');
}
sb.append(escape());
}
protected String escape() {
return _string;
}
public String getToken() {
return _string;
}
}
public static class Mi extends PToken {
public Mi(String s) {
_string = s;
}
public Mi(char c) {
_string = String.valueOf(c);
}
public String toMathML() {
return "" + _string + " ";
}
public String escape() {
return escape(_string);
}
}
public static class Mn extends PToken {
public Mn(String s) {
_string = s;
}
public String toMathML() {
return "" + _string + " ";
}
public String escape() {
if (_string.startsWith("-")) {
return "{" + _string + "}";
} else {
return _string;
}
}
}
public static class Mo extends PToken {
public Mo(String s) {
_string = s;
}
public String toMathML() {
return "" + _string + " ";
}
}
public static class Mtext extends PToken {
public Mtext(String s) {
_string = s;
}
public String toMathML() {
return "" + _string + " ";
}
public void fillTeXString(TeXStringBuilder sb) {
if (sb.isMathMode()) {
sb.append('$');
sb.goTextMode();
}
sb.append(escape());
}
public String escape() {
return escape(_string);
}
}
public static class Msub extends PElement {
public PElement base;
public PElement subscript;
public Msub(PElement base, PElement subscript) {
if (base == null) {
base = new Mrow();
}
this.base = base;
this.subscript = subscript;
}
public String toMathML() {
return "" + base.toMathML() + subscript.toMathML()
+ " ";
}
public void fillTeXString(TeXStringBuilder sb) {
if (sb.isTextMode()) {
sb.goMathMode();
sb.append('$');
}
base.fillTeXString(sb);
sb.append("_");
subscript.fillTeXString(sb);
}
}
public static class Msup extends PElement {
public PElement base;
public PElement superscript;
public Msup(PElement base, PElement superscript) {
if (base == null) {
base = new Mrow();
}
this.base = base;
this.superscript = superscript;
}
public String toMathML() {
return "" + base.toMathML() + superscript.toMathML()
+ " ";
}
public void fillTeXString(TeXStringBuilder sb) {
if (sb.isTextMode()) {
sb.goMathMode();
sb.append('$');
}
base.fillTeXString(sb);
sb.append("^");
superscript.fillTeXString(sb);
}
}
public static class Msubsup extends PElement {
public PElement base;
public PElement subscript;
public PElement superscript;
public Msubsup(PElement base, PElement sub, PElement sup) {
if (base == null) {
base = new Mrow();
}
this.base = base;
subscript = sub;
superscript = sup;
}
public String toMathML() {
return "" + base.toMathML() + subscript.toMathML()
+ superscript.toMathML() + " ";
}
public void fillTeXString(TeXStringBuilder sb) {
if (sb.isTextMode()) {
sb.goMathMode();
sb.append('$');
}
base.fillTeXString(sb);
sb.append("_");
subscript.fillTeXString(sb);
sb.append("^");
superscript.fillTeXString(sb);
}
}
private static class TeXStringBuilder {
private final StringBuilder sb = new StringBuilder();
private boolean mathMode;
public TeXStringBuilder() {
}
public void append(String string) {
sb.append(string);
}
public void append(char c) {
sb.append(c);
}
public boolean isTextMode() {
return !mathMode;
}
public boolean isMathMode() {
return mathMode;
}
public void goTextMode() {
mathMode = false;
}
public void goMathMode() {
mathMode = true;
}
public String toString() {
return sb.toString();
}
}
/** escape the special characters in the given string */
public static String escape(String s) {
return s.replace("\u005c\u005c", "\u005c\u005c\u005c\u005c")
.replace("$", "\u005c\u005c$").replace("{", "\u005c\u005c{")
.replace("}", "\u005c\u005c}");
}
}
Ads help maintain this website.