+++ /dev/null
-/****************************************************************************
-**
-** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of a Qt Solutions component.
-**
-** Commercial Usage
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Solutions Commercial License Agreement provided
-** with the Software or, alternatively, in accordance with the terms
-** contained in a written agreement between you and Nokia.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain
-** additional rights. These rights are described in the Nokia Qt LGPL
-** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
-** package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** Please note Third Party Software included with Qt Solutions may impose
-** additional restrictions and it is the user's responsibility to ensure
-** that they have met the licensing requirements of the GPL, LGPL, or Qt
-** Solutions Commercial license and the relevant license of the Third
-** Party Software they are using.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact Nokia at qt-info@nokia.com.
-**
-****************************************************************************/
-
-#include <QtGui/QApplication>
-#include <QtCore/QString>
-#include <QtCore/QMap>
-#include <QtGui/QDesktopWidget>
-#include <QtGui/QPainter>
-#include <QtGui/QPaintEvent>
-
-#include "qtmmlwidget.h"
-
-// *******************************************************************
-// Declarations
-// *******************************************************************
-
-#define ROUND(a) (int)((a)+.5)
-
-static bool g_draw_frames = false;
-static const double g_mfrac_spacing = 0.1;
-static const double g_mroot_base_margin = 0.1;
-static const double g_script_size_multiplier = 0.7071; // sqrt(1/2)
-static const int g_min_font_point_size = 8;
-static const QChar g_radical_char = QChar(0x1A, 0x22);
-static const unsigned g_oper_spec_rows = 9;
-
-struct Mml
-{
- enum NodeType {
- NoNode = 0, MiNode, MnNode, MfracNode, MrowNode, MsqrtNode,
- MrootNode, MsupNode, MsubNode, MsubsupNode, MoNode,
- MstyleNode, TextNode, MphantomNode, MfencedNode,
- MtableNode, MtrNode, MtdNode, MoverNode, MunderNode,
- MunderoverNode, MerrorNode, MtextNode, MpaddedNode,
- MspaceNode, MalignMarkNode, UnknownNode
- };
-
- enum MathVariant {
- NormalMV = 0x0000,
- BoldMV = 0x0001,
- ItalicMV = 0x0002,
- DoubleStruckMV = 0x0004,
- ScriptMV = 0x0008,
- FrakturMV = 0x0010,
- SansSerifMV = 0x0020,
- MonospaceMV = 0x0040
- };
-
- enum FormType { PrefixForm, InfixForm, PostfixForm };
- enum ColAlign { ColAlignLeft, ColAlignCenter, ColAlignRight };
- enum RowAlign { RowAlignTop, RowAlignCenter, RowAlignBottom,
- RowAlignAxis, RowAlignBaseline };
- enum FrameType { FrameNone, FrameSolid, FrameDashed };
-
- struct FrameSpacing {
- FrameSpacing(int hor = 0, int ver = 0)
- : m_hor(hor), m_ver(ver) {}
- int m_hor, m_ver;
- };
-};
-
-struct OperSpec {
- enum StretchDir { NoStretch, HStretch, VStretch, HVStretch };
-
- const char *name;
- Mml::FormType form;
- const char *attributes[g_oper_spec_rows];
- StretchDir stretch_dir;
-};
-
-struct NodeSpec
-{
- Mml::NodeType type;
- const char *tag;
- const char *type_str;
- int child_spec;
- const char *child_types;
- const char *attributes;
-
- enum ChildSpec {
- ChildAny = -1, // any number of children allowed
- ChildIgnore = -2, // do not build subexpression of children
- ImplicitMrow = -3 // if more than one child, build mrow
- };
-};
-
-struct EntitySpec
-{
- const char *name;
- const char *value;
-};
-
-typedef QMap<QString, QString> MmlAttributeMap;
-class MmlNode;
-
-class MmlDocument : public Mml
-{
- public:
- MmlDocument();
- ~MmlDocument();
- void clear();
-
- bool setContent(QString text, QString *errorMsg = 0,
- int *errorLine = 0, int *errorColumn = 0);
- void paint(QPainter *p, const QPoint &pos) const;
- void dump() const;
- QSize size() const;
- void layout();
-
- QString fontName(QtMmlWidget::MmlFont type) const;
- void setFontName(QtMmlWidget::MmlFont type, const QString &name);
-
- int baseFontPointSize() const
- { return m_base_font_point_size; }
- void setBaseFontPointSize(int size)
- { m_base_font_point_size = size; }
- QColor foregroundColor() const
- { return m_foreground_color; }
- void setForegroundColor(const QColor &color)
- { m_foreground_color = color; }
- QColor backgroundColor() const
- { return m_background_color; }
- void setBackgroundColor(const QColor &color)
- { m_background_color = color; }
-
- private:
- void _dump(const MmlNode *node, QString &indent) const;
- bool insertChild(MmlNode *parent, MmlNode *new_node, QString *errorMsg);
-
- MmlNode *domToMml(const QDomNode &dom_node, bool *ok, QString *errorMsg);
- MmlNode *createNode(NodeType type, const MmlAttributeMap &mml_attr,
- const QString &mml_value, QString *errorMsg);
- MmlNode *createImplicitMrowNode(const QDomNode &dom_node, bool *ok,
- QString *errorMsg);
-
- void insertOperator(MmlNode *node, const QString &text);
-
- MmlNode *m_root_node;
-
- QString m_normal_font_name;
- QString m_fraktur_font_name;
- QString m_sans_serif_font_name;
- QString m_script_font_name;
- QString m_monospace_font_name;
- QString m_doublestruck_font_name;
- int m_base_font_point_size;
- QColor m_foreground_color;
- QColor m_background_color;
-};
-
-class MmlNode : public Mml
-{
- friend class MmlDocument;
-
- public:
- MmlNode(NodeType type, MmlDocument *document, const MmlAttributeMap &attribute_map);
- virtual ~MmlNode();
-
- // Mml stuff
- NodeType nodeType() const
- { return m_node_type; }
-
- virtual QString toStr() const;
-
- void setRelOrigin(const QPoint &rel_origin);
- QPoint relOrigin() const
- { return m_rel_origin; }
- void stretchTo(const QRect &rect);
- bool isStretched() const
- { return m_stretched; }
- QPoint devicePoint(const QPoint &p) const;
-
- QRect myRect() const
- { return m_my_rect; }
- QRect parentRect() const;
- virtual QRect deviceRect() const;
- void updateMyRect();
- virtual void setMyRect(const QRect &rect)
- { m_my_rect = rect; }
-
- virtual void stretch();
- virtual void layout();
- virtual void paint(QPainter *p);
-
- int basePos() const;
- int overlinePos() const;
- int underlinePos() const;
- int em() const;
- int ex() const;
-
- QString explicitAttribute(const QString &name, const QString &def = QString::null) const;
- QString inheritAttributeFromMrow(const QString &name, const QString &def = QString::null) const;
-
- virtual QFont font() const;
- virtual QColor color() const;
- virtual QColor background() const;
- virtual int scriptlevel(const MmlNode *child = 0) const;
-
-
- // Node stuff
- MmlDocument *document() const
- { return m_document; }
- MmlNode *parent() const
- { return m_parent; }
- MmlNode *firstChild() const
- { return m_first_child; }
- MmlNode *nextSibling() const
- { return m_next_sibling; }
- MmlNode *previousSibling() const
- { return m_previous_sibling; }
- MmlNode *lastSibling() const;
- MmlNode *firstSibling() const;
- bool isLastSibling() const
- { return m_next_sibling == 0; }
- bool isFirstSibling() const
- { return m_previous_sibling == 0; }
- bool hasChildNodes() const
- { return m_first_child != 0; }
-
- protected:
- virtual void layoutSymbol();
- virtual void paintSymbol(QPainter *p) const;
- virtual QRect symbolRect() const
- { return QRect(0, 0, 0, 0); }
-
- MmlNode *parentWithExplicitAttribute(const QString &name, NodeType type = NoNode);
- int interpretSpacing(const QString &value, bool *ok) const;
-
- private:
- MmlAttributeMap m_attribute_map;
- bool m_stretched;
- QRect m_my_rect, m_parent_rect;
- QPoint m_rel_origin;
-
- NodeType m_node_type;
- MmlDocument *m_document;
-
- MmlNode *m_parent,
- *m_first_child,
- *m_next_sibling,
- *m_previous_sibling;
-};
-
-class MmlTokenNode : public MmlNode
-{
- public:
- MmlTokenNode(NodeType type, MmlDocument *document,
- const MmlAttributeMap &attribute_map)
- : MmlNode(type, document, attribute_map) {}
-
- QString text() const;
-};
-
-class MmlMphantomNode : public MmlNode
-{
- public:
- MmlMphantomNode(MmlDocument *document,
- const MmlAttributeMap &attribute_map)
- : MmlNode(MphantomNode, document, attribute_map) {}
-
- virtual void paint(QPainter *) {}
-};
-
-class MmlUnknownNode : public MmlNode
-{
- public:
- MmlUnknownNode(MmlDocument *document,
- const MmlAttributeMap &attribute_map)
- : MmlNode(UnknownNode, document, attribute_map) {}
-};
-
-class MmlMfencedNode : public MmlNode
-{
- public:
- MmlMfencedNode(MmlDocument *document,
- const MmlAttributeMap &attribute_map)
- : MmlNode(MfencedNode, document, attribute_map) {}
-};
-
-class MmlMalignMarkNode : public MmlNode
-{
- public:
- MmlMalignMarkNode(MmlDocument *document)
- : MmlNode(MalignMarkNode, document, MmlAttributeMap()) {}
-};
-
-class MmlMfracNode : public MmlNode
-{
- public:
- MmlMfracNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlNode(MfracNode, document, attribute_map) {}
-
- MmlNode *numerator() const;
- MmlNode *denominator() const;
-
- protected:
- virtual void layoutSymbol();
- virtual void paintSymbol(QPainter *p) const;
- virtual QRect symbolRect() const;
-};
-
-class MmlMrowNode : public MmlNode
-{
- public:
- MmlMrowNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlNode(MrowNode, document, attribute_map) {}
-};
-
-class MmlRootBaseNode : public MmlNode
-{
- public:
- MmlRootBaseNode(NodeType type, MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlNode(type, document, attribute_map) {}
-
- MmlNode *base() const;
- MmlNode *index() const;
-
- virtual int scriptlevel(const MmlNode *child = 0) const;
-
- protected:
- virtual void layoutSymbol();
- virtual void paintSymbol(QPainter *p) const;
- virtual QRect symbolRect() const;
- int tailWidth() const;
-};
-
-class MmlMrootNode : public MmlRootBaseNode
-{
- public:
- MmlMrootNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlRootBaseNode(MrootNode, document, attribute_map) {}
-};
-
-class MmlMsqrtNode : public MmlRootBaseNode
-{
- public:
- MmlMsqrtNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlRootBaseNode(MsqrtNode, document, attribute_map) {}
-
-};
-
-
-class MmlTextNode : public MmlNode
-{
- public:
- MmlTextNode(const QString &text, MmlDocument *document);
-
- virtual QString toStr() const;
- QString text() const
- { return m_text; }
-
- // TextNodes are not xml elements, so they can't have attributes of
- // their own. Everything is taken from the parent.
- virtual QFont font() const
- { return parent()->font(); }
- virtual int scriptlevel(const MmlNode* = 0) const
- { return parent()->scriptlevel(this); }
- virtual QColor color() const
- { return parent()->color(); }
- virtual QColor background() const
- { return parent()->background(); }
-
- protected:
- virtual void paintSymbol(QPainter *p) const;
- virtual QRect symbolRect() const;
-
- QString m_text;
-};
-
-class MmlMiNode : public MmlTokenNode
-{
- public:
- MmlMiNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlTokenNode(MiNode, document, attribute_map) {}
-};
-
-class MmlMnNode : public MmlTokenNode
-{
- public:
- MmlMnNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlTokenNode(MnNode, document, attribute_map) {}
-};
-
-class MmlSubsupBaseNode : public MmlNode
-{
- public:
- MmlSubsupBaseNode(NodeType type, MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlNode(type, document, attribute_map) {}
-
- MmlNode *base() const;
- MmlNode *sscript() const;
-
- virtual int scriptlevel(const MmlNode *child = 0) const;
-};
-
-class MmlMsupNode : public MmlSubsupBaseNode
-{
- public:
- MmlMsupNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlSubsupBaseNode(MsupNode, document, attribute_map) {}
-
- protected:
- virtual void layoutSymbol();
-};
-
-class MmlMsubNode : public MmlSubsupBaseNode
-{
- public:
- MmlMsubNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlSubsupBaseNode(MsubNode, document, attribute_map) {}
-
- protected:
- virtual void layoutSymbol();
-};
-
-class MmlMsubsupNode : public MmlNode
-{
- public:
- MmlMsubsupNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlNode(MsubsupNode, document, attribute_map) {}
-
- MmlNode *base() const;
- MmlNode *superscript() const;
- MmlNode *subscript() const;
-
- virtual int scriptlevel(const MmlNode *child = 0) const;
-
- protected:
- virtual void layoutSymbol();
-};
-
-class MmlMoNode : public MmlTokenNode
-{
- public:
- MmlMoNode(MmlDocument *document, const MmlAttributeMap &attribute_map);
-
- QString dictionaryAttribute(const QString &name) const;
- virtual void stretch();
- virtual int lspace() const;
- virtual int rspace() const;
-
- virtual QString toStr() const;
-
- protected:
- virtual void layoutSymbol();
- virtual QRect symbolRect() const;
-
- virtual FormType form() const;
-
- private:
- const OperSpec *m_oper_spec;
-};
-
-class MmlMstyleNode : public MmlNode
-{
- public:
- MmlMstyleNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlNode(MstyleNode, document, attribute_map) {}
-};
-
-class MmlTableBaseNode : public MmlNode
-{
- public:
- MmlTableBaseNode(NodeType type, MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlNode(type, document, attribute_map) {}
-};
-
-class MmlMtableNode : public MmlTableBaseNode
-{
- public:
- MmlMtableNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlTableBaseNode(MtableNode, document, attribute_map) {}
-
- int rowspacing() const;
- int columnspacing() const;
- int framespacing_hor() const;
- int framespacing_ver() const;
- FrameType frame() const;
- FrameType columnlines(int idx) const;
- FrameType rowlines(int idx) const;
-
- protected:
- virtual void layoutSymbol();
- virtual QRect symbolRect() const;
- virtual void paintSymbol(QPainter *p) const;
-
- private:
- struct CellSizeData
- {
- void init(const MmlNode *first_row);
- QList<int> col_widths, row_heights;
- int numCols() const { return col_widths.count(); }
- int numRows() const { return row_heights.count(); }
- uint colWidthSum() const;
- uint rowHeightSum() const;
- };
-
- CellSizeData m_cell_size_data;
- int m_content_width, m_content_height;
-};
-
-class MmlMtrNode : public MmlTableBaseNode
-{
- public:
- MmlMtrNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlTableBaseNode(MtrNode, document, attribute_map) {}
- void layoutCells(const QList<int> &col_widths, int col_spc);
-};
-
-class MmlMtdNode : public MmlTableBaseNode
-{
- public:
- MmlMtdNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlTableBaseNode(MtdNode, document, attribute_map)
- { m_scriptlevel_adjust = 0; }
- virtual void setMyRect(const QRect &rect);
-
- ColAlign columnalign();
- RowAlign rowalign();
- uint colNum();
- uint rowNum();
- virtual int scriptlevel(const MmlNode *child = 0) const;
-
- private:
- int m_scriptlevel_adjust; // added or subtracted to scriptlevel to
- // make contents fit the cell
-};
-
-class MmlMoverNode : public MmlNode
-{
- public:
- MmlMoverNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlNode(MoverNode, document, attribute_map) {}
- virtual int scriptlevel(const MmlNode *node = 0) const;
-
- protected:
- virtual void layoutSymbol();
-};
-
-class MmlMunderNode : public MmlNode
-{
- public:
- MmlMunderNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlNode(MunderNode, document, attribute_map) {}
- virtual int scriptlevel(const MmlNode *node = 0) const;
-
- protected:
- virtual void layoutSymbol();
-};
-
-class MmlMunderoverNode : public MmlNode
-{
- public:
- MmlMunderoverNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlNode(MunderoverNode, document, attribute_map) {}
- virtual int scriptlevel(const MmlNode *node = 0) const;
-
- protected:
- virtual void layoutSymbol();
-};
-
-class MmlMerrorNode : public MmlNode
-{
- public:
- MmlMerrorNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlNode(MerrorNode, document, attribute_map) {}
-};
-
-class MmlMtextNode : public MmlNode
-{
- public:
- MmlMtextNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlNode(MtextNode, document, attribute_map) {}
-};
-
-class MmlMpaddedNode : public MmlNode
-{
- public:
- MmlMpaddedNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlNode(MpaddedNode, document, attribute_map) {}
-
- public:
- int lspace() const;
- int width() const;
- int height() const;
- int depth() const;
-
- protected:
- int interpretSpacing(QString value, int base_value, bool *ok) const;
- virtual void layoutSymbol();
- virtual QRect symbolRect() const;
-};
-
-class MmlMspaceNode : public MmlNode
-{
- public:
- MmlMspaceNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlNode(MspaceNode, document, attribute_map) {}
-};
-
-static const NodeSpec *mmlFindNodeSpec(Mml::NodeType type);
-static const NodeSpec *mmlFindNodeSpec(const QString &tag);
-static bool mmlCheckChildType(Mml::NodeType parent_type,
- Mml::NodeType child_type, QString *error_str);
-static bool mmlCheckAttributes(Mml::NodeType child_type,
- const MmlAttributeMap &attr, QString *error_str);
-static QString mmlDictAttribute(const QString &name, const OperSpec *spec);
-static const OperSpec *mmlFindOperSpec(const QString &name, Mml::FormType form);
-static int interpretSpacing(QString name, int em, int ex, bool *ok);
-static int interpretPercentSpacing(QString value, int base, bool *ok);
-static uint interpretMathVariant(const QString &value, bool *ok);
-static Mml::FormType interpretForm(const QString &value, bool *ok);
-static Mml::FrameType interpretFrameType(const QString &value_list, uint idx, bool *ok);
-static Mml::FrameSpacing interpretFrameSpacing(const QString &value_list, int em, int ex, bool *ok);
-static Mml::ColAlign interpretColAlign(const QString &value_list, uint colnum, bool *ok);
-static Mml::RowAlign interpretRowAlign(const QString &value_list, uint rownum, bool *ok);
-static Mml::FrameType interpretFrameType(const QString &value_list, uint idx, bool *ok);
-static QFont interpretDepreciatedFontAttr(const MmlAttributeMap &font_attr, QFont &fn, int em, int ex);
-static QFont interpretMathSize(QString value, QFont &fn, int em, int ex, bool *ok);
-static QString interpretListAttr(const QString &value_list, int idx, const QString &def);
-static QString rectToStr(const QRect &rect);
-static QString entityDeclarations();
-
-
-#define MML_ATT_COMMON " class style id xref actiontype "
-#define MML_ATT_FONTSIZE " fontsize fontweight fontstyle fontfamily color "
-#define MML_ATT_MATHVARIANT " mathvariant mathsize mathcolor mathbackground "
-#define MML_ATT_FONTINFO MML_ATT_FONTSIZE MML_ATT_MATHVARIANT
-#define MML_ATT_OPINFO " form fence separator lspace rspace stretchy symmetric " \
- " maxsize minsize largeop movablelimits accent "
-#define MML_ATT_SIZEINFO " width height depth "
-#define MML_ATT_TABLEINFO " align rowalign columnalign columnwidth groupalign " \
- " alignmentscope side rowspacing columnspacing rowlines " \
- " columnlines width frame framespacing equalrows " \
- " equalcolumns displaystyle "
-#define MML_ATT_MFRAC " bevelled numalign denomalign linethickness "
-#define MML_ATT_MSTYLE MML_ATT_FONTINFO MML_ATT_OPINFO \
- " scriptlevel lquote rquote linethickness displaystyle " \
- " scriptsizemultiplier scriptminsize background " \
- " veryverythinmathspace verythinmathspace thinmathspace " \
- " mediummathspace thickmathspace verythickmathspace " \
- " veryverythickmathspace open close separators " \
- " subscriptshift superscriptshift accentunder tableinfo " \
- " rowspan columnspan edge selection bevelled "
-#define MML_ATT_MTABLE " align rowalign columnalign groupalign alignmentscope " \
- " columnwidth width rowspacing columnspacing rowlines columnlines " \
- " frame framespacing equalrows equalcolumns displaystyle side " \
- " minlabelspacing "
-
-static const NodeSpec g_node_spec_data[] = {
-
-// type tag type_str child_spec child_types attributes ""=none, 0=any
-// ----------------------- --------------- ------------------- ----------------------- ------------------------ ------------------------------------
- { Mml::MiNode, "mi", "MiNode", NodeSpec::ChildAny, " TextNode MalignMark ", MML_ATT_COMMON MML_ATT_FONTINFO },
- { Mml::MnNode, "mn", "MnNode", NodeSpec::ChildAny, " TextNode MalignMark ", MML_ATT_COMMON MML_ATT_FONTINFO },
- { Mml::MfracNode, "mfrac", "MfracNode", 2, 0, MML_ATT_COMMON MML_ATT_MFRAC },
- { Mml::MrowNode, "mrow", "MrowNode", NodeSpec::ChildAny, 0, MML_ATT_COMMON " display mode " },
- { Mml::MsqrtNode, "msqrt", "MsqrtNode", NodeSpec::ImplicitMrow, 0, MML_ATT_COMMON },
- { Mml::MrootNode, "mroot", "MrootNode", 2, 0, MML_ATT_COMMON },
- { Mml::MsupNode, "msup", "MsupNode", 2, 0, MML_ATT_COMMON " subscriptshift " },
- { Mml::MsubNode, "msub", "MsubNode", 2, 0, MML_ATT_COMMON " superscriptshift " },
- { Mml::MsubsupNode, "msubsup", "MsubsupNode", 3, 0, MML_ATT_COMMON " subscriptshift superscriptshift " },
- { Mml::MoNode, "mo", "MoNode", NodeSpec::ChildAny, " TextNode MalignMark ", MML_ATT_COMMON MML_ATT_FONTINFO MML_ATT_OPINFO },
- { Mml::MstyleNode, "mstyle", "MstyleNode", NodeSpec::ImplicitMrow, 0, MML_ATT_COMMON MML_ATT_MSTYLE },
- { Mml::MphantomNode, "mphantom", "MphantomNode", NodeSpec::ImplicitMrow, 0, MML_ATT_COMMON },
- { Mml::MalignMarkNode, "malignmark", "MalignMarkNode", 0, 0, "" },
- { Mml::MfencedNode, "mfenced", "MfencedNode", NodeSpec::ChildAny, 0, MML_ATT_COMMON " open close separators " },
- { Mml::MtableNode, "mtable", "MtableNode", NodeSpec::ChildAny, " MtrNode ", MML_ATT_COMMON MML_ATT_MTABLE },
- { Mml::MtrNode, "mtr", "MtrNode", NodeSpec::ChildAny, " MtdNode ", MML_ATT_COMMON " rowalign columnalign groupalign " },
- { Mml::MtdNode, "mtd", "MtdNode", NodeSpec::ImplicitMrow, 0, MML_ATT_COMMON " rowspan columnspan rowalign columnalign groupalign " },
- { Mml::MoverNode, "mover", "MoverNode", 2, 0, MML_ATT_COMMON " accent " },
- { Mml::MunderNode, "munder", "MunderNode", 2, 0, MML_ATT_COMMON " accentunder " },
- { Mml::MunderoverNode, "munderover", "MunderoverNode", 3, 0, MML_ATT_COMMON " accentunder accent " },
- { Mml::MerrorNode, "merror", "MerrorNode", NodeSpec::ImplicitMrow, 0, MML_ATT_COMMON },
- { Mml::MtextNode, "mtext", "MtextNode", 1, " TextNode ", MML_ATT_COMMON " width height depth linebreak " },
- { Mml::MpaddedNode, "mpadded", "MpaddedNode", NodeSpec::ImplicitMrow, 0, MML_ATT_COMMON " width height depth lspace " },
- { Mml::MspaceNode, "mspace", "MspaceNode", NodeSpec::ImplicitMrow, 0, MML_ATT_COMMON " width height depth linebreak " },
- { Mml::TextNode, 0, "TextNode", NodeSpec::ChildIgnore, 0, "" },
- { Mml::UnknownNode, 0, "UnknownNode", NodeSpec::ChildAny, 0, 0 },
- { Mml::NoNode, 0, 0, 0, 0, 0 }
-};
-
-static const char *g_oper_spec_names[g_oper_spec_rows] = { "accent", "fence", "largeop", "lspace", "minsize", "movablelimits", "rspace", "separator", "stretchy" /* stretchdir */ };
-static const OperSpec g_oper_spec_data[] = {
-
- { "!!" , Mml::PostfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "!!"
- { "!" , Mml::PostfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "!"
- { "!=" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "!="
- { "⩓" , Mml::InfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "mediummathspace", 0, "true" }, OperSpec::VStretch }, // "⩓"
- { "⁡" , Mml::InfixForm, { 0, 0, 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "⁡"
- { "≔" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≔"
- { "∖" , Mml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, "true" }, OperSpec::HVStretch }, // "∖"
- { "∵" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∵"
- { "˘" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "˘"
- { "⋒" , Mml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "⋒"
- { "ⅅ" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // ⅅ"
- { "¸" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "¸"
- { "·" , Mml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "·"
- { "⊙" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊙"
- { "⊖" , Mml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊖"
- { "⊕" , Mml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊕"
- { "⊗" , Mml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊗"
- { "∲" , Mml::PrefixForm, { 0, 0, "true", "0em", 0, 0, "0em", 0, "true"}, OperSpec::VStretch }, // ∲"
- { "”" , Mml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // ”"
- { "’" , Mml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "’"
- { "∷" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∷"
- { "≡" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≡"
- { "∮" , Mml::PrefixForm, { 0, 0, "true", "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // "∮"
- { "∐" , Mml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "∐"
- { "∳", Mml::PrefixForm, { 0, 0, "true", "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // &CounterClockwiseContourInteg
- { "⨯" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "⨯"
- { "⋓" , Mml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "⋓"
- { "≍" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≍"
- { "∇" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "∇"
- { "´" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "´"
- { "˙" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "˙"
- { "˝" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // ˝"
- { "`" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "`"
- { "&DiacriticalLeftArrow;" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // &DiacriticalLeftArrow;"
- { "&DiacriticalLeftRightArrow;" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // &DiacriticalLeftRightArrow;"
- { "&DiacriticalLeftRightVector;" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // &DiacriticalLeftRightVector;"
- { "&DiacriticalLeftVector;" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // &DiacriticalLeftVector;"
- { "&DiacriticalRightArrow;" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // &DiacriticalRightArrow;"
- { "&DiacriticalRightVector;" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // &DiacriticalRightVector;"
- { "˜" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::NoStretch }, // "˜"
- { "⋄" , Mml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "⋄"
- { "ⅆ" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "ⅆ"
- { "≐" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≐"
- { "∯" , Mml::PrefixForm, { 0, 0, "true", "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // ∯"
- { "¨" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "¨"
- { "⇓" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::VStretch }, // "⇓"
- { "⇐" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "⇐"
- { "⇔" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // ⇔"
- { "⫤" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⫤"
- { "⟸" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HStretch }, // "⟸"
- { "⟺" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HStretch }, // ⟺"
- { "⟹" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HStretch }, // ⟹"
- { "⇒" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "⇒"
- { "⊨" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊨"
- { "⇑" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::VStretch }, // "⇑"
- { "⇕" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::VStretch }, // "⇕"
- { "∥" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∥"
- { "↓" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::VStretch }, // "↓"
- { "⤓" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::VStretch }, // "⤓"
- { "⇵" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::VStretch }, // "⇵"
- { "̑" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "̑"
- { "⥐" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HVStretch }, // "⥐"
- { "⥞" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HVStretch }, // "⥞"
- { "↽" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HVStretch }, // "↽"
- { "⥖" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HVStretch }, // "⥖"
- { "⥟" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HVStretch }, // "⥟"
- { "⇁" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HVStretch }, // "⇁"
- { "⥗" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HVStretch }, // "⥗"
- { "⊤" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊤"
- { "↧" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::VStretch }, // "↧"
- { "∈" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∈"
- { "⩵" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⩵"
- { "≂" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≂"
- { "⇌" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "⇌"
- { "∃" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∃"
- { "∀" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∀"
- { "≥" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≥"
- { "⋛" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⋛"
- { "≧" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≧"
- { "⪢" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⪢"
- { "≷" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≷"
- { "⩾" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⩾"
- { "≳" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≳"
- { "ˇ" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::NoStretch }, // "ˇ"
- { "^" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // "^"
- { "─" , Mml::InfixForm, { 0, 0, 0, "0em", "0", 0, "0em", 0, "true" }, OperSpec::HStretch }, // "─"
- { "≎" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≎"
- { "≏" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≏"
- { "⇒" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "⇒"
- { "∫" , Mml::PrefixForm, { 0, 0, "true", "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "∫"
- { "⋂" , Mml::PrefixForm, { 0, 0, "true", "0em", 0, "true", "thinmathspace", 0, "true" }, OperSpec::HVStretch }, // "⋂"
- { "⁣" , Mml::InfixForm, { 0, 0, 0, "0em", 0, 0, "0em", "true", 0 }, OperSpec::NoStretch }, // "⁣"
- { "⁢" , Mml::InfixForm, { 0, 0, 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "⁢"
- { "⟨" , Mml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // "⟨"
- { "←" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "←"
- { "⇤" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "⇤"
- { "⇆" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "⇆"
- { "&LeftBracketingBar;" , Mml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // "&LeftBracketingBar;"
- { "⌈" , Mml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // "⌈"
- { "⟦" , Mml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // "⟦"
- { "&LeftDoubleBracketingBar;" , Mml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // &LeftDoubleBracketingBar;"
- { "⥡" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HVStretch }, // "⥡"
- { "⇃" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HVStretch }, // "⇃"
- { "⥙" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HVStretch }, // "⥙"
- { "⌊" , Mml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // "⌊"
- { "↔" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "↔"
- { "⥎" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "⥎"
- { "&LeftSkeleton;" , Mml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "&LeftSkeleton;"
- { "⊣" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊣"
- { "↤" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "↤"
- { "⥚" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "⥚"
- { "⊲" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊲"
- { "⧏" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⧏"
- { "⊴" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊴"
- { "⥑" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HVStretch }, // "⥑"
- { "⥠" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HVStretch }, // "⥠"
- { "↿" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HVStretch }, // "↿"
- { "⥘" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HVStretch }, // "⥘"
- { "↼" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "↼"
- { "⥒" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::VStretch }, // "⥒"
- { "⋚" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⋚"
- { "≦" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≦"
- { "≶" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≶"
- { "⪡" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⪡"
- { "⩽" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⩽"
- { "≲" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≲"
- { "⟵" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HStretch }, // "⟵"
- { "⟷" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HStretch }, // "⟷"
- { "⟶" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HStretch }, // "⟶"
- { "↙" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HVStretch }, // "↙"
- { "↘" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HVStretch }, // "↘"
- { "∓" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "veryverythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "∓"
- { "≫" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // ≫"
- { "≪" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≪"
- { "⫬" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⫬"
- { "≢" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≢"
- { "≭" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≭"
- { "∦" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // ∦"
- { "∉" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∉"
- { "≠" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≠"
- { "≂̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≂̸"
- { "∄" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∄"
- { "≯" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≯"
- { "≱" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≱"
- { "≧̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≧̸"
- { "≫̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≫̸"
- { "≹" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≹"
- { "⩾̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // ⩾̸"
- { "≵" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≵"
- { "≎̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≎̸"
- { "≏̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≏̸"
- { "⋪" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⋪"
- { "⧏̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⧏̸"
- { "⋬" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // ⋬"
- { "≮" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≮"
- { "≰" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≰"
- { "&NotLessFullEqual;" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "&NotLessFullEqual;"
- { "≸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≸"
- { "≪̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≪̸"
- { "⩽̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⩽̸"
- { "≴" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≴"
- { "⪢̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // ⪢̸"
- { "⪡̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⪡̸"
- { "⊀" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊀"
- { "⪯̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⪯̸"
- { "⋠" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // ⋠"
- { "&NotPrecedesTilde;" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "&NotPrecedesTilde;"
- { "∌" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∌"
- { "⋫" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⋫"
- { "⧐̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⧐̸"
- { "⋭" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // ⋭"
- { "⊏̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊏̸"
- { "⋢" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // ⋢"
- { "⊐̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊐̸"
- { "⋣" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // ⋣"
- { "⊂⃒" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊂⃒"
- { "⊈" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊈"
- { "⊁" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊁"
- { "⪰̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⪰̸"
- { "⋡" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // ⋡"
- { "≿̸" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≿̸"
- { "⊃⃒" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊃⃒"
- { "⊉" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊉"
- { "≁" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≁"
- { "≄" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≄"
- { "≇" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≇"
- { "≉" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≉"
- { "∤" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∤"
- { "“" , Mml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // “"
- { "‘" , Mml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "‘"
- { "⩔" , Mml::InfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "mediummathspace", 0, "true" }, OperSpec::VStretch }, // "⩔"
- { "‾" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // "‾"
- { "⏞" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // "⏞"
- { "⎴" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // "⎴"
- { "⏜" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // "⏜"
- { "∂" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "∂"
- { "±" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "veryverythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "±"
- { "≺" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≺"
- { "⪯" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⪯"
- { "≼" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≼"
- { "≾" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≾"
- { "∏" , Mml::PrefixForm, { 0, 0, "true", "0em", 0, "true", "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "∏"
- { "∷" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∷"
- { "∝" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∝"
- { "∋" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∋"
- { "⇋" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "⇋"
- { "⥯" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HStretch }, // ⥯"
- { "⟩" , Mml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // "⟩"
- { "→" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "→"
- { "⇥" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "⇥"
- { "⇄" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "⇄"
- { "&RightBracketingBar;" , Mml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // "&RightBracketingBar;"
- { "⌉" , Mml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // "⌉"
- { "⟧" , Mml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // "⟧"
- { "&RightDoubleBracketingBar;" , Mml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // &RightDoubleBracketingBar;"
- { "⥝" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HVStretch }, // "⥝"
- { "⇂" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HVStretch }, // "⇂"
- { "⥕" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HVStretch }, // "⥕"
- { "⌋" , Mml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // "⌋"
- { "&RightSkeleton;" , Mml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "&RightSkeleton;"
- { "⊢" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊢"
- { "↦" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "↦"
- { "⥛" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "⥛"
- { "⊳" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊳"
- { "⧐" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⧐"
- { "⊵" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊵"
- { "⥏" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::VStretch }, // "⥏"
- { "⥜" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HVStretch }, // "⥜"
- { "↾" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HVStretch }, // "↾"
- { "⥔" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::HVStretch }, // "⥔"
- { "⇀" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "⇀"
- { "⥓" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HStretch }, // "⥓"
- { "⥰" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⥰"
- { "↓" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "↓"
- { "←" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::HStretch }, // "←"
- { "→" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::HStretch }, // "→"
- { "↑" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::VStretch }, // "↑"
- { "∘" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "∘"
- { "√" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::VStretch }, // "√"
- { "□" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "□"
- { "⊓" , Mml::InfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "mediummathspace", 0, "true" }, OperSpec::HVStretch }, // "⊓"
- { "⊏" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊏"
- { "⊑" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊑"
- { "⊐" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊐"
- { "⊒" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊒"
- { "⊔" , Mml::InfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "mediummathspace", 0, "true" }, OperSpec::HVStretch }, // "⊔"
- { "⋆" , Mml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "⋆"
- { "⋐" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⋐"
- { "⊆" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊆"
- { "≻" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≻"
- { "⪰" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⪰"
- { "≽" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≽"
- { "≿" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≿"
- { "∋" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∋"
- { "∑" , Mml::PrefixForm, { 0, 0, "true", "0em", 0, "true", "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "∑"
- { "⊃" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊃"
- { "⊇" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊇"
- { "∴" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∴"
- { "∼" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∼"
- { "≃" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≃"
- { "≅" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≅"
- { "≈" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≈"
- { "⃛" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "⃛"
- { "_" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // "_"
- { "⏟" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // "⏟"
- { "⎵" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // "⎵"
- { "⏝" , Mml::PostfixForm, { "true", 0, 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::HStretch }, // "⏝"
- { "⋃" , Mml::PrefixForm, { 0, 0, "true", "0em", 0, "true", "thinmathspace", 0, "true" }, OperSpec::HVStretch }, // "⋃"
- { "⊎" , Mml::PrefixForm, { 0, 0, "true", "0em", 0, "true", "thinmathspace", 0, "true" }, OperSpec::HVStretch }, // "⊎"
- { "↑" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::VStretch }, // "↑"
- { "⤒" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::VStretch }, // "⤒"
- { "⇅" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::VStretch }, // "⇅"
- { "↕" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::VStretch }, // "↕"
- { "⥮" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::VStretch }, // "⥮"
- { "⊥" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "⊥"
- { "↥" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, "true" }, OperSpec::VStretch }, // "↥"
- { "↖" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HVStretch }, // "↖"
- { "↗" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::HVStretch }, // "↗"
- { "⋁" , Mml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "⋁"
- { "∣" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "∣"
- { "|" , Mml::InfixForm, { 0, 0, 0, "0em", "0", 0, "0em", 0, "true" }, OperSpec::VStretch }, // "|"
- { "❘" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::VStretch }, // "❘"
- { "≀" , Mml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "≀"
- { "⋀" , Mml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "⋀"
- { "&" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "&"
- { "&&" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "&&"
- { "≤" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "≤"
- { "<" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "<"
- { "<=" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "<="
- { "<>" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "<>"
- { "'" , Mml::PostfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "'"
- { "(" , Mml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // "("
- { ")" , Mml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // ")"
- { "*" , Mml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "*"
- { "**" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "**"
- { "*=" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "*="
- { "+" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "+"
- { "+" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "veryverythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "+"
- { "++" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "++"
- { "+=" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "+="
- { "," , Mml::InfixForm, { 0, 0, 0, "0em", 0, 0, "verythickmathspace", "true", 0 }, OperSpec::NoStretch }, // ","
- { "-" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "-"
- { "-" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "veryverythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "-"
- { "--" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "--"
- { "-=" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "-="
- { "->" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "->"
- { "." , Mml::InfixForm, { 0, 0, 0, "0em", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "."
- { ".." , Mml::PostfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // ".."
- { "..." , Mml::PostfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "0em", 0, 0 }, OperSpec::NoStretch }, // "..."
- { "/" , Mml::InfixForm, { 0, 0, 0, "thinmathspace", 0, 0, "thinmathspace", 0, "true" }, OperSpec::VStretch }, // "/"
- { "//" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "//"
- { "/=" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "/="
- { ":" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // ":"
- { ":=" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // ":="
- { ";" , Mml::InfixForm, { 0, 0, 0, "0em", 0, 0, "verythickmathspace", "true", 0 }, OperSpec::NoStretch }, // ";"
- { ";" , Mml::PostfixForm, { 0, 0, 0, "0em", 0, 0, "0em", "true", 0 }, OperSpec::NoStretch }, // ";"
- { "=" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "="
- { "==" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // "=="
- { ">" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // ">"
- { ">=" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, 0 }, OperSpec::NoStretch }, // ">="
- { "?" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "?"
- { "@" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "@"
- { "[" , Mml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // "["
- { "]" , Mml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // "]"
- { "^" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "^"
- { "_" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "_"
- { "lim" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, "true", "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "lim"
- { "max" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, "true", "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "max"
- { "min" , Mml::PrefixForm, { 0, 0, 0, "0em", 0, "true", "thinmathspace", 0, 0 }, OperSpec::NoStretch }, // "min"
- { "{" , Mml::PrefixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // "{"
- { "|" , Mml::InfixForm, { 0, 0, 0, "thickmathspace", 0, 0, "thickmathspace", 0, "true" }, OperSpec::VStretch }, // "|"
- { "||" , Mml::InfixForm, { 0, 0, 0, "mediummathspace", 0, 0, "mediummathspace", 0, 0 }, OperSpec::NoStretch }, // "||"
- { "}" , Mml::PostfixForm, { 0, "true", 0, "0em", 0, 0, "0em", 0, "true" }, OperSpec::VStretch }, // "}"
- { "~" , Mml::InfixForm, { 0, 0, 0, "verythinmathspace", 0, 0, "verythinmathspace", 0, 0 }, OperSpec::NoStretch }, // "~"
-
- { 0 , Mml::InfixForm, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, OperSpec::NoStretch }
-};
-
-static const OperSpec g_oper_spec_defaults =
- { 0 , Mml::InfixForm, { "false", "false", "false", "thickmathspace", "1", "false", "thickmathspace", "false", "false" }, OperSpec::NoStretch };
-
-static const uint g_oper_spec_count = sizeof(g_oper_spec_data)/sizeof(OperSpec) - 1;
-
-static const EntitySpec g_xml_entity_data[] = {
- { "angzarr", "⍼" },
- { "cirmid", "⫯" },
- { "cudarrl", "⤸" },
- { "cudarrr", "⤵" },
- { "cularr", "↶" },
- { "cularrp", "⤽" },
- { "curarr", "↷" },
- { "curarrm", "⤼" },
- { "Darr", "↡" },
- { "dArr", "⇓" },
- { "ddarr", "⇊" },
- { "DDotrahd", "⤑" },
- { "dfisht", "⥿" },
- { "dHar", "⥥" },
- { "dharl", "⇃" },
- { "dharr", "⇂" },
- { "duarr", "⇵" },
- { "duhar", "⥯" },
- { "dzigrarr", "⟿" },
- { "erarr", "⥱" },
- { "hArr", "⇔" },
- { "harr", "↔" },
- { "harrcir", "⥈" },
- { "harrw", "↭" },
- { "hoarr", "⇿" },
- { "imof", "⊷" },
- { "lAarr", "⇚" },
- { "Larr", "↞" },
- { "larrbfs", "⤟" },
- { "larrfs", "⤝" },
- { "larrhk", "↩" },
- { "larrlp", "↫" },
- { "larrpl", "⤹" },
- { "larrsim", "⥳" },
- { "larrtl", "↢" },
- { "lAtail", "⤛" },
- { "latail", "⤙" },
- { "lBarr", "⤎" },
- { "lbarr", "⤌" },
- { "ldca", "⤶" },
- { "ldrdhar", "⥧" },
- { "ldrushar", "⥋" },
- { "ldsh", "↲" },
- { "lfisht", "⥼" },
- { "lHar", "⥢" },
- { "lhard", "↽" },
- { "lharu", "↼" },
- { "lharul", "⥪" },
- { "llarr", "⇇" },
- { "llhard", "⥫" },
- { "loarr", "⇽" },
- { "lrarr", "⇆" },
- { "lrhar", "⇋" },
- { "lrhard", "⥭" },
- { "lsh", "↰" },
- { "lurdshar", "⥊" },
- { "luruhar", "⥦" },
- { "Map", "⤅" },
- { "map", "↦" },
- { "midcir", "⫰" },
- { "mumap", "⊸" },
- { "nearhk", "⤤" },
- { "neArr", "⇗" },
- { "nearr", "↗" },
- { "nesear", "⤨" },
- { "nhArr", "⇎" },
- { "nharr", "↮" },
- { "nlArr", "⇍" },
- { "nlarr", "↚" },
- { "nrArr", "⇏" },
- { "nrarr", "↛" },
- { "nrarrc", "⤳̸" },
- { "nrarrw", "↝̸" },
- { "nvHarr", "⤄" },
- { "nvlArr", "⤂" },
- { "nvrArr", "⤃" },
- { "nwarhk", "⤣" },
- { "nwArr", "⇖" },
- { "nwarr", "↖" },
- { "nwnear", "⤧" },
- { "olarr", "↺" },
- { "orarr", "↻" },
- { "origof", "⊶" },
- { "rAarr", "⇛" },
- { "Rarr", "↠" },
- { "rarrap", "⥵" },
- { "rarrbfs", "⤠" },
- { "rarrc", "⤳" },
- { "rarrfs", "⤞" },
- { "rarrhk", "↪" },
- { "rarrlp", "↬" },
- { "rarrpl", "⥅" },
- { "rarrsim", "⥴" },
- { "Rarrtl", "⤖" },
- { "rarrtl", "↣" },
- { "rarrw", "↝" },
- { "rAtail", "⤜" },
- { "ratail", "⤚" },
- { "RBarr", "⤐" },
- { "rBarr", "⤏" },
- { "rbarr", "⤍" },
- { "rdca", "⤷" },
- { "rdldhar", "⥩" },
- { "rdsh", "↳" },
- { "rfisht", "⥽" },
- { "rHar", "⥤" },
- { "rhard", "⇁" },
- { "rharu", "⇀" },
- { "rharul", "⥬" },
- { "rlarr", "⇄" },
- { "rlhar", "⇌" },
- { "roarr", "⇾" },
- { "rrarr", "⇉" },
- { "rsh", "↱" },
- { "ruluhar", "⥨" },
- { "searhk", "⤥" },
- { "seArr", "⇘" },
- { "searr", "↘" },
- { "seswar", "⤩" },
- { "simrarr", "⥲" },
- { "slarr", "←" },
- { "srarr", "→" },
- { "swarhk", "⤦" },
- { "swArr", "⇙" },
- { "swarr", "↙" },
- { "swnwar", "⤪" },
- { "Uarr", "↟" },
- { "uArr", "⇑" },
- { "Uarrocir", "⥉" },
- { "udarr", "⇅" },
- { "udhar", "⥮" },
- { "ufisht", "⥾" },
- { "uHar", "⥣" },
- { "uharl", "↿" },
- { "uharr", "↾" },
- { "uuarr", "⇈" },
- { "vArr", "⇕" },
- { "varr", "↕" },
- { "xhArr", "⟺" },
- { "xharr", "⟷" },
- { "xlArr", "⟸" },
- { "xlarr", "⟵" },
- { "xmap", "⟼" },
- { "xrArr", "⟹" },
- { "xrarr", "⟶" },
- { "zigrarr", "⇝" },
- { "ac", "∾" },
- { "acE", "∾̳" },
- { "amalg", "⨿" },
- { "barvee", "⊽" },
- { "Barwed", "⌆" },
- { "barwed", "⌅" },
- { "bsolb", "⧅" },
- { "Cap", "⋒" },
- { "capand", "⩄" },
- { "capbrcup", "⩉" },
- { "capcap", "⩋" },
- { "capcup", "⩇" },
- { "capdot", "⩀" },
- { "caps", "∩︀" },
- { "ccaps", "⩍" },
- { "ccups", "⩌" },
- { "ccupssm", "⩐" },
- { "coprod", "∐" },
- { "Cup", "⋓" },
- { "cupbrcap", "⩈" },
- { "cupcap", "⩆" },
- { "cupcup", "⩊" },
- { "cupdot", "⊍" },
- { "cupor", "⩅" },
- { "cups", "∪︀" },
- { "cuvee", "⋎" },
- { "cuwed", "⋏" },
- { "Dagger", "‡" },
- { "dagger", "†" },
- { "diam", "⋄" },
- { "divonx", "⋇" },
- { "eplus", "⩱" },
- { "hercon", "⊹" },
- { "intcal", "⊺" },
- { "iprod", "⨼" },
- { "loplus", "⨭" },
- { "lotimes", "⨴" },
- { "lthree", "⋋" },
- { "ltimes", "⋉" },
- { "midast", "*" },
- { "minusb", "⊟" },
- { "minusd", "∸" },
- { "minusdu", "⨪" },
- { "ncap", "⩃" },
- { "ncup", "⩂" },
- { "oast", "⊛" },
- { "ocir", "⊚" },
- { "odash", "⊝" },
- { "odiv", "⨸" },
- { "odot", "⊙" },
- { "odsold", "⦼" },
- { "ofcir", "⦿" },
- { "ogt", "⧁" },
- { "ohbar", "⦵" },
- { "olcir", "⦾" },
- { "olt", "⧀" },
- { "omid", "⦶" },
- { "ominus", "⊖" },
- { "opar", "⦷" },
- { "operp", "⦹" },
- { "oplus", "⊕" },
- { "osol", "⊘" },
- { "Otimes", "⨷" },
- { "otimes", "⊗" },
- { "otimesas", "⨶" },
- { "ovbar", "⌽" },
- { "plusacir", "⨣" },
- { "plusb", "⊞" },
- { "pluscir", "⨢" },
- { "plusdo", "∔" },
- { "plusdu", "⨥" },
- { "pluse", "⩲" },
- { "plussim", "⨦" },
- { "plustwo", "⨧" },
- { "prod", "∏" },
- { "race", "⧚" },
- { "roplus", "⨮" },
- { "rotimes", "⨵" },
- { "rthree", "⋌" },
- { "rtimes", "⋊" },
- { "sdot", "⋅" },
- { "sdotb", "⊡" },
- { "setmn", "∖" },
- { "simplus", "⨤" },
- { "smashp", "⨳" },
- { "solb", "⧄" },
- { "sqcap", "⊓" },
- { "sqcaps", "⊓︀" },
- { "sqcup", "⊔" },
- { "sqcups", "⊔︀" },
- { "ssetmn", "∖" },
- { "sstarf", "⋆" },
- { "subdot", "⪽" },
- { "sum", "∑" },
- { "supdot", "⪾" },
- { "timesb", "⊠" },
- { "timesbar", "⨱" },
- { "timesd", "⨰" },
- { "tridot", "◬" },
- { "triminus", "⨺" },
- { "triplus", "⨹" },
- { "trisb", "⧍" },
- { "tritime", "⨻" },
- { "uplus", "⊎" },
- { "veebar", "⊻" },
- { "wedbar", "⩟" },
- { "wreath", "≀" },
- { "xcap", "⋂" },
- { "xcirc", "◯" },
- { "xcup", "⋃" },
- { "xdtri", "▽" },
- { "xodot", "⨀" },
- { "xoplus", "⨁" },
- { "xotime", "⨂" },
- { "xsqcup", "⨆" },
- { "xuplus", "⨄" },
- { "xutri", "△" },
- { "xvee", "⋁" },
- { "xwedge", "⋀" },
- { "dlcorn", "⌞" },
- { "drcorn", "⌟" },
- { "gtlPar", "⦕" },
- { "langd", "⦑" },
- { "lbrke", "⦋" },
- { "lbrksld", "⦏" },
- { "lbrkslu", "⦍" },
- { "lceil", "⌈" },
- { "lfloor", "⌊" },
- { "lmoust", "⎰" },
- { "lparlt", "⦓" },
- { "ltrPar", "⦖" },
- { "rangd", "⦒" },
- { "rbrke", "⦌" },
- { "rbrksld", "⦎" },
- { "rbrkslu", "⦐" },
- { "rceil", "⌉" },
- { "rfloor", "⌋" },
- { "rmoust", "⎱" },
- { "rpargt", "⦔" },
- { "ulcorn", "⌜" },
- { "urcorn", "⌝" },
- { "gnap", "⪊" },
- { "gnE", "≩" },
- { "gne", "⪈" },
- { "gnsim", "⋧" },
- { "gvnE", "≩︀" },
- { "lnap", "⪉" },
- { "lnE", "≨" },
- { "lne", "⪇" },
- { "lnsim", "⋦" },
- { "lvnE", "≨︀" },
- { "nap", "≉" },
- { "napE", "⩰̸" },
- { "napid", "≋̸" },
- { "ncong", "≇" },
- { "ncongdot", "⩭̸" },
- { "nequiv", "≢" },
- { "ngE", "≧̸" },
- { "nge", "≱" },
- { "nges", "⩾̸" },
- { "nGg", "⋙̸" },
- { "ngsim", "≵" },
- { "nGt", "≫⃒" },
- { "ngt", "≯" },
- { "nGtv", "≫̸" },
- { "nlE", "≦̸" },
- { "nle", "≰" },
- { "nles", "⩽̸" },
- { "nLl", "⋘̸" },
- { "nlsim", "≴" },
- { "nLt", "≪⃒" },
- { "nlt", "≮" },
- { "nltri", "⋪" },
- { "nltrie", "⋬" },
- { "nLtv", "≪̸" },
- { "nmid", "∤" },
- { "npar", "∦" },
- { "npr", "⊀" },
- { "nprcue", "⋠" },
- { "npre", "⪯̸" },
- { "nrtri", "⋫" },
- { "nrtrie", "⋭" },
- { "nsc", "⊁" },
- { "nsccue", "⋡" },
- { "nsce", "⪰̸" },
- { "nsim", "≁" },
- { "nsime", "≄" },
- { "nsmid", "∤" },
- { "nspar", "∦" },
- { "nsqsube", "⋢" },
- { "nsqsupe", "⋣" },
- { "nsub", "⊄" },
- { "nsubE", "⫅̸" },
- { "nsube", "⊈" },
- { "nsup", "⊅" },
- { "nsupE", "⫆̸" },
- { "nsupe", "⊉" },
- { "ntgl", "≹" },
- { "ntlg", "≸" },
- { "nvap", "≍⃒" },
- { "nVDash", "⊯" },
- { "nVdash", "⊮" },
- { "nvDash", "⊭" },
- { "nvdash", "⊬" },
- { "nvge", "≥⃒" },
- { "nvgt", ">⃒" },
- { "nvle", "≤⃒" },
- { "nvlt", "<⃒" },
- { "nvltrie", "⊴⃒" },
- { "nvrtrie", "⊵⃒" },
- { "nvsim", "∼⃒" },
- { "parsim", "⫳" },
- { "prnap", "⪹" },
- { "prnE", "⪵" },
- { "prnsim", "⋨" },
- { "rnmid", "⫮" },
- { "scnap", "⪺" },
- { "scnE", "⪶" },
- { "scnsim", "⋩" },
- { "simne", "≆" },
- { "solbar", "⌿" },
- { "subnE", "⫋" },
- { "subne", "⊊" },
- { "supnE", "⫌" },
- { "supne", "⊋" },
- { "vnsub", "⊂⃒" },
- { "vnsup", "⊃⃒" },
- { "vsubnE", "⫋︀" },
- { "vsubne", "⊊︀" },
- { "vsupnE", "⫌︀" },
- { "vsupne", "⊋︀" },
- { "ang", "∠" },
- { "ange", "⦤" },
- { "angmsd", "∡" },
- { "angmsdaa", "⦨" },
- { "angmsdab", "⦩" },
- { "angmsdac", "⦪" },
- { "angmsdad", "⦫" },
- { "angmsdae", "⦬" },
- { "angmsdaf", "⦭" },
- { "angmsdag", "⦮" },
- { "angmsdah", "⦯" },
- { "angrtvb", "⊾" },
- { "angrtvbd", "⦝" },
- { "bbrk", "⎵" },
- { "bemptyv", "⦰" },
- { "beth", "ℶ" },
- { "boxbox", "⧉" },
- { "bprime", "‵" },
- { "bsemi", "⁏" },
- { "cemptyv", "⦲" },
- { "cirE", "⧃" },
- { "cirscir", "⧂" },
- { "comp", "∁" },
- { "daleth", "ℸ" },
- { "demptyv", "⦱" },
- { "ell", "ℓ" },
- { "empty", "∅" },
- { "emptyv", "∅" },
- { "gimel", "ℷ" },
- { "iiota", "℩" },
- { "image", "ℑ" },
- { "imath", "ı" },
- { "jmath", "j" },
- { "laemptyv", "⦴" },
- { "lltri", "◺" },
- { "lrtri", "⊿" },
- { "mho", "℧" },
- { "nang", "∠⃒" },
- { "nexist", "∄" },
- { "oS", "Ⓢ" },
- { "planck", "ℏ" },
- { "plankv", "ℏ" },
- { "raemptyv", "⦳" },
- { "range", "⦥" },
- { "real", "ℜ" },
- { "tbrk", "⎴" },
- { "ultri", "◸" },
- { "urtri", "◹" },
- { "vzigzag", "⦚" },
- { "weierp", "℘" },
- { "apE", "⩰" },
- { "ape", "≊" },
- { "apid", "≋" },
- { "asymp", "≈" },
- { "Barv", "⫧" },
- { "bcong", "≌" },
- { "bepsi", "϶" },
- { "bowtie", "⋈" },
- { "bsim", "∽" },
- { "bsime", "⋍" },
- { "bsolhsub", "\⊂" },
- { "bump", "≎" },
- { "bumpE", "⪮" },
- { "bumpe", "≏" },
- { "cire", "≗" },
- { "Colon", "∷" },
- { "Colone", "⩴" },
- { "colone", "≔" },
- { "congdot", "⩭" },
- { "csub", "⫏" },
- { "csube", "⫑" },
- { "csup", "⫐" },
- { "csupe", "⫒" },
- { "cuepr", "⋞" },
- { "cuesc", "⋟" },
- { "Dashv", "⫤" },
- { "dashv", "⊣" },
- { "easter", "⩮" },
- { "ecir", "≖" },
- { "ecolon", "≕" },
- { "eDDot", "⩷" },
- { "eDot", "≑" },
- { "efDot", "≒" },
- { "eg", "⪚" },
- { "egs", "⪖" },
- { "egsdot", "⪘" },
- { "el", "⪙" },
- { "els", "⪕" },
- { "elsdot", "⪗" },
- { "equest", "≟" },
- { "equivDD", "⩸" },
- { "erDot", "≓" },
- { "esdot", "≐" },
- { "Esim", "⩳" },
- { "esim", "≂" },
- { "fork", "⋔" },
- { "forkv", "⫙" },
- { "frown", "⌢" },
- { "gap", "⪆" },
- { "gE", "≧" },
- { "gEl", "⪌" },
- { "gel", "⋛" },
- { "ges", "⩾" },
- { "gescc", "⪩" },
- { "gesdot", "⪀" },
- { "gesdoto", "⪂" },
- { "gesdotol", "⪄" },
- { "gesl", "⋛︀" },
- { "gesles", "⪔" },
- { "Gg", "⋙" },
- { "gl", "≷" },
- { "gla", "⪥" },
- { "glE", "⪒" },
- { "glj", "⪤" },
- { "gsim", "≳" },
- { "gsime", "⪎" },
- { "gsiml", "⪐" },
- { "Gt", "≫" },
- { "gtcc", "⪧" },
- { "gtcir", "⩺" },
- { "gtdot", "⋗" },
- { "gtquest", "⩼" },
- { "gtrarr", "⥸" },
- { "homtht", "∻" },
- { "lap", "⪅" },
- { "lat", "⪫" },
- { "late", "⪭" },
- { "lates", "⪭︀" },
- { "lE", "≦" },
- { "lEg", "⪋" },
- { "leg", "⋚" },
- { "les", "⩽" },
- { "lescc", "⪨" },
- { "lesdot", "⩿" },
- { "lesdoto", "⪁" },
- { "lesdotor", "⪃" },
- { "lesg", "⋚︀" },
- { "lesges", "⪓" },
- { "lg", "≶" },
- { "lgE", "⪑" },
- { "Ll", "⋘" },
- { "lsim", "≲" },
- { "lsime", "⪍" },
- { "lsimg", "⪏" },
- { "Lt", "≪" },
- { "ltcc", "⪦" },
- { "ltcir", "⩹" },
- { "ltdot", "⋖" },
- { "ltlarr", "⥶" },
- { "ltquest", "⩻" },
- { "ltrie", "⊴" },
- { "mcomma", "⨩" },
- { "mDDot", "∺" },
- { "mid", "∣" },
- { "mlcp", "⫛" },
- { "models", "⊧" },
- { "mstpos", "∾" },
- { "Pr", "⪻" },
- { "pr", "≺" },
- { "prap", "⪷" },
- { "prcue", "≼" },
- { "prE", "⪳" },
- { "pre", "⪯" },
- { "prsim", "≾" },
- { "prurel", "⊰" },
- { "ratio", "∶" },
- { "rtrie", "⊵" },
- { "rtriltri", "⧎" },
- { "Sc", "⪼" },
- { "sc", "≻" },
- { "scap", "⪸" },
- { "sccue", "≽" },
- { "scE", "⪴" },
- { "sce", "⪰" },
- { "scsim", "≿" },
- { "sdote", "⩦" },
- { "simg", "⪞" },
- { "simgE", "⪠" },
- { "siml", "⪝" },
- { "simlE", "⪟" },
- { "smid", "∣" },
- { "smile", "⌣" },
- { "smt", "⪪" },
- { "smte", "⪬" },
- { "smtes", "⪬︀" },
- { "spar", "∥" },
- { "sqsub", "⊏" },
- { "sqsube", "⊑" },
- { "sqsup", "⊐" },
- { "sqsupe", "⊒" },
- { "Sub", "⋐" },
- { "subE", "⫅" },
- { "subedot", "⫃" },
- { "submult", "⫁" },
- { "subplus", "⪿" },
- { "subrarr", "⥹" },
- { "subsim", "⫇" },
- { "subsub", "⫕" },
- { "subsup", "⫓" },
- { "Sup", "⋑" },
- { "supdsub", "⫘" },
- { "supE", "⫆" },
- { "supedot", "⫄" },
- { "suphsol", "⊅" },
- { "suphsub", "⫗" },
- { "suplarr", "⥻" },
- { "supmult", "⫂" },
- { "supplus", "⫀" },
- { "supsim", "⫈" },
- { "supsub", "⫔" },
- { "supsup", "⫖" },
- { "thkap", "≈" },
- { "topfork", "⫚" },
- { "trie", "≜" },
- { "twixt", "≬" },
- { "Vbar", "⫫" },
- { "vBar", "⫨" },
- { "vBarv", "⫩" },
- { "VDash", "⊫" },
- { "Vdash", "⊩" },
- { "vDash", "⊨" },
- { "vdash", "⊢" },
- { "Vdashl", "⫦" },
- { "vltri", "⊲" },
- { "vprop", "∝" },
- { "vrtri", "⊳" },
- { "Vvdash", "⊪" },
- { "alpha", "α" },
- { "beta", "β" },
- { "chi", "χ" },
- { "Delta", "Δ" },
- { "delta", "δ" },
- { "epsi", "ε" },
- { "epsiv", "ɛ" },
- { "eta", "η" },
- { "Gamma", "Γ" },
- { "gamma", "γ" },
- { "Gammad", "Ϝ" },
- { "gammad", "ϝ" },
- { "iota", "ι" },
- { "kappa", "κ" },
- { "kappav", "ϰ" },
- { "Lambda", "Λ" },
- { "lambda", "λ" },
- { "mu", "μ" },
- { "nu", "ν" },
- { "Omega", "Ω" },
- { "omega", "ω" },
- { "Phi", "Φ" },
- { "phi", "ϕ" },
- { "phiv", "φ" },
- { "Pi", "Π" },
- { "pi", "π" },
- { "piv", "ϖ" },
- { "Psi", "Ψ" },
- { "psi", "ψ" },
- { "rho", "ρ" },
- { "rhov", "ϱ" },
- { "Sigma", "Σ" },
- { "sigma", "σ" },
- { "sigmav", "ς" },
- { "tau", "τ" },
- { "Theta", "Θ" },
- { "theta", "θ" },
- { "thetav", "ϑ" },
- { "Upsi", "ϒ" },
- { "upsi", "υ" },
- { "Xi", "Ξ" },
- { "xi", "ξ" },
- { "zeta", "ζ" },
- { "Cfr", "ℭ" },
- { "Hfr", "ℌ" },
- { "Ifr", "ℑ" },
- { "Rfr", "ℜ" },
- { "Zfr", "ℨ" },
- { "Copf", "ℂ" },
- { "Hopf", "ℍ" },
- { "Nopf", "ℕ" },
- { "Popf", "ℙ" },
- { "Qopf", "ℚ" },
- { "Ropf", "ℝ" },
- { "Zopf", "ℤ" },
- { "Bscr", "ℬ" },
- { "Escr", "ℰ" },
- { "escr", "ℯ" },
- { "Fscr", "ℱ" },
- { "gscr", "ℊ" },
- { "Hscr", "ℋ" },
- { "Iscr", "ℐ" },
- { "Lscr", "ℒ" },
- { "Mscr", "ℳ" },
- { "oscr", "ℴ" },
- { "pscr", "𝓅" },
- { "Rscr", "ℛ" },
- { "acd", "∿" },
- { "aleph", "ℵ" },
- { "And", "⩓" },
- { "and", "∧" },
- { "andand", "⩕" },
- { "andd", "⩜" },
- { "andslope", "⩘" },
- { "andv", "⩚" },
- { "angrt", "∟" },
- { "angsph", "∢" },
- { "angst", "Å" },
- { "ap", "≈" },
- { "apacir", "⩯" },
- { "awconint", "∳" },
- { "awint", "⨑" },
- { "becaus", "∵" },
- { "bernou", "ℬ" },
- { "bne", "=⃥" },
- { "bnequiv", "≡⃥" },
- { "bNot", "⫭" },
- { "bnot", "⌐" },
- { "bottom", "⊥" },
- { "cap", "∩" },
- { "Cconint", "∰" },
- { "cirfnint", "⨐" },
- { "compfn", "∘" },
- { "cong", "≅" },
- { "Conint", "∯" },
- { "conint", "∮" },
- { "ctdot", "⋯" },
- { "cup", "∪" },
- { "cwconint", "∲" },
- { "cwint", "∱" },
- { "cylcty", "⌭" },
- { "disin", "⋲" },
- { "Dot", "¨" },
- { "DotDot", "⃜" },
- { "dsol", "⧶" },
- { "dtdot", "⋱" },
- { "dwangle", "⦦" },
- { "epar", "⋕" },
- { "eparsl", "⧣" },
- { "equiv", "≡" },
- { "eqvparsl", "⧥" },
- { "exist", "∃" },
- { "fnof", "ƒ" },
- { "forall", "∀" },
- { "fpartint", "⨍" },
- { "ge", "≥" },
- { "hamilt", "ℋ" },
- { "iff", "⇔" },
- { "iinfin", "⧜" },
- { "infin", "∞" },
- { "Int", "∬" },
- { "int", "∫" },
- { "intlarhk", "⨗" },
- { "isin", "∈" },
- { "isindot", "⋵" },
- { "isinE", "⋹" },
- { "isins", "⋴" },
- { "isinsv", "⋳" },
- { "isinv", "∈" },
- { "lagran", "ℒ" },
- { "Lang", "《" },
- { "lang", "〈" },
- { "lArr", "⇐" },
- { "lbbrk", "〔" },
- { "le", "≤" },
- { "loang", "〘" },
- { "lobrk", "〚" },
- { "lopar", "⦅" },
- { "lowast", "∗" },
- { "minus", "−" },
- { "mnplus", "∓" },
- { "nabla", "∇" },
- { "ne", "≠" },
- { "nedot", "≐̸" },
- { "nhpar", "⫲" },
- { "ni", "∋" },
- { "nis", "⋼" },
- { "nisd", "⋺" },
- { "niv", "∋" },
- { "Not", "⫬" },
- { "notin", "∉" },
- { "notindot", "⋵̸" },
- { "notinva", "∉" },
- { "notinvb", "⋷" },
- { "notinvc", "⋶" },
- { "notni", "∌" },
- { "notniva", "∌" },
- { "notnivb", "⋾" },
- { "notnivc", "⋽" },
- { "nparsl", "⫽⃥" },
- { "npart", "∂̸" },
- { "npolint", "⨔" },
- { "nvinfin", "⧞" },
- { "olcross", "⦻" },
- { "Or", "⩔" },
- { "or", "∨" },
- { "ord", "⩝" },
- { "order", "ℴ" },
- { "oror", "⩖" },
- { "orslope", "⩗" },
- { "orv", "⩛" },
- { "par", "∥" },
- { "parsl", "⫽" },
- { "part", "∂" },
- { "permil", "‰" },
- { "perp", "⊥" },
- { "pertenk", "‱" },
- { "phmmat", "ℳ" },
- { "pointint", "⨕" },
- { "Prime", "″" },
- { "prime", "′" },
- { "profalar", "⌮" },
- { "profline", "⌒" },
- { "profsurf", "⌓" },
- { "prop", "∝" },
- { "qint", "⨌" },
- { "qprime", "⁗" },
- { "quatint", "⨖" },
- { "radic", "√" },
- { "Rang", "》" },
- { "rang", "〉" },
- { "rArr", "⇒" },
- { "rbbrk", "〕" },
- { "roang", "〙" },
- { "robrk", "〛" },
- { "ropar", "⦆" },
- { "rppolint", "⨒" },
- { "scpolint", "⨓" },
- { "sim", "∼" },
- { "simdot", "⩪" },
- { "sime", "≃" },
- { "smeparsl", "⧤" },
- { "square", "□" },
- { "squarf", "▪" },
- { "sub", "⊂" },
- { "sube", "⊆" },
- { "sup", "⊃" },
- { "supe", "⊇" },
- { "tdot", "⃛" },
- { "there4", "∴" },
- { "tint", "∭" },
- { "top", "⊤" },
- { "topbot", "⌶" },
- { "topcir", "⫱" },
- { "tprime", "‴" },
- { "utdot", "⋰" },
- { "uwangle", "⦧" },
- { "vangrt", "⦜" },
- { "veeeq", "≚" },
- { "Verbar", "‖" },
- { "wedgeq", "≙" },
- { "xnis", "⋻" },
- { "boxDL", "╗" },
- { "boxDl", "╖" },
- { "boxdL", "╕" },
- { "boxdl", "┐" },
- { "boxDR", "╔" },
- { "boxDr", "╓" },
- { "boxdR", "╒" },
- { "boxdr", "┌" },
- { "boxH", "═" },
- { "boxh", "─" },
- { "boxHD", "╦" },
- { "boxHd", "╤" },
- { "boxhD", "╥" },
- { "boxhd", "┬" },
- { "boxHU", "╩" },
- { "boxHu", "╧" },
- { "boxhU", "╨" },
- { "boxhu", "┴" },
- { "boxUL", "╝" },
- { "boxUl", "╜" },
- { "boxuL", "╛" },
- { "boxul", "┘" },
- { "boxUR", "╚" },
- { "boxUr", "╙" },
- { "boxuR", "╘" },
- { "boxur", "└" },
- { "boxV", "║" },
- { "boxv", "│" },
- { "boxVH", "╬" },
- { "boxVh", "╫" },
- { "boxvH", "╪" },
- { "boxvh", "┼" },
- { "boxVL", "╣" },
- { "boxVl", "╢" },
- { "boxvL", "╡" },
- { "boxvl", "┤" },
- { "boxVR", "╠" },
- { "boxVr", "╟" },
- { "boxvR", "╞" },
- { "boxvr", "├" },
- { "Acy", "А" },
- { "acy", "а" },
- { "Bcy", "Б" },
- { "bcy", "б" },
- { "CHcy", "Ч" },
- { "chcy", "ч" },
- { "Dcy", "Д" },
- { "dcy", "д" },
- { "Ecy", "Э" },
- { "ecy", "э" },
- { "Fcy", "Ф" },
- { "fcy", "ф" },
- { "Gcy", "Г" },
- { "gcy", "г" },
- { "HARDcy", "Ъ" },
- { "hardcy", "ъ" },
- { "Icy", "И" },
- { "icy", "и" },
- { "IEcy", "Е" },
- { "iecy", "е" },
- { "IOcy", "Ё" },
- { "iocy", "ё" },
- { "Jcy", "Й" },
- { "jcy", "й" },
- { "Kcy", "К" },
- { "kcy", "к" },
- { "KHcy", "Х" },
- { "khcy", "х" },
- { "Lcy", "Л" },
- { "lcy", "л" },
- { "Mcy", "М" },
- { "mcy", "м" },
- { "Ncy", "Н" },
- { "ncy", "н" },
- { "numero", "№" },
- { "Ocy", "О" },
- { "ocy", "о" },
- { "Pcy", "П" },
- { "pcy", "п" },
- { "Rcy", "Р" },
- { "rcy", "р" },
- { "Scy", "С" },
- { "scy", "с" },
- { "SHCHcy", "Щ" },
- { "shchcy", "щ" },
- { "SHcy", "Ш" },
- { "shcy", "ш" },
- { "SOFTcy", "Ь" },
- { "softcy", "ь" },
- { "Tcy", "Т" },
- { "tcy", "т" },
- { "TScy", "Ц" },
- { "tscy", "ц" },
- { "Ucy", "У" },
- { "ucy", "у" },
- { "Vcy", "В" },
- { "vcy", "в" },
- { "YAcy", "Я" },
- { "yacy", "я" },
- { "Ycy", "Ы" },
- { "ycy", "ы" },
- { "YUcy", "Ю" },
- { "yucy", "ю" },
- { "Zcy", "З" },
- { "zcy", "з" },
- { "ZHcy", "Ж" },
- { "zhcy", "ж" },
- { "DJcy", "Ђ" },
- { "djcy", "ђ" },
- { "DScy", "Ѕ" },
- { "dscy", "ѕ" },
- { "DZcy", "Џ" },
- { "dzcy", "џ" },
- { "GJcy", "Ѓ" },
- { "gjcy", "ѓ" },
- { "Iukcy", "І" },
- { "iukcy", "і" },
- { "Jsercy", "Ј" },
- { "jsercy", "ј" },
- { "Jukcy", "Є" },
- { "jukcy", "є" },
- { "KJcy", "Ќ" },
- { "kjcy", "ќ" },
- { "LJcy", "Љ" },
- { "ljcy", "љ" },
- { "NJcy", "Њ" },
- { "njcy", "њ" },
- { "TSHcy", "Ћ" },
- { "tshcy", "ћ" },
- { "Ubrcy", "Ў" },
- { "ubrcy", "ў" },
- { "YIcy", "Ї" },
- { "yicy", "ї" },
- { "acute", "´" },
- { "breve", "˘" },
- { "caron", "ˇ" },
- { "cedil", "¸" },
- { "circ", "ˆ" },
- { "dblac", "˝" },
- { "die", "¨" },
- { "dot", "˙" },
- { "grave", "`" },
- { "macr", "¯" },
- { "ogon", "˛" },
- { "ring", "˚" },
- { "tilde", "˜" },
- { "uml", "¨" },
- { "Aacute", "Á" },
- { "aacute", "á" },
- { "Acirc", "Â" },
- { "acirc", "â" },
- { "AElig", "Æ" },
- { "aelig", "æ" },
- { "Agrave", "À" },
- { "agrave", "à" },
- { "Aring", "Å" },
- { "aring", "å" },
- { "Atilde", "Ã" },
- { "atilde", "ã" },
- { "Auml", "Ä" },
- { "auml", "ä" },
- { "Ccedil", "Ç" },
- { "ccedil", "ç" },
- { "Eacute", "É" },
- { "eacute", "é" },
- { "Ecirc", "Ê" },
- { "ecirc", "ê" },
- { "Egrave", "È" },
- { "egrave", "è" },
- { "ETH", "Ð" },
- { "eth", "ð" },
- { "Euml", "Ë" },
- { "euml", "ë" },
- { "Iacute", "Í" },
- { "iacute", "í" },
- { "Icirc", "Î" },
- { "icirc", "î" },
- { "Igrave", "Ì" },
- { "igrave", "ì" },
- { "Iuml", "Ï" },
- { "iuml", "ï" },
- { "Ntilde", "Ñ" },
- { "ntilde", "ñ" },
- { "Oacute", "Ó" },
- { "oacute", "ó" },
- { "Ocirc", "Ô" },
- { "ocirc", "ô" },
- { "Ograve", "Ò" },
- { "ograve", "ò" },
- { "Oslash", "Ø" },
- { "oslash", "ø" },
- { "Otilde", "Õ" },
- { "otilde", "õ" },
- { "Ouml", "Ö" },
- { "ouml", "ö" },
- { "szlig", "ß" },
- { "THORN", "Þ" },
- { "thorn", "þ" },
- { "Uacute", "Ú" },
- { "uacute", "ú" },
- { "Ucirc", "Û" },
- { "ucirc", "û" },
- { "Ugrave", "Ù" },
- { "ugrave", "ù" },
- { "Uuml", "Ü" },
- { "uuml", "ü" },
- { "Yacute", "Ý" },
- { "yacute", "ý" },
- { "yuml", "ÿ" },
- { "Abreve", "Ă" },
- { "abreve", "ă" },
- { "Amacr", "Ā" },
- { "amacr", "ā" },
- { "Aogon", "Ą" },
- { "aogon", "ą" },
- { "Cacute", "Ć" },
- { "cacute", "ć" },
- { "Ccaron", "Č" },
- { "ccaron", "č" },
- { "Ccirc", "Ĉ" },
- { "ccirc", "ĉ" },
- { "Cdot", "Ċ" },
- { "cdot", "ċ" },
- { "Dcaron", "Ď" },
- { "dcaron", "ď" },
- { "Dstrok", "Đ" },
- { "dstrok", "đ" },
- { "Ecaron", "Ě" },
- { "ecaron", "ě" },
- { "Edot", "Ė" },
- { "edot", "ė" },
- { "Emacr", "Ē" },
- { "emacr", "ē" },
- { "ENG", "Ŋ" },
- { "eng", "ŋ" },
- { "Eogon", "Ę" },
- { "eogon", "ę" },
- { "gacute", "ǵ" },
- { "Gbreve", "Ğ" },
- { "gbreve", "ğ" },
- { "Gcedil", "Ģ" },
- { "Gcirc", "Ĝ" },
- { "gcirc", "ĝ" },
- { "Gdot", "Ġ" },
- { "gdot", "ġ" },
- { "Hcirc", "Ĥ" },
- { "hcirc", "ĥ" },
- { "Hstrok", "Ħ" },
- { "hstrok", "ħ" },
- { "Idot", "İ" },
- { "IJlig", "IJ" },
- { "ijlig", "ij" },
- { "Imacr", "Ī" },
- { "imacr", "ī" },
- { "inodot", "ı" },
- { "Iogon", "Į" },
- { "iogon", "į" },
- { "Itilde", "Ĩ" },
- { "itilde", "ĩ" },
- { "Jcirc", "Ĵ" },
- { "jcirc", "ĵ" },
- { "Kcedil", "Ķ" },
- { "kcedil", "ķ" },
- { "kgreen", "ĸ" },
- { "Lacute", "Ĺ" },
- { "lacute", "ĺ" },
- { "Lcaron", "Ľ" },
- { "lcaron", "ľ" },
- { "Lcedil", "Ļ" },
- { "lcedil", "ļ" },
- { "Lmidot", "Ŀ" },
- { "lmidot", "ŀ" },
- { "Lstrok", "Ł" },
- { "lstrok", "ł" },
- { "Nacute", "Ń" },
- { "nacute", "ń" },
- { "napos", "ʼn" },
- { "Ncaron", "Ň" },
- { "ncaron", "ň" },
- { "Ncedil", "Ņ" },
- { "ncedil", "ņ" },
- { "Odblac", "Ő" },
- { "odblac", "ő" },
- { "OElig", "Œ" },
- { "oelig", "œ" },
- { "Omacr", "Ō" },
- { "omacr", "ō" },
- { "Racute", "Ŕ" },
- { "racute", "ŕ" },
- { "Rcaron", "Ř" },
- { "rcaron", "ř" },
- { "Rcedil", "Ŗ" },
- { "rcedil", "ŗ" },
- { "Sacute", "Ś" },
- { "sacute", "ś" },
- { "Scaron", "Š" },
- { "scaron", "š" },
- { "Scedil", "Ş" },
- { "scedil", "ş" },
- { "Scirc", "Ŝ" },
- { "scirc", "ŝ" },
- { "Tcaron", "Ť" },
- { "tcaron", "ť" },
- { "Tcedil", "Ţ" },
- { "tcedil", "ţ" },
- { "Tstrok", "Ŧ" },
- { "tstrok", "ŧ" },
- { "Ubreve", "Ŭ" },
- { "ubreve", "ŭ" },
- { "Udblac", "Ű" },
- { "udblac", "ű" },
- { "Umacr", "Ū" },
- { "umacr", "ū" },
- { "Uogon", "Ų" },
- { "uogon", "ų" },
- { "Uring", "Ů" },
- { "uring", "ů" },
- { "Utilde", "Ũ" },
- { "utilde", "ũ" },
- { "Wcirc", "Ŵ" },
- { "wcirc", "ŵ" },
- { "Ycirc", "Ŷ" },
- { "ycirc", "ŷ" },
- { "Yuml", "Ÿ" },
- { "Zacute", "Ź" },
- { "zacute", "ź" },
- { "Zcaron", "Ž" },
- { "zcaron", "ž" },
- { "Zdot", "Ż" },
- { "zdot", "ż" },
- { "apos", "'" },
- { "ast", "*" },
- { "brvbar", "¦" },
- { "bsol", "\" },
- { "cent", "¢" },
- { "colon", ":" },
- { "comma", "," },
- { "commat", "@" },
- { "copy", "©" },
- { "curren", "¤" },
- { "darr", "↓" },
- { "deg", "°" },
- { "divide", "÷" },
- { "dollar", "$" },
- { "equals", "=" },
- { "excl", "!" },
- { "frac12", "½" },
- { "frac14", "¼" },
- { "frac18", "⅛" },
- { "frac34", "¾" },
- { "frac38", "⅜" },
- { "frac58", "⅝" },
- { "frac78", "⅞" },
- { "gt", ">" },
- { "half", "½" },
- { "horbar", "―" },
- { "hyphen", "‐" },
- { "iexcl", "¡" },
- { "iquest", "¿" },
- { "laquo", "«" },
- { "larr", "←" },
- { "lcub", "{" },
- { "ldquo", "“" },
- { "lowbar", "_" },
- { "lpar", "(" },
- { "lsqb", "[" },
- { "lsquo", "‘" },
- { "lt", "<" },
- { "micro", "µ" },
- { "middot", "·" },
- { "nbsp", " " },
- { "not", "¬" },
- { "num", "#" },
- { "ohm", "Ω" },
- { "ordf", "ª" },
- { "ordm", "º" },
- { "para", "¶" },
- { "percnt", "%" },
- { "period", "." },
- { "plus", "+" },
- { "plusmn", "±" },
- { "pound", "£" },
- { "quest", "?" },
- { "quot", """ },
- { "raquo", "»" },
- { "rarr", "→" },
- { "rcub", "}" },
- { "rdquo", "”" },
- { "reg", "®" },
- { "rpar", ")" },
- { "rsqb", "]" },
- { "rsquo", "’" },
- { "sect", "§" },
- { "semi", ";" },
- { "shy", "­" },
- { "sol", "/" },
- { "sung", "♪" },
- { "sup1", "¹" },
- { "sup2", "²" },
- { "sup3", "³" },
- { "times", "×" },
- { "trade", "™" },
- { "uarr", "↑" },
- { "verbar", "|" },
- { "yen", "¥" },
- { "blank", "␣" },
- { "blk12", "▒" },
- { "blk14", "░" },
- { "blk34", "▓" },
- { "block", "█" },
- { "bull", "•" },
- { "caret", "⁁" },
- { "check", "✓" },
- { "cir", "○" },
- { "clubs", "♣" },
- { "copysr", "℗" },
- { "cross", "✗" },
- { "Dagger", "‡" },
- { "dagger", "†" },
- { "dash", "‐" },
- { "diams", "♦" },
- { "dlcrop", "⌍" },
- { "drcrop", "⌌" },
- { "dtri", "▿" },
- { "dtrif", "▾" },
- { "emsp", " " },
- { "emsp13", " " },
- { "emsp14", " " },
- { "ensp", " " },
- { "female", "♀" },
- { "ffilig", "ffi" },
- { "fflig", "ff" },
- { "ffllig", "ffl" },
- { "filig", "fi" },
- { "flat", "♭" },
- { "fllig", "fl" },
- { "frac13", "⅓" },
- { "frac15", "⅕" },
- { "frac16", "⅙" },
- { "frac23", "⅔" },
- { "frac25", "⅖" },
- { "frac35", "⅗" },
- { "frac45", "⅘" },
- { "frac56", "⅚" },
- { "hairsp", " " },
- { "hearts", "♥" },
- { "hellip", "…" },
- { "hybull", "⁃" },
- { "incare", "℅" },
- { "ldquor", "„" },
- { "lhblk", "▄" },
- { "loz", "◊" },
- { "lozf", "⧫" },
- { "lsquor", "‚" },
- { "ltri", "◃" },
- { "ltrif", "◂" },
- { "male", "♂" },
- { "malt", "✠" },
- { "marker", "▮" },
- { "mdash", "—" },
- { "mldr", "…" },
- { "natur", "♮" },
- { "ndash", "–" },
- { "nldr", "‥" },
- { "numsp", " " },
- { "phone", "☎" },
- { "puncsp", " " },
- { "rdquor", "”" },
- { "rect", "▭" },
- { "rsquor", "’" },
- { "rtri", "▹" },
- { "rtrif", "▸" },
- { "rx", "℞" },
- { "sext", "✶" },
- { "sharp", "♯" },
- { "spades", "♠" },
- { "squ", "□" },
- { "squf", "▪" },
- { "star", "☆" },
- { "starf", "★" },
- { "target", "⌖" },
- { "telrec", "⌕" },
- { "thinsp", " " },
- { "uhblk", "▀" },
- { "ulcrop", "⌏" },
- { "urcrop", "⌎" },
- { "utri", "▵" },
- { "utrif", "▴" },
- { "vellip", "⋮" },
- { "af", "⁡" },
- { "asympeq", "≍" },
- { "Cross", "⨯" },
- { "DD", "ⅅ" },
- { "dd", "ⅆ" },
- { "DownArrowBar", "⤓" },
- { "DownBreve", "̑" },
- { "DownLeftRightVector", "⥐" },
- { "DownLeftTeeVector", "⥞" },
- { "DownLeftVectorBar", "⥖" },
- { "DownRightTeeVector", "⥟" },
- { "DownRightVectorBar", "⥗" },
- { "ee", "ⅇ" },
- { "EmptySmallSquare", "◻" },
- { "EmptyVerySmallSquare", "▫" },
- { "Equal", "⩵" },
- { "FilledSmallSquare", "◼" },
- { "FilledVerySmallSquare", "▪" },
- { "GreaterGreater", "⪢" },
- { "Hat", "^" },
- { "HorizontalLine", "─" },
- { "ic", "⁣" },
- { "ii", "ⅈ" },
- { "it", "⁢" },
- { "larrb", "⇤" },
- { "LeftDownTeeVector", "⥡" },
- { "LeftDownVectorBar", "⥙" },
- { "LeftRightVector", "⥎" },
- { "LeftTeeVector", "⥚" },
- { "LeftTriangleBar", "⧏" },
- { "LeftUpDownVector", "⥑" },
- { "LeftUpTeeVector", "⥠" },
- { "LeftUpVectorBar", "⥘" },
- { "LeftVectorBar", "⥒" },
- { "LessLess", "⪡" },
- { "mapstodown", "↧" },
- { "mapstoleft", "↤" },
- { "mapstoup", "↥" },
- { "MediumSpace", " " },
- { "nbump", "≎̸" },
- { "nbumpe", "≏̸" },
- { "nesim", "≂̸" },
- { "NewLine", "
" },
- { "NoBreak", "⁠" },
- { "NotCupCap", "≭" },
- { "NotHumpEqual", "≏̸" },
- { "NotLeftTriangleBar", "⧏̸" },
- { "NotNestedGreaterGreater", "⪢̸" },
- { "NotNestedLessLess", "⪡̸" },
- { "NotRightTriangleBar", "⧐̸" },
- { "NotSquareSubset", "⊏̸" },
- { "NotSquareSuperset", "⊐̸" },
- { "NotSucceedsTilde", "≿̸" },
- { "OverBar", "¯" },
- { "OverBrace", "︷" },
- { "OverBracket", "⎴" },
- { "OverParenthesis", "︵" },
- { "planckh", "ℎ" },
- { "Product", "∏" },
- { "rarrb", "⇥" },
- { "RightDownTeeVector", "⥝" },
- { "RightDownVectorBar", "⥕" },
- { "RightTeeVector", "⥛" },
- { "RightTriangleBar", "⧐" },
- { "RightUpDownVector", "⥏" },
- { "RightUpTeeVector", "⥜" },
- { "RightUpVectorBar", "⥔" },
- { "RightVectorBar", "⥓" },
- { "RoundImplies", "⥰" },
- { "RuleDelayed", "⧴" },
- { "Tab", "	" },
- { "ThickSpace", "   " },
- { "UnderBar", "̲" },
- { "UnderBrace", "︸" },
- { "UnderBracket", "⎵" },
- { "UnderParenthesis", "︶" },
- { "UpArrowBar", "⤒" },
- { "Upsilon", "Υ" },
- { "VerticalLine", "|" },
- { "VerticalSeparator", "❘" },
- { "ZeroWidthSpace", "​" },
- { "angle", "∠" },
- { "ApplyFunction", "⁡" },
- { "approx", "≈" },
- { "approxeq", "≊" },
- { "Assign", "≔" },
- { "backcong", "≌" },
- { "backepsilon", "϶" },
- { "backprime", "‵" },
- { "backsim", "∽" },
- { "backsimeq", "⋍" },
- { "Backslash", "∖" },
- { "barwedge", "⌅" },
- { "Because", "∵" },
- { "because", "∵" },
- { "Bernoullis", "ℬ" },
- { "between", "≬" },
- { "bigcap", "⋂" },
- { "bigcirc", "◯" },
- { "bigcup", "⋃" },
- { "bigodot", "⨀" },
- { "bigoplus", "⨁" },
- { "bigotimes", "⨂" },
- { "bigsqcup", "⨆" },
- { "bigstar", "★" },
- { "bigtriangledown", "▽" },
- { "bigtriangleup", "△" },
- { "biguplus", "⨄" },
- { "bigvee", "⋁" },
- { "bigwedge", "⋀" },
- { "bkarow", "⤍" },
- { "blacklozenge", "⧫" },
- { "blacksquare", "▪" },
- { "blacktriangle", "▴" },
- { "blacktriangledown", "▾" },
- { "blacktriangleleft", "◂" },
- { "blacktriangleright", "▸" },
- { "bot", "⊥" },
- { "boxminus", "⊟" },
- { "boxplus", "⊞" },
- { "boxtimes", "⊠" },
- { "Breve", "˘" },
- { "bullet", "•" },
- { "Bumpeq", "≎" },
- { "bumpeq", "≏" },
- { "CapitalDifferentialD", "ⅅ" },
- { "Cayleys", "ℭ" },
- { "Cedilla", "¸" },
- { "CenterDot", "·" },
- { "centerdot", "·" },
- { "checkmark", "✓" },
- { "circeq", "≗" },
- { "circlearrowleft", "↺" },
- { "circlearrowright", "↻" },
- { "circledast", "⊛" },
- { "circledcirc", "⊚" },
- { "circleddash", "⊝" },
- { "CircleDot", "⊙" },
- { "circledR", "®" },
- { "circledS", "Ⓢ" },
- { "CircleMinus", "⊖" },
- { "CirclePlus", "⊕" },
- { "CircleTimes", "⊗" },
- { "ClockwiseContourIntegral", "∲" },
- { "CloseCurlyDoubleQuote", "”" },
- { "CloseCurlyQuote", "’" },
- { "clubsuit", "♣" },
- { "coloneq", "≔" },
- { "complement", "∁" },
- { "complexes", "ℂ" },
- { "Congruent", "≡" },
- { "ContourIntegral", "∮" },
- { "Coproduct", "∐" },
- { "CounterClockwiseContourIntegral", "∳" },
- { "CupCap", "≍" },
- { "curlyeqprec", "⋞" },
- { "curlyeqsucc", "⋟" },
- { "curlyvee", "⋎" },
- { "curlywedge", "⋏" },
- { "curvearrowleft", "↶" },
- { "curvearrowright", "↷" },
- { "dbkarow", "⤏" },
- { "ddagger", "‡" },
- { "ddotseq", "⩷" },
- { "Del", "∇" },
- { "DiacriticalAcute", "´" },
- { "DiacriticalDot", "˙" },
- { "DiacriticalDoubleAcute", "˝" },
- { "DiacriticalGrave", "`" },
- { "DiacriticalTilde", "˜" },
- { "Diamond", "⋄" },
- { "diamond", "⋄" },
- { "diamondsuit", "♦" },
- { "DifferentialD", "ⅆ" },
- { "digamma", "ϝ" },
- { "div", "÷" },
- { "divideontimes", "⋇" },
- { "doteq", "≐" },
- { "doteqdot", "≑" },
- { "DotEqual", "≐" },
- { "dotminus", "∸" },
- { "dotplus", "∔" },
- { "dotsquare", "⊡" },
- { "doublebarwedge", "⌆" },
- { "DoubleContourIntegral", "∯" },
- { "DoubleDot", "¨" },
- { "DoubleDownArrow", "⇓" },
- { "DoubleLeftArrow", "⇐" },
- { "DoubleLeftRightArrow", "⇔" },
- { "DoubleLeftTee", "⫤" },
- { "DoubleLongLeftArrow", "⟸" },
- { "DoubleLongLeftRightArrow", "⟺" },
- { "DoubleLongRightArrow", "⟹" },
- { "DoubleRightArrow", "⇒" },
- { "DoubleRightTee", "⊨" },
- { "DoubleUpArrow", "⇑" },
- { "DoubleUpDownArrow", "⇕" },
- { "DoubleVerticalBar", "∥" },
- { "DownArrow", "↓" },
- { "Downarrow", "⇓" },
- { "downarrow", "↓" },
- { "DownArrowUpArrow", "⇵" },
- { "downdownarrows", "⇊" },
- { "downharpoonleft", "⇃" },
- { "downharpoonright", "⇂" },
- { "DownLeftVector", "↽" },
- { "DownRightVector", "⇁" },
- { "DownTee", "⊤" },
- { "DownTeeArrow", "↧" },
- { "drbkarow", "⤐" },
- { "Element", "∈" },
- { "emptyset", "∅" },
- { "eqcirc", "≖" },
- { "eqcolon", "≕" },
- { "eqsim", "≂" },
- { "eqslantgtr", "⪖" },
- { "eqslantless", "⪕" },
- { "EqualTilde", "≂" },
- { "Equilibrium", "⇌" },
- { "Exists", "∃" },
- { "expectation", "ℰ" },
- { "ExponentialE", "ⅇ" },
- { "exponentiale", "ⅇ" },
- { "fallingdotseq", "≒" },
- { "ForAll", "∀" },
- { "Fouriertrf", "ℱ" },
- { "geq", "≥" },
- { "geqq", "≧" },
- { "geqslant", "⩾" },
- { "gg", "≫" },
- { "ggg", "⋙" },
- { "gnapprox", "⪊" },
- { "gneq", "⪈" },
- { "gneqq", "≩" },
- { "GreaterEqual", "≥" },
- { "GreaterEqualLess", "⋛" },
- { "GreaterFullEqual", "≧" },
- { "GreaterLess", "≷" },
- { "GreaterSlantEqual", "⩾" },
- { "GreaterTilde", "≳" },
- { "gtrapprox", "⪆" },
- { "gtrdot", "⋗" },
- { "gtreqless", "⋛" },
- { "gtreqqless", "⪌" },
- { "gtrless", "≷" },
- { "gtrsim", "≳" },
- { "gvertneqq", "≩︀" },
- { "Hacek", "ˇ" },
- { "hbar", "ℏ" },
- { "heartsuit", "♥" },
- { "HilbertSpace", "ℋ" },
- { "hksearow", "⤥" },
- { "hkswarow", "⤦" },
- { "hookleftarrow", "↩" },
- { "hookrightarrow", "↪" },
- { "hslash", "ℏ" },
- { "HumpDownHump", "≎" },
- { "HumpEqual", "≏" },
- { "iiiint", "⨌" },
- { "iiint", "∭" },
- { "Im", "ℑ" },
- { "ImaginaryI", "ⅈ" },
- { "imagline", "ℐ" },
- { "imagpart", "ℑ" },
- { "Implies", "⇒" },
- { "in", "∈" },
- { "integers", "ℤ" },
- { "Integral", "∫" },
- { "intercal", "⊺" },
- { "Intersection", "⋂" },
- { "intprod", "⨼" },
- { "InvisibleComma", "⁣" },
- { "InvisibleTimes", "⁢" },
- { "langle", "〈" },
- { "Laplacetrf", "ℒ" },
- { "lbrace", "{" },
- { "lbrack", "[" },
- { "LeftAngleBracket", "〈" },
- { "LeftArrow", "←" },
- { "Leftarrow", "⇐" },
- { "leftarrow", "←" },
- { "LeftArrowBar", "⇤" },
- { "LeftArrowRightArrow", "⇆" },
- { "leftarrowtail", "↢" },
- { "LeftCeiling", "⌈" },
- { "LeftDoubleBracket", "〚" },
- { "LeftDownVector", "⇃" },
- { "LeftFloor", "⌊" },
- { "leftharpoondown", "↽" },
- { "leftharpoonup", "↼" },
- { "leftleftarrows", "⇇" },
- { "LeftRightArrow", "↔" },
- { "Leftrightarrow", "⇔" },
- { "leftrightarrow", "↔" },
- { "leftrightarrows", "⇆" },
- { "leftrightharpoons", "⇋" },
- { "leftrightsquigarrow", "↭" },
- { "LeftTee", "⊣" },
- { "LeftTeeArrow", "↤" },
- { "leftthreetimes", "⋋" },
- { "LeftTriangle", "⊲" },
- { "LeftTriangleEqual", "⊴" },
- { "LeftUpVector", "↿" },
- { "LeftVector", "↼" },
- { "leq", "≤" },
- { "leqq", "≦" },
- { "leqslant", "⩽" },
- { "lessapprox", "⪅" },
- { "lessdot", "⋖" },
- { "lesseqgtr", "⋚" },
- { "lesseqqgtr", "⪋" },
- { "LessEqualGreater", "⋚" },
- { "LessFullEqual", "≦" },
- { "LessGreater", "≶" },
- { "lessgtr", "≶" },
- { "lesssim", "≲" },
- { "LessSlantEqual", "⩽" },
- { "LessTilde", "≲" },
- { "ll", "≪" },
- { "llcorner", "⌞" },
- { "Lleftarrow", "⇚" },
- { "lmoustache", "⎰" },
- { "lnapprox", "⪉" },
- { "lneq", "⪇" },
- { "lneqq", "≨" },
- { "LongLeftArrow", "⟵" },
- { "Longleftarrow", "⟸" },
- { "longleftarrow", "⟵" },
- { "LongLeftRightArrow", "⟷" },
- { "Longleftrightarrow", "⟺" },
- { "longleftrightarrow", "⟷" },
- { "longmapsto", "⟼" },
- { "LongRightArrow", "⟶" },
- { "Longrightarrow", "⟹" },
- { "longrightarrow", "⟶" },
- { "looparrowleft", "↫" },
- { "looparrowright", "↬" },
- { "LowerLeftArrow", "↙" },
- { "LowerRightArrow", "↘" },
- { "lozenge", "◊" },
- { "lrcorner", "⌟" },
- { "Lsh", "↰" },
- { "lvertneqq", "≨︀" },
- { "maltese", "✠" },
- { "mapsto", "↦" },
- { "measuredangle", "∡" },
- { "Mellintrf", "ℳ" },
- { "MinusPlus", "∓" },
- { "mp", "∓" },
- { "multimap", "⊸" },
- { "napprox", "≉" },
- { "natural", "♮" },
- { "naturals", "ℕ" },
- { "nearrow", "↗" },
- { "NegativeMediumSpace", "​" },
- { "NegativeThickSpace", "​" },
- { "NegativeThinSpace", "​" },
- { "NegativeVeryThinSpace", "​" },
- { "NestedGreaterGreater", "≫" },
- { "NestedLessLess", "≪" },
- { "nexists", "∄" },
- { "ngeq", "≱" },
- { "ngeqq", "≧̸" },
- { "ngeqslant", "⩾̸" },
- { "ngtr", "≯" },
- { "nLeftarrow", "⇍" },
- { "nleftarrow", "↚" },
- { "nLeftrightarrow", "⇎" },
- { "nleftrightarrow", "↮" },
- { "nleq", "≰" },
- { "nleqq", "≦̸" },
- { "nleqslant", "⩽̸" },
- { "nless", "≮" },
- { "NonBreakingSpace", " " },
- { "NotCongruent", "≢" },
- { "NotDoubleVerticalBar", "∦" },
- { "NotElement", "∉" },
- { "NotEqual", "≠" },
- { "NotEqualTilde", "≂̸" },
- { "NotExists", "∄" },
- { "NotGreater", "≯" },
- { "NotGreaterEqual", "≱" },
- { "NotGreaterFullEqual", "≦̸" },
- { "NotGreaterGreater", "≫̸" },
- { "NotGreaterLess", "≹" },
- { "NotGreaterSlantEqual", "⩾̸" },
- { "NotGreaterTilde", "≵" },
- { "NotHumpDownHump", "≎̸" },
- { "NotLeftTriangle", "⋪" },
- { "NotLeftTriangleEqual", "⋬" },
- { "NotLess", "≮" },
- { "NotLessEqual", "≰" },
- { "NotLessGreater", "≸" },
- { "NotLessLess", "≪̸" },
- { "NotLessSlantEqual", "⩽̸" },
- { "NotLessTilde", "≴" },
- { "NotPrecedes", "⊀" },
- { "NotPrecedesEqual", "⪯̸" },
- { "NotPrecedesSlantEqual", "⋠" },
- { "NotReverseElement", "∌" },
- { "NotRightTriangle", "⋫" },
- { "NotRightTriangleEqual", "⋭" },
- { "NotSquareSubsetEqual", "⋢" },
- { "NotSquareSupersetEqual", "⋣" },
- { "NotSubset", "⊂⃒" },
- { "NotSubsetEqual", "⊈" },
- { "NotSucceeds", "⊁" },
- { "NotSucceedsEqual", "⪰̸" },
- { "NotSucceedsSlantEqual", "⋡" },
- { "NotSuperset", "⊃⃒" },
- { "NotSupersetEqual", "⊉" },
- { "NotTilde", "≁" },
- { "NotTildeEqual", "≄" },
- { "NotTildeFullEqual", "≇" },
- { "NotTildeTilde", "≉" },
- { "NotVerticalBar", "∤" },
- { "nparallel", "∦" },
- { "nprec", "⊀" },
- { "npreceq", "⪯̸" },
- { "nRightarrow", "⇏" },
- { "nrightarrow", "↛" },
- { "nshortmid", "∤" },
- { "nshortparallel", "∦" },
- { "nsimeq", "≄" },
- { "nsubset", "⊂⃒" },
- { "nsubseteq", "⊈" },
- { "nsubseteqq", "⫅̸" },
- { "nsucc", "⊁" },
- { "nsucceq", "⪰̸" },
- { "nsupset", "⊃⃒" },
- { "nsupseteq", "⊉" },
- { "nsupseteqq", "⫆̸" },
- { "ntriangleleft", "⋪" },
- { "ntrianglelefteq", "⋬" },
- { "ntriangleright", "⋫" },
- { "ntrianglerighteq", "⋭" },
- { "nwarrow", "↖" },
- { "oint", "∮" },
- { "OpenCurlyDoubleQuote", "“" },
- { "OpenCurlyQuote", "‘" },
- { "orderof", "ℴ" },
- { "parallel", "∥" },
- { "PartialD", "∂" },
- { "pitchfork", "⋔" },
- { "PlusMinus", "±" },
- { "pm", "±" },
- { "Poincareplane", "ℌ" },
- { "prec", "≺" },
- { "precapprox", "⪷" },
- { "preccurlyeq", "≼" },
- { "Precedes", "≺" },
- { "PrecedesEqual", "⪯" },
- { "PrecedesSlantEqual", "≼" },
- { "PrecedesTilde", "≾" },
- { "preceq", "⪯" },
- { "precnapprox", "⪹" },
- { "precneqq", "⪵" },
- { "precnsim", "⋨" },
- { "precsim", "≾" },
- { "primes", "ℙ" },
- { "Proportion", "∷" },
- { "Proportional", "∝" },
- { "propto", "∝" },
- { "quaternions", "ℍ" },
- { "questeq", "≟" },
- { "rangle", "〉" },
- { "rationals", "ℚ" },
- { "rbrace", "}" },
- { "rbrack", "]" },
- { "Re", "ℜ" },
- { "realine", "ℛ" },
- { "realpart", "ℜ" },
- { "reals", "ℝ" },
- { "ReverseElement", "∋" },
- { "ReverseEquilibrium", "⇋" },
- { "ReverseUpEquilibrium", "⥯" },
- { "RightAngleBracket", "〉" },
- { "RightArrow", "→" },
- { "Rightarrow", "⇒" },
- { "rightarrow", "→" },
- { "RightArrowBar", "⇥" },
- { "RightArrowLeftArrow", "⇄" },
- { "rightarrowtail", "↣" },
- { "RightCeiling", "⌉" },
- { "RightDoubleBracket", "〛" },
- { "RightDownVector", "⇂" },
- { "RightFloor", "⌋" },
- { "rightharpoondown", "⇁" },
- { "rightharpoonup", "⇀" },
- { "rightleftarrows", "⇄" },
- { "rightleftharpoons", "⇌" },
- { "rightrightarrows", "⇉" },
- { "rightsquigarrow", "↝" },
- { "RightTee", "⊢" },
- { "RightTeeArrow", "↦" },
- { "rightthreetimes", "⋌" },
- { "RightTriangle", "⊳" },
- { "RightTriangleEqual", "⊵" },
- { "RightUpVector", "↾" },
- { "RightVector", "⇀" },
- { "risingdotseq", "≓" },
- { "rmoustache", "⎱" },
- { "Rrightarrow", "⇛" },
- { "Rsh", "↱" },
- { "searrow", "↘" },
- { "setminus", "∖" },
- { "ShortDownArrow", "↓" },
- { "ShortLeftArrow", "←" },
- { "shortmid", "∣" },
- { "shortparallel", "∥" },
- { "ShortRightArrow", "→" },
- { "ShortUpArrow", "↑" },
- { "simeq", "≃" },
- { "SmallCircle", "∘" },
- { "smallsetminus", "∖" },
- { "spadesuit", "♠" },
- { "Sqrt", "√" },
- { "sqsubset", "⊏" },
- { "sqsubseteq", "⊑" },
- { "sqsupset", "⊐" },
- { "sqsupseteq", "⊒" },
- { "Square", "□" },
- { "SquareIntersection", "⊓" },
- { "SquareSubset", "⊏" },
- { "SquareSubsetEqual", "⊑" },
- { "SquareSuperset", "⊐" },
- { "SquareSupersetEqual", "⊒" },
- { "SquareUnion", "⊔" },
- { "Star", "⋆" },
- { "straightepsilon", "ε" },
- { "straightphi", "ϕ" },
- { "Subset", "⋐" },
- { "subset", "⊂" },
- { "subseteq", "⊆" },
- { "subseteqq", "⫅" },
- { "SubsetEqual", "⊆" },
- { "subsetneq", "⊊" },
- { "subsetneqq", "⫋" },
- { "succ", "≻" },
- { "succapprox", "⪸" },
- { "succcurlyeq", "≽" },
- { "Succeeds", "≻" },
- { "SucceedsEqual", "⪰" },
- { "SucceedsSlantEqual", "≽" },
- { "SucceedsTilde", "≿" },
- { "succeq", "⪰" },
- { "succnapprox", "⪺" },
- { "succneqq", "⪶" },
- { "succnsim", "⋩" },
- { "succsim", "≿" },
- { "SuchThat", "∋" },
- { "Sum", "∑" },
- { "Superset", "⊃" },
- { "SupersetEqual", "⊇" },
- { "Supset", "⋑" },
- { "supset", "⊃" },
- { "supseteq", "⊇" },
- { "supseteqq", "⫆" },
- { "supsetneq", "⊋" },
- { "supsetneqq", "⫌" },
- { "swarrow", "↙" },
- { "Therefore", "∴" },
- { "therefore", "∴" },
- { "thickapprox", "≈" },
- { "thicksim", "∼" },
- { "ThinSpace", " " },
- { "Tilde", "∼" },
- { "TildeEqual", "≃" },
- { "TildeFullEqual", "≅" },
- { "TildeTilde", "≈" },
- { "toea", "⤨" },
- { "tosa", "⤩" },
- { "triangle", "▵" },
- { "triangledown", "▿" },
- { "triangleleft", "◃" },
- { "trianglelefteq", "⊴" },
- { "triangleq", "≜" },
- { "triangleright", "▹" },
- { "trianglerighteq", "⊵" },
- { "TripleDot", "⃛" },
- { "twoheadleftarrow", "↞" },
- { "twoheadrightarrow", "↠" },
- { "ulcorner", "⌜" },
- { "Union", "⋃" },
- { "UnionPlus", "⊎" },
- { "UpArrow", "↑" },
- { "Uparrow", "⇑" },
- { "uparrow", "↑" },
- { "UpArrowDownArrow", "⇅" },
- { "UpDownArrow", "↕" },
- { "Updownarrow", "⇕" },
- { "updownarrow", "↕" },
- { "UpEquilibrium", "⥮" },
- { "upharpoonleft", "↿" },
- { "upharpoonright", "↾" },
- { "UpperLeftArrow", "↖" },
- { "UpperRightArrow", "↗" },
- { "upsilon", "υ" },
- { "UpTee", "⊥" },
- { "UpTeeArrow", "↥" },
- { "upuparrows", "⇈" },
- { "urcorner", "⌝" },
- { "varepsilon", "ɛ" },
- { "varkappa", "ϰ" },
- { "varnothing", "∅" },
- { "varphi", "φ" },
- { "varpi", "ϖ" },
- { "varpropto", "∝" },
- { "varrho", "ϱ" },
- { "varsigma", "ς" },
- { "varsubsetneq", "⊊︀" },
- { "varsubsetneqq", "⫋︀" },
- { "varsupsetneq", "⊋︀" },
- { "varsupsetneqq", "⫌︀" },
- { "vartheta", "ϑ" },
- { "vartriangleleft", "⊲" },
- { "vartriangleright", "⊳" },
- { "Vee", "⋁" },
- { "vee", "∨" },
- { "Vert", "‖" },
- { "vert", "|" },
- { "VerticalBar", "∣" },
- { "VerticalTilde", "≀" },
- { "VeryThinSpace", " " },
- { "Wedge", "⋀" },
- { "wedge", "∧" },
- { "wp", "℘" },
- { "wr", "≀" },
- { "zeetrf", "ℨ" },
- { 0, 0 }
-};
-
-// *******************************************************************
-// MmlDocument
-// *******************************************************************
-
-QString MmlDocument::fontName(QtMmlWidget::MmlFont type) const
-{
- switch (type) {
- case QtMmlWidget::NormalFont:
- return m_normal_font_name;
- case QtMmlWidget::FrakturFont:
- return m_fraktur_font_name;
- case QtMmlWidget::SansSerifFont:
- return m_sans_serif_font_name;
- case QtMmlWidget::ScriptFont:
- return m_script_font_name;
- case QtMmlWidget::MonospaceFont:
- return m_monospace_font_name;
- case QtMmlWidget::DoublestruckFont:
- return m_doublestruck_font_name;
- };
-
- return QString::null;
-}
-
-void MmlDocument::setFontName(QtMmlWidget::MmlFont type, const QString &name)
-{
- switch (type) {
- case QtMmlWidget::NormalFont:
- m_normal_font_name = name;
- break;
- case QtMmlWidget::FrakturFont:
- m_fraktur_font_name = name;
- break;
- case QtMmlWidget::SansSerifFont:
- m_sans_serif_font_name = name;
- break;
- case QtMmlWidget::ScriptFont:
- m_script_font_name = name;
- break;
- case QtMmlWidget::MonospaceFont:
- m_monospace_font_name = name;
- break;
- case QtMmlWidget::DoublestruckFont:
- m_doublestruck_font_name = name;
- break;
- };
-}
-
-Mml::NodeType domToMmlNodeType(const QDomNode &dom_node)
-{
- Mml::NodeType mml_type = Mml::NoNode;
-
- switch (dom_node.nodeType()) {
- case QDomNode::ElementNode: {
- QString tag = dom_node.nodeName();
- const NodeSpec *spec = mmlFindNodeSpec(tag);
-
- // treat urecognised tags as mrow
- if (spec == 0)
- mml_type = Mml::UnknownNode;
- else
- mml_type = spec->type;
-
- break;
- }
- case QDomNode::TextNode:
- mml_type = Mml::TextNode;
- break;
-
- case QDomNode::DocumentNode:
- mml_type = Mml::MrowNode;
- break;
-
- case QDomNode::EntityReferenceNode:
-// qWarning("EntityReferenceNode: name=\"" + dom_node.nodeName() + "\" value=\"" + dom_node.nodeValue() + "\"");
- break;
-
- case QDomNode::AttributeNode:
- case QDomNode::CDATASectionNode:
- case QDomNode::EntityNode:
- case QDomNode::ProcessingInstructionNode:
- case QDomNode::CommentNode:
- case QDomNode::DocumentTypeNode:
- case QDomNode::DocumentFragmentNode:
- case QDomNode::NotationNode:
- case QDomNode::BaseNode:
- case QDomNode::CharacterDataNode:
- break;
- }
-
- return mml_type;
-}
-
-
-MmlDocument::MmlDocument()
-{
- m_root_node = 0;
-
- // Some defaults which happen to work on my computer,
- // but probably won't work on other's
-#if defined(Q_WS_WIN)
- m_normal_font_name = "Times New Roman";
-#else
- m_normal_font_name = "Century Schoolbook L";
-#endif
- m_fraktur_font_name = "Fraktur";
- m_sans_serif_font_name = "Luxi Sans";
- m_script_font_name = "Urw Chancery L";
- m_monospace_font_name = "Luxi Mono";
- m_doublestruck_font_name = "Doublestruck";
- m_base_font_point_size = 16;
- m_foreground_color = Qt::black;
- m_background_color = Qt::white;
-}
-
-MmlDocument::~MmlDocument()
-{
- clear();
-}
-
-void MmlDocument::clear()
-{
- delete m_root_node;
- m_root_node = 0;
-}
-
-void MmlDocument::dump() const
-{
- if (m_root_node == 0)
- return;
-
- QString indent;
- _dump(m_root_node, indent);
-}
-
-void MmlDocument::_dump(const MmlNode *node, QString &indent) const
-{
- if (node == 0) return;
-
- qWarning("%s", qPrintable(QString(indent + node->toStr())));
-
- indent += " ";
- const MmlNode *child = node->firstChild();
- for (; child != 0; child = child->nextSibling())
- _dump(child, indent);
- indent.truncate(indent.length() - 2);
-}
-
-bool MmlDocument::setContent(QString text, QString *errorMsg,
- int *errorLine, int *errorColumn)
-{
- clear();
-
- QString prefix = "<?xml version=\"2.0\"?>\n";
- prefix.append(entityDeclarations());
-
- uint prefix_lines = 0;
- for (int i = 0; i < prefix.length(); ++i) {
- if (prefix.at(i) == '\n')
- ++prefix_lines;
- }
-
- QDomDocument dom;
- if (!dom.setContent(prefix + text, false, errorMsg, errorLine, errorColumn)) {
- if (errorLine != 0)
- *errorLine -= prefix_lines;
- return false;
- }
-
- // we don't have access to line info from now on
- if (errorLine != 0) *errorLine = -1;
- if (errorColumn != 0) *errorColumn = -1;
-
- bool ok;
- MmlNode *root_node = domToMml(dom, &ok, errorMsg);
- if (!ok)
- return false;
-
- if (root_node == 0) {
- if (errorMsg != 0)
- *errorMsg = "empty document";
- return false;
- }
-
- insertChild(0, root_node, 0);
- layout();
-
-/* QFile of("/tmp/dump.xml");
- of.open(IO_WriteOnly);
- QTextStream os(&of);
- os.setEncoding(QTextStream::UnicodeUTF8);
- os << dom.toString(); */
-
- return true;
-}
-
-void MmlDocument::layout()
-{
- if (m_root_node == 0)
- return;
-
- m_root_node->layout();
- m_root_node->stretch();
-// dump();
-}
-
-bool MmlDocument::insertChild(MmlNode *parent, MmlNode *new_node,
- QString *errorMsg)
-{
- if (new_node == 0)
- return true;
-
- Q_ASSERT(new_node->parent() == 0
- && new_node->nextSibling() == 0
- && new_node->previousSibling() == 0);
-
- if (parent != 0) {
- if (!mmlCheckChildType(parent->nodeType(), new_node->nodeType(), errorMsg))
- return false;
- }
-
- if (parent == 0) {
- if (m_root_node == 0)
- m_root_node = new_node;
- else {
- MmlNode *n = m_root_node->lastSibling();
- n->m_next_sibling = new_node;
- new_node->m_previous_sibling = n;
- }
- }
- else {
- new_node->m_parent = parent;
- if (parent->hasChildNodes()) {
- MmlNode *n = parent->firstChild()->lastSibling();
- n->m_next_sibling = new_node;
- new_node->m_previous_sibling = n;
- }
- else parent->m_first_child = new_node;
- }
-
- return true;
-}
-
-MmlNode *MmlDocument::createNode(NodeType type,
- const MmlAttributeMap &mml_attr,
- const QString &mml_value,
- QString *errorMsg)
-{
- Q_ASSERT(type != NoNode);
-
- MmlNode *mml_node = 0;
-
- if (!mmlCheckAttributes(type, mml_attr, errorMsg))
- return 0;
-
- switch (type) {
- case MiNode:
- mml_node = new MmlMiNode(this, mml_attr);
- break;
- case MnNode:
- mml_node = new MmlMnNode(this, mml_attr);
- break;
- case MfracNode:
- mml_node = new MmlMfracNode(this, mml_attr);
- break;
- case MrowNode:
- mml_node = new MmlMrowNode(this, mml_attr);
- break;
- case MsqrtNode:
- mml_node = new MmlMsqrtNode(this, mml_attr);
- break;
- case MrootNode:
- mml_node = new MmlMrootNode(this, mml_attr);
- break;
- case MsupNode:
- mml_node = new MmlMsupNode(this, mml_attr);
- break;
- case MsubNode:
- mml_node = new MmlMsubNode(this, mml_attr);
- break;
- case MsubsupNode:
- mml_node = new MmlMsubsupNode(this, mml_attr);
- break;
- case MoNode:
- mml_node = new MmlMoNode(this, mml_attr);
- break;
- case MstyleNode:
- mml_node = new MmlMstyleNode(this, mml_attr);
- break;
- case TextNode:
- mml_node = new MmlTextNode(mml_value, this);
- break;
- case MphantomNode:
- mml_node = new MmlMphantomNode(this, mml_attr);
- break;
- case MfencedNode:
- mml_node = new MmlMfencedNode(this, mml_attr);
- break;
- case MtableNode:
- mml_node = new MmlMtableNode(this, mml_attr);
- break;
- case MtrNode:
- mml_node = new MmlMtrNode(this, mml_attr);
- break;
- case MtdNode:
- mml_node = new MmlMtdNode(this, mml_attr);
- break;
- case MoverNode:
- mml_node = new MmlMoverNode(this, mml_attr);
- break;
- case MunderNode:
- mml_node = new MmlMunderNode(this, mml_attr);
- break;
- case MunderoverNode:
- mml_node = new MmlMunderoverNode(this, mml_attr);
- break;
- case MalignMarkNode:
- mml_node = new MmlMalignMarkNode(this);
- break;
- case MerrorNode:
- mml_node = new MmlMerrorNode(this, mml_attr);
- break;
- case MtextNode:
- mml_node = new MmlMtextNode(this, mml_attr);
- break;
- case MpaddedNode:
- mml_node = new MmlMpaddedNode(this, mml_attr);
- break;
- case MspaceNode:
- mml_node = new MmlMspaceNode(this, mml_attr);
- break;
- case UnknownNode:
- mml_node = new MmlUnknownNode(this, mml_attr);
- break;
- case NoNode:
- mml_node = 0;
- break;
- }
-
- return mml_node;
-}
-
-void MmlDocument::insertOperator(MmlNode *node, const QString &text)
-{
- MmlNode *text_node = createNode(TextNode, MmlAttributeMap(), text, 0);
- MmlNode *mo_node = createNode(MoNode, MmlAttributeMap(), QString::null, 0);
-
- bool ok = insertChild(node, mo_node, 0);
- Q_ASSERT( ok );
- ok = insertChild(mo_node, text_node, 0);
- Q_ASSERT( ok );
-}
-
-MmlNode *MmlDocument::domToMml(const QDomNode &dom_node, bool *ok, QString *errorMsg)
-{
- // create the node
-
- Q_ASSERT(ok != 0);
-
- NodeType mml_type = domToMmlNodeType(dom_node);
-
- if (mml_type == NoNode) {
- *ok = true;
- return 0;
- }
-
- QDomNamedNodeMap dom_attr = dom_node.attributes();
- MmlAttributeMap mml_attr;
- for (unsigned i = 0; i < dom_attr.length(); ++i) {
- QDomNode attr_node = dom_attr.item(i);
- Q_ASSERT(!attr_node.nodeName().isNull());
- Q_ASSERT(!attr_node.nodeValue().isNull());
- mml_attr[attr_node.nodeName()] = attr_node.nodeValue();
- }
-
- QString mml_value;
- if (mml_type == TextNode)
- mml_value = dom_node.nodeValue();
- MmlNode *mml_node = createNode(mml_type, mml_attr, mml_value, errorMsg);
- if (mml_node == 0) {
- *ok = false;
- return 0;
- }
-
- // create the node's children according to the child_spec
-
- const NodeSpec *spec = mmlFindNodeSpec(mml_type);
- QDomNodeList dom_child_list = dom_node.childNodes();
- int child_cnt = dom_child_list.count();
- MmlNode *mml_child = 0;
-
- QString separator_list;
- if (mml_type == MfencedNode)
- separator_list = mml_node->explicitAttribute("separators", ",");
-
- switch (spec->child_spec) {
- case NodeSpec::ChildIgnore:
- break;
-
- case NodeSpec::ImplicitMrow:
-
- if (child_cnt > 0) {
- mml_child = createImplicitMrowNode(dom_node, ok, errorMsg);
- if (!*ok) {
- delete mml_node;
- return 0;
- }
-
- if (!insertChild(mml_node, mml_child, errorMsg)) {
- delete mml_node;
- delete mml_child;
- *ok = false;
- return 0;
- }
- }
-
- break;
-
- default:
- // exact ammount of children specified - check...
- if (spec->child_spec != child_cnt) {
- if (errorMsg != 0)
- *errorMsg = QString("element ")
- + spec->tag
- + " requires exactly "
- + QString::number(spec->child_spec)
- + " arguments, got "
- + QString::number(child_cnt);
- delete mml_node;
- *ok = false;
- return 0;
- }
-
- // ...and continue just as in ChildAny
-
- case NodeSpec::ChildAny:
- if (mml_type == MfencedNode)
- insertOperator(mml_node, mml_node->explicitAttribute("open", "("));
-
- for (int i = 0; i < child_cnt; ++i) {
- QDomNode dom_child = dom_child_list.item(i);
-
- MmlNode *mml_child = domToMml(dom_child, ok, errorMsg);
- if (!*ok) {
- delete mml_node;
- return 0;
- }
-
- if (mml_type == MtableNode && mml_child->nodeType() != MtrNode) {
- MmlNode *mtr_node = createNode(MtrNode, MmlAttributeMap(), QString::null, 0);
- insertChild(mml_node, mtr_node, 0);
- if (!insertChild(mtr_node, mml_child, errorMsg)) {
- delete mml_node;
- delete mml_child;
- *ok = false;
- return 0;
- }
- }
- else if (mml_type == MtrNode && mml_child->nodeType() != MtdNode) {
- MmlNode *mtd_node = createNode(MtdNode, MmlAttributeMap(), QString::null, 0);
- insertChild(mml_node, mtd_node, 0);
- if (!insertChild(mtd_node, mml_child, errorMsg)) {
- delete mml_node;
- delete mml_child;
- *ok = false;
- return 0;
- }
- }
- else {
- if (!insertChild(mml_node, mml_child, errorMsg)) {
- delete mml_node;
- delete mml_child;
- *ok = false;
- return 0;
- }
- }
-
- if (i < child_cnt - 1 && mml_type == MfencedNode && !separator_list.isEmpty()) {
- QChar separator;
- if (i >= (int)separator_list.length())
- separator = separator_list.at(separator_list.length() - 1);
- else
- separator = separator_list[i];
- insertOperator(mml_node, QString(separator));
- }
- }
-
- if (mml_type == MfencedNode)
- insertOperator(mml_node, mml_node->explicitAttribute("close", ")"));
-
- break;
- }
-
- *ok = true;
- return mml_node;
-}
-
-MmlNode *MmlDocument::createImplicitMrowNode(const QDomNode &dom_node, bool *ok,
- QString *errorMsg)
-{
- QDomNodeList dom_child_list = dom_node.childNodes();
- int child_cnt = dom_child_list.count();
-
- if (child_cnt == 0) {
- *ok = true;
- return 0;
- }
-
- if (child_cnt == 1)
- return domToMml(dom_child_list.item(0), ok, errorMsg);
-
- MmlNode *mml_node = createNode(MrowNode, MmlAttributeMap(),
- QString::null, errorMsg);
- Q_ASSERT(mml_node != 0); // there is no reason in heaven or hell for this to fail
-
- for (int i = 0; i < child_cnt; ++i) {
- QDomNode dom_child = dom_child_list.item(i);
-
- MmlNode *mml_child = domToMml(dom_child, ok, errorMsg);
- if (!*ok) {
- delete mml_node;
- return 0;
- }
-
- if (!insertChild(mml_node, mml_child, errorMsg)) {
- delete mml_node;
- delete mml_child;
- *ok = false;
- return 0;
- }
- }
-
- return mml_node;
-}
-
-void MmlDocument::paint(QPainter *p, const QPoint &pos) const
-{
- if (m_root_node == 0)
- return;
-
-/* p->save();
- p->setPen(Qt::blue);
- p->drawLine(pos.x() - 5, pos.y(), pos.x() + 5, pos.y());
- p->drawLine(pos.x(), pos.y() - 5, pos.x(), pos.y() + 5);
- p->restore(); */
-
- QRect mr = m_root_node->myRect();
- m_root_node->setRelOrigin(pos - mr.topLeft());
- m_root_node->paint(p);
-}
-
-QSize MmlDocument::size() const
-{
- if (m_root_node == 0)
- return QSize(0, 0);
- return m_root_node->deviceRect().size();
-}
-
-
-
-
-// *******************************************************************
-// MmlNode
-// *******************************************************************
-
-
-MmlNode::MmlNode(NodeType type, MmlDocument *document, const MmlAttributeMap &attribute_map)
-{
- m_parent = 0;
- m_first_child = 0;
- m_next_sibling = 0;
- m_previous_sibling = 0;
-
- m_node_type = type;
- m_document = document;
- m_attribute_map = attribute_map;
-
- m_my_rect = m_parent_rect = QRect(0, 0, 0, 0);
- m_rel_origin = QPoint(0, 0);
- m_stretched = false;
-}
-
-MmlNode::~MmlNode()
-{
- MmlNode *n = firstChild();
- while (n != 0) {
- MmlNode *tmp = n->nextSibling();
- delete n;
- n = tmp;
- }
-}
-
-static QString rectToStr(const QRect &rect)
-{
- return QString("[(%1, %2), %3x%4]")
- .arg(rect.x())
- .arg(rect.y())
- .arg(rect.width())
- .arg(rect.height());
-}
-
-QString MmlNode::toStr() const
-{
- const NodeSpec *spec = mmlFindNodeSpec(nodeType());
- Q_ASSERT(spec != 0);
-
- return QString("%1 %2 mr=%3 pr=%4 dr=%5 ro=(%7, %8) str=%9")
- .arg(spec->type_str)
- .arg((quintptr)this, 0, 16)
- .arg(rectToStr(myRect()))
- .arg(rectToStr(parentRect()))
- .arg(rectToStr(deviceRect()))
- .arg(m_rel_origin.x())
- .arg(m_rel_origin.y())
- .arg((int)isStretched());
-}
-
-int MmlNode::interpretSpacing(const QString &value, bool *ok) const
-{
- return ::interpretSpacing(value, em(), ex(), ok);
-}
-
-int MmlNode::basePos() const
-{
- QFontMetrics fm(font());
- return fm.strikeOutPos();
-}
-
-int MmlNode::underlinePos() const
-{
- QFontMetrics fm(font());
- return basePos() + fm.underlinePos();
-}
-int MmlNode::overlinePos() const
-{
- QFontMetrics fm(font());
- return basePos() - fm.overlinePos();
-}
-
-MmlNode *MmlNode::lastSibling() const
-{
- const MmlNode *n = this;
- while (!n->isLastSibling())
- n = n->nextSibling();
- return const_cast<MmlNode*>(n);
-}
-
-MmlNode *MmlNode::firstSibling() const
-{
- const MmlNode *n = this;
- while (!n->isFirstSibling())
- n = n->previousSibling();
- return const_cast<MmlNode*>(n);
-}
-
-int MmlNode::em() const
-{
- return QFontMetrics(font()).boundingRect('m').width();
-}
-
-int MmlNode::ex() const
-{
- return QFontMetrics(font()).boundingRect('x').height();
-}
-
-int MmlNode::scriptlevel(const MmlNode *) const
-{
- int parent_sl;
- const MmlNode *p = parent();
- if (p == 0)
- parent_sl = 0;
- else
- parent_sl = p->scriptlevel(this);
-
- QString expl_sl_str = explicitAttribute("scriptlevel");
- if (expl_sl_str.isNull())
- return parent_sl;
-
- if (expl_sl_str.startsWith("+") || expl_sl_str.startsWith("-")) {
- bool ok;
- int expl_sl = expl_sl_str.toInt(&ok);
- if (ok) {
- return parent_sl + expl_sl;
- }
- else {
- qWarning("MmlNode::scriptlevel(): bad value: %s", qPrintable(expl_sl_str));
- return parent_sl;
- }
- }
-
- bool ok;
- int expl_sl = expl_sl_str.toInt(&ok);
- if (ok)
- return expl_sl;
-
-
- if (expl_sl_str == "+")
- return parent_sl + 1;
- else if (expl_sl_str == "-")
- return parent_sl - 1;
- else {
- qWarning("MmlNode::scriptlevel(): could not parse value: \"%s\"", qPrintable(expl_sl_str));
- return parent_sl;
- }
-}
-
-QPoint MmlNode::devicePoint(const QPoint &p) const
-{
- QRect mr = myRect();
- QRect dr = deviceRect();
-
- if (isStretched())
- return dr.topLeft() + QPoint((p.x() - mr.left())*dr.width()/mr.width(),
- (p.y() - mr.top())*dr.height()/mr.height());
- else
- return dr.topLeft() + p - mr.topLeft();
-}
-
-QString MmlNode::inheritAttributeFromMrow(const QString &name,
- const QString &def) const
-{
- const MmlNode *p = this;
- for (; p != 0; p = p->parent()) {
- if (p == this || p->nodeType() == MstyleNode) {
- QString value = p->explicitAttribute(name);
- if (!value.isNull())
- return value;
- }
- }
-
- return def;
-}
-
-QColor MmlNode::color() const
-{
- // If we are child of <merror> return red
- const MmlNode *p = this;
- for (; p != 0; p = p->parent()) {
- if (p->nodeType() == MerrorNode)
- return QColor("red");
- }
-
- QString value_str = inheritAttributeFromMrow("mathcolor");
- if (value_str.isNull())
- value_str = inheritAttributeFromMrow("color");
- if (value_str.isNull())
- return QColor();
-
- return QColor(value_str);
-}
-
-QColor MmlNode::background() const
-{
- QString value_str = inheritAttributeFromMrow("mathbackground");
- if (value_str.isNull())
- value_str = inheritAttributeFromMrow("background");
- if (value_str.isNull())
- return QColor();
-
- return QColor(value_str);
-}
-
-static void updateFontAttr(MmlAttributeMap &font_attr, const MmlNode *n,
- const QString &name, const QString &preferred_name = QString::null)
-{
- if (font_attr.contains(preferred_name) || font_attr.contains(name))
- return;
- QString value = n->explicitAttribute(name);
- if (!value.isNull())
- font_attr[name] = value;
-}
-
-static MmlAttributeMap collectFontAttributes(const MmlNode *node)
-{
- MmlAttributeMap font_attr;
-
- for (const MmlNode *n = node; n != 0; n = n->parent()) {
- if (n == node || n->nodeType() == Mml::MstyleNode) {
- updateFontAttr(font_attr, n, "mathvariant");
- updateFontAttr(font_attr, n, "mathsize");
-
- // depreciated attributes
- updateFontAttr(font_attr, n, "fontsize", "mathsize");
- updateFontAttr(font_attr, n, "fontweight", "mathvariant");
- updateFontAttr(font_attr, n, "fontstyle", "mathvariant");
- updateFontAttr(font_attr, n, "fontfamily", "mathvariant");
- }
- }
-
- return font_attr;
-}
-
-QFont MmlNode::font() const
-{
- QFont fn(document()->fontName(QtMmlWidget::NormalFont),
- document()->baseFontPointSize());
-
- int ps = fn.pointSize();
- int sl = scriptlevel();
- if (sl >= 0) {
- for (int i = 0; i < sl; ++i)
- ps = (int)(ps*g_script_size_multiplier);
- }
- else {
- for (int i = 0; i > sl; --i)
- ps = (int)(ps/g_script_size_multiplier);
- }
- if (ps < g_min_font_point_size)
- ps = g_min_font_point_size;
- fn.setPointSize(ps);
-
- int em = QFontMetrics(fn).boundingRect('m').width();
- int ex = QFontMetrics(fn).boundingRect('x').height();
-
- MmlAttributeMap font_attr = collectFontAttributes(this);
-
- if (font_attr.contains("mathvariant")) {
- QString value = font_attr["mathvariant"];
-
- bool ok;
- uint mv = interpretMathVariant(value, &ok);
-
- if (ok) {
- if (mv & ScriptMV)
- fn.setFamily(document()->fontName(QtMmlWidget::ScriptFont));
-
- if (mv & FrakturMV)
- fn.setFamily(document()->fontName(QtMmlWidget::FrakturFont));
-
- if (mv & SansSerifMV)
- fn.setFamily(document()->fontName(QtMmlWidget::SansSerifFont));
-
- if (mv & MonospaceMV)
- fn.setFamily(document()->fontName(QtMmlWidget::MonospaceFont));
-
- if (mv & DoubleStruckMV)
- fn.setFamily(document()->fontName(QtMmlWidget::DoublestruckFont));
-
- if (mv & BoldMV)
- fn.setBold(true);
-
- if (mv & ItalicMV)
- fn.setItalic(true);
- }
- }
-
- if (font_attr.contains("mathsize")) {
- QString value = font_attr["mathsize"];
- fn = interpretMathSize(value, fn, em, ex, 0);
- }
-
- fn = interpretDepreciatedFontAttr(font_attr, fn, em, ex);
-
- if (nodeType() == MiNode
- && !font_attr.contains("mathvariant")
- && !font_attr.contains("fontstyle")) {
- const MmlMiNode *mi_node = (const MmlMiNode*) this;
- if (mi_node->text().length() == 1)
- fn.setItalic(true);
- }
-
- if (nodeType() == MoNode) {
- fn.setItalic(false);
- fn.setBold(false);
- }
-
- return fn;
-}
-
-QString MmlNode::explicitAttribute(const QString &name, const QString &def) const
-{
- MmlAttributeMap::const_iterator it = m_attribute_map.find(name);
- if (it != m_attribute_map.end())
- return *it;
- return def;
-}
-
-
-QRect MmlNode::parentRect() const
-{
- if (isStretched())
- return m_parent_rect;
-
- QRect mr = myRect();
- QPoint ro = relOrigin();
-
- return QRect(ro + mr.topLeft(), mr.size());
-}
-
-
-void MmlNode::stretchTo(const QRect &rect)
-{
- m_parent_rect = rect;
- m_stretched = true;
-}
-
-void MmlNode::setRelOrigin(const QPoint &rel_origin)
-{
- m_rel_origin = rel_origin + QPoint(-myRect().left(), 0);
- m_stretched = false;
-}
-
-void MmlNode::updateMyRect()
-{
- m_my_rect = symbolRect();
- MmlNode *child = firstChild();
- for (; child != 0; child = child->nextSibling())
- m_my_rect |= child->parentRect();
-}
-
-void MmlNode::layout()
-{
- m_parent_rect = QRect(0, 0, 0, 0);
- m_stretched = false;
- m_rel_origin = QPoint(0, 0);
-
- MmlNode *child = firstChild();
- for (; child != 0; child = child->nextSibling())
- child->layout();
-
- layoutSymbol();
-
- updateMyRect();
-
- if (parent() == 0)
- m_rel_origin = QPoint(0, 0);
-}
-
-
-QRect MmlNode::deviceRect() const
-{
- if (parent() == 0)
- return QRect(relOrigin() + myRect().topLeft(), myRect().size());
-
-/* if (!isStretched()) {
- QRect pdr = parent()->deviceRect();
- QRect pmr = parent()->myRect();
- QRect pr = parentRect();
- QRect mr = myRect();
- return QRect(pdr.left() + pr.left() - pmr.left(),
- pdr.top() + pr.top() - pmr.top(),
- mr.width(), mr.height());
- }
-*/
- QRect pdr = parent()->deviceRect();
- QRect pr = parentRect();
- QRect pmr = parent()->myRect();
-
- float scale_w = 0;
- if (pmr.width() != 0)
- scale_w = (float)pdr.width()/pmr.width();
- float scale_h = 0;
- if (pmr.height() != 0)
- scale_h = (float)pdr.height()/pmr.height();
-
- return QRect(pdr.left() + ROUND((pr.left() - pmr.left())*scale_w),
- pdr.top() + ROUND((pr.top() - pmr.top())*scale_h),
- ROUND((pr.width()*scale_w)),
- ROUND((pr.height()*scale_h)));
-}
-
-void MmlNode::layoutSymbol()
-{
- // default behaves like an mrow
-
- // now lay them out in a neat row, aligning their origins to my origin
- int w = 0;
- MmlNode *child = firstChild();
- for (; child != 0; child = child->nextSibling()) {
- child->setRelOrigin(QPoint(w, 0));
- w += child->parentRect().width() + 1;
- }
-}
-
-void MmlNode::paint(QPainter *p)
-{
- if (!myRect().isValid())
- return;
- p->save();
- p->setViewport(deviceRect());
- p->setWindow(myRect());
-
-
- QColor fg = color();
- QColor bg = background();
- if (bg.isValid())
- p->fillRect(myRect(), bg);
- if (fg.isValid())
- p->setPen(color());
-
- MmlNode *child = firstChild();
- for (; child != 0; child = child->nextSibling())
- child->paint(p);
-
- paintSymbol(p);
-
- p->restore();
-}
-
-void MmlNode::paintSymbol(QPainter *p) const
-{
- if (g_draw_frames && myRect().isValid()) {
- p->save();
- p->setPen(Qt::red);
- p->drawRect(m_my_rect);
- QPen pen = p->pen();
- pen.setStyle(Qt::DotLine);
- p->setPen(pen);
- p->drawLine(myRect().left(), 0, myRect().right(), 0);
- p->restore();
- }
-}
-
-void MmlNode::stretch()
-{
- MmlNode *child = firstChild();
- for (; child != 0; child = child->nextSibling())
- child->stretch();
-}
-
-QString MmlTokenNode::text() const
-{
- QString result;
-
- const MmlNode *child = firstChild();
- for (; child != 0; child = child->nextSibling()) {
- if (child->nodeType() != TextNode) continue;
- if (!result.isEmpty())
- result += ' ';
- result += ((MmlTextNode*)child)->text();
- }
-
- return result;
-}
-
-MmlNode *MmlMfracNode::numerator() const
-{
- MmlNode *node = firstChild();
- Q_ASSERT(node != 0);
- return node;
-}
-
-MmlNode *MmlMfracNode::denominator() const
-{
- MmlNode *node = numerator()->nextSibling();
- Q_ASSERT(node != 0);
- return node;
-}
-
-QRect MmlMfracNode::symbolRect() const
-{
- int num_width = numerator()->myRect().width();
- int denom_width = denominator()->myRect().width();
- int my_width = qMax(num_width, denom_width) + 4;
-
- return QRect(-my_width/2, 0, my_width, 1);
-}
-
-void MmlMfracNode::layoutSymbol()
-{
- MmlNode *num = numerator();
- MmlNode *denom = denominator();
-
- QRect num_rect = num->myRect();
- QRect denom_rect = denom->myRect();
-
- int spacing = (int)(g_mfrac_spacing*(num_rect.height() + denom_rect.height()));
-
- num->setRelOrigin(QPoint(-num_rect.width()/2, - spacing - num_rect.bottom()));
- denom->setRelOrigin(QPoint(-denom_rect.width()/2, spacing - denom_rect.top()));
-}
-
-static bool zeroLineThickness(const QString &s)
-{
- if (s.length() == 0 || !s[0].isDigit())
- return false;
-
- for (int i = 0; i < s.length(); ++i) {
- QChar c = s.at(i);
- if (c.isDigit() && c != '0')
- return false;
- }
- return true;
-}
-
-void MmlMfracNode::paintSymbol(QPainter *p) const
-{
- QString linethickness_str = inheritAttributeFromMrow("linethickness", "1");
-
- /* InterpretSpacing returns an int, which might be 0 even if the thickness
- is > 0, though very very small. That's ok, because the painter then paints
- a line of thickness 1. However, we have to run this check if the line
- thickness really is zero */
- if (!zeroLineThickness(linethickness_str)) {
- bool ok;
- int linethickness = interpretSpacing(linethickness_str, &ok);
- if (!ok)
- linethickness = 1;
-
- p->save();
- QPen pen = p->pen();
- pen.setWidth(linethickness);
- p->setPen(pen);
- QSize s = myRect().size();
- p->drawLine(-s.width()/2, 0, s.width()/2, 0);
- p->restore();
- }
-}
-
-MmlNode *MmlRootBaseNode::base() const
-{
- MmlNode *node = firstChild();
-// Q_ASSERT(node != 0);
- return node;
-}
-
-MmlNode *MmlRootBaseNode::index() const
-{
- MmlNode *b = base();
- if (b == 0)
- return 0;
- return b->nextSibling();
-}
-
-int MmlRootBaseNode::scriptlevel(const MmlNode *child) const
-{
- int sl = MmlNode::scriptlevel();
-
- MmlNode *i = index();
- if (child != 0 && child == i)
- return sl + 1;
- else
- return sl;
-}
-
-
-QRect MmlRootBaseNode::symbolRect() const
-{
- MmlNode *b = base();
- QRect base_rect;
- if (b == 0)
- base_rect = QRect(0, 0, 1, 1);
- else
- base_rect = base()->myRect();
-
- int margin = (int)(g_mroot_base_margin*base_rect.height());
- int tw = tailWidth();
-
- return QRect(-tw, base_rect.top() - margin, tw,
- base_rect.height() + 2*margin);
-}
-
-int MmlRootBaseNode::tailWidth() const
-{
- QFontMetrics fm(font());
- return fm.boundingRect(g_radical_char).width();
-}
-
-void MmlRootBaseNode::layoutSymbol()
-{
- MmlNode *b = base();
- QSize base_size;
- if (b != 0) {
- b->setRelOrigin(QPoint(0, 0));
- base_size = base()->myRect().size();
- } else
- base_size = QSize(1, 1);
-
- MmlNode *i = index();
- if (i != 0) {
- int tw = tailWidth();
-
- QRect i_rect = i->myRect();
- i->setRelOrigin(QPoint(-tw/2 - i_rect.width(),
- -i_rect.bottom() - 4));
- }
-}
-
-void MmlRootBaseNode::paintSymbol(QPainter *p) const
-{
- QFont fn = font();
-
- p->save();
-
- QRect sr = symbolRect();
-
- QRect r = sr;
- r.moveTopLeft(devicePoint(sr.topLeft()));
- p->setViewport(r);
- p->setWindow(QFontMetrics(fn).boundingRect(g_radical_char));
- p->setFont(font());
- p->drawText(0, 0, QString(g_radical_char));
-
- p->restore();
-
- p->drawLine(sr.right(), sr.top(), myRect().right(), sr.top());
-}
-
-MmlTextNode::MmlTextNode(const QString &text, MmlDocument *document)
- : MmlNode(TextNode, document, MmlAttributeMap())
-{
- m_text = text;
- // Trim whitespace from ends, but keep nbsp and thinsp
- m_text.remove(QRegExp("^[^\\S\\x00a0\\x2009]+"));
- m_text.remove(QRegExp("[^\\S\\x00a0\\x2009]+$"));
-
- if (m_text == QString(QChar(0x62, 0x20)) // ⁢
- || m_text == QString(QChar(0x63, 0x20)) // ⁣
- || m_text == QString(QChar(0x61, 0x20))) // ⁡
- m_text = "";
-}
-
-QString MmlTextNode::toStr() const
-{
- return MmlNode::toStr() + ", text=\"" + m_text + "\"";
-}
-
-void MmlTextNode::paintSymbol(QPainter *p) const
-{
- MmlNode::paintSymbol(p);
-
- QFont fn = font();
-
- QFontInfo fi(fn);
-// qWarning("MmlTextNode::paintSymbol(): requested: %s, used: %s, size=%d, italic=%d, bold=%d, text=\"%s\" sl=%d",
-// fn.family().latin1(), fi.family().latin1(), fi.pointSize(), (int)fi.italic(), (int)fi.bold(), m_text.latin1(), scriptlevel());
-
- QFontMetrics fm(fn);
-
- p->save();
- p->setFont(fn);
-
- p->drawText(0, fm.strikeOutPos(), m_text);
- p->restore();
-}
-
-QRect MmlTextNode::symbolRect() const
-{
- QFontMetrics fm(font());
-
- QRect br = fm.tightBoundingRect(m_text);
- br.translate(0, fm.strikeOutPos());
-
- return br;
-}
-
-MmlNode *MmlSubsupBaseNode::base() const
-{
- MmlNode *b = firstChild();
- Q_ASSERT(b != 0);
- return b;
-}
-
-MmlNode *MmlSubsupBaseNode::sscript() const
-{
- MmlNode *s = base()->nextSibling();
- Q_ASSERT(s != 0);
- return s;
-}
-
-int MmlSubsupBaseNode::scriptlevel(const MmlNode *child) const
-{
- int sl = MmlNode::scriptlevel();
-
- MmlNode *s = sscript();
- if (child != 0 && child == s)
- return sl + 1;
- else
- return sl;
-}
-
-void MmlMsupNode::layoutSymbol()
-{
- MmlNode *b = base();
- MmlNode *s = sscript();
-
- b->setRelOrigin(QPoint(-b->myRect().width(), 0));
- s->setRelOrigin(QPoint(0, b->myRect().top()));
-}
-
-void MmlMsubNode::layoutSymbol()
-{
- MmlNode *b = base();
- MmlNode *s = sscript();
-
- b->setRelOrigin(QPoint(-b->myRect().width(), 0));
- s->setRelOrigin(QPoint(0, b->myRect().bottom()));
-}
-
-MmlNode *MmlMsubsupNode::base() const
-{
- MmlNode *b = firstChild();
- Q_ASSERT(b != 0);
- return b;
-}
-
-MmlNode *MmlMsubsupNode::subscript() const
-{
- MmlNode *sub = base()->nextSibling();
- Q_ASSERT(sub != 0);
- return sub;
-}
-
-MmlNode *MmlMsubsupNode::superscript() const
-{
- MmlNode *sup = subscript()->nextSibling();
- Q_ASSERT(sup != 0);
- return sup;
-}
-
-void MmlMsubsupNode::layoutSymbol()
-{
- MmlNode *b = base();
- MmlNode *sub = subscript();
- MmlNode *sup = superscript();
-
- b->setRelOrigin(QPoint(-b->myRect().width(), 0));
- sub->setRelOrigin(QPoint(0, b->myRect().bottom()));
- sup->setRelOrigin(QPoint(0, b->myRect().top()));
-}
-
-int MmlMsubsupNode::scriptlevel(const MmlNode *child) const
-{
- int sl = MmlNode::scriptlevel();
-
- MmlNode *sub = subscript();
- MmlNode *sup = superscript();
-
- if (child != 0 && (child == sup || child == sub))
- return sl + 1;
- else
- return sl;
-}
-
-QString MmlMoNode::toStr() const
-{
- return MmlNode::toStr() + QString(" form=%1").arg((int)form());
-}
-
-void MmlMoNode::layoutSymbol()
-{
- MmlNode *child = firstChild();
- if (child == 0)
- return;
-
- child->setRelOrigin(QPoint(0, 0));
-
- if (m_oper_spec == 0)
- m_oper_spec = mmlFindOperSpec(text(), form());
-}
-
-MmlMoNode::MmlMoNode(MmlDocument *document, const MmlAttributeMap &attribute_map)
- : MmlTokenNode(MoNode, document, attribute_map)
-{
- m_oper_spec = 0;
-}
-
-QString MmlMoNode::dictionaryAttribute(const QString &name) const
-{
- const MmlNode *p = this;
- for (; p != 0; p = p->parent()) {
- if (p == this || p->nodeType() == MstyleNode) {
- QString expl_attr = p->explicitAttribute(name);
- if (!expl_attr.isNull())
- return expl_attr;
- }
- }
-
- return mmlDictAttribute(name, m_oper_spec);
-}
-
-Mml::FormType MmlMoNode::form() const
-{
- QString value_str = inheritAttributeFromMrow("form");
- if (!value_str.isNull()) {
- bool ok;
- FormType value = interpretForm(value_str, &ok);
- if (ok)
- return value;
- else
- qWarning("Could not convert %s to form", value_str.toLatin1().data());
-
- }
-
- // Default heuristic.
- if (firstSibling() == (MmlNode*)this && lastSibling() != (MmlNode*)this)
- return PrefixForm;
- else if (lastSibling() == (MmlNode*)this && firstSibling() != (MmlNode*)this)
- return PostfixForm;
- else return InfixForm;
-
-}
-
-void MmlMoNode::stretch()
-{
- if (parent() == 0)
- return;
-
- if (m_oper_spec == 0)
- return;
-
- if (m_oper_spec->stretch_dir == OperSpec::HStretch
- && parent()->nodeType() == MrowNode
- && (nextSibling() != 0 || previousSibling() != 0))
- return;
-
- QRect pmr = parent()->myRect();
- QRect pr = parentRect();
-
- switch (m_oper_spec->stretch_dir) {
- case OperSpec::VStretch:
- stretchTo(QRect(pr.left(), pmr.top(), pr.width(), pmr.height()));
- break;
- case OperSpec::HStretch:
- stretchTo(QRect(pmr.left(), pr.top(), pmr.width(), pr.height()));
- break;
- case OperSpec::HVStretch:
- stretchTo(pmr);
- break;
- case OperSpec::NoStretch:
- break;
- }
-}
-
-int MmlMoNode::lspace() const
-{
- Q_ASSERT(m_oper_spec != 0);
- if (parent() == 0
- || (parent()->nodeType() != MrowNode
- && parent()->nodeType() != MfencedNode
- && parent()->nodeType() != UnknownNode)
- || (previousSibling() == 0 && nextSibling() == 0))
- return 0;
- else
- return interpretSpacing(dictionaryAttribute("lspace"), 0);
-}
-
-int MmlMoNode::rspace() const
-{
- Q_ASSERT(m_oper_spec != 0);
- if (parent() == 0
- || (parent()->nodeType() != MrowNode
- && parent()->nodeType() != MfencedNode
- && parent()->nodeType() != UnknownNode)
- || (previousSibling() == 0 && nextSibling() == 0))
- return 0;
- else
- return interpretSpacing(dictionaryAttribute("rspace"), 0);
-}
-
-QRect MmlMoNode::symbolRect() const
-{
- const MmlNode *child = firstChild();
-
- if (child == 0)
- return QRect(0, 0, 0, 0);
-
- QRect cmr = child->myRect();
-
- return QRect(-lspace(), cmr.top(),
- cmr.width() + lspace() + rspace(), cmr.height());
-}
-
-int MmlMtableNode::rowspacing() const
-{
- QString value = explicitAttribute("rowspacing");
- if (value.isNull())
- return ex();
- bool ok;
- int r = interpretSpacing(value, &ok);
-
- if (ok)
- return r;
- else
- return ex();
-}
-
-int MmlMtableNode::columnspacing() const
-{
- QString value = explicitAttribute("columnspacing");
- if (value.isNull())
- return (int)(0.8*em());
- bool ok;
- int r = interpretSpacing(value, &ok);
-
- if (ok)
- return r;
- else
- return (int)(0.8*em());
-}
-
-uint MmlMtableNode::CellSizeData::colWidthSum() const
-{
- uint w = 0;
- for (int i = 0; i < col_widths.count(); ++i)
- w += col_widths[i];
- return w;
-}
-
-uint MmlMtableNode::CellSizeData::rowHeightSum() const
-{
- uint h = 0;
- for (int i = 0; i < row_heights.count(); ++i)
- h += row_heights[i];
- return h;
-}
-
-void MmlMtableNode::CellSizeData::init(const MmlNode *first_row)
-{
- col_widths.clear();
- row_heights.clear();
-
- const MmlNode *mtr = first_row;
- for (; mtr != 0; mtr = mtr->nextSibling()) {
-
- Q_ASSERT(mtr->nodeType() == MtrNode);
-
- int col_cnt = 0;
- const MmlNode *mtd = mtr->firstChild();
- for (; mtd != 0; mtd = mtd->nextSibling(), ++col_cnt) {
-
- Q_ASSERT(mtd->nodeType() == MtdNode);
-
- QRect mtdmr = mtd->myRect();
-
- if (col_cnt == col_widths.count())
- col_widths.append(mtdmr.width());
- else
- col_widths[col_cnt] = qMax(col_widths[col_cnt], mtdmr.width());
- }
-
- row_heights.append(mtr->myRect().height());
- }
-}
-
-void MmlMtableNode::layoutSymbol()
-{
- // Obtain natural widths of columns
- m_cell_size_data.init(firstChild());
-
- int col_spc = columnspacing();
- int row_spc = rowspacing();
- int frame_spc_hor = framespacing_hor();
- QString columnwidth_attr = explicitAttribute("columnwidth", "auto");
-
- // Is table width set by user? If so, set col_width_sum and never ever change it.
- int col_width_sum = m_cell_size_data.colWidthSum();
- bool width_set_by_user = false;
- QString width_str = explicitAttribute("width", "auto");
- if (width_str != "auto") {
- bool ok;
-
- int w = interpretSpacing(width_str, &ok);
- if (ok) {
- col_width_sum = w
- - col_spc*(m_cell_size_data.numCols() - 1)
- - frame_spc_hor*2;
- width_set_by_user = true;
- }
- }
-
- // Find out what kind of columns we are dealing with and set the widths of
- // statically sized columns.
- int fixed_width_sum = 0; // sum of widths of statically sized set columns
- int auto_width_sum = 0; // sum of natural widths of auto sized columns
- int relative_width_sum = 0; // sum of natural widths of relatively sized columns
- double relative_fraction_sum = 0; // total fraction of width taken by relatively
- // sized columns
- int i;
- for (i = 0; i < m_cell_size_data.numCols(); ++i) {
- QString value = interpretListAttr(columnwidth_attr, i, "auto");
-
- // Is it an auto sized column?
- if (value == "auto" || value == "fit") {
- auto_width_sum += m_cell_size_data.col_widths[i];
- continue;
- }
-
- // Is it a statically sized column?
- bool ok;
- int w = interpretSpacing(value, &ok);
- if (ok) {
- // Yup, sets its width to the user specified value
- m_cell_size_data.col_widths[i] = w;
- fixed_width_sum += w;
- continue;
- }
-
- // Is it a relatively sized column?
- if (value.endsWith("%")) {
- value.truncate(value.length() - 1);
- double factor = value.toFloat(&ok);
- if (ok && !value.isEmpty()) {
- factor /= 100.0;
- relative_width_sum += m_cell_size_data.col_widths[i];
- relative_fraction_sum += factor;
- if (!width_set_by_user) {
- // If the table width was not set by the user, we are free to increase
- // it so that the width of this column will be >= than its natural width
- int min_col_width_sum = ROUND(m_cell_size_data.col_widths[i]/factor);
- if (min_col_width_sum > col_width_sum)
- col_width_sum = min_col_width_sum;
- }
- continue;
- }
- else
- qWarning("MmlMtableNode::layoutSymbol(): could not parse value %s%%", value.toLatin1().data());
- }
-
- // Relatively sized column, but we failed to parse the factor. Treat is like an auto
- // column.
- auto_width_sum += m_cell_size_data.col_widths[i];
- }
-
- // Work out how much space remains for the auto olumns, after allocating
- // the statically sized and the relatively sized columns.
- int required_auto_width_sum = col_width_sum
- - ROUND(relative_fraction_sum*col_width_sum)
- - fixed_width_sum;
-
- if (!width_set_by_user && required_auto_width_sum < auto_width_sum) {
- if (relative_fraction_sum < 1)
- col_width_sum = ROUND((fixed_width_sum + auto_width_sum)/(1 - relative_fraction_sum));
- else
- col_width_sum = fixed_width_sum + auto_width_sum + relative_width_sum;
- required_auto_width_sum = auto_width_sum;
- }
-
- // Ratio by which we have to shring/grow all auto sized columns to make it all fit
- double auto_width_scale = 1;
- if (auto_width_sum > 0)
- auto_width_scale = (float)required_auto_width_sum/auto_width_sum;
-
- // Set correct sizes for the auto sized and the relatively sized columns.
- for (i = 0; i < m_cell_size_data.numCols(); ++i) {
- QString value = interpretListAttr(columnwidth_attr, i, "auto");
-
- // Is it a relatively sized column?
- if (value.endsWith("%")) {
- bool ok;
- int w = interpretPercentSpacing(value, col_width_sum, &ok);
- if (ok)
- m_cell_size_data.col_widths[i] = w;
- else
- // We're treating parsing errors here as auto sized columns
- m_cell_size_data.col_widths[i]
- = ROUND(auto_width_scale*m_cell_size_data.col_widths[i]);
- }
- // Is it an auto sized column?
- else if (value == "auto") {
- m_cell_size_data.col_widths[i]
- = ROUND(auto_width_scale*m_cell_size_data.col_widths[i]);
- }
- }
-
- QString s;
- QList<int> &col_widths = m_cell_size_data.col_widths;
- for (i = 0; i < col_widths.count(); ++i) {
- s += QString("[w=%1 %2%%]")
- .arg(col_widths[i])
- .arg(100*col_widths[i]/m_cell_size_data.colWidthSum());
- }
-// qWarning(s);
-
- m_content_width = m_cell_size_data.colWidthSum()
- + col_spc*(m_cell_size_data.numCols() - 1);
- m_content_height = m_cell_size_data.rowHeightSum()
- + row_spc*(m_cell_size_data.numRows() - 1);
-
- int bottom = -m_content_height/2;
- MmlNode *child = firstChild();
- for (; child != 0; child = child->nextSibling()) {
- Q_ASSERT(child->nodeType() == MtrNode);
- MmlMtrNode *row = (MmlMtrNode*) child;
-
- row->layoutCells(m_cell_size_data.col_widths, col_spc);
- QRect rmr = row->myRect();
- row->setRelOrigin(QPoint(0, bottom - rmr.top()));
- bottom += rmr.height() + row_spc;
- }
-}
-
-QRect MmlMtableNode::symbolRect() const
-{
- int frame_spc_hor = framespacing_hor();
- int frame_spc_ver = framespacing_ver();
-
- return QRect(-frame_spc_hor,
- -m_content_height/2 - frame_spc_ver,
- m_content_width + 2*frame_spc_hor,
- m_content_height + 2*frame_spc_ver);
-}
-
-Mml::FrameType MmlMtableNode::frame() const
-{
- QString value = explicitAttribute("frame", "none");
- return interpretFrameType(value, 0, 0);
-}
-
-Mml::FrameType MmlMtableNode::columnlines(int idx) const
-{
- QString value = explicitAttribute("columnlines", "none");
- return interpretFrameType(value, idx, 0);
-}
-
-Mml::FrameType MmlMtableNode::rowlines(int idx) const
-{
- QString value = explicitAttribute("rowlines", "none");
- return interpretFrameType(value, idx, 0);
-}
-
-void MmlMtableNode::paintSymbol(QPainter *p) const
-{
- FrameType f = frame();
- if (f != FrameNone) {
- p->save();
-
- QPen pen = p->pen();
- if (f == FrameDashed)
- pen.setStyle(Qt::DashLine);
- else
- pen.setStyle(Qt::SolidLine);
- p->setPen(pen);
- p->drawRect(myRect());
-
- p->restore();
- }
-
- p->save();
-
- int col_spc = columnspacing();
- int row_spc = rowspacing();
-
- QPen pen = p->pen();
- int col_offset = 0;
- int i;
- for (i = 0; i < m_cell_size_data.numCols() - 1; ++i) {
- FrameType f = columnlines(i);
- col_offset += m_cell_size_data.col_widths[i];
-
- if (f != FrameNone) {
- if (f == FrameDashed)
- pen.setStyle(Qt::DashLine);
- else if (f == FrameSolid)
- pen.setStyle(Qt::SolidLine);
-
- p->setPen(pen);
- int x = col_offset + col_spc/2;
- p->drawLine(x, -m_content_height/2, x, m_content_height/2 );
- }
- col_offset += col_spc;
- }
-
- int row_offset = 0;
- for (i = 0; i < m_cell_size_data.numRows() - 1; ++i) {
- FrameType f = rowlines(i);
- row_offset += m_cell_size_data.row_heights[i];
-
- if (f != FrameNone) {
- if (f == FrameDashed)
- pen.setStyle(Qt::DashLine);
- else if (f == FrameSolid)
- pen.setStyle(Qt::SolidLine);
-
- p->setPen(pen);
- int y = row_offset + row_spc/2 - m_content_height/2;
- p->drawLine(0, y, m_content_width, y);
- }
- row_offset += row_spc;
- }
-
- p->restore();
-}
-
-int MmlMtableNode::framespacing_ver() const
-{
- if (frame() == FrameNone)
- return (int)(0.2*em());
-
- QString value = explicitAttribute("framespacing", "0.4em 0.5ex");
-
- bool ok;
- FrameSpacing fs = interpretFrameSpacing(value, em(), ex(), &ok);
- if (ok)
- return fs.m_ver;
- else
- return (int)(0.5*ex());
-}
-
-int MmlMtableNode::framespacing_hor() const
-{
- if (frame() == FrameNone)
- return (int)(0.2*em());
-
- QString value = explicitAttribute("framespacing", "0.4em 0.5ex");
-
- bool ok;
- FrameSpacing fs = interpretFrameSpacing(value, em(), ex(), &ok);
- if (ok)
- return fs.m_hor;
- else
- return (int)(0.4*em());
-}
-
-void MmlMtrNode::layoutCells(const QList<int> &col_widths,
- int col_spc)
-{
- QRect mr = myRect();
-
- MmlNode *child = firstChild();
- int col_offset = 0;
- uint colnum = 0;
- for (; child != 0; child = child->nextSibling(), ++colnum) {
- Q_ASSERT(child->nodeType() == MtdNode);
- MmlMtdNode *mtd = (MmlMtdNode*) child;
-
- QRect r = QRect(0, mr.top(), col_widths[colnum], mr.height());
- mtd->setMyRect(r);
- mtd->setRelOrigin(QPoint(col_offset, 0));
- col_offset += col_widths[colnum] + col_spc;
- }
-
- updateMyRect();
-}
-
-int MmlMtdNode::scriptlevel(const MmlNode *child) const
-{
- int sl = MmlNode::scriptlevel();
- if (child != 0 && child == firstChild())
- return sl + m_scriptlevel_adjust;
- else
- return sl;
-}
-
-void MmlMtdNode::setMyRect(const QRect &rect)
-{
- MmlNode::setMyRect(rect);
- MmlNode *child = firstChild();
- if (child == 0)
- return;
-
- if (rect.width() < child->myRect().width()) {
- while (rect.width() < child->myRect().width()
- && child->font().pointSize() > g_min_font_point_size) {
-
-// qWarning("MmlMtdNode::setMyRect(): rect.width()=%d, child()->myRect().width=%d sl=%d",
-// rect.width(), child->myRect().width(), m_scriptlevel_adjust);
-
- ++m_scriptlevel_adjust;
- child->layout();
- }
-
-// qWarning("MmlMtdNode::setMyRect(): rect.width()=%d, child()->myRect().width=%d sl=%d",
-// rect.width(), child->myRect().width(), m_scriptlevel_adjust);
- }
-
- QRect mr = myRect();
- QRect cmr = child->myRect();
-
- QPoint child_rel_origin;
-
- switch (columnalign()) {
- case ColAlignLeft:
- child_rel_origin.setX(0);
- break;
- case ColAlignCenter:
- child_rel_origin.setX(mr.left() + (mr.width() - cmr.width())/2);
- break;
- case ColAlignRight:
- child_rel_origin.setX(mr.right() - cmr.width());
- break;
- }
-
- switch (rowalign()) {
- case RowAlignTop:
- child_rel_origin.setY(mr.top() - cmr.top());
- break;
- case RowAlignCenter:
- case RowAlignBaseline:
- child_rel_origin.setY(mr.top() -cmr.top() + (mr.height() - cmr.height())/2);
- break;
- case RowAlignBottom:
- child_rel_origin.setY(mr.bottom() - cmr.bottom());
- break;
- case RowAlignAxis:
- child_rel_origin.setY(0);
- break;
- }
-
- child->setRelOrigin(child_rel_origin);
-}
-
-uint MmlMtdNode::colNum()
-{
- MmlNode *syb = previousSibling();
-
- uint i = 0;
- for (; syb != 0; syb = syb->previousSibling())
- ++i;
-
- return i;
-}
-
-uint MmlMtdNode::rowNum()
-{
- MmlNode *row = parent()->previousSibling();
-
- uint i = 0;
- for (; row != 0; row = row->previousSibling())
- ++i;
-
- return i;
-}
-
-MmlMtdNode::ColAlign MmlMtdNode::columnalign()
-{
- QString val = explicitAttribute("columnalign");
- if (!val.isNull())
- return interpretColAlign(val, 0, 0);
-
- MmlNode *node = parent(); // <mtr>
- if (node == 0)
- return ColAlignCenter;
-
- uint colnum = colNum();
- val = node->explicitAttribute("columnalign");
- if (!val.isNull())
- return interpretColAlign(val, colnum, 0);
-
- node = node->parent(); // <mtable>
- if (node == 0)
- return ColAlignCenter;
-
- val = node->explicitAttribute("columnalign");
- if (!val.isNull())
- return interpretColAlign(val, colnum, 0);
-
- return ColAlignCenter;
-}
-
-MmlMtdNode::RowAlign MmlMtdNode::rowalign()
-{
- QString val = explicitAttribute("rowalign");
- if (!val.isNull())
- return interpretRowAlign(val, 0, 0);
-
- MmlNode *node = parent(); // <mtr>
- if (node == 0)
- return RowAlignAxis;
-
- uint rownum = rowNum();
- val = node->explicitAttribute("rowalign");
- if (!val.isNull())
- return interpretRowAlign(val, rownum, 0);
-
- node = node->parent(); // <mtable>
- if (node == 0)
- return RowAlignAxis;
-
- val = node->explicitAttribute("rowalign");
- if (!val.isNull())
- return interpretRowAlign(val, rownum, 0);
-
- return RowAlignAxis;
-}
-
-void MmlMoverNode::layoutSymbol()
-{
- MmlNode *base = firstChild();
- Q_ASSERT(base != 0);
- MmlNode *over = base->nextSibling();
- Q_ASSERT(over != 0);
-
- QRect base_rect = base->myRect();
- QRect over_rect = over->myRect();
-
- int spacing = (int)(g_mfrac_spacing*(over_rect.height()
- + base_rect.height()));
-
- base->setRelOrigin(QPoint(-base_rect.width()/2, 0));
- over->setRelOrigin(QPoint(-over_rect.width()/2,
- base_rect.top() - spacing - over_rect.bottom()));
-}
-
-int MmlMoverNode::scriptlevel(const MmlNode *node) const
-{
- MmlNode *base = firstChild();
- Q_ASSERT(base != 0);
- MmlNode *over = base->nextSibling();
- Q_ASSERT(over != 0);
-
- int sl = MmlNode::scriptlevel();
- if (node != 0 && node == over)
- return sl + 1;
- else
- return sl;
-}
-
-void MmlMunderNode::layoutSymbol()
-{
- MmlNode *base = firstChild();
- Q_ASSERT(base != 0);
- MmlNode *under = base->nextSibling();
- Q_ASSERT(under != 0);
-
- QRect base_rect = base->myRect();
- QRect under_rect = under->myRect();
-
- int spacing = (int)(g_mfrac_spacing*(under_rect.height() + base_rect.height()));
-
- base->setRelOrigin(QPoint(-base_rect.width()/2, 0));
- under->setRelOrigin(QPoint(-under_rect.width()/2, base_rect.bottom() + spacing - under_rect.top()));
-}
-
-int MmlMunderNode::scriptlevel(const MmlNode *node) const
-{
- MmlNode *base = firstChild();
- Q_ASSERT(base != 0);
- MmlNode *under = base->nextSibling();
- Q_ASSERT(under != 0);
-
- int sl = MmlNode::scriptlevel();
- if (node != 0 && node == under)
- return sl + 1;
- else
- return sl;
-}
-
-void MmlMunderoverNode::layoutSymbol()
-{
- MmlNode *base = firstChild();
- Q_ASSERT(base != 0);
- MmlNode *under = base->nextSibling();
- Q_ASSERT(under != 0);
- MmlNode *over = under->nextSibling();
- Q_ASSERT(over != 0);
-
- QRect base_rect = base->myRect();
- QRect under_rect = under->myRect();
- QRect over_rect = over->myRect();
-
- int spacing = (int)(g_mfrac_spacing*( base_rect.height()
- + under_rect.height()
- + over_rect.height()) );
-
- base->setRelOrigin(QPoint(-base_rect.width()/2, 0));
- under->setRelOrigin(QPoint(-under_rect.width()/2, base_rect.bottom() + spacing - under_rect.top()));
- over->setRelOrigin(QPoint(-over_rect.width()/2, base_rect.top() - spacing - under_rect.bottom()));
-}
-
-int MmlMunderoverNode::scriptlevel(const MmlNode *node) const
-{
- MmlNode *base = firstChild();
- Q_ASSERT(base != 0);
- MmlNode *under = base->nextSibling();
- Q_ASSERT(under != 0);
- MmlNode *over = under->nextSibling();
- Q_ASSERT(over != 0);
-
- int sl = MmlNode::scriptlevel();
- if (node != 0 && (node == under || node == over))
- return sl + 1;
- else
- return sl;
-}
-
-int MmlMpaddedNode::interpretSpacing(QString value, int base_value, bool *ok) const
-{
- if (ok != 0)
- *ok = false;
-
- value.replace(' ', "");
-
- QString sign, factor_str, pseudo_unit;
- bool percent = false;
-
- // extract the sign
- int idx = 0;
- if (idx < value.length() && (value.at(idx) == '+' || value.at(idx) == '-'))
- sign = value.at(idx++);
-
- // extract the factor
- while (idx < value.length() && (value.at(idx).isDigit() || value.at(idx) == '.'))
- factor_str.append(value.at(idx++));
-
- // extract the % sign
- if (idx < value.length() && value.at(idx) == '%') {
- percent = true;
- ++idx;
- }
-
- // extract the pseudo-unit
- pseudo_unit = value.mid(idx);
-
- bool float_ok;
- double factor = factor_str.toFloat(&float_ok);
- if (!float_ok || factor < 0) {
- qWarning("MmlMpaddedNode::interpretSpacing(): could not parse \"%s\"", value.toLatin1().data());
- return 0;
- }
-
- if (percent)
- factor /= 100.0;
-
- QRect cr;
- if (firstChild() == 0)
- cr = QRect(0, 0, 0, 0);
- else
- cr = firstChild()->myRect();
-
- int unit_size;
-
- if (pseudo_unit.isEmpty())
- unit_size = base_value;
- else if (pseudo_unit == "width")
- unit_size = cr.width();
- else if (pseudo_unit == "height")
- unit_size = -cr.top();
- else if (pseudo_unit == "depth")
- unit_size = cr.bottom();
- else {
- bool unit_ok;
- unit_size = MmlNode::interpretSpacing("1" + pseudo_unit, &unit_ok);
- if (!unit_ok) {
- qWarning("MmlMpaddedNode::interpretSpacing(): could not parse \"%s\"", value.toLatin1().data());
- return 0;
- }
- }
-
- if (ok != 0)
- *ok = true;
-
- if (sign.isNull())
- return (int)(factor*unit_size);
- else if (sign == "+")
- return base_value + (int)(factor*unit_size);
- else // sign == "-"
- return base_value - (int)(factor*unit_size);
-}
-
-int MmlMpaddedNode::lspace() const
-{
- QString value = explicitAttribute("lspace");
-
- if (value.isNull())
- return 0;
-
- bool ok;
- int lspace = interpretSpacing(value, 0, &ok);
-
- if (ok)
- return lspace;
-
- return 0;
-}
-
-int MmlMpaddedNode::width() const
-{
- int child_width = 0;
- if (firstChild() != 0)
- child_width = firstChild()->myRect().width();
-
- QString value = explicitAttribute("width");
- if (value.isNull())
- return child_width;
-
- bool ok;
- int w = interpretSpacing(value, child_width, &ok);
- if (ok)
- return w;
-
- return child_width;
-}
-
-int MmlMpaddedNode::height() const
-{
- QRect cr;
- if (firstChild() == 0)
- cr = QRect(0, 0, 0, 0);
- else
- cr = firstChild()->myRect();
-
- QString value = explicitAttribute("height");
- if (value.isNull())
- return -cr.top();
-
- bool ok;
- int h = interpretSpacing(value, -cr.top(), &ok);
- if (ok)
- return h;
-
- return -cr.top();
-}
-
-int MmlMpaddedNode::depth() const
-{
- QRect cr;
- if (firstChild() == 0)
- cr = QRect(0, 0, 0, 0);
- else
- cr = firstChild()->myRect();
-
- QString value = explicitAttribute("depth");
- if (value.isNull())
- return cr.bottom();
-
- bool ok;
- int h = interpretSpacing(value, cr.bottom(), &ok);
- if (ok)
- return h;
-
- return cr.bottom();
-}
-
-void MmlMpaddedNode::layoutSymbol()
-{
- MmlNode *child = firstChild();
- if (child == 0)
- return;
-
- child->setRelOrigin(QPoint(0, 0));
-}
-
-
-QRect MmlMpaddedNode::symbolRect() const
-{
- return QRect(-lspace(), -height(), lspace() + width(), height() + depth());
-}
-
-// *******************************************************************
-// QtMmlWidget
-// *******************************************************************
-
-/*!
- \class QtMmlWidget
-
- \brief The QtMmlWidget class renders mathematical formulas written in MathML 2.0.
-
- QtMmlWidget implements the Presentation Markup subset of the
- MathML 2.0 specification, with a few \link overview.html exceptions\endlink.
-
- \code
- QtMmlWidget *mmlWidget = new QtMmlWidget(this);
- QString errorMsg;
- int errorLine;
- int errorColumn;
- bool ok = mmlWidget->setContent(mmlText, &errorMsg, &errorLine, &errorColumn);
- if (!ok) {
- qWarning("MathML error: %s, Line: %d, Column: %d",
- errorMsg.latin1(), errorLine, errorColumn);
- }
- \endcode
-
-*/
-
-
-/*!
- \enum QtMmlWidget::MmlFont
-
- This ennumerated type is used in fontName() and setFontName() to
- specify a font type.
-
- \value NormalFont The default font type, used to render
- expressions for which no mathvariant or fontfamily is specified,
- or for which the "normal" mathvariant is specified.
-
- \value FrakturFont The font type used to render expressions for
- which the "fraktur" mathvariant is specified.
-
- \value SansSerifFont The font type used to render expressions
- for which the "sans-serif" mathvariant is specified.
-
- \value ScriptFont The font type used to render expressions
- for which the "script" mathvariant is specified.
-
- \value MonospaceFont The font type used to render expressions
- for which the "monospace" mathvariant is specified.
-
- \value DoublestruckFont The font type used to render expressions
- for which the "doublestruck" mathvariant is specified.
-
- \sa setFontName() fontName() setBaseFontPointSize() baseFontPointSize()
-*/
-
-/*!
- Constructs a QtMmlWidget object. The \a parent
- parameter is passed to QFrame's constructor.
-*/
-
-QtMmlWidget::QtMmlWidget(QWidget *parent)
- : QFrame(parent)
-{
- m_doc = new MmlDocument;
-}
-
-/*!
- Destructs a QtMmlWidget object.
-*/
-
-QtMmlWidget::~QtMmlWidget()
-{
- delete m_doc;
-}
-
-/*!
- Returns the name of the font used to render the font \a type.
-
- \sa setFontName() setBaseFontPointSize() baseFontPointSize() QtMmlWidget::MmlFont
-*/
-
-QString QtMmlWidget::fontName(MmlFont type) const
-{
- return m_doc->fontName(type);
-}
-
-/*!
- Sets the name of the font used to render the font \a type to \a name.
-
- \sa fontName() setBaseFontPointSize() baseFontPointSize() QtMmlWidget::MmlFont
-*/
-
-void QtMmlWidget::setFontName(MmlFont type, const QString &name)
-{
- m_doc->setFontName(type, name);
- m_doc->layout();
- update();
-}
-
-/*!
- If \a b is true, draws a red bounding rectangle around each
- expression; if \a b is false, no such rectangle is drawn.
- This is mostly useful for debugging MathML expressions.
-
- \sa drawFrames()
-*/
-
-void QtMmlWidget::setDrawFrames(bool b)
-{
- g_draw_frames = b;
- update();
-}
-
-/*!
- Returns true if each expression should be drawn with a red
- bounding rectangle; otherwise returns false.
- This is mostly useful for debugging MathML expressions.
-
- \sa setDrawFrames()
-*/
-
-bool QtMmlWidget::drawFrames() const
-{
- return g_draw_frames;
-}
-
-/*!
- Clears the contents of this widget.
-*/
-void QtMmlWidget::clear()
-{
- m_doc->clear();
-}
-
-/*!
- Returns the point size of the font used to render expressions
- whose scriptlevel is 0.
-
- \sa setBaseFontPointSize() fontName() setFontName()
-*/
-
-int QtMmlWidget::baseFontPointSize() const
-{
- return m_doc->baseFontPointSize();
-}
-
-/*!
- Sets the point \a size of the font used to render expressions
- whose scriptlevel is 0.
-
- \sa baseFontPointSize() fontName() setFontName()
-*/
-
-void QtMmlWidget::setBaseFontPointSize(int size)
-{
- if (size < g_min_font_point_size)
- return;
-
- m_doc->setBaseFontPointSize(size);
- m_doc->layout();
- update();
-}
-
-/*!
- Returns the size of the formula in pixels.
-*/
-
-QSize QtMmlWidget::sizeHint() const
-{
- QSize size = m_doc->size();
- if (size == QSize(0, 0))
- return QSize(100, 50);
- return m_doc->size();
-}
-
-/*!
- Sets the MathML expression to be rendered. The expression is given
- in the string \a text. If the expression is successfully parsed,
- this method returns true; otherwise it returns false. If an error
- occured \a errorMsg is set to a diagnostic message, while \a
- errorLine and \a errorColumn contain the location of the error.
- Any of \a errorMsg, \a errorLine and \a errorColumn may be 0,
- in which case they are not set.
-
- \a text should contain MathML 2.0 presentation markup elements enclosed
- in a <math> element.
-*/
-
-bool QtMmlWidget::setContent(const QString &text, QString *errorMsg,
- int *errorLine, int *errorColumn)
-{
- bool result = m_doc->setContent(text, errorMsg, errorLine, errorColumn);
- if (result)
- update();
- return result;
-}
-
-/*! \internal */
-
-void QtMmlWidget::paintEvent(QPaintEvent *e)
-{
- QFrame::paintEvent(e);
- QPainter p(this);
- if (e->rect().intersects(contentsRect()))
- p.setClipRegion(e->region().intersect(contentsRect()));
-
- QSize s = m_doc->size();
- int x = (width() - s.width())/2;
- int y = (height() - s.height())/2;
- m_doc->paint(&p, QPoint(x, y));
-}
-
-/*! \internal */
-
-void QtMmlWidget::dump() const
-{
- m_doc->dump();
-}
-
-// *******************************************************************
-// Static helper functions
-// *******************************************************************
-
-static QString entityDeclarations()
-{
- QString result = "<!DOCTYPE math [\n";
-
- const EntitySpec *ent = g_xml_entity_data;
- for (; ent->name != 0; ++ent) {
- result += "\t<!ENTITY " + QString(ent->name) + " \"" + ent->value + "\">\n";
- }
-
- result += "]>\n";
-
- return result;
-}
-
-static int interpretSpacing(QString value, int em, int ex, bool *ok)
-{
- if (ok != 0)
- *ok = true;
-
- if (value == "thin")
- return 1;
-
- if (value == "medium")
- return 2;
-
- if (value == "thick")
- return 3;
-
- struct HSpacingValue {
- const char *name;
- float factor;
- };
-
- static const HSpacingValue g_h_spacing_data[] =
- {
- { "veryverythinmathspace", (float) 0.0555556 },
- { "verythinmathspace", (float) 0.111111 },
- { "thinmathspace", (float) 0.166667 },
- { "mediummathspace", (float) 0.222222 },
- { "thickmathspace", (float) 0.277778 },
- { "verythickmathspace", (float) 0.333333 },
- { "veryverythickmathspace", (float) 0.388889 },
- { 0, (float) 0 }
- };
-
- const HSpacingValue *v = g_h_spacing_data;
- for (; v->name != 0; ++v) {
- if (value == v->name)
- return (int)(em*v->factor);
- }
-
- if (value.endsWith("em")) {
- value.truncate(value.length() - 2);
- bool float_ok;
- float factor = value.toFloat(&float_ok);
- if (float_ok && factor >= 0)
- return (int)(em*factor);
- else {
- qWarning("interpretSpacing(): could not parse \"%sem\"", value.toLatin1().data());
- if (ok != 0)
- *ok = false;
- return 0;
- }
- }
-
- if (value.endsWith("ex")) {
- value.truncate(value.length() - 2);
- bool float_ok;
- float factor = value.toFloat(&float_ok);
- if (float_ok && factor >= 0)
- return (int)(ex*factor);
- else {
- qWarning("interpretSpacing(): could not parse \"%sex\"", value.toLatin1().data());
- if (ok != 0)
- *ok = false;
- return 0;
- }
- }
-
- if (value.endsWith("cm")) {
- value.truncate(value.length() - 2);
- bool float_ok;
- float factor = value.toFloat(&float_ok);
- if (float_ok && factor >= 0) {
- Q_ASSERT(qApp->desktop() != 0);
- QDesktopWidget *dw = qApp->desktop();
- Q_ASSERT(dw->width() != 0);
- Q_ASSERT(dw->widthMM() != 0);
- return (int)(factor*10*dw->width()/dw->widthMM());
- }
- else {
- qWarning("interpretSpacing(): could not parse \"%scm\"", value.toLatin1().data());
- if (ok != 0)
- *ok = false;
- return 0;
- }
- }
-
- if (value.endsWith("mm")) {
- value.truncate(value.length() - 2);
- bool float_ok;
- float factor = value.toFloat(&float_ok);
- if (float_ok && factor >= 0) {
- Q_ASSERT(qApp->desktop() != 0);
- QDesktopWidget *dw = qApp->desktop();
- Q_ASSERT(dw->width() != 0);
- Q_ASSERT(dw->widthMM() != 0);
- return (int)(factor*dw->width()/dw->widthMM());
- }
- else {
- qWarning("interpretSpacing(): could not parse \"%smm\"", value.toLatin1().data());
- if (ok != 0)
- *ok = false;
- return 0;
- }
- }
-
- if (value.endsWith("in")) {
- value.truncate(value.length() - 2);
- bool float_ok;
- float factor = value.toFloat(&float_ok);
- if (float_ok && factor >= 0) {
- Q_ASSERT(qApp->desktop() != 0);
- QDesktopWidget *dw = qApp->desktop();
- Q_ASSERT(dw->width() != 0);
- Q_ASSERT(dw->widthMM() != 0);
- return (int)(factor*10*dw->width()/(2.54*dw->widthMM()));
- }
- else {
- qWarning("interpretSpacing(): could not parse \"%sin\"", value.toLatin1().data());
- if (ok != 0)
- *ok = false;
- return 0;
- }
- }
-
- if (value.endsWith("px")) {
- value.truncate(value.length() - 2);
- bool float_ok;
- int i = (int) value.toFloat(&float_ok);
- if (float_ok && i >= 0)
- return i;
- else {
- qWarning("interpretSpacing(): could not parse \"%spx\"", value.toLatin1().data());
- if (ok != 0)
- *ok = false;
- return 0;
- }
- }
-
- bool float_ok;
- int i = (int)value.toFloat(&float_ok);
- if (float_ok && i >= 0)
- return i;
-
- qWarning("interpretSpacing(): could not parse \"%s\"", value.toLatin1().data());
- if (ok != 0)
- *ok = false;
- return 0;
-}
-
-static int interpretPercentSpacing(QString value, int base, bool *ok)
-{
- if (!value.endsWith("%")) {
- if (ok != 0)
- *ok = false;
- return 0;
- }
-
- value.truncate(value.length() - 1);
- bool float_ok;
- float factor = value.toFloat(&float_ok);
- if (float_ok && factor >= 0) {
- if (ok != 0)
- *ok = true;
- return (int)(base*factor/100.0);
- }
-
- qWarning("interpretPercentSpacing(): could not parse \"%s%%\"", value.toLatin1().data());
- if (ok != 0)
- *ok = false;
- return 0;
-}
-
-static int interpretPointSize(QString value, bool *ok)
-{
- if (!value.endsWith("pt")) {
- if (ok != 0)
- *ok = false;
- return 0;
- }
-
- value.truncate(value.length() - 2);
- bool float_ok;
- int pt_size = (int) value.toFloat(&float_ok);
- if (float_ok && pt_size > 0) {
- if (ok != 0)
- *ok = true;
- return pt_size;
- }
-
- qWarning("interpretPointSize(): could not parse \"%spt\"", value.toLatin1().data());
- if (ok != 0)
- *ok = false;
- return 0;
-}
-
-static const NodeSpec *mmlFindNodeSpec(Mml::NodeType type)
-{
- const NodeSpec *spec = g_node_spec_data;
- for (; spec->type != Mml::NoNode; ++spec) {
- if (type == spec->type) return spec;
- }
- return 0;
-}
-
-static const NodeSpec *mmlFindNodeSpec(const QString &tag)
-{
- const NodeSpec *spec = g_node_spec_data;
- for (; spec->type != Mml::NoNode; ++spec) {
- if (tag == spec->tag) return spec;
- }
- return 0;
-}
-
-static bool mmlCheckChildType(Mml::NodeType parent_type, Mml::NodeType child_type,
- QString *error_str)
-{
- if (parent_type == Mml::UnknownNode || child_type == Mml::UnknownNode)
- return true;
-
- const NodeSpec *child_spec = mmlFindNodeSpec(child_type);
- const NodeSpec *parent_spec = mmlFindNodeSpec(parent_type);
-
- Q_ASSERT(parent_spec != 0);
- Q_ASSERT(child_spec != 0);
-
- QString allowed_child_types(parent_spec->child_types);
- // null list means any child type is valid
- if (allowed_child_types.isNull())
- return true;
-
- QString child_type_str = QString(" ") + child_spec->type_str + " ";
- if (!allowed_child_types.contains(child_type_str)) {
- if (error_str != 0)
- *error_str = QString("illegal child ")
- + child_spec->type_str
- + " for parent "
- + parent_spec->type_str;
- return false;
- }
-
- return true;
-}
-
-static bool mmlCheckAttributes(Mml::NodeType child_type, const MmlAttributeMap &attr,
- QString *error_str)
-{
- const NodeSpec *spec = mmlFindNodeSpec(child_type);
- Q_ASSERT(spec != 0);
-
- QString allowed_attr(spec->attributes);
- // empty list means any attr is valid
- if (allowed_attr.isEmpty())
- return true;
-
- MmlAttributeMap::const_iterator it = attr.begin(), end = attr.end();
- for (; it != end; ++it) {
- QString name = it.key();
-
- if (name.indexOf(':') != -1)
- continue;
-
- QString padded_name = " " + name + " ";
- if (!allowed_attr.contains(padded_name)) {
- if (error_str != 0)
- *error_str = QString("illegal attribute ")
- + name
- + " in "
- + spec->type_str;
- return false;
- }
- }
-
- return true;
-}
-
-static int attributeIndex(const QString &name)
-{
- for (unsigned i = 0; i < g_oper_spec_rows; ++i) {
- if (name == g_oper_spec_names[i])
- return i;
- }
- return -1;
-}
-
-static QString decodeEntityValue(QString literal)
-{
- QString result;
-
- while (!literal.isEmpty()) {
-
- if (!literal.startsWith("&#")) {
- qWarning("decodeEntityValue(): bad entity literal: \"%s\"", qPrintable(literal));
- return QString::null;
- }
-
- literal = literal.right(literal.length() - 2);
-
- int i = literal.indexOf(';');
- if (i == -1) {
- qWarning("decodeEntityValue(): bad entity literal: \"%s\"", qPrintable(literal));
- return QString::null;
- }
-
- QString char_code = literal.left(i);
- literal = literal.right(literal.length() - i - 1);
-
- if (char_code.isEmpty()) {
- qWarning("decodeEntityValue(): bad entity literal: \"%s\"", qPrintable(literal));
- return QString::null;
- }
-
- if (char_code.at(0) == 'x') {
- char_code = char_code.right(char_code.length() - 1);
- bool ok;
- unsigned c = char_code.toUInt(&ok, 16);
- if (!ok) {
- qWarning("decodeEntityValue(): bad entity literal: \"%s\"", qPrintable(literal));
- return QString::null;
- }
- result += QChar(c);
- }
- else {
- bool ok;
- unsigned c = char_code.toUInt(&ok, 10);
- if (!ok) {
- qWarning("decodeEntityValue(): bad entity literal: \"%s\"", qPrintable(literal));
- return QString::null;
- }
- result += QChar(c);
- }
- }
-
- return result;
-}
-
-static const EntitySpec *searchEntitySpecData(const QString &value, const EntitySpec *from = 0)
-{
- const EntitySpec *ent = from;
- if (ent == 0)
- ent = g_xml_entity_data;
- for (; ent->name != 0; ++ent) {
- QString ent_value = decodeEntityValue(ent->value);
- if (value == ent_value)
- return ent;
- }
- return 0;
-}
-
-struct OperSpecSearchResult
-{
- OperSpecSearchResult() { prefix_form = infix_form = postfix_form = 0; }
-
- const OperSpec *prefix_form,
- *infix_form,
- *postfix_form;
-
- const OperSpec *&getForm(Mml::FormType f);
- bool haveForm(Mml::FormType f)
- { return getForm(f) != 0; }
- void addForm(const OperSpec *spec)
- { getForm(spec->form) = spec; }
-};
-
-const OperSpec *&OperSpecSearchResult::getForm(Mml::FormType f)
-{
- switch (f) {
- case Mml::PrefixForm:
- return prefix_form;
- case Mml::InfixForm:
- return infix_form;
- case Mml::PostfixForm:
- return postfix_form;
- }
- return postfix_form; // just to avoid warning
-}
-
-/*
- Searches g_oper_spec_data and returns any instance of operator name. There may
- be more instances, but since the list is sorted, they will be next to each other.
-*/
-static const OperSpec *searchOperSpecData(const QString &name)
-{
- const char *name_latin1 = name.toLatin1().data();
-
- // binary search
- // establish invariant g_oper_spec_data[begin].name < name < g_oper_spec_data[end].name
-
- int cmp = qstrcmp(name_latin1, g_oper_spec_data[0].name);
- if (cmp < 0)
- return 0;
-
- if (cmp == 0)
- return g_oper_spec_data;
-
- uint begin = 0;
- uint end = g_oper_spec_count;
-
- // invariant holds
- while (end - begin > 1) {
- uint mid = (begin + end)/2;
-
- const OperSpec *spec = g_oper_spec_data + mid;
- int cmp = qstrcmp(name_latin1, spec->name);
- if (cmp < 0)
- end = mid;
- else if (cmp > 0)
- begin = mid;
- else
- return spec;
- }
-
- return 0;
-}
-
-/*
- This searches g_oper_spec_data until at least one name in name_list is found with FormType form,
- or until name_list is exhausted. The idea here is that if we don't find the operator in the
- specified form, we still want to use some other available form of that operator.
-*/
-static OperSpecSearchResult _mmlFindOperSpec(const QStringList &name_list, Mml::FormType form)
-{
- OperSpecSearchResult result;
-
- QStringList::const_iterator it = name_list.begin();
- for (; it != name_list.end(); ++it) {
- const QString &name = *it;
-
- const OperSpec *spec = searchOperSpecData(name);
-
- if (spec == 0)
- continue;
-
- const char *name_latin1 = name.toLatin1().data();
-
- // backtrack to the first instance of name
- while (spec > g_oper_spec_data && qstrcmp((spec - 1)->name, name_latin1) == 0)
- --spec;
-
- // iterate over instances of name until the instances are exhausted or until we
- // find an instance in the specified form.
- do {
- result.addForm(spec++);
- if (result.haveForm(form))
- break;
- } while (qstrcmp(spec->name, name_latin1) == 0);
-
- if (result.haveForm(form))
- break;
- }
-
- return result;
-}
-
-/*
- text is a string between <mo> and </mo>. It can be a character ('+'), an
- entity reference ("∞") or a character reference ("∞"). Our
- job is to find an operator spec in the operator dictionary (g_oper_spec_data)
- that matches text. Things are further complicated by the fact, that many
- operators come in several forms (prefix, infix, postfix).
-
- If available, this function returns an operator spec matching text in the specified
- form. If such operator is not available, returns an operator spec that matches
- text, but of some other form in the preference order specified by the MathML spec.
- If that's not available either, returns the default operator spec.
-*/
-static const OperSpec *mmlFindOperSpec(const QString &text, Mml::FormType form)
-{
- QStringList name_list;
- name_list.append(text);
-
- // First, just try to find text in the operator dictionary.
- OperSpecSearchResult result = _mmlFindOperSpec(name_list, form);
-
- if (!result.haveForm(form)) {
- // Try to find other names for the operator represented by text.
-
- const EntitySpec *ent = 0;
- for (;;) {
- ent = searchEntitySpecData(text, ent);
- if (ent == 0)
- break;
- name_list.append('&' + QString(ent->name) + ';');
- ++ent;
- }
-
- result = _mmlFindOperSpec(name_list, form);
- }
-
- const OperSpec *spec = result.getForm(form);
- if (spec != 0)
- return spec;
-
- spec = result.getForm(Mml::InfixForm);
- if (spec != 0)
- return spec;
-
- spec = result.getForm(Mml::PostfixForm);
- if (spec != 0)
- return spec;
-
- spec = result.getForm(Mml::PrefixForm);
- if (spec != 0)
- return spec;
-
- return &g_oper_spec_defaults;
-}
-
-static QString mmlDictAttribute(const QString &name, const OperSpec *spec)
-{
- int i = attributeIndex(name);
- if (i == -1)
- return QString::null;
- else
- return spec->attributes[i];
-}
-
-static uint interpretMathVariant(const QString &value, bool *ok)
-{
- struct MathVariantValue {
- const char *value;
- uint mv;
- };
-
- static const MathVariantValue g_mv_data[] =
- {
- { "normal", Mml::NormalMV },
- { "bold", Mml::BoldMV },
- { "italic", Mml::ItalicMV },
- { "bold-italic", Mml::BoldMV | Mml::ItalicMV },
- { "double-struck", Mml::DoubleStruckMV },
- { "bold-fraktur", Mml::BoldMV | Mml::FrakturMV },
- { "script", Mml::ScriptMV },
- { "bold-script", Mml::BoldMV | Mml::ScriptMV },
- { "fraktur", Mml::FrakturMV },
- { "sans-serif", Mml::SansSerifMV },
- { "bold-sans-serif", Mml::BoldMV | Mml::SansSerifMV },
- { "sans-serif-italic", Mml::SansSerifMV | Mml::ItalicMV },
- { "sans-serif-bold-italic", Mml::SansSerifMV | Mml::ItalicMV | Mml::BoldMV },
- { "monospace", Mml::MonospaceMV },
- { 0, 0 }
- };
-
- const MathVariantValue *v = g_mv_data;
- for (; v->value != 0; ++v) {
- if (value == v->value) {
- if (ok != 0)
- *ok = true;
- return v->mv;
- }
- }
-
- if (ok != 0)
- *ok = false;
-
- qWarning("interpretMathVariant(): could not parse value: \"%s\"", value.toLatin1().data());
-
- return Mml::NormalMV;
-}
-
-static Mml::FormType interpretForm(const QString &value, bool *ok)
-{
- if (ok != 0)
- *ok = true;
-
- if (value == "prefix")
- return Mml::PrefixForm;
- if (value == "infix")
- return Mml::InfixForm;
- if (value == "postfix")
- return Mml::PostfixForm;
-
- if (ok != 0)
- *ok = false;
-
- qWarning("interpretForm(): could not parse value \"%s\"", value.toLatin1().data());
- return Mml::InfixForm;
-}
-
-static Mml::ColAlign interpretColAlign(const QString &value_list, uint colnum, bool *ok)
-{
- QString value = interpretListAttr(value_list, colnum, "center");
-
- if (ok != 0)
- *ok = true;
-
- if (value == "left")
- return Mml::ColAlignLeft;
- if (value == "right")
- return Mml::ColAlignRight;
- if (value == "center")
- return Mml::ColAlignCenter;
-
- if (ok != 0)
- *ok = false;
-
- qWarning("interpretColAlign(): could not parse value \"%s\"", value.toLatin1().data());
- return Mml::ColAlignCenter;
-}
-
-static Mml::RowAlign interpretRowAlign(const QString &value_list, uint rownum, bool *ok)
-{
- QString value = interpretListAttr(value_list, rownum, "axis");
-
- if (ok != 0)
- *ok = true;
-
- if (value == "top")
- return Mml::RowAlignTop;
- if (value == "center")
- return Mml::RowAlignCenter;
- if (value == "bottom")
- return Mml::RowAlignBottom;
- if (value == "baseline")
- return Mml::RowAlignBaseline;
- if (value == "axis")
- return Mml::RowAlignAxis;
-
- if (ok != 0)
- *ok = false;
-
- qWarning("interpretRowAlign(): could not parse value \"%s\"", value.toLatin1().data());
- return Mml::RowAlignAxis;
-}
-
-static QString interpretListAttr(const QString &value_list, int idx, const QString &def)
-{
- QStringList l = value_list.split(' ');
-
- if (l.count() == 0)
- return def;
-
- if (l.count() <= idx)
- return l[l.count() - 1];
- else
- return l[idx];
-}
-
-static Mml::FrameType interpretFrameType(const QString &value_list, uint idx, bool *ok)
-{
- if (ok != 0)
- *ok = true;
-
- QString value = interpretListAttr(value_list, idx, "none");
-
- if (value == "none")
- return Mml::FrameNone;
- if (value == "solid")
- return Mml::FrameSolid;
- if (value == "dashed")
- return Mml::FrameDashed;
-
- if (ok != 0)
- *ok = false;
-
- qWarning("interpretFrameType(): could not parse value \"%s\"", value.toLatin1().data());
- return Mml::FrameNone;
-}
-
-
-static Mml::FrameSpacing interpretFrameSpacing(const QString &value_list, int em, int ex, bool *ok)
-{
- Mml::FrameSpacing fs;
-
- QStringList l = value_list.split(' ');
- if (l.count() != 2) {
- qWarning("interpretFrameSpacing: could not parse value \"%s\"", value_list.toLatin1().data());
- if (ok != 0)
- *ok = false;
- return Mml::FrameSpacing((int)(0.4*em), (int)(0.5*ex));
- }
-
- bool hor_ok, ver_ok;
- fs.m_hor = interpretSpacing(l[0], em, ex, &hor_ok);
- fs.m_ver = interpretSpacing(l[1], em, ex, &ver_ok);
-
- if (ok != 0)
- *ok = hor_ok && ver_ok;
-
- return fs;
-}
-
-static QFont interpretDepreciatedFontAttr(const MmlAttributeMap &font_attr, QFont &fn, int em, int ex)
-{
- if (font_attr.contains("fontsize")) {
- QString value = font_attr["fontsize"];
-
- for (;;) {
-
- bool ok;
- int ptsize = interpretPointSize(value, &ok);
- if (ok) {
- fn.setPointSize(ptsize);
- break;
- }
-
- ptsize = interpretPercentSpacing(value, fn.pointSize(), &ok);
- if (ok) {
- fn.setPointSize(ptsize);
- break;
- }
-
- int size = interpretSpacing(value, em, ex, &ok);
- if (ok) {
- fn.setPixelSize(size);
- break;
- }
-
- break;
- }
- }
-
- if (font_attr.contains("fontweight")) {
- QString value = font_attr["fontweight"];
- if (value == "normal")
- fn.setBold(false);
- else if (value == "bold")
- fn.setBold(true);
- else
- qWarning("interpretDepreciatedFontAttr(): could not parse fontweight \"%s\"", value.toLatin1().data());
- }
-
- if (font_attr.contains("fontstyle")) {
- QString value = font_attr["fontstyle"];
- if (value == "normal")
- fn.setItalic(false);
- else if (value == "italic")
- fn.setItalic(true);
- else
- qWarning("interpretDepreciatedFontAttr(): could not parse fontstyle \"%s\"", value.toLatin1().data());
- }
-
- if (font_attr.contains("fontfamily")) {
- QString value = font_attr["fontfamily"];
- fn.setFamily(value);
- }
-
- return fn;
-}
-
-static QFont interpretMathSize(QString value, QFont &fn, int em, int ex, bool *ok)
-{
- if (ok != 0)
- *ok = true;
-
- if (value == "small") {
- fn.setPointSize((int)(fn.pointSize()*0.7));
- return fn;
- }
-
- if (value == "normal")
- return fn;
-
- if (value == "big") {
- fn.setPointSize((int)(fn.pointSize()*1.5));
- return fn;
- }
-
- bool size_ok;
-
- int ptsize = interpretPointSize(value, &size_ok);
- if (size_ok) {
- fn.setPointSize(ptsize);
- return fn;
- }
-
- int size = interpretSpacing(value, em, ex, &size_ok);
- if (size_ok) {
- fn.setPixelSize(size);
- return fn;
- }
-
- if (ok != 0)
- *ok = false;
- qWarning("interpretMathSize(): could not parse mathsize \"%s\"", value.toLatin1().data());
- return fn;
-}
-
-/*!
- \class QtMmlDocument
-
- \brief The QtMmlDocument class renders mathematical formulas written in MathML 2.0.
-
- This class provides a direct API to the rendering engine used by
- QtMmlWidget. It can be used to paint MathML inside other widgets.
-
- All methods work the same as the corresponding methods in QtMmlWidget.
-*/
-
-/*!
- Constructs an empty MML document.
-*/
-QtMmlDocument::QtMmlDocument()
-{
- m_doc = new MmlDocument;
-}
-
-/*!
- Destroys the MML document.
-*/
-QtMmlDocument::~QtMmlDocument()
-{
- delete m_doc;
-}
-
-/*!
- Clears the contents of this MML document.
-*/
-void QtMmlDocument::clear()
-{
- m_doc->clear();
-}
-
-/*!
- Sets the MathML expression to be rendered. The expression is given
- in the string \a text. If the expression is successfully parsed,
- this method returns true; otherwise it returns false. If an error
- occured \a errorMsg is set to a diagnostic message, while \a
- errorLine and \a errorColumn contain the location of the error.
- Any of \a errorMsg, \a errorLine and \a errorColumn may be 0,
- in which case they are not set.
-
- \a text should contain MathML 2.0 presentation markup elements enclosed
- in a <math> element.
-*/
-bool QtMmlDocument::setContent(QString text, QString *errorMsg,
- int *errorLine, int *errorColumn)
-{
- return m_doc->setContent(text, errorMsg, errorLine, errorColumn);
-}
-
-/*!
- Renders this MML document with the painter \a p at position \a pos.
-*/
-void QtMmlDocument::paint(QPainter *p, const QPoint &pos) const
-{
- m_doc->paint(p, pos);
-}
-
-/*!
- Returns the size of this MML document, as rendered, in pixels.
-*/
-QSize QtMmlDocument::size() const
-{
- return m_doc->size();
-}
-
-/*!
- Returns the name of the font used to render the font \a type.
-
- \sa setFontName() setBaseFontPointSize() baseFontPointSize() QtMmlWidget::MmlFont
-*/
-QString QtMmlDocument::fontName(QtMmlWidget::MmlFont type) const
-{
- return m_doc->fontName(type);
-}
-
-/*!
- Sets the name of the font used to render the font \a type to \a name.
-
- \sa fontName() setBaseFontPointSize() baseFontPointSize() QtMmlWidget::MmlFont
-*/
-void QtMmlDocument::setFontName(QtMmlWidget::MmlFont type, const QString &name)
-{
- m_doc->setFontName(type, name);
-}
-
-/*!
- Returns the point size of the font used to render expressions
- whose scriptlevel is 0.
-
- \sa setBaseFontPointSize() fontName() setFontName()
-*/
-int QtMmlDocument::baseFontPointSize() const
-{
- return m_doc->baseFontPointSize();
-}
-
-/*!
- Sets the point \a size of the font used to render expressions
- whose scriptlevel is 0.
-
- \sa baseFontPointSize() fontName() setFontName()
-*/
-void QtMmlDocument::setBaseFontPointSize(int size)
-{
- m_doc->setBaseFontPointSize(size);
-}