1 #include <QApplication>
2 #include <QMap>
3 #include <QDesktopWidget>
4 #include <QPainter>
5 #include <QDomNode>
6 #include <QDebug>
7 
8 #include "qwt_mml_document.h"
9 
10 // *******************************************************************
11 // Declarations
12 // *******************************************************************
13 
14 #define ROUND(a) (int)((a)+.5)
15 
16 static bool           g_draw_frames         = false;
17 static const double   g_mfrac_spacing           = 0.1;
18 static const double   g_mroot_base_margin       = 0.1;
19 static const double   g_script_size_multiplier          = 0.7071; // sqrt(1/2)
20 static const int      g_min_font_point_size     = 8;
21 static const QChar    g_radical_char                    = QChar( 0x1A, 0x22 );
22 static const unsigned g_oper_spec_rows              = 9;
23 
24 struct QwtMml
25 {
26     enum NodeType
27     {
28         NoNode = 0, MiNode, MnNode, MfracNode, MrowNode, MsqrtNode,
29         MrootNode, MsupNode, MsubNode, MsubsupNode, MoNode,
30         MstyleNode, TextNode, MphantomNode, MfencedNode,
31         MtableNode, MtrNode, MtdNode, MoverNode, MunderNode,
32         MunderoverNode, MerrorNode, MtextNode, MpaddedNode,
33         MspaceNode, MalignMarkNode, UnknownNode
34     };
35 
36     enum MathVariant
37     {
38         NormalMV        = 0x0000,
39         BoldMV          = 0x0001,
40         ItalicMV        = 0x0002,
41         DoubleStruckMV  = 0x0004,
42         ScriptMV        = 0x0008,
43         FrakturMV       = 0x0010,
44         SansSerifMV     = 0x0020,
45         MonospaceMV     = 0x0040
46     };
47 
48     enum FormType { PrefixForm, InfixForm, PostfixForm };
49     enum ColAlign { ColAlignLeft, ColAlignCenter, ColAlignRight };
50     enum RowAlign { RowAlignTop, RowAlignCenter, RowAlignBottom,
51                     RowAlignAxis, RowAlignBaseline
52                   };
53     enum FrameType { FrameNone, FrameSolid, FrameDashed };
54 
55     struct FrameSpacing
56     {
FrameSpacingQwtMml::FrameSpacing57         FrameSpacing( int hor = 0, int ver = 0 )
58             : m_hor( hor ), m_ver( ver ) {}
59         int m_hor, m_ver;
60     };
61 };
62 
63 struct QwtMmlOperSpec
64 {
65     enum StretchDir { NoStretch, HStretch, VStretch, HVStretch };
66 
67     const char *name;
68     QwtMml::FormType form;
69     const char *attributes[g_oper_spec_rows];
70     StretchDir stretch_dir;
71 };
72 
73 struct QwtMmlNodeSpec
74 {
75     QwtMml::NodeType type;
76     const char *tag;
77     const char *type_str;
78     int child_spec;
79     const char *child_types;
80     const char *attributes;
81 
82     enum ChildSpec
83     {
84         ChildAny     = -1, // any number of children allowed
85         ChildIgnore  = -2, // do not build subexpression of children
86         ImplicitMrow = -3  // if more than one child, build mrow
87     };
88 };
89 
90 struct QwtMmlEntitySpec
91 {
92     const char *name;
93     const char *value;
94 };
95 
96 typedef QMap<QString, QString> QwtMmlAttributeMap;
97 class QwtMmlNode;
98 
99 class QwtMmlDocument : public QwtMml
100 {
101 public:
102     QwtMmlDocument();
103     ~QwtMmlDocument();
104     void clear();
105 
106     bool setContent( QString text, QString *errorMsg = 0,
107                      int *errorLine = 0, int *errorColumn = 0 );
108     void paint( QPainter *p, const QPoint &pos ) const;
109     void dump() const;
110     QSize size() const;
111     void layout();
112 
113     QString fontName( QwtMathMLDocument::MmlFont type ) const;
114     void setFontName( QwtMathMLDocument::MmlFont type, const QString &name );
115 
baseFontPointSize() const116     int baseFontPointSize() const
117     { return m_base_font_point_size; }
setBaseFontPointSize(int size)118     void setBaseFontPointSize( int size )
119     { m_base_font_point_size = size; }
foregroundColor() const120     QColor foregroundColor() const
121     { return m_foreground_color; }
setForegroundColor(const QColor & color)122     void setForegroundColor( const QColor &color )
123     { m_foreground_color = color; }
backgroundColor() const124     QColor backgroundColor() const
125     { return m_background_color; }
setBackgroundColor(const QColor & color)126     void setBackgroundColor( const QColor &color )
127     { m_background_color = color; }
128 
129 private:
130     void _dump( const QwtMmlNode *node, QString &indent ) const;
131     bool insertChild( QwtMmlNode *parent, QwtMmlNode *new_node, QString *errorMsg );
132 
133     QwtMmlNode *domToMml( const QDomNode &dom_node, bool *ok, QString *errorMsg );
134     QwtMmlNode *createNode( NodeType type, const QwtMmlAttributeMap &mml_attr,
135                          const QString &mml_value, QString *errorMsg );
136     QwtMmlNode *createImplicitMrowNode( const QDomNode &dom_node, bool *ok,
137                                      QString *errorMsg );
138 
139     void insertOperator( QwtMmlNode *node, const QString &text );
140 
141     QwtMmlNode *m_root_node;
142 
143     QString m_normal_font_name;
144     QString m_fraktur_font_name;
145     QString m_sans_serif_font_name;
146     QString m_script_font_name;
147     QString m_monospace_font_name;
148     QString m_doublestruck_font_name;
149     int m_base_font_point_size;
150     QColor m_foreground_color;
151     QColor m_background_color;
152 };
153 
154 class QwtMmlNode : public QwtMml
155 {
156     friend class QwtMmlDocument;
157 
158 public:
159     QwtMmlNode( NodeType type, QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map );
160     virtual ~QwtMmlNode();
161 
162     // Mml stuff
nodeType() const163     NodeType nodeType() const
164     { return m_node_type; }
165 
166     virtual QString toStr() const;
167 
168     void setRelOrigin( const QPoint &rel_origin );
relOrigin() const169     QPoint relOrigin() const
170     { return m_rel_origin; }
171     void stretchTo( const QRect &rect );
isStretched() const172     bool isStretched() const
173     { return m_stretched; }
174     QPoint devicePoint( const QPoint &p ) const;
175 
myRect() const176     QRect myRect() const
177     { return m_my_rect; }
178     QRect parentRect() const;
179     virtual QRect deviceRect() const;
180     void updateMyRect();
setMyRect(const QRect & rect)181     virtual void setMyRect( const QRect &rect )
182     { m_my_rect = rect; }
183 
184     virtual void stretch();
185     virtual void layout();
186     virtual void paint( QPainter *p );
187 
188     int basePos() const;
189     int overlinePos() const;
190     int underlinePos() const;
191     int em() const;
192     int ex() const;
193 
194     QString explicitAttribute( const QString &name, const QString &def = QString() ) const;
195     QString inheritAttributeFromMrow( const QString &name, const QString &def = QString() ) const;
196 
197     virtual QFont font() const;
198     virtual QColor color() const;
199     virtual QColor background() const;
200     virtual int scriptlevel( const QwtMmlNode *child = 0 ) const;
201 
202 
203     // Node stuff
document() const204     QwtMmlDocument *document() const
205     { return m_document; }
parent() const206     QwtMmlNode *parent() const
207     { return m_parent; }
firstChild() const208     QwtMmlNode *firstChild() const
209     { return m_first_child; }
nextSibling() const210     QwtMmlNode *nextSibling() const
211     { return m_next_sibling; }
previousSibling() const212     QwtMmlNode *previousSibling() const
213     { return m_previous_sibling; }
214     QwtMmlNode *lastSibling() const;
215     QwtMmlNode *firstSibling() const;
isLastSibling() const216     bool isLastSibling() const
217     { return m_next_sibling == 0; }
isFirstSibling() const218     bool isFirstSibling() const
219     { return m_previous_sibling == 0; }
hasChildNodes() const220     bool hasChildNodes() const
221     { return m_first_child != 0; }
222 
223 protected:
224     virtual void layoutSymbol();
225     virtual void paintSymbol( QPainter *p ) const;
symbolRect() const226     virtual QRect symbolRect() const
227     { return QRect( 0, 0, 0, 0 ); }
228 
229     QwtMmlNode *parentWithExplicitAttribute( const QString &name, NodeType type = NoNode );
230     int interpretSpacing( const QString &value, bool *ok ) const;
231 
232 private:
233     QwtMmlAttributeMap m_attribute_map;
234     bool m_stretched;
235     QRect m_my_rect, m_parent_rect;
236     QPoint m_rel_origin;
237 
238     NodeType m_node_type;
239     QwtMmlDocument *m_document;
240 
241     QwtMmlNode *m_parent,
242             *m_first_child,
243             *m_next_sibling,
244             *m_previous_sibling;
245 };
246 
247 class QwtMmlTokenNode : public QwtMmlNode
248 {
249 public:
QwtMmlTokenNode(NodeType type,QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)250     QwtMmlTokenNode( NodeType type, QwtMmlDocument *document,
251                   const QwtMmlAttributeMap &attribute_map )
252         : QwtMmlNode( type, document, attribute_map ) {}
253 
254     QString text() const;
255 };
256 
257 class QwtMmlMphantomNode : public QwtMmlNode
258 {
259 public:
QwtMmlMphantomNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)260     QwtMmlMphantomNode( QwtMmlDocument *document,
261                      const QwtMmlAttributeMap &attribute_map )
262         : QwtMmlNode( MphantomNode, document, attribute_map ) {}
263 
paint(QPainter *)264     virtual void paint( QPainter * ) {}
265 };
266 
267 class QwtMmlUnknownNode : public QwtMmlNode
268 {
269 public:
QwtMmlUnknownNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)270     QwtMmlUnknownNode( QwtMmlDocument *document,
271                     const QwtMmlAttributeMap &attribute_map )
272         : QwtMmlNode( UnknownNode, document, attribute_map ) {}
273 };
274 
275 class QwtMmlMfencedNode : public QwtMmlNode
276 {
277 public:
QwtMmlMfencedNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)278     QwtMmlMfencedNode( QwtMmlDocument *document,
279                     const QwtMmlAttributeMap &attribute_map )
280         : QwtMmlNode( MfencedNode, document, attribute_map ) {}
281 };
282 
283 class QwtMmlMalignMarkNode : public QwtMmlNode
284 {
285 public:
QwtMmlMalignMarkNode(QwtMmlDocument * document)286     QwtMmlMalignMarkNode( QwtMmlDocument *document )
287         : QwtMmlNode( MalignMarkNode, document, QwtMmlAttributeMap() ) {}
288 };
289 
290 class QwtMmlMfracNode : public QwtMmlNode
291 {
292 public:
QwtMmlMfracNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)293     QwtMmlMfracNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
294         : QwtMmlNode( MfracNode, document, attribute_map ) {}
295 
296     QwtMmlNode *numerator() const;
297     QwtMmlNode *denominator() const;
298 
299 protected:
300     virtual void layoutSymbol();
301     virtual void paintSymbol( QPainter *p ) const;
302     virtual QRect symbolRect() const;
303 };
304 
305 class QwtMmlMrowNode : public QwtMmlNode
306 {
307 public:
QwtMmlMrowNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)308     QwtMmlMrowNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
309         : QwtMmlNode( MrowNode, document, attribute_map ) {}
310 };
311 
312 class QwtMmlRootBaseNode : public QwtMmlNode
313 {
314 public:
QwtMmlRootBaseNode(NodeType type,QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)315     QwtMmlRootBaseNode( NodeType type, QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
316         : QwtMmlNode( type, document, attribute_map ) {}
317 
318     QwtMmlNode *base() const;
319     QwtMmlNode *index() const;
320 
321     virtual int scriptlevel( const QwtMmlNode *child = 0 ) const;
322 
323 protected:
324     virtual void layoutSymbol();
325     virtual void paintSymbol( QPainter *p ) const;
326     virtual QRect symbolRect() const;
327     int tailWidth() const;
328 };
329 
330 class QwtMmlMrootNode : public QwtMmlRootBaseNode
331 {
332 public:
QwtMmlMrootNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)333     QwtMmlMrootNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
334         : QwtMmlRootBaseNode( MrootNode, document, attribute_map ) {}
335 };
336 
337 class QwtMmlMsqrtNode : public QwtMmlRootBaseNode
338 {
339 public:
QwtMmlMsqrtNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)340     QwtMmlMsqrtNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
341         : QwtMmlRootBaseNode( MsqrtNode, document, attribute_map ) {}
342 
343 };
344 
345 
346 class QwtMmlTextNode : public QwtMmlNode
347 {
348 public:
349     QwtMmlTextNode( const QString &text, QwtMmlDocument *document );
350 
351     virtual QString toStr() const;
text() const352     QString text() const
353     { return m_text; }
354 
355     // TextNodes are not xml elements, so they can't have attributes of
356     // their own. Everything is taken from the parent.
font() const357     virtual QFont font() const
358     { return parent()->font(); }
scriptlevel(const QwtMmlNode * =0) const359     virtual int scriptlevel( const QwtMmlNode* = 0 ) const
360     { return parent()->scriptlevel( this ); }
color() const361     virtual QColor color() const
362     { return parent()->color(); }
background() const363     virtual QColor background() const
364     { return parent()->background(); }
365 
366 protected:
367     virtual void paintSymbol( QPainter *p ) const;
368     virtual QRect symbolRect() const;
369 
370     QString m_text;
371 };
372 
373 class QwtMmlMiNode : public QwtMmlTokenNode
374 {
375 public:
QwtMmlMiNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)376     QwtMmlMiNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
377         : QwtMmlTokenNode( MiNode, document, attribute_map ) {}
378 };
379 
380 class QwtMmlMnNode : public QwtMmlTokenNode
381 {
382 public:
QwtMmlMnNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)383     QwtMmlMnNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
384         : QwtMmlTokenNode( MnNode, document, attribute_map ) {}
385 };
386 
387 class QwtMmlSubsupBaseNode : public QwtMmlNode
388 {
389 public:
QwtMmlSubsupBaseNode(NodeType type,QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)390     QwtMmlSubsupBaseNode( NodeType type, QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
391         : QwtMmlNode( type, document, attribute_map ) {}
392 
393     QwtMmlNode *base() const;
394     QwtMmlNode *sscript() const;
395 
396     virtual int scriptlevel( const QwtMmlNode *child = 0 ) const;
397 };
398 
399 class QwtMmlMsupNode : public QwtMmlSubsupBaseNode
400 {
401 public:
QwtMmlMsupNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)402     QwtMmlMsupNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
403         : QwtMmlSubsupBaseNode( MsupNode, document, attribute_map ) {}
404 
405 protected:
406     virtual void layoutSymbol();
407 };
408 
409 class QwtMmlMsubNode : public QwtMmlSubsupBaseNode
410 {
411 public:
QwtMmlMsubNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)412     QwtMmlMsubNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
413         : QwtMmlSubsupBaseNode( MsubNode, document, attribute_map ) {}
414 
415 protected:
416     virtual void layoutSymbol();
417 };
418 
419 class QwtMmlMsubsupNode : public QwtMmlNode
420 {
421 public:
QwtMmlMsubsupNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)422     QwtMmlMsubsupNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
423         : QwtMmlNode( MsubsupNode, document, attribute_map ) {}
424 
425     QwtMmlNode *base() const;
426     QwtMmlNode *superscript() const;
427     QwtMmlNode *subscript() const;
428 
429     virtual int scriptlevel( const QwtMmlNode *child = 0 ) const;
430 
431 protected:
432     virtual void layoutSymbol();
433 };
434 
435 class QwtMmlMoNode : public QwtMmlTokenNode
436 {
437 public:
438     QwtMmlMoNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map );
439 
440     QString dictionaryAttribute( const QString &name ) const;
441     virtual void stretch();
442     virtual int lspace() const;
443     virtual int rspace() const;
444 
445     virtual QString toStr() const;
446 
447 protected:
448     virtual void layoutSymbol();
449     virtual QRect symbolRect() const;
450 
451     virtual FormType form() const;
452 
453 private:
454     const QwtMmlOperSpec *m_oper_spec;
455 };
456 
457 class QwtMmlMstyleNode : public QwtMmlNode
458 {
459 public:
QwtMmlMstyleNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)460     QwtMmlMstyleNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
461         : QwtMmlNode( MstyleNode, document, attribute_map ) {}
462 };
463 
464 class QwtMmlTableBaseNode : public QwtMmlNode
465 {
466 public:
QwtMmlTableBaseNode(NodeType type,QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)467     QwtMmlTableBaseNode( NodeType type, QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
468         : QwtMmlNode( type, document, attribute_map ) {}
469 };
470 
471 class QwtMmlMtableNode : public QwtMmlTableBaseNode
472 {
473 public:
QwtMmlMtableNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)474     QwtMmlMtableNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
475         : QwtMmlTableBaseNode( MtableNode, document, attribute_map ) {}
476 
477     int rowspacing() const;
478     int columnspacing() const;
479     int framespacing_hor() const;
480     int framespacing_ver() const;
481     FrameType frame() const;
482     FrameType columnlines( int idx ) const;
483     FrameType rowlines( int idx ) const;
484 
485 protected:
486     virtual void layoutSymbol();
487     virtual QRect symbolRect() const;
488     virtual void paintSymbol( QPainter *p ) const;
489 
490 private:
491     struct CellSizeData
492     {
493         void init( const QwtMmlNode *first_row );
494         QList<int> col_widths, row_heights;
numColsQwtMmlMtableNode::CellSizeData495         int numCols() const { return col_widths.count(); }
numRowsQwtMmlMtableNode::CellSizeData496         int numRows() const { return row_heights.count(); }
497         uint colWidthSum() const;
498         uint rowHeightSum() const;
499     };
500 
501     CellSizeData m_cell_size_data;
502     int m_content_width, m_content_height;
503 };
504 
505 class QwtMmlMtrNode : public QwtMmlTableBaseNode
506 {
507 public:
QwtMmlMtrNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)508     QwtMmlMtrNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
509         : QwtMmlTableBaseNode( MtrNode, document, attribute_map ) {}
510     void layoutCells( const QList<int> &col_widths, int col_spc );
511 };
512 
513 class QwtMmlMtdNode : public QwtMmlTableBaseNode
514 {
515 public:
QwtMmlMtdNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)516     QwtMmlMtdNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
517         : QwtMmlTableBaseNode( MtdNode, document, attribute_map )
518     { m_scriptlevel_adjust = 0; }
519     virtual void setMyRect( const QRect &rect );
520 
521     ColAlign columnalign();
522     RowAlign rowalign();
523     uint colNum();
524     uint rowNum();
525     virtual int scriptlevel( const QwtMmlNode *child = 0 ) const;
526 
527 private:
528     int m_scriptlevel_adjust; // added or subtracted to scriptlevel to
529     // make contents fit the cell
530 };
531 
532 class QwtMmlMoverNode : public QwtMmlNode
533 {
534 public:
QwtMmlMoverNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)535     QwtMmlMoverNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
536         : QwtMmlNode( MoverNode, document, attribute_map ) {}
537     virtual int scriptlevel( const QwtMmlNode *node = 0 ) const;
538 
539 protected:
540     virtual void layoutSymbol();
541 };
542 
543 class QwtMmlMunderNode : public QwtMmlNode
544 {
545 public:
QwtMmlMunderNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)546     QwtMmlMunderNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
547         : QwtMmlNode( MunderNode, document, attribute_map ) {}
548     virtual int scriptlevel( const QwtMmlNode *node = 0 ) const;
549 
550 protected:
551     virtual void layoutSymbol();
552 };
553 
554 class QwtMmlMunderoverNode : public QwtMmlNode
555 {
556 public:
QwtMmlMunderoverNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)557     QwtMmlMunderoverNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
558         : QwtMmlNode( MunderoverNode, document, attribute_map ) {}
559     virtual int scriptlevel( const QwtMmlNode *node = 0 ) const;
560 
561 protected:
562     virtual void layoutSymbol();
563 };
564 
565 class QwtMmlMerrorNode : public QwtMmlNode
566 {
567 public:
QwtMmlMerrorNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)568     QwtMmlMerrorNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
569         : QwtMmlNode( MerrorNode, document, attribute_map ) {}
570 };
571 
572 class QwtMmlMtextNode : public QwtMmlNode
573 {
574 public:
QwtMmlMtextNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)575     QwtMmlMtextNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
576         : QwtMmlNode( MtextNode, document, attribute_map ) {}
577 };
578 
579 class QwtMmlMpaddedNode : public QwtMmlNode
580 {
581 public:
QwtMmlMpaddedNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)582     QwtMmlMpaddedNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
583         : QwtMmlNode( MpaddedNode, document, attribute_map ) {}
584 
585 public:
586     int lspace() const;
587     int width() const;
588     int height() const;
589     int depth() const;
590 
591 protected:
592     int interpretSpacing( QString value, int base_value, bool *ok ) const;
593     virtual void layoutSymbol();
594     virtual QRect symbolRect() const;
595 };
596 
597 class QwtMmlMspaceNode : public QwtMmlNode
598 {
599 public:
QwtMmlMspaceNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)600     QwtMmlMspaceNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
601         : QwtMmlNode( MspaceNode, document, attribute_map ) {}
602 };
603 
604 static const QwtMmlNodeSpec *mmlFindNodeSpec( QwtMml::NodeType type );
605 static const QwtMmlNodeSpec *mmlFindNodeSpec( const QString &tag );
606 static bool mmlCheckChildType( QwtMml::NodeType parent_type,
607                                QwtMml::NodeType child_type, QString *error_str );
608 static bool mmlCheckAttributes( QwtMml::NodeType child_type,
609                                 const QwtMmlAttributeMap &attr, QString *error_str );
610 static QString mmlDictAttribute( const QString &name, const QwtMmlOperSpec *spec );
611 static const QwtMmlOperSpec *mmlFindOperSpec( const QString &name, QwtMml::FormType form );
612 static int interpretSpacing( QString name, int em, int ex, bool *ok );
613 static int interpretPercentSpacing( QString value, int base, bool *ok );
614 static uint interpretMathVariant( const QString &value, bool *ok );
615 static QwtMml::FormType interpretForm( const QString &value, bool *ok );
616 static QwtMml::FrameType interpretFrameType( const QString &value_list, uint idx, bool *ok );
617 static QwtMml::FrameSpacing interpretFrameSpacing( const QString &value_list, int em, int ex, bool *ok );
618 static QwtMml::ColAlign interpretColAlign( const QString &value_list, uint colnum, bool *ok );
619 static QwtMml::RowAlign interpretRowAlign( const QString &value_list, uint rownum, bool *ok );
620 static QwtMml::FrameType interpretFrameType( const QString &value_list, uint idx, bool *ok );
621 static QFont interpretDepreciatedFontAttr( const QwtMmlAttributeMap &font_attr, QFont &fn, int em, int ex );
622 static QFont interpretMathSize( QString value, QFont &fn, int em, int ex, bool *ok );
623 static QString interpretListAttr( const QString &value_list, int idx, const QString &def );
624 static QString rectToStr( const QRect &rect );
625 static QString entityDeclarations();
626 
627 
628 #define MML_ATT_COMMON      " class style id xref actiontype "
629 #define MML_ATT_FONTSIZE    " fontsize fontweight fontstyle fontfamily color "
630 #define MML_ATT_MATHVARIANT " mathvariant mathsize mathcolor mathbackground "
631 #define MML_ATT_FONTINFO    MML_ATT_FONTSIZE MML_ATT_MATHVARIANT
632 #define MML_ATT_OPINFO      " form fence separator lspace rspace stretchy symmetric " \
633     " maxsize minsize largeop movablelimits accent "
634 #define MML_ATT_SIZEINFO    " width height depth "
635 #define MML_ATT_TABLEINFO   " align rowalign columnalign columnwidth groupalign " \
636     " alignmentscope side rowspacing columnspacing rowlines " \
637     " columnlines width frame framespacing equalrows " \
638     " equalcolumns displaystyle "
639 #define MML_ATT_MFRAC       " bevelled numalign denomalign linethickness "
640 #define MML_ATT_MSTYLE      MML_ATT_FONTINFO MML_ATT_OPINFO \
641     " scriptlevel lquote rquote linethickness displaystyle " \
642     " scriptsizemultiplier scriptminsize background " \
643     " veryverythinmathspace verythinmathspace thinmathspace " \
644     " mediummathspace thickmathspace verythickmathspace " \
645     " veryverythickmathspace open close separators " \
646     " subscriptshift superscriptshift accentunder tableinfo " \
647     " rowspan columnspan edge selection bevelled "
648 #define MML_ATT_MTABLE      " align rowalign columnalign groupalign alignmentscope " \
649     " columnwidth width rowspacing columnspacing rowlines columnlines " \
650     " frame framespacing equalrows equalcolumns displaystyle side " \
651     " minlabelspacing "
652 
653 static const QwtMmlNodeSpec g_node_spec_data[] =
654 {
655 
656 //      type                    tag             type_str            child_spec              child_types              attributes ""=none, 0=any
657 //      ----------------------- --------------- ------------------- ----------------------- ------------------------ ------------------------------------
658     {   QwtMml::MiNode,         "mi",           "MiNode",           QwtMmlNodeSpec::ChildAny,      " TextNode MalignMark ", MML_ATT_COMMON MML_ATT_FONTINFO     },
659     {   QwtMml::MnNode,         "mn",           "MnNode",           QwtMmlNodeSpec::ChildAny,      " TextNode MalignMark ", MML_ATT_COMMON MML_ATT_FONTINFO     },
660     {   QwtMml::MfracNode,      "mfrac",        "MfracNode",        2,              0,                       MML_ATT_COMMON MML_ATT_MFRAC         },
661     {   QwtMml::MrowNode,       "mrow",         "MrowNode",         QwtMmlNodeSpec::ChildAny,     0,                       MML_ATT_COMMON " display mode "      },
662     {   QwtMml::MsqrtNode,      "msqrt",        "MsqrtNode",        QwtMmlNodeSpec::ImplicitMrow, 0,                       MML_ATT_COMMON                      },
663     {   QwtMml::MrootNode,      "mroot",        "MrootNode",        2,              0,                       MML_ATT_COMMON                       },
664     {   QwtMml::MsupNode,       "msup",         "MsupNode",         2,                      0,                       MML_ATT_COMMON " subscriptshift "    },
665     {   QwtMml::MsubNode,       "msub",         "MsubNode",         2,                      0,                       MML_ATT_COMMON " superscriptshift "  },
666     {   QwtMml::MsubsupNode,    "msubsup",      "MsubsupNode",      3,                      0,                       MML_ATT_COMMON " subscriptshift superscriptshift " },
667     {   QwtMml::MoNode,         "mo",           "MoNode",           QwtMmlNodeSpec::ChildAny,     " TextNode MalignMark ", MML_ATT_COMMON MML_ATT_FONTINFO MML_ATT_OPINFO    },
668     {   QwtMml::MstyleNode,     "mstyle",       "MstyleNode",       QwtMmlNodeSpec::ImplicitMrow, 0,                       MML_ATT_COMMON MML_ATT_MSTYLE       },
669     {   QwtMml::MphantomNode,   "mphantom",     "MphantomNode",     QwtMmlNodeSpec::ImplicitMrow, 0,                       MML_ATT_COMMON                     },
670     {   QwtMml::MalignMarkNode, "malignmark",   "MalignMarkNode",   0,                      0,                       ""                                  },
671     {   QwtMml::MfencedNode,    "mfenced",  "MfencedNode",      QwtMmlNodeSpec::ChildAny,       0,                       MML_ATT_COMMON " open close separators "           },
672     {   QwtMml::MtableNode,     "mtable",       "MtableNode",       QwtMmlNodeSpec::ChildAny,       " MtrNode ",             MML_ATT_COMMON MML_ATT_MTABLE       },
673     {   QwtMml::MtrNode,            "mtr",      "MtrNode",      QwtMmlNodeSpec::ChildAny,       " MtdNode ",             MML_ATT_COMMON " rowalign columnalign groupalign " },
674     {   QwtMml::MtdNode,            "mtd",      "MtdNode",      QwtMmlNodeSpec::ImplicitMrow, 0,                     MML_ATT_COMMON " rowspan columnspan rowalign columnalign groupalign " },
675     {   QwtMml::MoverNode,      "mover",    "MoverNode",        2,                      0,                   MML_ATT_COMMON " accent "           },
676     {   QwtMml::MunderNode,     "munder",       "MunderNode",       2,                      0,                   MML_ATT_COMMON " accentunder "  },
677     {   QwtMml::MunderoverNode,    "munderover",   "MunderoverNode",   3,                       0,                   MML_ATT_COMMON " accentunder accent " },
678     {   QwtMml::MerrorNode,     "merror",       "MerrorNode",       QwtMmlNodeSpec::ImplicitMrow, 0,                       MML_ATT_COMMON                    },
679     {   QwtMml::MtextNode,      "mtext",    "MtextNode",        1,                      " TextNode ",            MML_ATT_COMMON " width height depth linebreak " },
680     {   QwtMml::MpaddedNode,    "mpadded",      "MpaddedNode",      QwtMmlNodeSpec::ImplicitMrow, 0,                       MML_ATT_COMMON " width height depth lspace " },
681     {   QwtMml::MspaceNode,     "mspace",       "MspaceNode",       QwtMmlNodeSpec::ImplicitMrow, 0,                       MML_ATT_COMMON " width height depth linebreak " },
682     {   QwtMml::TextNode,       0,              "TextNode",         QwtMmlNodeSpec::ChildIgnore,  0,                       ""                                  },
683     {   QwtMml::UnknownNode,    0,          "UnknownNode",      QwtMmlNodeSpec::ChildAny,     0,                       0                                     },
684     {   QwtMml::NoNode,         0,          0,                  0,                      0,                       0                                   }
685 };
686 
687 static const char *g_oper_spec_names[g_oper_spec_rows] = {                                   "accent",                 "fence",               "largeop",                "lspace",               "minsize",         "movablelimits",                "rspace",             "separator",              "stretchy"       /* stretchdir */ };
688 static const QwtMmlOperSpec g_oper_spec_data[] =
689 {
690 
691     { "!!"                      ,       QwtMml::PostfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "!!"
692     { "!"                       ,       QwtMml::PostfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "!"
693     { "!="                      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "!="
694     { "&And;"               ,         QwtMml::InfixForm, {              0,               0,               0,       "mediummathspace",           0,           0,   "mediummathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&And;"
695     { "&ApplyFunction;"     ,         QwtMml::InfixForm, {              0,               0,               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&ApplyFunction;"
696     { "&Assign;"                ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Assign;"
697     { "&Backslash;"             ,         QwtMml::InfixForm, {              0,               0,               0,     "thinmathspace",           0,           0,     "thinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&Backslash;"
698     { "&Because;"               ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Because;"
699     { "&Breve;"             ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Breve;"
700     { "&Cap;"               ,         QwtMml::InfixForm, {              0,               0,               0,     "thinmathspace",           0,           0,     "thinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Cap;"
701     { "&CapitalDifferentialD;"       ,       QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // &CapitalDifferentialD;"
702     { "&Cedilla;"               ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Cedilla;"
703     { "&CenterDot;"             ,         QwtMml::InfixForm, {              0,               0,               0,     "thinmathspace",           0,           0,     "thinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&CenterDot;"
704     { "&CircleDot;"             ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&CircleDot;"
705     { "&CircleMinus;"       ,         QwtMml::InfixForm, {              0,               0,               0,     "thinmathspace",           0,           0,     "thinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&CircleMinus;"
706     { "&CirclePlus;"        ,         QwtMml::InfixForm, {              0,               0,               0,     "thinmathspace",           0,           0,     "thinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&CirclePlus;"
707     { "&CircleTimes;"       ,         QwtMml::InfixForm, {              0,               0,               0,     "thinmathspace",           0,           0,     "thinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&CircleTimes;"
708     { "&ClockwiseContourIntegral;"   ,       QwtMml::PrefixForm, {              0,               0,          "true",           "0em",           0,           0,           "0em",               0,           "true"},            QwtMmlOperSpec::VStretch }, // &ClockwiseContourIntegral;"
709     { "&CloseCurlyDoubleQuote;"      ,      QwtMml::PostfixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // &CloseCurlyDoubleQuote;"
710     { "&CloseCurlyQuote;"       ,       QwtMml::PostfixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&CloseCurlyQuote;"
711     { "&Colon;"             ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Colon;"
712     { "&Congruent;"             ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Congruent;"
713     { "&ContourIntegral;"       ,        QwtMml::PrefixForm, {              0,               0,          "true",           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&ContourIntegral;"
714     { "&Coproduct;"             ,         QwtMml::InfixForm, {              0,               0,               0,     "thinmathspace",           0,           0,     "thinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Coproduct;"
715     { "&CounterClockwiseContourIntegral;",       QwtMml::PrefixForm, {                  0,               0,          "true",           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // &CounterClockwiseContourInteg
716     { "&Cross;"             ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Cross;"
717     { "&Cup;"               ,         QwtMml::InfixForm, {              0,               0,               0,     "thinmathspace",           0,           0,     "thinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Cup;"
718     { "&CupCap;"                ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&CupCap;"
719     { "&Del;"               ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Del;"
720     { "&DiacriticalAcute;"      ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&DiacriticalAcute;"
721     { "&DiacriticalDot;"        ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&DiacriticalDot;"
722     { "&DiacriticalDoubleAcute;"    ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // &DiacriticalDoubleAcute;"
723     { "&DiacriticalGrave;"      ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&DiacriticalGrave;"
724     { "&DiacriticalLeftArrow;"      ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // &DiacriticalLeftArrow;"
725     { "&DiacriticalLeftRightArrow;"  ,      QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // &DiacriticalLeftRightArrow;"
726     { "&DiacriticalLeftRightVector;" ,      QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // &DiacriticalLeftRightVector;"
727     { "&DiacriticalLeftVector;"      ,      QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // &DiacriticalLeftVector;"
728     { "&DiacriticalRightArrow;"     ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // &DiacriticalRightArrow;"
729     { "&DiacriticalRightVector;"    ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // &DiacriticalRightVector;"
730     { "&DiacriticalTilde;"      ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },           QwtMmlOperSpec::NoStretch }, // "&DiacriticalTilde;"
731     { "&Diamond;"               ,         QwtMml::InfixForm, {              0,               0,               0,     "thinmathspace",           0,           0,     "thinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Diamond;"
732     { "&DifferentialD;"     ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&DifferentialD;"
733     { "&DotEqual;"              ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&DotEqual;"
734     { "&DoubleContourIntegral;"      ,       QwtMml::PrefixForm, {              0,               0,          "true",           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // &DoubleContourIntegral;"
735     { "&DoubleDot;"             ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&DoubleDot;"
736     { "&DoubleDownArrow;"       ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&DoubleDownArrow;"
737     { "&DoubleLeftArrow;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&DoubleLeftArrow;"
738     { "&DoubleLeftRightArrow;"       ,        QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // &DoubleLeftRightArrow;"
739     { "&DoubleLeftTee;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&DoubleLeftTee;"
740     { "&DoubleLongLeftArrow;"   ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&DoubleLongLeftArrow;"
741     { "&DoubleLongLeftRightArrow;"  ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // &DoubleLongLeftRightArrow;"
742     { "&DoubleLongRightArrow;"       ,        QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // &DoubleLongRightArrow;"
743     { "&DoubleRightArrow;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&DoubleRightArrow;"
744     { "&DoubleRightTee;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&DoubleRightTee;"
745     { "&DoubleUpArrow;"     ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&DoubleUpArrow;"
746     { "&DoubleUpDownArrow;"     ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&DoubleUpDownArrow;"
747     { "&DoubleVerticalBar;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&DoubleVerticalBar;"
748     { "&DownArrow;"             ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&DownArrow;"
749     { "&DownArrowBar;"      ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&DownArrowBar;"
750     { "&DownArrowUpArrow;"      ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&DownArrowUpArrow;"
751     { "&DownBreve;"             ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&DownBreve;"
752     { "&DownLeftRightVector;"   ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&DownLeftRightVector;"
753     { "&DownLeftTeeVector;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&DownLeftTeeVector;"
754     { "&DownLeftVector;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&DownLeftVector;"
755     { "&DownLeftVectorBar;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&DownLeftVectorBar;"
756     { "&DownRightTeeVector;"    ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&DownRightTeeVector;"
757     { "&DownRightVector;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&DownRightVector;"
758     { "&DownRightVectorBar;"    ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&DownRightVectorBar;"
759     { "&DownTee;"               ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&DownTee;"
760     { "&DownTeeArrow;"      ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&DownTeeArrow;"
761     { "&Element;"               ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Element;"
762     { "&Equal;"             ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Equal;"
763     { "&EqualTilde;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&EqualTilde;"
764     { "&Equilibrium;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&Equilibrium;"
765     { "&Exists;"                ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Exists;"
766     { "&ForAll;"                ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&ForAll;"
767     { "&GreaterEqual;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&GreaterEqual;"
768     { "&GreaterEqualLess;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&GreaterEqualLess;"
769     { "&GreaterFullEqual;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&GreaterFullEqual;"
770     { "&GreaterGreater;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&GreaterGreater;"
771     { "&GreaterLess;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&GreaterLess;"
772     { "&GreaterSlantEqual;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&GreaterSlantEqual;"
773     { "&GreaterTilde;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&GreaterTilde;"
774     { "&Hacek;"             ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },           QwtMmlOperSpec::NoStretch }, // "&Hacek;"
775     { "&Hat;"               ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&Hat;"
776     { "&HorizontalLine;"        ,         QwtMml::InfixForm, {              0,               0,               0,           "0em",             "0",           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&HorizontalLine;"
777     { "&HumpDownHump;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&HumpDownHump;"
778     { "&HumpEqual;"             ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&HumpEqual;"
779     { "&Implies;"               ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&Implies;"
780     { "&Integral;"              ,        QwtMml::PrefixForm, {              0,               0,          "true",           "0em",           0,           0,           "0em",               0,                   0 },           QwtMmlOperSpec::NoStretch }, // "&Integral;"
781     { "&Intersection;"      ,        QwtMml::PrefixForm, {              0,               0,          "true",           "0em",           0,          "true",     "thinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&Intersection;"
782     { "&InvisibleComma;"        ,         QwtMml::InfixForm, {              0,               0,               0,           "0em",           0,           0,           "0em",              "true",               0 },           QwtMmlOperSpec::NoStretch }, // "&InvisibleComma;"
783     { "&InvisibleTimes;"        ,         QwtMml::InfixForm, {              0,               0,               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&InvisibleTimes;"
784     { "&LeftAngleBracket;"      ,        QwtMml::PrefixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&LeftAngleBracket;"
785     { "&LeftArrow;"             ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&LeftArrow;"
786     { "&LeftArrowBar;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&LeftArrowBar;"
787     { "&LeftArrowRightArrow;"   ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&LeftArrowRightArrow;"
788     { "&LeftBracketingBar;"     ,        QwtMml::PrefixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&LeftBracketingBar;"
789     { "&LeftCeiling;"       ,        QwtMml::PrefixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&LeftCeiling;"
790     { "&LeftDoubleBracket;"     ,        QwtMml::PrefixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&LeftDoubleBracket;"
791     { "&LeftDoubleBracketingBar;"    ,       QwtMml::PrefixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // &LeftDoubleBracketingBar;"
792     { "&LeftDownTeeVector;"     ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&LeftDownTeeVector;"
793     { "&LeftDownVector;"        ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&LeftDownVector;"
794     { "&LeftDownVectorBar;"     ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&LeftDownVectorBar;"
795     { "&LeftFloor;"             ,        QwtMml::PrefixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&LeftFloor;"
796     { "&LeftRightArrow;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&LeftRightArrow;"
797     { "&LeftRightVector;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&LeftRightVector;"
798     { "&LeftSkeleton;"      ,        QwtMml::PrefixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&LeftSkeleton;"
799     { "&LeftTee;"               ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&LeftTee;"
800     { "&LeftTeeArrow;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&LeftTeeArrow;"
801     { "&LeftTeeVector;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&LeftTeeVector;"
802     { "&LeftTriangle;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&LeftTriangle;"
803     { "&LeftTriangleBar;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&LeftTriangleBar;"
804     { "&LeftTriangleEqual;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&LeftTriangleEqual;"
805     { "&LeftUpDownVector;"      ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&LeftUpDownVector;"
806     { "&LeftUpTeeVector;"       ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&LeftUpTeeVector;"
807     { "&LeftUpVector;"      ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&LeftUpVector;"
808     { "&LeftUpVectorBar;"       ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&LeftUpVectorBar;"
809     { "&LeftVector;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&LeftVector;"
810     { "&LeftVectorBar;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&LeftVectorBar;"
811     { "&LessEqualGreater;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&LessEqualGreater;"
812     { "&LessFullEqual;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&LessFullEqual;"
813     { "&LessGreater;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&LessGreater;"
814     { "&LessLess;"              ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&LessLess;"
815     { "&LessSlantEqual;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&LessSlantEqual;"
816     { "&LessTilde;"             ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&LessTilde;"
817     { "&LongLeftArrow;"     ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&LongLeftArrow;"
818     { "&LongLeftRightArrow;"        ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&LongLeftRightArrow;"
819     { "&LongRightArrow;"        ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&LongRightArrow;"
820     { "&LowerLeftArrow;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&LowerLeftArrow;"
821     { "&LowerRightArrow;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&LowerRightArrow;"
822     { "&MinusPlus;"             ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,           0, "veryverythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&MinusPlus;"
823     { "&NestedGreaterGreater;"       ,        QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // &NestedGreaterGreater;"
824     { "&NestedLessLess;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NestedLessLess;"
825     { "&Not;"               ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Not;"
826     { "&NotCongruent;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotCongruent;"
827     { "&NotCupCap;"             ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotCupCap;"
828     { "&NotDoubleVerticalBar;"       ,        QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // &NotDoubleVerticalBar;"
829     { "&NotElement;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotElement;"
830     { "&NotEqual;"              ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotEqual;"
831     { "&NotEqualTilde;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotEqualTilde;"
832     { "&NotExists;"             ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotExists;"
833     { "&NotGreater;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotGreater;"
834     { "&NotGreaterEqual;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotGreaterEqual;"
835     { "&NotGreaterFullEqual;"   ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotGreaterFullEqual;"
836     { "&NotGreaterGreater;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotGreaterGreater;"
837     { "&NotGreaterLess;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotGreaterLess;"
838     { "&NotGreaterSlantEqual;"       ,        QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // &NotGreaterSlantEqual;"
839     { "&NotGreaterTilde;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotGreaterTilde;"
840     { "&NotHumpDownHump;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotHumpDownHump;"
841     { "&NotHumpEqual;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotHumpEqual;"
842     { "&NotLeftTriangle;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotLeftTriangle;"
843     { "&NotLeftTriangleBar;"    ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotLeftTriangleBar;"
844     { "&NotLeftTriangleEqual;"       ,        QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // &NotLeftTriangleEqual;"
845     { "&NotLess;"               ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotLess;"
846     { "&NotLessEqual;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotLessEqual;"
847     { "&NotLessFullEqual;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotLessFullEqual;"
848     { "&NotLessGreater;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotLessGreater;"
849     { "&NotLessLess;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotLessLess;"
850     { "&NotLessSlantEqual;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotLessSlantEqual;"
851     { "&NotLessTilde;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotLessTilde;"
852     { "&NotNestedGreaterGreater;"    ,        QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // &NotNestedGreaterGreater;"
853     { "&NotNestedLessLess;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotNestedLessLess;"
854     { "&NotPrecedes;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotPrecedes;"
855     { "&NotPrecedesEqual;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotPrecedesEqual;"
856     { "&NotPrecedesSlantEqual;"      ,        QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // &NotPrecedesSlantEqual;"
857     { "&NotPrecedesTilde;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotPrecedesTilde;"
858     { "&NotReverseElement;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotReverseElement;"
859     { "&NotRightTriangle;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotRightTriangle;"
860     { "&NotRightTriangleBar;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotRightTriangleBar;"
861     { "&NotRightTriangleEqual;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // &NotRightTriangleEqual;"
862     { "&NotSquareSubset;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotSquareSubset;"
863     { "&NotSquareSubsetEqual;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // &NotSquareSubsetEqual;"
864     { "&NotSquareSuperset;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotSquareSuperset;"
865     { "&NotSquareSupersetEqual;"     ,        QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // &NotSquareSupersetEqual;"
866     { "&NotSubset;"             ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotSubset;"
867     { "&NotSubsetEqual;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotSubsetEqual;"
868     { "&NotSucceeds;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotSucceeds;"
869     { "&NotSucceedsEqual;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotSucceedsEqual;"
870     { "&NotSucceedsSlantEqual;"      ,        QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // &NotSucceedsSlantEqual;"
871     { "&NotSucceedsTilde;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotSucceedsTilde;"
872     { "&NotSuperset;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotSuperset;"
873     { "&NotSupersetEqual;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotSupersetEqual;"
874     { "&NotTilde;"              ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotTilde;"
875     { "&NotTildeEqual;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotTildeEqual;"
876     { "&NotTildeFullEqual;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotTildeFullEqual;"
877     { "&NotTildeTilde;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotTildeTilde;"
878     { "&NotVerticalBar;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&NotVerticalBar;"
879     { "&OpenCurlyDoubleQuote;"       ,       QwtMml::PrefixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // &OpenCurlyDoubleQuote;"
880     { "&OpenCurlyQuote;"        ,        QwtMml::PrefixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&OpenCurlyQuote;"
881     { "&Or;"                ,         QwtMml::InfixForm, {              0,               0,               0,       "mediummathspace",           0,           0,   "mediummathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&Or;"
882     { "&OverBar;"               ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&OverBar;"
883     { "&OverBrace;"             ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&OverBrace;"
884     { "&OverBracket;"       ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&OverBracket;"
885     { "&OverParenthesis;"       ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&OverParenthesis;"
886     { "&PartialD;"              ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&PartialD;"
887     { "&PlusMinus;"             ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,           0, "veryverythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&PlusMinus;"
888     { "&Precedes;"              ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Precedes;"
889     { "&PrecedesEqual;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&PrecedesEqual;"
890     { "&PrecedesSlantEqual;"    ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&PrecedesSlantEqual;"
891     { "&PrecedesTilde;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&PrecedesTilde;"
892     { "&Product;"               ,        QwtMml::PrefixForm, {              0,               0,          "true",           "0em",           0,          "true",     "thinmathspace",               0,                   0 },           QwtMmlOperSpec::NoStretch }, // "&Product;"
893     { "&Proportion;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Proportion;"
894     { "&Proportional;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Proportional;"
895     { "&ReverseElement;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&ReverseElement;"
896     { "&ReverseEquilibrium;"    ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&ReverseEquilibrium;"
897     { "&ReverseUpEquilibrium;"      ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // &ReverseUpEquilibrium;"
898     { "&RightAngleBracket;"     ,       QwtMml::PostfixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&RightAngleBracket;"
899     { "&RightArrow;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&RightArrow;"
900     { "&RightArrowBar;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&RightArrowBar;"
901     { "&RightArrowLeftArrow;"   ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&RightArrowLeftArrow;"
902     { "&RightBracketingBar;"    ,       QwtMml::PostfixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&RightBracketingBar;"
903     { "&RightCeiling;"      ,       QwtMml::PostfixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&RightCeiling;"
904     { "&RightDoubleBracket;"    ,       QwtMml::PostfixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&RightDoubleBracket;"
905     { "&RightDoubleBracketingBar;"   ,      QwtMml::PostfixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // &RightDoubleBracketingBar;"
906     { "&RightDownTeeVector;"    ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&RightDownTeeVector;"
907     { "&RightDownVector;"       ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&RightDownVector;"
908     { "&RightDownVectorBar;"    ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&RightDownVectorBar;"
909     { "&RightFloor;"        ,       QwtMml::PostfixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&RightFloor;"
910     { "&RightSkeleton;"     ,       QwtMml::PostfixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&RightSkeleton;"
911     { "&RightTee;"              ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&RightTee;"
912     { "&RightTeeArrow;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&RightTeeArrow;"
913     { "&RightTeeVector;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&RightTeeVector;"
914     { "&RightTriangle;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&RightTriangle;"
915     { "&RightTriangleBar;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&RightTriangleBar;"
916     { "&RightTriangleEqual;"    ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&RightTriangleEqual;"
917     { "&RightUpDownVector;"     ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&RightUpDownVector;"
918     { "&RightUpTeeVector;"      ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&RightUpTeeVector;"
919     { "&RightUpVector;"     ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&RightUpVector;"
920     { "&RightUpVectorBar;"      ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&RightUpVectorBar;"
921     { "&RightVector;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&RightVector;"
922     { "&RightVectorBar;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&RightVectorBar;"
923     { "&RoundImplies;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&RoundImplies;"
924     { "&ShortDownArrow;"        ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&ShortDownArrow;"
925     { "&ShortLeftArrow;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },            QwtMmlOperSpec::HStretch }, // "&ShortLeftArrow;"
926     { "&ShortRightArrow;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },            QwtMmlOperSpec::HStretch }, // "&ShortRightArrow;"
927     { "&ShortUpArrow;"      ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,               0 },            QwtMmlOperSpec::VStretch }, // "&ShortUpArrow;"
928     { "&SmallCircle;"       ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&SmallCircle;"
929     { "&Sqrt;"              ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&Sqrt;"
930     { "&Square;"                ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Square;"
931     { "&SquareIntersection;"    ,         QwtMml::InfixForm, {              0,               0,               0,       "mediummathspace",           0,           0,   "mediummathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&SquareIntersection;"
932     { "&SquareSubset;"      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&SquareSubset;"
933     { "&SquareSubsetEqual;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&SquareSubsetEqual;"
934     { "&SquareSuperset;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&SquareSuperset;"
935     { "&SquareSupersetEqual;"   ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&SquareSupersetEqual;"
936     { "&SquareUnion;"       ,         QwtMml::InfixForm, {              0,               0,               0,       "mediummathspace",           0,           0,   "mediummathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&SquareUnion;"
937     { "&Star;"              ,         QwtMml::InfixForm, {              0,               0,               0,     "thinmathspace",           0,           0,     "thinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Star;"
938     { "&Subset;"                ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Subset;"
939     { "&SubsetEqual;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&SubsetEqual;"
940     { "&Succeeds;"              ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Succeeds;"
941     { "&SucceedsEqual;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&SucceedsEqual;"
942     { "&SucceedsSlantEqual;"    ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&SucceedsSlantEqual;"
943     { "&SucceedsTilde;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&SucceedsTilde;"
944     { "&SuchThat;"              ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&SuchThat;"
945     { "&Sum;"               ,        QwtMml::PrefixForm, {              0,               0,          "true",           "0em",           0,          "true",     "thinmathspace",               0,                   0 },           QwtMmlOperSpec::NoStretch }, // "&Sum;"
946     { "&Superset;"              ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Superset;"
947     { "&SupersetEqual;"     ,                 QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&SupersetEqual;"
948     { "&Therefore;"             ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Therefore;"
949     { "&Tilde;"             ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Tilde;"
950     { "&TildeEqual;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&TildeEqual;"
951     { "&TildeFullEqual;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&TildeFullEqual;"
952     { "&TildeTilde;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&TildeTilde;"
953     { "&TripleDot;"             ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&TripleDot;"
954     { "&UnderBar;"              ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&UnderBar;"
955     { "&UnderBrace;"        ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&UnderBrace;"
956     { "&UnderBracket;"      ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },           QwtMmlOperSpec::HStretch }, // "&UnderBracket;"
957     { "&UnderParenthesis;"      ,       QwtMml::PostfixForm, {             "true",               0,               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::HStretch }, // "&UnderParenthesis;"
958     { "&Union;"             ,        QwtMml::PrefixForm, {              0,               0,          "true",           "0em",           0,          "true",     "thinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&Union;"
959     { "&UnionPlus;"             ,        QwtMml::PrefixForm, {              0,               0,          "true",           "0em",           0,          "true",     "thinmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&UnionPlus;"
960     { "&UpArrow;"               ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&UpArrow;"
961     { "&UpArrowBar;"        ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&UpArrowBar;"
962     { "&UpArrowDownArrow;"      ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&UpArrowDownArrow;"
963     { "&UpDownArrow;"       ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&UpDownArrow;"
964     { "&UpEquilibrium;"     ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&UpEquilibrium;"
965     { "&UpTee;"             ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&UpTee;"
966     { "&UpTeeArrow;"        ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&UpTeeArrow;"
967     { "&UpperLeftArrow;"        ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&UpperLeftArrow;"
968     { "&UpperRightArrow;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },           QwtMmlOperSpec::HVStretch }, // "&UpperRightArrow;"
969     { "&Vee;"               ,         QwtMml::InfixForm, {              0,               0,               0,     "thinmathspace",           0,           0,     "thinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Vee;"
970     { "&VerticalBar;"       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&VerticalBar;"
971     { "&VerticalLine;"      ,         QwtMml::InfixForm, {              0,               0,               0,           "0em",             "0",           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&VerticalLine;"
972     { "&VerticalSeparator;"     ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "&VerticalSeparator;"
973     { "&VerticalTilde;"     ,         QwtMml::InfixForm, {              0,               0,               0,     "thinmathspace",           0,           0,     "thinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&VerticalTilde;"
974     { "&Wedge;"             ,         QwtMml::InfixForm, {              0,               0,               0,     "thinmathspace",           0,           0,     "thinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&Wedge;"
975     { "&amp;"               ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&amp;"
976     { "&amp;&amp;"              ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&amp;&amp;"
977     { "&le;"                ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&le;"
978     { "&lt;"                ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&lt;"
979     { "&lt;="               ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&lt;="
980     { "&lt;>"               ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "&lt;>"
981     { "'"                       ,       QwtMml::PostfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "'"
982     { "("                       ,        QwtMml::PrefixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "("
983     { ")"                       ,       QwtMml::PostfixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // ")"
984     { "*"                       ,         QwtMml::InfixForm, {              0,               0,               0,     "thinmathspace",           0,           0,     "thinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "*"
985     { "**"                      ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "**"
986     { "*="                      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "*="
987     { "+"                       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "+"
988     { "+"                       ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,           0, "veryverythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "+"
989     { "++"                      ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "++"
990     { "+="                      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "+="
991     { ","                       ,         QwtMml::InfixForm, {              0,               0,               0,           "0em",           0,           0,    "verythickmathspace",              "true",               0 },           QwtMmlOperSpec::NoStretch }, // ","
992     { "-"                       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "-"
993     { "-"                       ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,           0, "veryverythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "-"
994     { "--"                      ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, //   "--"
995     { "-="                      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "-="
996     { "->"                      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "->"
997     { "."                       ,         QwtMml::InfixForm, {              0,               0,               0,           "0em",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "."
998     { ".."                      ,       QwtMml::PostfixForm, {              0,               0,               0,       "mediummathspace",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // ".."
999     { "..."                     ,       QwtMml::PostfixForm, {              0,               0,               0,       "mediummathspace",           0,           0,           "0em",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "..."
1000     { "/"                       ,         QwtMml::InfixForm, {              0,               0,               0,     "thinmathspace",           0,           0,     "thinmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "/"
1001     { "//"                      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "//"
1002     { "/="                      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "/="
1003     { ":"                       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // ":"
1004     { ":="                      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // ":="
1005     { ";"                       ,         QwtMml::InfixForm, {              0,               0,               0,           "0em",           0,           0,    "verythickmathspace",              "true",               0 },           QwtMmlOperSpec::NoStretch }, // ";"
1006     { ";"                       ,       QwtMml::PostfixForm, {              0,               0,               0,           "0em",           0,           0,           "0em",              "true",               0 },           QwtMmlOperSpec::NoStretch }, // ";"
1007     { "="                       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "="
1008     { "=="                      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "=="
1009     { ">"                       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // ">"
1010     { ">="                      ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // ">="
1011     { "?"                       ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "?"
1012     { "@"                       ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "@"
1013     { "["                       ,        QwtMml::PrefixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "["
1014     { "]"                       ,       QwtMml::PostfixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "]"
1015     { "^"                       ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "^"
1016     { "_"                       ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "_"
1017     { "lim"                     ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,          "true",     "thinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "lim"
1018     { "max"                     ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,          "true",     "thinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "max"
1019     { "min"                     ,        QwtMml::PrefixForm, {              0,               0,               0,           "0em",           0,          "true",     "thinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "min"
1020     { "{"                   ,        QwtMml::PrefixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "{"
1021     { "|"                       ,         QwtMml::InfixForm, {              0,               0,               0,    "thickmathspace",           0,           0,    "thickmathspace",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "|"
1022     { "||"                      ,         QwtMml::InfixForm, {              0,               0,               0,       "mediummathspace",           0,           0,   "mediummathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "||"
1023     { "}"                       ,       QwtMml::PostfixForm, {              0,          "true",               0,           "0em",           0,           0,           "0em",               0,              "true" },            QwtMmlOperSpec::VStretch }, // "}"
1024     { "~"                       ,         QwtMml::InfixForm, {              0,               0,               0,     "verythinmathspace",           0,           0, "verythinmathspace",               0,               0 },           QwtMmlOperSpec::NoStretch }, // "~"
1025 
1026     {  0                            ,                 QwtMml::InfixForm, {                      0,                       0,                       0,                       0,                       0,               0,                       0,                       0,                       0 },           QwtMmlOperSpec::NoStretch }
1027 };
1028 
1029 static const QwtMmlOperSpec g_oper_spec_defaults =
1030 {  0                            ,                 QwtMml::InfixForm, {                "false",                 "false",                 "false",         "thickmathspace",                     "1",            "false",        "thickmathspace",                 "false",                 "false" },           QwtMmlOperSpec::NoStretch  };
1031 
1032 static const uint g_oper_spec_count = sizeof( g_oper_spec_data ) / sizeof( QwtMmlOperSpec ) - 1;
1033 
1034 static const QwtMmlEntitySpec g_xml_entity_data[] =
1035 {
1036     { "angzarr",    "&#x0237C;" },
1037     { "cirmid", "&#x02AEF;" },
1038     { "cudarrl",    "&#x02938;" },
1039     { "cudarrr",    "&#x02935;" },
1040     { "cularr", "&#x021B6;" },
1041     { "cularrp",    "&#x0293D;" },
1042     { "curarr", "&#x021B7;" },
1043     { "curarrm",    "&#x0293C;" },
1044     { "Darr",   "&#x021A1;" },
1045     { "dArr",   "&#x021D3;" },
1046     { "ddarr",  "&#x021CA;" },
1047     { "DDotrahd",   "&#x02911;" },
1048     { "dfisht", "&#x0297F;" },
1049     { "dHar",   "&#x02965;" },
1050     { "dharl",  "&#x021C3;" },
1051     { "dharr",  "&#x021C2;" },
1052     { "duarr",  "&#x021F5;" },
1053     { "duhar",  "&#x0296F;" },
1054     { "dzigrarr",   "&#x027FF;" },
1055     { "erarr",  "&#x02971;" },
1056     { "hArr",   "&#x021D4;" },
1057     { "harr",   "&#x02194;" },
1058     { "harrcir",    "&#x02948;" },
1059     { "harrw",  "&#x021AD;" },
1060     { "hoarr",  "&#x021FF;" },
1061     { "imof",   "&#x022B7;" },
1062     { "lAarr",  "&#x021DA;" },
1063     { "Larr",   "&#x0219E;" },
1064     { "larrbfs",    "&#x0291F;" },
1065     { "larrfs", "&#x0291D;" },
1066     { "larrhk", "&#x021A9;" },
1067     { "larrlp", "&#x021AB;" },
1068     { "larrpl", "&#x02939;" },
1069     { "larrsim",    "&#x02973;" },
1070     { "larrtl", "&#x021A2;" },
1071     { "lAtail", "&#x0291B;" },
1072     { "latail", "&#x02919;" },
1073     { "lBarr",  "&#x0290E;" },
1074     { "lbarr",  "&#x0290C;" },
1075     { "ldca",   "&#x02936;" },
1076     { "ldrdhar",    "&#x02967;" },
1077     { "ldrushar",   "&#x0294B;" },
1078     { "ldsh",   "&#x021B2;" },
1079     { "lfisht", "&#x0297C;" },
1080     { "lHar",   "&#x02962;" },
1081     { "lhard",  "&#x021BD;" },
1082     { "lharu",  "&#x021BC;" },
1083     { "lharul", "&#x0296A;" },
1084     { "llarr",  "&#x021C7;" },
1085     { "llhard", "&#x0296B;" },
1086     { "loarr",  "&#x021FD;" },
1087     { "lrarr",  "&#x021C6;" },
1088     { "lrhar",  "&#x021CB;" },
1089     { "lrhard", "&#x0296D;" },
1090     { "lsh",    "&#x021B0;" },
1091     { "lurdshar",   "&#x0294A;" },
1092     { "luruhar",    "&#x02966;" },
1093     { "Map",    "&#x02905;" },
1094     { "map",    "&#x021A6;" },
1095     { "midcir", "&#x02AF0;" },
1096     { "mumap",  "&#x022B8;" },
1097     { "nearhk", "&#x02924;" },
1098     { "neArr",  "&#x021D7;" },
1099     { "nearr",  "&#x02197;" },
1100     { "nesear", "&#x02928;" },
1101     { "nhArr",  "&#x021CE;" },
1102     { "nharr",  "&#x021AE;" },
1103     { "nlArr",  "&#x021CD;" },
1104     { "nlarr",  "&#x0219A;" },
1105     { "nrArr",  "&#x021CF;" },
1106     { "nrarr",  "&#x0219B;" },
1107     { "nrarrc", "&#x02933;&#x00338;" },
1108     { "nrarrw", "&#x0219D;&#x00338;" },
1109     { "nvHarr", "&#x02904;" },
1110     { "nvlArr", "&#x02902;" },
1111     { "nvrArr", "&#x02903;" },
1112     { "nwarhk", "&#x02923;" },
1113     { "nwArr",  "&#x021D6;" },
1114     { "nwarr",  "&#x02196;" },
1115     { "nwnear", "&#x02927;" },
1116     { "olarr",  "&#x021BA;" },
1117     { "orarr",  "&#x021BB;" },
1118     { "origof", "&#x022B6;" },
1119     { "rAarr",  "&#x021DB;" },
1120     { "Rarr",   "&#x021A0;" },
1121     { "rarrap", "&#x02975;" },
1122     { "rarrbfs",    "&#x02920;" },
1123     { "rarrc",  "&#x02933;" },
1124     { "rarrfs", "&#x0291E;" },
1125     { "rarrhk", "&#x021AA;" },
1126     { "rarrlp", "&#x021AC;" },
1127     { "rarrpl", "&#x02945;" },
1128     { "rarrsim",    "&#x02974;" },
1129     { "Rarrtl", "&#x02916;" },
1130     { "rarrtl", "&#x021A3;" },
1131     { "rarrw",  "&#x0219D;" },
1132     { "rAtail", "&#x0291C;" },
1133     { "ratail", "&#x0291A;" },
1134     { "RBarr",  "&#x02910;" },
1135     { "rBarr",  "&#x0290F;" },
1136     { "rbarr",  "&#x0290D;" },
1137     { "rdca",   "&#x02937;" },
1138     { "rdldhar",    "&#x02969;" },
1139     { "rdsh",   "&#x021B3;" },
1140     { "rfisht", "&#x0297D;" },
1141     { "rHar",   "&#x02964;" },
1142     { "rhard",  "&#x021C1;" },
1143     { "rharu",  "&#x021C0;" },
1144     { "rharul", "&#x0296C;" },
1145     { "rlarr",  "&#x021C4;" },
1146     { "rlhar",  "&#x021CC;" },
1147     { "roarr",  "&#x021FE;" },
1148     { "rrarr",  "&#x021C9;" },
1149     { "rsh",    "&#x021B1;" },
1150     { "ruluhar",    "&#x02968;" },
1151     { "searhk", "&#x02925;" },
1152     { "seArr",  "&#x021D8;" },
1153     { "searr",  "&#x02198;" },
1154     { "seswar", "&#x02929;" },
1155     { "simrarr",    "&#x02972;" },
1156     { "slarr",  "&#x02190;" },
1157     { "srarr",  "&#x02192;" },
1158     { "swarhk", "&#x02926;" },
1159     { "swArr",  "&#x021D9;" },
1160     { "swarr",  "&#x02199;" },
1161     { "swnwar", "&#x0292A;" },
1162     { "Uarr",   "&#x0219F;" },
1163     { "uArr",   "&#x021D1;" },
1164     { "Uarrocir",   "&#x02949;" },
1165     { "udarr",  "&#x021C5;" },
1166     { "udhar",  "&#x0296E;" },
1167     { "ufisht", "&#x0297E;" },
1168     { "uHar",   "&#x02963;" },
1169     { "uharl",  "&#x021BF;" },
1170     { "uharr",  "&#x021BE;" },
1171     { "uuarr",  "&#x021C8;" },
1172     { "vArr",   "&#x021D5;" },
1173     { "varr",   "&#x02195;" },
1174     { "xhArr",  "&#x027FA;" },
1175     { "xharr",  "&#x027F7;" },
1176     { "xlArr",  "&#x027F8;" },
1177     { "xlarr",  "&#x027F5;" },
1178     { "xmap",   "&#x027FC;" },
1179     { "xrArr",  "&#x027F9;" },
1180     { "xrarr",  "&#x027F6;" },
1181     { "zigrarr",    "&#x021DD;" },
1182     { "ac", "&#x0223E;" },
1183     { "acE",    "&#x0223E;&#x00333;" },
1184     { "amalg",  "&#x02A3F;" },
1185     { "barvee", "&#x022BD;" },
1186     { "Barwed", "&#x02306;" },
1187     { "barwed", "&#x02305;" },
1188     { "bsolb",  "&#x029C5;" },
1189     { "Cap",    "&#x022D2;" },
1190     { "capand", "&#x02A44;" },
1191     { "capbrcup",   "&#x02A49;" },
1192     { "capcap", "&#x02A4B;" },
1193     { "capcup", "&#x02A47;" },
1194     { "capdot", "&#x02A40;" },
1195     { "caps",   "&#x02229;&#x0FE00;" },
1196     { "ccaps",  "&#x02A4D;" },
1197     { "ccups",  "&#x02A4C;" },
1198     { "ccupssm",    "&#x02A50;" },
1199     { "coprod", "&#x02210;" },
1200     { "Cup",    "&#x022D3;" },
1201     { "cupbrcap",   "&#x02A48;" },
1202     { "cupcap", "&#x02A46;" },
1203     { "cupcup", "&#x02A4A;" },
1204     { "cupdot", "&#x0228D;" },
1205     { "cupor",  "&#x02A45;" },
1206     { "cups",   "&#x0222A;&#x0FE00;" },
1207     { "cuvee",  "&#x022CE;" },
1208     { "cuwed",  "&#x022CF;" },
1209     { "Dagger", "&#x02021;" },
1210     { "dagger", "&#x02020;" },
1211     { "diam",   "&#x022C4;" },
1212     { "divonx", "&#x022C7;" },
1213     { "eplus",  "&#x02A71;" },
1214     { "hercon", "&#x022B9;" },
1215     { "intcal", "&#x022BA;" },
1216     { "iprod",  "&#x02A3C;" },
1217     { "loplus", "&#x02A2D;" },
1218     { "lotimes",    "&#x02A34;" },
1219     { "lthree", "&#x022CB;" },
1220     { "ltimes", "&#x022C9;" },
1221     { "midast", "&#x0002A;" },
1222     { "minusb", "&#x0229F;" },
1223     { "minusd", "&#x02238;" },
1224     { "minusdu",    "&#x02A2A;" },
1225     { "ncap",   "&#x02A43;" },
1226     { "ncup",   "&#x02A42;" },
1227     { "oast",   "&#x0229B;" },
1228     { "ocir",   "&#x0229A;" },
1229     { "odash",  "&#x0229D;" },
1230     { "odiv",   "&#x02A38;" },
1231     { "odot",   "&#x02299;" },
1232     { "odsold", "&#x029BC;" },
1233     { "ofcir",  "&#x029BF;" },
1234     { "ogt",    "&#x029C1;" },
1235     { "ohbar",  "&#x029B5;" },
1236     { "olcir",  "&#x029BE;" },
1237     { "olt",    "&#x029C0;" },
1238     { "omid",   "&#x029B6;" },
1239     { "ominus", "&#x02296;" },
1240     { "opar",   "&#x029B7;" },
1241     { "operp",  "&#x029B9;" },
1242     { "oplus",  "&#x02295;" },
1243     { "osol",   "&#x02298;" },
1244     { "Otimes", "&#x02A37;" },
1245     { "otimes", "&#x02297;" },
1246     { "otimesas",   "&#x02A36;" },
1247     { "ovbar",  "&#x0233D;" },
1248     { "plusacir",   "&#x02A23;" },
1249     { "plusb",  "&#x0229E;" },
1250     { "pluscir",    "&#x02A22;" },
1251     { "plusdo", "&#x02214;" },
1252     { "plusdu", "&#x02A25;" },
1253     { "pluse",  "&#x02A72;" },
1254     { "plussim",    "&#x02A26;" },
1255     { "plustwo",    "&#x02A27;" },
1256     { "prod",   "&#x0220F;" },
1257     { "race",   "&#x029DA;" },
1258     { "roplus", "&#x02A2E;" },
1259     { "rotimes",    "&#x02A35;" },
1260     { "rthree", "&#x022CC;" },
1261     { "rtimes", "&#x022CA;" },
1262     { "sdot",   "&#x022C5;" },
1263     { "sdotb",  "&#x022A1;" },
1264     { "setmn",  "&#x02216;" },
1265     { "simplus",    "&#x02A24;" },
1266     { "smashp", "&#x02A33;" },
1267     { "solb",   "&#x029C4;" },
1268     { "sqcap",  "&#x02293;" },
1269     { "sqcaps", "&#x02293;&#x0FE00;" },
1270     { "sqcup",  "&#x02294;" },
1271     { "sqcups", "&#x02294;&#x0FE00;" },
1272     { "ssetmn", "&#x02216;" },
1273     { "sstarf", "&#x022C6;" },
1274     { "subdot", "&#x02ABD;" },
1275     { "sum",    "&#x02211;" },
1276     { "supdot", "&#x02ABE;" },
1277     { "timesb", "&#x022A0;" },
1278     { "timesbar",   "&#x02A31;" },
1279     { "timesd", "&#x02A30;" },
1280     { "tridot", "&#x025EC;" },
1281     { "triminus",   "&#x02A3A;" },
1282     { "triplus",    "&#x02A39;" },
1283     { "trisb",  "&#x029CD;" },
1284     { "tritime",    "&#x02A3B;" },
1285     { "uplus",  "&#x0228E;" },
1286     { "veebar", "&#x022BB;" },
1287     { "wedbar", "&#x02A5F;" },
1288     { "wreath", "&#x02240;" },
1289     { "xcap",   "&#x022C2;" },
1290     { "xcirc",  "&#x025EF;" },
1291     { "xcup",   "&#x022C3;" },
1292     { "xdtri",  "&#x025BD;" },
1293     { "xodot",  "&#x02A00;" },
1294     { "xoplus", "&#x02A01;" },
1295     { "xotime", "&#x02A02;" },
1296     { "xsqcup", "&#x02A06;" },
1297     { "xuplus", "&#x02A04;" },
1298     { "xutri",  "&#x025B3;" },
1299     { "xvee",   "&#x022C1;" },
1300     { "xwedge", "&#x022C0;" },
1301     { "dlcorn", "&#x0231E;" },
1302     { "drcorn", "&#x0231F;" },
1303     { "gtlPar", "&#x02995;" },
1304     { "langd",  "&#x02991;" },
1305     { "lbrke",  "&#x0298B;" },
1306     { "lbrksld",    "&#x0298F;" },
1307     { "lbrkslu",    "&#x0298D;" },
1308     { "lceil",  "&#x02308;" },
1309     { "lfloor", "&#x0230A;" },
1310     { "lmoust", "&#x023B0;" },
1311     { "lparlt", "&#x02993;" },
1312     { "ltrPar", "&#x02996;" },
1313     { "rangd",  "&#x02992;" },
1314     { "rbrke",  "&#x0298C;" },
1315     { "rbrksld",    "&#x0298E;" },
1316     { "rbrkslu",    "&#x02990;" },
1317     { "rceil",  "&#x02309;" },
1318     { "rfloor", "&#x0230B;" },
1319     { "rmoust", "&#x023B1;" },
1320     { "rpargt", "&#x02994;" },
1321     { "ulcorn", "&#x0231C;" },
1322     { "urcorn", "&#x0231D;" },
1323     { "gnap",   "&#x02A8A;" },
1324     { "gnE",    "&#x02269;" },
1325     { "gne",    "&#x02A88;" },
1326     { "gnsim",  "&#x022E7;" },
1327     { "gvnE",   "&#x02269;&#x0FE00;" },
1328     { "lnap",   "&#x02A89;" },
1329     { "lnE",    "&#x02268;" },
1330     { "lne",    "&#x02A87;" },
1331     { "lnsim",  "&#x022E6;" },
1332     { "lvnE",   "&#x02268;&#x0FE00;" },
1333     { "nap",    "&#x02249;" },
1334     { "napE",   "&#x02A70;&#x00338;" },
1335     { "napid",  "&#x0224B;&#x00338;" },
1336     { "ncong",  "&#x02247;" },
1337     { "ncongdot",   "&#x02A6D;&#x00338;" },
1338     { "nequiv", "&#x02262;" },
1339     { "ngE",    "&#x02267;&#x00338;" },
1340     { "nge",    "&#x02271;" },
1341     { "nges",   "&#x02A7E;&#x00338;" },
1342     { "nGg",    "&#x022D9;&#x00338;" },
1343     { "ngsim",  "&#x02275;" },
1344     { "nGt",    "&#x0226B;&#x020D2;" },
1345     { "ngt",    "&#x0226F;" },
1346     { "nGtv",   "&#x0226B;&#x00338;" },
1347     { "nlE",    "&#x02266;&#x00338;" },
1348     { "nle",    "&#x02270;" },
1349     { "nles",   "&#x02A7D;&#x00338;" },
1350     { "nLl",    "&#x022D8;&#x00338;" },
1351     { "nlsim",  "&#x02274;" },
1352     { "nLt",    "&#x0226A;&#x020D2;" },
1353     { "nlt",    "&#x0226E;" },
1354     { "nltri",  "&#x022EA;" },
1355     { "nltrie", "&#x022EC;" },
1356     { "nLtv",   "&#x0226A;&#x00338;" },
1357     { "nmid",   "&#x02224;" },
1358     { "npar",   "&#x02226;" },
1359     { "npr",    "&#x02280;" },
1360     { "nprcue", "&#x022E0;" },
1361     { "npre",   "&#x02AAF;&#x00338;" },
1362     { "nrtri",  "&#x022EB;" },
1363     { "nrtrie", "&#x022ED;" },
1364     { "nsc",    "&#x02281;" },
1365     { "nsccue", "&#x022E1;" },
1366     { "nsce",   "&#x02AB0;&#x00338;" },
1367     { "nsim",   "&#x02241;" },
1368     { "nsime",  "&#x02244;" },
1369     { "nsmid",  "&#x02224;" },
1370     { "nspar",  "&#x02226;" },
1371     { "nsqsube",    "&#x022E2;" },
1372     { "nsqsupe",    "&#x022E3;" },
1373     { "nsub",   "&#x02284;" },
1374     { "nsubE",  "&#x02AC5;&#x0338;" },
1375     { "nsube",  "&#x02288;" },
1376     { "nsup",   "&#x02285;" },
1377     { "nsupE",  "&#x02AC6;&#x0338;" },
1378     { "nsupe",  "&#x02289;" },
1379     { "ntgl",   "&#x02279;" },
1380     { "ntlg",   "&#x02278;" },
1381     { "nvap",   "&#x0224D;&#x020D2;" },
1382     { "nVDash", "&#x022AF;" },
1383     { "nVdash", "&#x022AE;" },
1384     { "nvDash", "&#x022AD;" },
1385     { "nvdash", "&#x022AC;" },
1386     { "nvge",   "&#x02265;&#x020D2;" },
1387     { "nvgt",   "&#x0003E;&#x020D2;" },
1388     { "nvle",   "&#x02264;&#x020D2;" },
1389     { "nvlt",   "&#x0003C;&#x020D2;" },
1390     { "nvltrie",    "&#x022B4;&#x020D2;" },
1391     { "nvrtrie",    "&#x022B5;&#x020D2;" },
1392     { "nvsim",  "&#x0223C;&#x020D2;" },
1393     { "parsim", "&#x02AF3;" },
1394     { "prnap",  "&#x02AB9;" },
1395     { "prnE",   "&#x02AB5;" },
1396     { "prnsim", "&#x022E8;" },
1397     { "rnmid",  "&#x02AEE;" },
1398     { "scnap",  "&#x02ABA;" },
1399     { "scnE",   "&#x02AB6;" },
1400     { "scnsim", "&#x022E9;" },
1401     { "simne",  "&#x02246;" },
1402     { "solbar", "&#x0233F;" },
1403     { "subnE",  "&#x02ACB;" },
1404     { "subne",  "&#x0228A;" },
1405     { "supnE",  "&#x02ACC;" },
1406     { "supne",  "&#x0228B;" },
1407     { "vnsub",  "&#x02282;&#x020D2;" },
1408     { "vnsup",  "&#x02283;&#x020D2;" },
1409     { "vsubnE", "&#x02ACB;&#x0FE00;" },
1410     { "vsubne", "&#x0228A;&#x0FE00;" },
1411     { "vsupnE", "&#x02ACC;&#x0FE00;" },
1412     { "vsupne", "&#x0228B;&#x0FE00;" },
1413     { "ang",    "&#x02220;" },
1414     { "ange",   "&#x029A4;" },
1415     { "angmsd", "&#x02221;" },
1416     { "angmsdaa",   "&#x029A8;" },
1417     { "angmsdab",   "&#x029A9;" },
1418     { "angmsdac",   "&#x029AA;" },
1419     { "angmsdad",   "&#x029AB;" },
1420     { "angmsdae",   "&#x029AC;" },
1421     { "angmsdaf",   "&#x029AD;" },
1422     { "angmsdag",   "&#x029AE;" },
1423     { "angmsdah",   "&#x029AF;" },
1424     { "angrtvb",    "&#x022BE;" },
1425     { "angrtvbd",   "&#x0299D;" },
1426     { "bbrk",   "&#x023B5;" },
1427     { "bemptyv",    "&#x029B0;" },
1428     { "beth",   "&#x02136;" },
1429     { "boxbox", "&#x029C9;" },
1430     { "bprime", "&#x02035;" },
1431     { "bsemi",  "&#x0204F;" },
1432     { "cemptyv",    "&#x029B2;" },
1433     { "cirE",   "&#x029C3;" },
1434     { "cirscir",    "&#x029C2;" },
1435     { "comp",   "&#x02201;" },
1436     { "daleth", "&#x02138;" },
1437     { "demptyv",    "&#x029B1;" },
1438     { "ell",    "&#x02113;" },
1439     { "empty",  "&#x02205;" },
1440     { "emptyv", "&#x02205;" },
1441     { "gimel",  "&#x02137;" },
1442     { "iiota",  "&#x02129;" },
1443     { "image",  "&#x02111;" },
1444     { "imath",  "&#x00131;" },
1445     { "jmath",  "&#x0006A;" },
1446     { "laemptyv",   "&#x029B4;" },
1447     { "lltri",  "&#x025FA;" },
1448     { "lrtri",  "&#x022BF;" },
1449     { "mho",    "&#x02127;" },
1450     { "nang",   "&#x02220;&#x020D2;" },
1451     { "nexist", "&#x02204;" },
1452     { "oS", "&#x024C8;" },
1453     { "planck", "&#x0210F;" },
1454     { "plankv", "&#x0210F;" },
1455     { "raemptyv",   "&#x029B3;" },
1456     { "range",  "&#x029A5;" },
1457     { "real",   "&#x0211C;" },
1458     { "tbrk",   "&#x023B4;" },
1459     { "ultri",  "&#x025F8;" },
1460     { "urtri",  "&#x025F9;" },
1461     { "vzigzag",    "&#x0299A;" },
1462     { "weierp", "&#x02118;" },
1463     { "apE",    "&#x02A70;" },
1464     { "ape",    "&#x0224A;" },
1465     { "apid",   "&#x0224B;" },
1466     { "asymp",  "&#x02248;" },
1467     { "Barv",   "&#x02AE7;" },
1468     { "bcong",  "&#x0224C;" },
1469     { "bepsi",  "&#x003F6;" },
1470     { "bowtie", "&#x022C8;" },
1471     { "bsim",   "&#x0223D;" },
1472     { "bsime",  "&#x022CD;" },
1473     { "bsolhsub",   "&#x0005C;&#x02282;" },
1474     { "bump",   "&#x0224E;" },
1475     { "bumpE",  "&#x02AAE;" },
1476     { "bumpe",  "&#x0224F;" },
1477     { "cire",   "&#x02257;" },
1478     { "Colon",  "&#x02237;" },
1479     { "Colone", "&#x02A74;" },
1480     { "colone", "&#x02254;" },
1481     { "congdot",    "&#x02A6D;" },
1482     { "csub",   "&#x02ACF;" },
1483     { "csube",  "&#x02AD1;" },
1484     { "csup",   "&#x02AD0;" },
1485     { "csupe",  "&#x02AD2;" },
1486     { "cuepr",  "&#x022DE;" },
1487     { "cuesc",  "&#x022DF;" },
1488     { "Dashv",  "&#x02AE4;" },
1489     { "dashv",  "&#x022A3;" },
1490     { "easter", "&#x02A6E;" },
1491     { "ecir",   "&#x02256;" },
1492     { "ecolon", "&#x02255;" },
1493     { "eDDot",  "&#x02A77;" },
1494     { "eDot",   "&#x02251;" },
1495     { "efDot",  "&#x02252;" },
1496     { "eg", "&#x02A9A;" },
1497     { "egs",    "&#x02A96;" },
1498     { "egsdot", "&#x02A98;" },
1499     { "el", "&#x02A99;" },
1500     { "els",    "&#x02A95;" },
1501     { "elsdot", "&#x02A97;" },
1502     { "equest", "&#x0225F;" },
1503     { "equivDD",    "&#x02A78;" },
1504     { "erDot",  "&#x02253;" },
1505     { "esdot",  "&#x02250;" },
1506     { "Esim",   "&#x02A73;" },
1507     { "esim",   "&#x02242;" },
1508     { "fork",   "&#x022D4;" },
1509     { "forkv",  "&#x02AD9;" },
1510     { "frown",  "&#x02322;" },
1511     { "gap",    "&#x02A86;" },
1512     { "gE", "&#x02267;" },
1513     { "gEl",    "&#x02A8C;" },
1514     { "gel",    "&#x022DB;" },
1515     { "ges",    "&#x02A7E;" },
1516     { "gescc",  "&#x02AA9;" },
1517     { "gesdot", "&#x02A80;" },
1518     { "gesdoto",    "&#x02A82;" },
1519     { "gesdotol",   "&#x02A84;" },
1520     { "gesl",   "&#x022DB;&#x0FE00;" },
1521     { "gesles", "&#x02A94;" },
1522     { "Gg", "&#x022D9;" },
1523     { "gl", "&#x02277;" },
1524     { "gla",    "&#x02AA5;" },
1525     { "glE",    "&#x02A92;" },
1526     { "glj",    "&#x02AA4;" },
1527     { "gsim",   "&#x02273;" },
1528     { "gsime",  "&#x02A8E;" },
1529     { "gsiml",  "&#x02A90;" },
1530     { "Gt", "&#x0226B;" },
1531     { "gtcc",   "&#x02AA7;" },
1532     { "gtcir",  "&#x02A7A;" },
1533     { "gtdot",  "&#x022D7;" },
1534     { "gtquest",    "&#x02A7C;" },
1535     { "gtrarr", "&#x02978;" },
1536     { "homtht", "&#x0223B;" },
1537     { "lap",    "&#x02A85;" },
1538     { "lat",    "&#x02AAB;" },
1539     { "late",   "&#x02AAD;" },
1540     { "lates",  "&#x02AAD;&#x0FE00;" },
1541     { "lE", "&#x02266;" },
1542     { "lEg",    "&#x02A8B;" },
1543     { "leg",    "&#x022DA;" },
1544     { "les",    "&#x02A7D;" },
1545     { "lescc",  "&#x02AA8;" },
1546     { "lesdot", "&#x02A7F;" },
1547     { "lesdoto",    "&#x02A81;" },
1548     { "lesdotor",   "&#x02A83;" },
1549     { "lesg",   "&#x022DA;&#x0FE00;" },
1550     { "lesges", "&#x02A93;" },
1551     { "lg", "&#x02276;" },
1552     { "lgE",    "&#x02A91;" },
1553     { "Ll", "&#x022D8;" },
1554     { "lsim",   "&#x02272;" },
1555     { "lsime",  "&#x02A8D;" },
1556     { "lsimg",  "&#x02A8F;" },
1557     { "Lt", "&#x0226A;" },
1558     { "ltcc",   "&#x02AA6;" },
1559     { "ltcir",  "&#x02A79;" },
1560     { "ltdot",  "&#x022D6;" },
1561     { "ltlarr", "&#x02976;" },
1562     { "ltquest",    "&#x02A7B;" },
1563     { "ltrie",  "&#x022B4;" },
1564     { "mcomma", "&#x02A29;" },
1565     { "mDDot",  "&#x0223A;" },
1566     { "mid",    "&#x02223;" },
1567     { "mlcp",   "&#x02ADB;" },
1568     { "models", "&#x022A7;" },
1569     { "mstpos", "&#x0223E;" },
1570     { "Pr", "&#x02ABB;" },
1571     { "pr", "&#x0227A;" },
1572     { "prap",   "&#x02AB7;" },
1573     { "prcue",  "&#x0227C;" },
1574     { "prE",    "&#x02AB3;" },
1575     { "pre",    "&#x02AAF;" },
1576     { "prsim",  "&#x0227E;" },
1577     { "prurel", "&#x022B0;" },
1578     { "ratio",  "&#x02236;" },
1579     { "rtrie",  "&#x022B5;" },
1580     { "rtriltri",   "&#x029CE;" },
1581     { "Sc", "&#x02ABC;" },
1582     { "sc", "&#x0227B;" },
1583     { "scap",   "&#x02AB8;" },
1584     { "sccue",  "&#x0227D;" },
1585     { "scE",    "&#x02AB4;" },
1586     { "sce",    "&#x02AB0;" },
1587     { "scsim",  "&#x0227F;" },
1588     { "sdote",  "&#x02A66;" },
1589     { "simg",   "&#x02A9E;" },
1590     { "simgE",  "&#x02AA0;" },
1591     { "siml",   "&#x02A9D;" },
1592     { "simlE",  "&#x02A9F;" },
1593     { "smid",   "&#x02223;" },
1594     { "smile",  "&#x02323;" },
1595     { "smt",    "&#x02AAA;" },
1596     { "smte",   "&#x02AAC;" },
1597     { "smtes",  "&#x02AAC;&#x0FE00;" },
1598     { "spar",   "&#x02225;" },
1599     { "sqsub",  "&#x0228F;" },
1600     { "sqsube", "&#x02291;" },
1601     { "sqsup",  "&#x02290;" },
1602     { "sqsupe", "&#x02292;" },
1603     { "Sub",    "&#x022D0;" },
1604     { "subE",   "&#x02AC5;" },
1605     { "subedot",    "&#x02AC3;" },
1606     { "submult",    "&#x02AC1;" },
1607     { "subplus",    "&#x02ABF;" },
1608     { "subrarr",    "&#x02979;" },
1609     { "subsim", "&#x02AC7;" },
1610     { "subsub", "&#x02AD5;" },
1611     { "subsup", "&#x02AD3;" },
1612     { "Sup",    "&#x022D1;" },
1613     { "supdsub",    "&#x02AD8;" },
1614     { "supE",   "&#x02AC6;" },
1615     { "supedot",    "&#x02AC4;" },
1616     { "suphsol",    "&#x02283;&#x00338;" },
1617     { "suphsub",    "&#x02AD7;" },
1618     { "suplarr",    "&#x0297B;" },
1619     { "supmult",    "&#x02AC2;" },
1620     { "supplus",    "&#x02AC0;" },
1621     { "supsim", "&#x02AC8;" },
1622     { "supsub", "&#x02AD4;" },
1623     { "supsup", "&#x02AD6;" },
1624     { "thkap",  "&#x02248;" },
1625     { "topfork",    "&#x02ADA;" },
1626     { "trie",   "&#x0225C;" },
1627     { "twixt",  "&#x0226C;" },
1628     { "Vbar",   "&#x02AEB;" },
1629     { "vBar",   "&#x02AE8;" },
1630     { "vBarv",  "&#x02AE9;" },
1631     { "VDash",  "&#x022AB;" },
1632     { "Vdash",  "&#x022A9;" },
1633     { "vDash",  "&#x022A8;" },
1634     { "vdash",  "&#x022A2;" },
1635     { "Vdashl", "&#x02AE6;" },
1636     { "vltri",  "&#x022B2;" },
1637     { "vprop",  "&#x0221D;" },
1638     { "vrtri",  "&#x022B3;" },
1639     { "Vvdash", "&#x022AA;" },
1640     { "alpha",  "&#x003B1;" },
1641     { "beta",   "&#x003B2;" },
1642     { "chi",    "&#x003C7;" },
1643     { "Delta",  "&#x00394;" },
1644     { "delta",  "&#x003B4;" },
1645     { "epsi",   "&#x003B5;" },
1646     { "epsiv",  "&#x0025B;" },
1647     { "eta",    "&#x003B7;" },
1648     { "Gamma",  "&#x00393;" },
1649     { "gamma",  "&#x003B3;" },
1650     { "Gammad", "&#x003DC;" },
1651     { "gammad", "&#x003DD;" },
1652     { "iota",   "&#x003B9;" },
1653     { "kappa",  "&#x003BA;" },
1654     { "kappav", "&#x003F0;" },
1655     { "Lambda", "&#x0039B;" },
1656     { "lambda", "&#x003BB;" },
1657     { "mu", "&#x003BC;" },
1658     { "nu", "&#x003BD;" },
1659     { "Omega",  "&#x003A9;" },
1660     { "omega",  "&#x003C9;" },
1661     { "Phi",    "&#x003A6;" },
1662     { "phi",    "&#x003D5;" },
1663     { "phiv",   "&#x003C6;" },
1664     { "Pi", "&#x003A0;" },
1665     { "pi", "&#x003C0;" },
1666     { "piv",    "&#x003D6;" },
1667     { "Psi",    "&#x003A8;" },
1668     { "psi",    "&#x003C8;" },
1669     { "rho",    "&#x003C1;" },
1670     { "rhov",   "&#x003F1;" },
1671     { "Sigma",  "&#x003A3;" },
1672     { "sigma",  "&#x003C3;" },
1673     { "sigmav", "&#x003C2;" },
1674     { "tau",    "&#x003C4;" },
1675     { "Theta",  "&#x00398;" },
1676     { "theta",  "&#x003B8;" },
1677     { "thetav", "&#x003D1;" },
1678     { "Upsi",   "&#x003D2;" },
1679     { "upsi",   "&#x003C5;" },
1680     { "Xi", "&#x0039E;" },
1681     { "xi", "&#x003BE;" },
1682     { "zeta",   "&#x003B6;" },
1683     { "Cfr",    "&#x0212D;" },
1684     { "Hfr",    "&#x0210C;" },
1685     { "Ifr",    "&#x02111;" },
1686     { "Rfr",    "&#x0211C;" },
1687     { "Zfr",    "&#x02128;" },
1688     { "Copf",   "&#x02102;" },
1689     { "Hopf",   "&#x0210D;" },
1690     { "Nopf",   "&#x02115;" },
1691     { "Popf",   "&#x02119;" },
1692     { "Qopf",   "&#x0211A;" },
1693     { "Ropf",   "&#x0211D;" },
1694     { "Zopf",   "&#x02124;" },
1695     { "Bscr",   "&#x0212C;" },
1696     { "Escr",   "&#x02130;" },
1697     { "escr",   "&#x0212F;" },
1698     { "Fscr",   "&#x02131;" },
1699     { "gscr",   "&#x0210A;" },
1700     { "Hscr",   "&#x0210B;" },
1701     { "Iscr",   "&#x02110;" },
1702     { "Lscr",   "&#x02112;" },
1703     { "Mscr",   "&#x02133;" },
1704     { "oscr",   "&#x02134;" },
1705     { "pscr",   "&#x1D4C5;" },
1706     { "Rscr",   "&#x0211B;" },
1707     { "acd",    "&#x0223F;" },
1708     { "aleph",  "&#x02135;" },
1709     { "And",    "&#x02A53;" },
1710     { "and",    "&#x02227;" },
1711     { "andand", "&#x02A55;" },
1712     { "andd",   "&#x02A5C;" },
1713     { "andslope",   "&#x02A58;" },
1714     { "andv",   "&#x02A5A;" },
1715     { "angrt",  "&#x0221F;" },
1716     { "angsph", "&#x02222;" },
1717     { "angst",  "&#x0212B;" },
1718     { "ap", "&#x02248;" },
1719     { "apacir", "&#x02A6F;" },
1720     { "awconint",   "&#x02233;" },
1721     { "awint",  "&#x02A11;" },
1722     { "becaus", "&#x02235;" },
1723     { "bernou", "&#x0212C;" },
1724     { "bne",    "&#x0003D;&#x020E5;" },
1725     { "bnequiv",    "&#x02261;&#x020E5;" },
1726     { "bNot",   "&#x02AED;" },
1727     { "bnot",   "&#x02310;" },
1728     { "bottom", "&#x022A5;" },
1729     { "cap",    "&#x02229;" },
1730     { "Cconint",    "&#x02230;" },
1731     { "cirfnint",   "&#x02A10;" },
1732     { "compfn", "&#x02218;" },
1733     { "cong",   "&#x02245;" },
1734     { "Conint", "&#x0222F;" },
1735     { "conint", "&#x0222E;" },
1736     { "ctdot",  "&#x022EF;" },
1737     { "cup",    "&#x0222A;" },
1738     { "cwconint",   "&#x02232;" },
1739     { "cwint",  "&#x02231;" },
1740     { "cylcty", "&#x0232D;" },
1741     { "disin",  "&#x022F2;" },
1742     { "Dot",    "&#x000A8;" },
1743     { "DotDot", "&#x020DC;" },
1744     { "dsol",   "&#x029F6;" },
1745     { "dtdot",  "&#x022F1;" },
1746     { "dwangle",    "&#x029A6;" },
1747     { "epar",   "&#x022D5;" },
1748     { "eparsl", "&#x029E3;" },
1749     { "equiv",  "&#x02261;" },
1750     { "eqvparsl",   "&#x029E5;" },
1751     { "exist",  "&#x02203;" },
1752     { "fnof",   "&#x00192;" },
1753     { "forall", "&#x02200;" },
1754     { "fpartint",   "&#x02A0D;" },
1755     { "ge", "&#x02265;" },
1756     { "hamilt", "&#x0210B;" },
1757     { "iff",    "&#x021D4;" },
1758     { "iinfin", "&#x029DC;" },
1759     { "infin",  "&#x0221E;" },
1760     { "Int",    "&#x0222C;" },
1761     { "int",    "&#x0222B;" },
1762     { "intlarhk",   "&#x02A17;" },
1763     { "isin",   "&#x02208;" },
1764     { "isindot",    "&#x022F5;" },
1765     { "isinE",  "&#x022F9;" },
1766     { "isins",  "&#x022F4;" },
1767     { "isinsv", "&#x022F3;" },
1768     { "isinv",  "&#x02208;" },
1769     { "lagran", "&#x02112;" },
1770     { "Lang",   "&#x0300A;" },
1771     { "lang",   "&#x02329;" },
1772     { "lArr",   "&#x021D0;" },
1773     { "lbbrk",  "&#x03014;" },
1774     { "le", "&#x02264;" },
1775     { "loang",  "&#x03018;" },
1776     { "lobrk",  "&#x0301A;" },
1777     { "lopar",  "&#x02985;" },
1778     { "lowast", "&#x02217;" },
1779     { "minus",  "&#x02212;" },
1780     { "mnplus", "&#x02213;" },
1781     { "nabla",  "&#x02207;" },
1782     { "ne", "&#x02260;" },
1783     { "nedot",  "&#x02250;&#x00338;" },
1784     { "nhpar",  "&#x02AF2;" },
1785     { "ni", "&#x0220B;" },
1786     { "nis",    "&#x022FC;" },
1787     { "nisd",   "&#x022FA;" },
1788     { "niv",    "&#x0220B;" },
1789     { "Not",    "&#x02AEC;" },
1790     { "notin",  "&#x02209;" },
1791     { "notindot",   "&#x022F5;&#x00338;" },
1792     { "notinva",    "&#x02209;" },
1793     { "notinvb",    "&#x022F7;" },
1794     { "notinvc",    "&#x022F6;" },
1795     { "notni",  "&#x0220C;" },
1796     { "notniva",    "&#x0220C;" },
1797     { "notnivb",    "&#x022FE;" },
1798     { "notnivc",    "&#x022FD;" },
1799     { "nparsl", "&#x02AFD;&#x020E5;" },
1800     { "npart",  "&#x02202;&#x00338;" },
1801     { "npolint",    "&#x02A14;" },
1802     { "nvinfin",    "&#x029DE;" },
1803     { "olcross",    "&#x029BB;" },
1804     { "Or", "&#x02A54;" },
1805     { "or", "&#x02228;" },
1806     { "ord",    "&#x02A5D;" },
1807     { "order",  "&#x02134;" },
1808     { "oror",   "&#x02A56;" },
1809     { "orslope",    "&#x02A57;" },
1810     { "orv",    "&#x02A5B;" },
1811     { "par",    "&#x02225;" },
1812     { "parsl",  "&#x02AFD;" },
1813     { "part",   "&#x02202;" },
1814     { "permil", "&#x02030;" },
1815     { "perp",   "&#x022A5;" },
1816     { "pertenk",    "&#x02031;" },
1817     { "phmmat", "&#x02133;" },
1818     { "pointint",   "&#x02A15;" },
1819     { "Prime",  "&#x02033;" },
1820     { "prime",  "&#x02032;" },
1821     { "profalar",   "&#x0232E;" },
1822     { "profline",   "&#x02312;" },
1823     { "profsurf",   "&#x02313;" },
1824     { "prop",   "&#x0221D;" },
1825     { "qint",   "&#x02A0C;" },
1826     { "qprime", "&#x02057;" },
1827     { "quatint",    "&#x02A16;" },
1828     { "radic",  "&#x0221A;" },
1829     { "Rang",   "&#x0300B;" },
1830     { "rang",   "&#x0232A;" },
1831     { "rArr",   "&#x021D2;" },
1832     { "rbbrk",  "&#x03015;" },
1833     { "roang",  "&#x03019;" },
1834     { "robrk",  "&#x0301B;" },
1835     { "ropar",  "&#x02986;" },
1836     { "rppolint",   "&#x02A12;" },
1837     { "scpolint",   "&#x02A13;" },
1838     { "sim",    "&#x0223C;" },
1839     { "simdot", "&#x02A6A;" },
1840     { "sime",   "&#x02243;" },
1841     { "smeparsl",   "&#x029E4;" },
1842     { "square", "&#x025A1;" },
1843     { "squarf", "&#x025AA;" },
1844     { "sub",    "&#x02282;" },
1845     { "sube",   "&#x02286;" },
1846     { "sup",    "&#x02283;" },
1847     { "supe",   "&#x02287;" },
1848     { "tdot",   "&#x020DB;" },
1849     { "there4", "&#x02234;" },
1850     { "tint",   "&#x0222D;" },
1851     { "top",    "&#x022A4;" },
1852     { "topbot", "&#x02336;" },
1853     { "topcir", "&#x02AF1;" },
1854     { "tprime", "&#x02034;" },
1855     { "utdot",  "&#x022F0;" },
1856     { "uwangle",    "&#x029A7;" },
1857     { "vangrt", "&#x0299C;" },
1858     { "veeeq",  "&#x0225A;" },
1859     { "Verbar", "&#x02016;" },
1860     { "wedgeq", "&#x02259;" },
1861     { "xnis",   "&#x022FB;" },
1862     { "boxDL",  "&#x02557;" },
1863     { "boxDl",  "&#x02556;" },
1864     { "boxdL",  "&#x02555;" },
1865     { "boxdl",  "&#x02510;" },
1866     { "boxDR",  "&#x02554;" },
1867     { "boxDr",  "&#x02553;" },
1868     { "boxdR",  "&#x02552;" },
1869     { "boxdr",  "&#x0250C;" },
1870     { "boxH",   "&#x02550;" },
1871     { "boxh",   "&#x02500;" },
1872     { "boxHD",  "&#x02566;" },
1873     { "boxHd",  "&#x02564;" },
1874     { "boxhD",  "&#x02565;" },
1875     { "boxhd",  "&#x0252C;" },
1876     { "boxHU",  "&#x02569;" },
1877     { "boxHu",  "&#x02567;" },
1878     { "boxhU",  "&#x02568;" },
1879     { "boxhu",  "&#x02534;" },
1880     { "boxUL",  "&#x0255D;" },
1881     { "boxUl",  "&#x0255C;" },
1882     { "boxuL",  "&#x0255B;" },
1883     { "boxul",  "&#x02518;" },
1884     { "boxUR",  "&#x0255A;" },
1885     { "boxUr",  "&#x02559;" },
1886     { "boxuR",  "&#x02558;" },
1887     { "boxur",  "&#x02514;" },
1888     { "boxV",   "&#x02551;" },
1889     { "boxv",   "&#x02502;" },
1890     { "boxVH",  "&#x0256C;" },
1891     { "boxVh",  "&#x0256B;" },
1892     { "boxvH",  "&#x0256A;" },
1893     { "boxvh",  "&#x0253C;" },
1894     { "boxVL",  "&#x02563;" },
1895     { "boxVl",  "&#x02562;" },
1896     { "boxvL",  "&#x02561;" },
1897     { "boxvl",  "&#x02524;" },
1898     { "boxVR",  "&#x02560;" },
1899     { "boxVr",  "&#x0255F;" },
1900     { "boxvR",  "&#x0255E;" },
1901     { "boxvr",  "&#x0251C;" },
1902     { "Acy",    "&#x00410;" },
1903     { "acy",    "&#x00430;" },
1904     { "Bcy",    "&#x00411;" },
1905     { "bcy",    "&#x00431;" },
1906     { "CHcy",   "&#x00427;" },
1907     { "chcy",   "&#x00447;" },
1908     { "Dcy",    "&#x00414;" },
1909     { "dcy",    "&#x00434;" },
1910     { "Ecy",    "&#x0042D;" },
1911     { "ecy",    "&#x0044D;" },
1912     { "Fcy",    "&#x00424;" },
1913     { "fcy",    "&#x00444;" },
1914     { "Gcy",    "&#x00413;" },
1915     { "gcy",    "&#x00433;" },
1916     { "HARDcy", "&#x0042A;" },
1917     { "hardcy", "&#x0044A;" },
1918     { "Icy",    "&#x00418;" },
1919     { "icy",    "&#x00438;" },
1920     { "IEcy",   "&#x00415;" },
1921     { "iecy",   "&#x00435;" },
1922     { "IOcy",   "&#x00401;" },
1923     { "iocy",   "&#x00451;" },
1924     { "Jcy",    "&#x00419;" },
1925     { "jcy",    "&#x00439;" },
1926     { "Kcy",    "&#x0041A;" },
1927     { "kcy",    "&#x0043A;" },
1928     { "KHcy",   "&#x00425;" },
1929     { "khcy",   "&#x00445;" },
1930     { "Lcy",    "&#x0041B;" },
1931     { "lcy",    "&#x0043B;" },
1932     { "Mcy",    "&#x0041C;" },
1933     { "mcy",    "&#x0043C;" },
1934     { "Ncy",    "&#x0041D;" },
1935     { "ncy",    "&#x0043D;" },
1936     { "numero", "&#x02116;" },
1937     { "Ocy",    "&#x0041E;" },
1938     { "ocy",    "&#x0043E;" },
1939     { "Pcy",    "&#x0041F;" },
1940     { "pcy",    "&#x0043F;" },
1941     { "Rcy",    "&#x00420;" },
1942     { "rcy",    "&#x00440;" },
1943     { "Scy",    "&#x00421;" },
1944     { "scy",    "&#x00441;" },
1945     { "SHCHcy", "&#x00429;" },
1946     { "shchcy", "&#x00449;" },
1947     { "SHcy",   "&#x00428;" },
1948     { "shcy",   "&#x00448;" },
1949     { "SOFTcy", "&#x0042C;" },
1950     { "softcy", "&#x0044C;" },
1951     { "Tcy",    "&#x00422;" },
1952     { "tcy",    "&#x00442;" },
1953     { "TScy",   "&#x00426;" },
1954     { "tscy",   "&#x00446;" },
1955     { "Ucy",    "&#x00423;" },
1956     { "ucy",    "&#x00443;" },
1957     { "Vcy",    "&#x00412;" },
1958     { "vcy",    "&#x00432;" },
1959     { "YAcy",   "&#x0042F;" },
1960     { "yacy",   "&#x0044F;" },
1961     { "Ycy",    "&#x0042B;" },
1962     { "ycy",    "&#x0044B;" },
1963     { "YUcy",   "&#x0042E;" },
1964     { "yucy",   "&#x0044E;" },
1965     { "Zcy",    "&#x00417;" },
1966     { "zcy",    "&#x00437;" },
1967     { "ZHcy",   "&#x00416;" },
1968     { "zhcy",   "&#x00436;" },
1969     { "DJcy",   "&#x00402;" },
1970     { "djcy",   "&#x00452;" },
1971     { "DScy",   "&#x00405;" },
1972     { "dscy",   "&#x00455;" },
1973     { "DZcy",   "&#x0040F;" },
1974     { "dzcy",   "&#x0045F;" },
1975     { "GJcy",   "&#x00403;" },
1976     { "gjcy",   "&#x00453;" },
1977     { "Iukcy",  "&#x00406;" },
1978     { "iukcy",  "&#x00456;" },
1979     { "Jsercy", "&#x00408;" },
1980     { "jsercy", "&#x00458;" },
1981     { "Jukcy",  "&#x00404;" },
1982     { "jukcy",  "&#x00454;" },
1983     { "KJcy",   "&#x0040C;" },
1984     { "kjcy",   "&#x0045C;" },
1985     { "LJcy",   "&#x00409;" },
1986     { "ljcy",   "&#x00459;" },
1987     { "NJcy",   "&#x0040A;" },
1988     { "njcy",   "&#x0045A;" },
1989     { "TSHcy",  "&#x0040B;" },
1990     { "tshcy",  "&#x0045B;" },
1991     { "Ubrcy",  "&#x0040E;" },
1992     { "ubrcy",  "&#x0045E;" },
1993     { "YIcy",   "&#x00407;" },
1994     { "yicy",   "&#x00457;" },
1995     { "acute",  "&#x000B4;" },
1996     { "breve",  "&#x002D8;" },
1997     { "caron",  "&#x002C7;" },
1998     { "cedil",  "&#x000B8;" },
1999     { "circ",   "&#x002C6;" },
2000     { "dblac",  "&#x002DD;" },
2001     { "die",    "&#x000A8;" },
2002     { "dot",    "&#x002D9;" },
2003     { "grave",  "&#x00060;" },
2004     { "macr",   "&#x000AF;" },
2005     { "ogon",   "&#x002DB;" },
2006     { "ring",   "&#x002DA;" },
2007     { "tilde",  "&#x002DC;" },
2008     { "uml",    "&#x000A8;" },
2009     { "Aacute", "&#x000C1;" },
2010     { "aacute", "&#x000E1;" },
2011     { "Acirc",  "&#x000C2;" },
2012     { "acirc",  "&#x000E2;" },
2013     { "AElig",  "&#x000C6;" },
2014     { "aelig",  "&#x000E6;" },
2015     { "Agrave", "&#x000C0;" },
2016     { "agrave", "&#x000E0;" },
2017     { "Aring",  "&#x000C5;" },
2018     { "aring",  "&#x000E5;" },
2019     { "Atilde", "&#x000C3;" },
2020     { "atilde", "&#x000E3;" },
2021     { "Auml",   "&#x000C4;" },
2022     { "auml",   "&#x000E4;" },
2023     { "Ccedil", "&#x000C7;" },
2024     { "ccedil", "&#x000E7;" },
2025     { "Eacute", "&#x000C9;" },
2026     { "eacute", "&#x000E9;" },
2027     { "Ecirc",  "&#x000CA;" },
2028     { "ecirc",  "&#x000EA;" },
2029     { "Egrave", "&#x000C8;" },
2030     { "egrave", "&#x000E8;" },
2031     { "ETH",    "&#x000D0;" },
2032     { "eth",    "&#x000F0;" },
2033     { "Euml",   "&#x000CB;" },
2034     { "euml",   "&#x000EB;" },
2035     { "Iacute", "&#x000CD;" },
2036     { "iacute", "&#x000ED;" },
2037     { "Icirc",  "&#x000CE;" },
2038     { "icirc",  "&#x000EE;" },
2039     { "Igrave", "&#x000CC;" },
2040     { "igrave", "&#x000EC;" },
2041     { "Iuml",   "&#x000CF;" },
2042     { "iuml",   "&#x000EF;" },
2043     { "Ntilde", "&#x000D1;" },
2044     { "ntilde", "&#x000F1;" },
2045     { "Oacute", "&#x000D3;" },
2046     { "oacute", "&#x000F3;" },
2047     { "Ocirc",  "&#x000D4;" },
2048     { "ocirc",  "&#x000F4;" },
2049     { "Ograve", "&#x000D2;" },
2050     { "ograve", "&#x000F2;" },
2051     { "Oslash", "&#x000D8;" },
2052     { "oslash", "&#x000F8;" },
2053     { "Otilde", "&#x000D5;" },
2054     { "otilde", "&#x000F5;" },
2055     { "Ouml",   "&#x000D6;" },
2056     { "ouml",   "&#x000F6;" },
2057     { "szlig",  "&#x000DF;" },
2058     { "THORN",  "&#x000DE;" },
2059     { "thorn",  "&#x000FE;" },
2060     { "Uacute", "&#x000DA;" },
2061     { "uacute", "&#x000FA;" },
2062     { "Ucirc",  "&#x000DB;" },
2063     { "ucirc",  "&#x000FB;" },
2064     { "Ugrave", "&#x000D9;" },
2065     { "ugrave", "&#x000F9;" },
2066     { "Uuml",   "&#x000DC;" },
2067     { "uuml",   "&#x000FC;" },
2068     { "Yacute", "&#x000DD;" },
2069     { "yacute", "&#x000FD;" },
2070     { "yuml",   "&#x000FF;" },
2071     { "Abreve", "&#x00102;" },
2072     { "abreve", "&#x00103;" },
2073     { "Amacr",  "&#x00100;" },
2074     { "amacr",  "&#x00101;" },
2075     { "Aogon",  "&#x00104;" },
2076     { "aogon",  "&#x00105;" },
2077     { "Cacute", "&#x00106;" },
2078     { "cacute", "&#x00107;" },
2079     { "Ccaron", "&#x0010C;" },
2080     { "ccaron", "&#x0010D;" },
2081     { "Ccirc",  "&#x00108;" },
2082     { "ccirc",  "&#x00109;" },
2083     { "Cdot",   "&#x0010A;" },
2084     { "cdot",   "&#x0010B;" },
2085     { "Dcaron", "&#x0010E;" },
2086     { "dcaron", "&#x0010F;" },
2087     { "Dstrok", "&#x00110;" },
2088     { "dstrok", "&#x00111;" },
2089     { "Ecaron", "&#x0011A;" },
2090     { "ecaron", "&#x0011B;" },
2091     { "Edot",   "&#x00116;" },
2092     { "edot",   "&#x00117;" },
2093     { "Emacr",  "&#x00112;" },
2094     { "emacr",  "&#x00113;" },
2095     { "ENG",    "&#x0014A;" },
2096     { "eng",    "&#x0014B;" },
2097     { "Eogon",  "&#x00118;" },
2098     { "eogon",  "&#x00119;" },
2099     { "gacute", "&#x001F5;" },
2100     { "Gbreve", "&#x0011E;" },
2101     { "gbreve", "&#x0011F;" },
2102     { "Gcedil", "&#x00122;" },
2103     { "Gcirc",  "&#x0011C;" },
2104     { "gcirc",  "&#x0011D;" },
2105     { "Gdot",   "&#x00120;" },
2106     { "gdot",   "&#x00121;" },
2107     { "Hcirc",  "&#x00124;" },
2108     { "hcirc",  "&#x00125;" },
2109     { "Hstrok", "&#x00126;" },
2110     { "hstrok", "&#x00127;" },
2111     { "Idot",   "&#x00130;" },
2112     { "IJlig",  "&#x00132;" },
2113     { "ijlig",  "&#x00133;" },
2114     { "Imacr",  "&#x0012A;" },
2115     { "imacr",  "&#x0012B;" },
2116     { "inodot", "&#x00131;" },
2117     { "Iogon",  "&#x0012E;" },
2118     { "iogon",  "&#x0012F;" },
2119     { "Itilde", "&#x00128;" },
2120     { "itilde", "&#x00129;" },
2121     { "Jcirc",  "&#x00134;" },
2122     { "jcirc",  "&#x00135;" },
2123     { "Kcedil", "&#x00136;" },
2124     { "kcedil", "&#x00137;" },
2125     { "kgreen", "&#x00138;" },
2126     { "Lacute", "&#x00139;" },
2127     { "lacute", "&#x0013A;" },
2128     { "Lcaron", "&#x0013D;" },
2129     { "lcaron", "&#x0013E;" },
2130     { "Lcedil", "&#x0013B;" },
2131     { "lcedil", "&#x0013C;" },
2132     { "Lmidot", "&#x0013F;" },
2133     { "lmidot", "&#x00140;" },
2134     { "Lstrok", "&#x00141;" },
2135     { "lstrok", "&#x00142;" },
2136     { "Nacute", "&#x00143;" },
2137     { "nacute", "&#x00144;" },
2138     { "napos",  "&#x00149;" },
2139     { "Ncaron", "&#x00147;" },
2140     { "ncaron", "&#x00148;" },
2141     { "Ncedil", "&#x00145;" },
2142     { "ncedil", "&#x00146;" },
2143     { "Odblac", "&#x00150;" },
2144     { "odblac", "&#x00151;" },
2145     { "OElig",  "&#x00152;" },
2146     { "oelig",  "&#x00153;" },
2147     { "Omacr",  "&#x0014C;" },
2148     { "omacr",  "&#x0014D;" },
2149     { "Racute", "&#x00154;" },
2150     { "racute", "&#x00155;" },
2151     { "Rcaron", "&#x00158;" },
2152     { "rcaron", "&#x00159;" },
2153     { "Rcedil", "&#x00156;" },
2154     { "rcedil", "&#x00157;" },
2155     { "Sacute", "&#x0015A;" },
2156     { "sacute", "&#x0015B;" },
2157     { "Scaron", "&#x00160;" },
2158     { "scaron", "&#x00161;" },
2159     { "Scedil", "&#x0015E;" },
2160     { "scedil", "&#x0015F;" },
2161     { "Scirc",  "&#x0015C;" },
2162     { "scirc",  "&#x0015D;" },
2163     { "Tcaron", "&#x00164;" },
2164     { "tcaron", "&#x00165;" },
2165     { "Tcedil", "&#x00162;" },
2166     { "tcedil", "&#x00163;" },
2167     { "Tstrok", "&#x00166;" },
2168     { "tstrok", "&#x00167;" },
2169     { "Ubreve", "&#x0016C;" },
2170     { "ubreve", "&#x0016D;" },
2171     { "Udblac", "&#x00170;" },
2172     { "udblac", "&#x00171;" },
2173     { "Umacr",  "&#x0016A;" },
2174     { "umacr",  "&#x0016B;" },
2175     { "Uogon",  "&#x00172;" },
2176     { "uogon",  "&#x00173;" },
2177     { "Uring",  "&#x0016E;" },
2178     { "uring",  "&#x0016F;" },
2179     { "Utilde", "&#x00168;" },
2180     { "utilde", "&#x00169;" },
2181     { "Wcirc",  "&#x00174;" },
2182     { "wcirc",  "&#x00175;" },
2183     { "Ycirc",  "&#x00176;" },
2184     { "ycirc",  "&#x00177;" },
2185     { "Yuml",   "&#x00178;" },
2186     { "Zacute", "&#x00179;" },
2187     { "zacute", "&#x0017A;" },
2188     { "Zcaron", "&#x0017D;" },
2189     { "zcaron", "&#x0017E;" },
2190     { "Zdot",   "&#x0017B;" },
2191     { "zdot",   "&#x0017C;" },
2192     { "apos",   "&#x00027;" },
2193     { "ast",    "&#x0002A;" },
2194     { "brvbar", "&#x000A6;" },
2195     { "bsol",   "&#x0005C;" },
2196     { "cent",   "&#x000A2;" },
2197     { "colon",  "&#x0003A;" },
2198     { "comma",  "&#x0002C;" },
2199     { "commat", "&#x00040;" },
2200     { "copy",   "&#x000A9;" },
2201     { "curren", "&#x000A4;" },
2202     { "darr",   "&#x02193;" },
2203     { "deg",    "&#x000B0;" },
2204     { "divide", "&#x000F7;" },
2205     { "dollar", "&#x00024;" },
2206     { "equals", "&#x0003D;" },
2207     { "excl",   "&#x00021;" },
2208     { "frac12", "&#x000BD;" },
2209     { "frac14", "&#x000BC;" },
2210     { "frac18", "&#x0215B;" },
2211     { "frac34", "&#x000BE;" },
2212     { "frac38", "&#x0215C;" },
2213     { "frac58", "&#x0215D;" },
2214     { "frac78", "&#x0215E;" },
2215     { "gt", "&#x0003E;" },
2216     { "half",   "&#x000BD;" },
2217     { "horbar", "&#x02015;" },
2218     { "hyphen", "&#x02010;" },
2219     { "iexcl",  "&#x000A1;" },
2220     { "iquest", "&#x000BF;" },
2221     { "laquo",  "&#x000AB;" },
2222     { "larr",   "&#x02190;" },
2223     { "lcub",   "&#x0007B;" },
2224     { "ldquo",  "&#x0201C;" },
2225     { "lowbar", "&#x0005F;" },
2226     { "lpar",   "&#x00028;" },
2227     { "lsqb",   "&#x0005B;" },
2228     { "lsquo",  "&#x02018;" },
2229     { "lt", "&#x0003C;" },
2230     { "micro",  "&#x000B5;" },
2231     { "middot", "&#x000B7;" },
2232     { "nbsp",   "&#x000A0;" },
2233     { "not",    "&#x000AC;" },
2234     { "num",    "&#x00023;" },
2235     { "ohm",    "&#x02126;" },
2236     { "ordf",   "&#x000AA;" },
2237     { "ordm",   "&#x000BA;" },
2238     { "para",   "&#x000B6;" },
2239     { "percnt", "&#x00025;" },
2240     { "period", "&#x0002E;" },
2241     { "plus",   "&#x0002B;" },
2242     { "plusmn", "&#x000B1;" },
2243     { "pound",  "&#x000A3;" },
2244     { "quest",  "&#x0003F;" },
2245     { "quot",   "&#x00022;" },
2246     { "raquo",  "&#x000BB;" },
2247     { "rarr",   "&#x02192;" },
2248     { "rcub",   "&#x0007D;" },
2249     { "rdquo",  "&#x0201D;" },
2250     { "reg",    "&#x000AE;" },
2251     { "rpar",   "&#x00029;" },
2252     { "rsqb",   "&#x0005D;" },
2253     { "rsquo",  "&#x02019;" },
2254     { "sect",   "&#x000A7;" },
2255     { "semi",   "&#x0003B;" },
2256     { "shy",    "&#x000AD;" },
2257     { "sol",    "&#x0002F;" },
2258     { "sung",   "&#x0266A;" },
2259     { "sup1",   "&#x000B9;" },
2260     { "sup2",   "&#x000B2;" },
2261     { "sup3",   "&#x000B3;" },
2262     { "times",  "&#x000D7;" },
2263     { "trade",  "&#x02122;" },
2264     { "uarr",   "&#x02191;" },
2265     { "verbar", "&#x0007C;" },
2266     { "yen",    "&#x000A5;" },
2267     { "blank",  "&#x02423;" },
2268     { "blk12",  "&#x02592;" },
2269     { "blk14",  "&#x02591;" },
2270     { "blk34",  "&#x02593;" },
2271     { "block",  "&#x02588;" },
2272     { "bull",   "&#x02022;" },
2273     { "caret",  "&#x02041;" },
2274     { "check",  "&#x02713;" },
2275     { "cir",    "&#x025CB;" },
2276     { "clubs",  "&#x02663;" },
2277     { "copysr", "&#x02117;" },
2278     { "cross",  "&#x02717;" },
2279     { "Dagger", "&#x02021;" },
2280     { "dagger", "&#x02020;" },
2281     { "dash",   "&#x02010;" },
2282     { "diams",  "&#x02666;" },
2283     { "dlcrop", "&#x0230D;" },
2284     { "drcrop", "&#x0230C;" },
2285     { "dtri",   "&#x025BF;" },
2286     { "dtrif",  "&#x025BE;" },
2287     { "emsp",   "&#x02003;" },
2288     { "emsp13", "&#x02004;" },
2289     { "emsp14", "&#x02005;" },
2290     { "ensp",   "&#x02002;" },
2291     { "female", "&#x02640;" },
2292     { "ffilig", "&#x0FB03;" },
2293     { "fflig",  "&#x0FB00;" },
2294     { "ffllig", "&#x0FB04;" },
2295     { "filig",  "&#x0FB01;" },
2296     { "flat",   "&#x0266D;" },
2297     { "fllig",  "&#x0FB02;" },
2298     { "frac13", "&#x02153;" },
2299     { "frac15", "&#x02155;" },
2300     { "frac16", "&#x02159;" },
2301     { "frac23", "&#x02154;" },
2302     { "frac25", "&#x02156;" },
2303     { "frac35", "&#x02157;" },
2304     { "frac45", "&#x02158;" },
2305     { "frac56", "&#x0215A;" },
2306     { "hairsp", "&#x0200A;" },
2307     { "hearts", "&#x02665;" },
2308     { "hellip", "&#x02026;" },
2309     { "hybull", "&#x02043;" },
2310     { "incare", "&#x02105;" },
2311     { "ldquor", "&#x0201E;" },
2312     { "lhblk",  "&#x02584;" },
2313     { "loz",    "&#x025CA;" },
2314     { "lozf",   "&#x029EB;" },
2315     { "lsquor", "&#x0201A;" },
2316     { "ltri",   "&#x025C3;" },
2317     { "ltrif",  "&#x025C2;" },
2318     { "male",   "&#x02642;" },
2319     { "malt",   "&#x02720;" },
2320     { "marker", "&#x025AE;" },
2321     { "mdash",  "&#x02014;" },
2322     { "mldr",   "&#x02026;" },
2323     { "natur",  "&#x0266E;" },
2324     { "ndash",  "&#x02013;" },
2325     { "nldr",   "&#x02025;" },
2326     { "numsp",  "&#x02007;" },
2327     { "phone",  "&#x0260E;" },
2328     { "puncsp", "&#x02008;" },
2329     { "rdquor", "&#x0201D;" },
2330     { "rect",   "&#x025AD;" },
2331     { "rsquor", "&#x02019;" },
2332     { "rtri",   "&#x025B9;" },
2333     { "rtrif",  "&#x025B8;" },
2334     { "rx", "&#x0211E;" },
2335     { "sext",   "&#x02736;" },
2336     { "sharp",  "&#x0266F;" },
2337     { "spades", "&#x02660;" },
2338     { "squ",    "&#x025A1;" },
2339     { "squf",   "&#x025AA;" },
2340     { "star",   "&#x02606;" },
2341     { "starf",  "&#x02605;" },
2342     { "target", "&#x02316;" },
2343     { "telrec", "&#x02315;" },
2344     { "thinsp", "&#x02009;" },
2345     { "uhblk",  "&#x02580;" },
2346     { "ulcrop", "&#x0230F;" },
2347     { "urcrop", "&#x0230E;" },
2348     { "utri",   "&#x025B5;" },
2349     { "utrif",  "&#x025B4;" },
2350     { "vellip", "&#x022EE;" },
2351     { "af", "&#x02061;" },
2352     { "asympeq",    "&#x0224D;" },
2353     { "Cross",  "&#x02A2F;" },
2354     { "DD", "&#x02145;" },
2355     { "dd", "&#x02146;" },
2356     { "DownArrowBar",   "&#x02913;" },
2357     { "DownBreve",  "&#x00311;" },
2358     { "DownLeftRightVector",    "&#x02950;" },
2359     { "DownLeftTeeVector",  "&#x0295E;" },
2360     { "DownLeftVectorBar",  "&#x02956;" },
2361     { "DownRightTeeVector", "&#x0295F;" },
2362     { "DownRightVectorBar", "&#x02957;" },
2363     { "ee", "&#x02147;" },
2364     { "EmptySmallSquare",   "&#x025FB;" },
2365     { "EmptyVerySmallSquare",   "&#x025AB;" },
2366     { "Equal",  "&#x02A75;" },
2367     { "FilledSmallSquare",  "&#x025FC;" },
2368     { "FilledVerySmallSquare",  "&#x025AA;" },
2369     { "GreaterGreater", "&#x02AA2;" },
2370     { "Hat",    "&#x0005E;" },
2371     { "HorizontalLine", "&#x02500;" },
2372     { "ic", "&#x02063;" },
2373     { "ii", "&#x02148;" },
2374     { "it", "&#x02062;" },
2375     { "larrb",  "&#x021E4;" },
2376     { "LeftDownTeeVector",  "&#x02961;" },
2377     { "LeftDownVectorBar",  "&#x02959;" },
2378     { "LeftRightVector",    "&#x0294E;" },
2379     { "LeftTeeVector",  "&#x0295A;" },
2380     { "LeftTriangleBar",    "&#x029CF;" },
2381     { "LeftUpDownVector",   "&#x02951;" },
2382     { "LeftUpTeeVector",    "&#x02960;" },
2383     { "LeftUpVectorBar",    "&#x02958;" },
2384     { "LeftVectorBar",  "&#x02952;" },
2385     { "LessLess",   "&#x02AA1;" },
2386     { "mapstodown", "&#x021A7;" },
2387     { "mapstoleft", "&#x021A4;" },
2388     { "mapstoup",   "&#x021A5;" },
2389     { "MediumSpace",    "&#x0205F;" },
2390     { "nbump",  "&#x0224E;&#x00338;" },
2391     { "nbumpe", "&#x0224F;&#x00338;" },
2392     { "nesim",  "&#x02242;&#x00338;" },
2393     { "NewLine",    "&#x0000A;" },
2394     { "NoBreak",    "&#x02060;" },
2395     { "NotCupCap",  "&#x0226D;" },
2396     { "NotHumpEqual",   "&#x0224F;&#x00338;" },
2397     { "NotLeftTriangleBar", "&#x029CF;&#x00338;" },
2398     { "NotNestedGreaterGreater",    "&#x02AA2;&#x00338;" },
2399     { "NotNestedLessLess",  "&#x02AA1;&#x00338;" },
2400     { "NotRightTriangleBar",    "&#x029D0;&#x00338;" },
2401     { "NotSquareSubset",    "&#x0228F;&#x00338;" },
2402     { "NotSquareSuperset",  "&#x02290;&#x00338;" },
2403     { "NotSucceedsTilde",   "&#x0227F;&#x00338;" },
2404     { "OverBar",    "&#x000AF;" },
2405     { "OverBrace",  "&#x0FE37;" },
2406     { "OverBracket",    "&#x023B4;" },
2407     { "OverParenthesis",    "&#x0FE35;" },
2408     { "planckh",    "&#x0210E;" },
2409     { "Product",    "&#x0220F;" },
2410     { "rarrb",  "&#x021E5;" },
2411     { "RightDownTeeVector", "&#x0295D;" },
2412     { "RightDownVectorBar", "&#x02955;" },
2413     { "RightTeeVector", "&#x0295B;" },
2414     { "RightTriangleBar",   "&#x029D0;" },
2415     { "RightUpDownVector",  "&#x0294F;" },
2416     { "RightUpTeeVector",   "&#x0295C;" },
2417     { "RightUpVectorBar",   "&#x02954;" },
2418     { "RightVectorBar", "&#x02953;" },
2419     { "RoundImplies",   "&#x02970;" },
2420     { "RuleDelayed",    "&#x029F4;" },
2421     { "Tab",    "&#x00009;" },
2422     { "ThickSpace", "&#x02009;&#x0200A;&#x0200A;" },
2423     { "UnderBar",   "&#x00332;" },
2424     { "UnderBrace", "&#x0FE38;" },
2425     { "UnderBracket",   "&#x023B5;" },
2426     { "UnderParenthesis",   "&#x0FE36;" },
2427     { "UpArrowBar", "&#x02912;" },
2428     { "Upsilon",    "&#x003A5;" },
2429     { "VerticalLine",   "&#x0007C;" },
2430     { "VerticalSeparator",  "&#x02758;" },
2431     { "ZeroWidthSpace", "&#x0200B;" },
2432     { "angle",  "&#x02220;" },
2433     { "ApplyFunction",  "&#x02061;" },
2434     { "approx", "&#x02248;" },
2435     { "approxeq",   "&#x0224A;" },
2436     { "Assign", "&#x02254;" },
2437     { "backcong",   "&#x0224C;" },
2438     { "backepsilon",    "&#x003F6;" },
2439     { "backprime",  "&#x02035;" },
2440     { "backsim",    "&#x0223D;" },
2441     { "backsimeq",  "&#x022CD;" },
2442     { "Backslash",  "&#x02216;" },
2443     { "barwedge",   "&#x02305;" },
2444     { "Because",    "&#x02235;" },
2445     { "because",    "&#x02235;" },
2446     { "Bernoullis", "&#x0212C;" },
2447     { "between",    "&#x0226C;" },
2448     { "bigcap", "&#x022C2;" },
2449     { "bigcirc",    "&#x025EF;" },
2450     { "bigcup", "&#x022C3;" },
2451     { "bigodot",    "&#x02A00;" },
2452     { "bigoplus",   "&#x02A01;" },
2453     { "bigotimes",  "&#x02A02;" },
2454     { "bigsqcup",   "&#x02A06;" },
2455     { "bigstar",    "&#x02605;" },
2456     { "bigtriangledown",    "&#x025BD;" },
2457     { "bigtriangleup",  "&#x025B3;" },
2458     { "biguplus",   "&#x02A04;" },
2459     { "bigvee", "&#x022C1;" },
2460     { "bigwedge",   "&#x022C0;" },
2461     { "bkarow", "&#x0290D;" },
2462     { "blacklozenge",   "&#x029EB;" },
2463     { "blacksquare",    "&#x025AA;" },
2464     { "blacktriangle",  "&#x025B4;" },
2465     { "blacktriangledown",  "&#x025BE;" },
2466     { "blacktriangleleft",  "&#x025C2;" },
2467     { "blacktriangleright", "&#x025B8;" },
2468     { "bot",    "&#x022A5;" },
2469     { "boxminus",   "&#x0229F;" },
2470     { "boxplus",    "&#x0229E;" },
2471     { "boxtimes",   "&#x022A0;" },
2472     { "Breve",  "&#x002D8;" },
2473     { "bullet", "&#x02022;" },
2474     { "Bumpeq", "&#x0224E;" },
2475     { "bumpeq", "&#x0224F;" },
2476     { "CapitalDifferentialD",   "&#x02145;" },
2477     { "Cayleys",    "&#x0212D;" },
2478     { "Cedilla",    "&#x000B8;" },
2479     { "CenterDot",  "&#x000B7;" },
2480     { "centerdot",  "&#x000B7;" },
2481     { "checkmark",  "&#x02713;" },
2482     { "circeq", "&#x02257;" },
2483     { "circlearrowleft",    "&#x021BA;" },
2484     { "circlearrowright",   "&#x021BB;" },
2485     { "circledast", "&#x0229B;" },
2486     { "circledcirc",    "&#x0229A;" },
2487     { "circleddash",    "&#x0229D;" },
2488     { "CircleDot",  "&#x02299;" },
2489     { "circledR",   "&#x000AE;" },
2490     { "circledS",   "&#x024C8;" },
2491     { "CircleMinus",    "&#x02296;" },
2492     { "CirclePlus", "&#x02295;" },
2493     { "CircleTimes",    "&#x02297;" },
2494     { "ClockwiseContourIntegral",   "&#x02232;" },
2495     { "CloseCurlyDoubleQuote",  "&#x0201D;" },
2496     { "CloseCurlyQuote",    "&#x02019;" },
2497     { "clubsuit",   "&#x02663;" },
2498     { "coloneq",    "&#x02254;" },
2499     { "complement", "&#x02201;" },
2500     { "complexes",  "&#x02102;" },
2501     { "Congruent",  "&#x02261;" },
2502     { "ContourIntegral",    "&#x0222E;" },
2503     { "Coproduct",  "&#x02210;" },
2504     { "CounterClockwiseContourIntegral",    "&#x02233;" },
2505     { "CupCap", "&#x0224D;" },
2506     { "curlyeqprec",    "&#x022DE;" },
2507     { "curlyeqsucc",    "&#x022DF;" },
2508     { "curlyvee",   "&#x022CE;" },
2509     { "curlywedge", "&#x022CF;" },
2510     { "curvearrowleft", "&#x021B6;" },
2511     { "curvearrowright",    "&#x021B7;" },
2512     { "dbkarow",    "&#x0290F;" },
2513     { "ddagger",    "&#x02021;" },
2514     { "ddotseq",    "&#x02A77;" },
2515     { "Del",    "&#x02207;" },
2516     { "DiacriticalAcute",   "&#x000B4;" },
2517     { "DiacriticalDot", "&#x002D9;" },
2518     { "DiacriticalDoubleAcute", "&#x002DD;" },
2519     { "DiacriticalGrave",   "&#x00060;" },
2520     { "DiacriticalTilde",   "&#x002DC;" },
2521     { "Diamond",    "&#x022C4;" },
2522     { "diamond",    "&#x022C4;" },
2523     { "diamondsuit",    "&#x02666;" },
2524     { "DifferentialD",  "&#x02146;" },
2525     { "digamma",    "&#x003DD;" },
2526     { "div",    "&#x000F7;" },
2527     { "divideontimes",  "&#x022C7;" },
2528     { "doteq",  "&#x02250;" },
2529     { "doteqdot",   "&#x02251;" },
2530     { "DotEqual",   "&#x02250;" },
2531     { "dotminus",   "&#x02238;" },
2532     { "dotplus",    "&#x02214;" },
2533     { "dotsquare",  "&#x022A1;" },
2534     { "doublebarwedge", "&#x02306;" },
2535     { "DoubleContourIntegral",  "&#x0222F;" },
2536     { "DoubleDot",  "&#x000A8;" },
2537     { "DoubleDownArrow",    "&#x021D3;" },
2538     { "DoubleLeftArrow",    "&#x021D0;" },
2539     { "DoubleLeftRightArrow",   "&#x021D4;" },
2540     { "DoubleLeftTee",  "&#x02AE4;" },
2541     { "DoubleLongLeftArrow",    "&#x027F8;" },
2542     { "DoubleLongLeftRightArrow",   "&#x027FA;" },
2543     { "DoubleLongRightArrow",   "&#x027F9;" },
2544     { "DoubleRightArrow",   "&#x021D2;" },
2545     { "DoubleRightTee", "&#x022A8;" },
2546     { "DoubleUpArrow",  "&#x021D1;" },
2547     { "DoubleUpDownArrow",  "&#x021D5;" },
2548     { "DoubleVerticalBar",  "&#x02225;" },
2549     { "DownArrow",  "&#x02193;" },
2550     { "Downarrow",  "&#x021D3;" },
2551     { "downarrow",  "&#x02193;" },
2552     { "DownArrowUpArrow",   "&#x021F5;" },
2553     { "downdownarrows", "&#x021CA;" },
2554     { "downharpoonleft",    "&#x021C3;" },
2555     { "downharpoonright",   "&#x021C2;" },
2556     { "DownLeftVector", "&#x021BD;" },
2557     { "DownRightVector",    "&#x021C1;" },
2558     { "DownTee",    "&#x022A4;" },
2559     { "DownTeeArrow",   "&#x021A7;" },
2560     { "drbkarow",   "&#x02910;" },
2561     { "Element",    "&#x02208;" },
2562     { "emptyset",   "&#x02205;" },
2563     { "eqcirc", "&#x02256;" },
2564     { "eqcolon",    "&#x02255;" },
2565     { "eqsim",  "&#x02242;" },
2566     { "eqslantgtr", "&#x02A96;" },
2567     { "eqslantless",    "&#x02A95;" },
2568     { "EqualTilde", "&#x02242;" },
2569     { "Equilibrium",    "&#x021CC;" },
2570     { "Exists", "&#x02203;" },
2571     { "expectation",    "&#x02130;" },
2572     { "ExponentialE",   "&#x02147;" },
2573     { "exponentiale",   "&#x02147;" },
2574     { "fallingdotseq",  "&#x02252;" },
2575     { "ForAll", "&#x02200;" },
2576     { "Fouriertrf", "&#x02131;" },
2577     { "geq",    "&#x02265;" },
2578     { "geqq",   "&#x02267;" },
2579     { "geqslant",   "&#x02A7E;" },
2580     { "gg", "&#x0226B;" },
2581     { "ggg",    "&#x022D9;" },
2582     { "gnapprox",   "&#x02A8A;" },
2583     { "gneq",   "&#x02A88;" },
2584     { "gneqq",  "&#x02269;" },
2585     { "GreaterEqual",   "&#x02265;" },
2586     { "GreaterEqualLess",   "&#x022DB;" },
2587     { "GreaterFullEqual",   "&#x02267;" },
2588     { "GreaterLess",    "&#x02277;" },
2589     { "GreaterSlantEqual",  "&#x02A7E;" },
2590     { "GreaterTilde",   "&#x02273;" },
2591     { "gtrapprox",  "&#x02A86;" },
2592     { "gtrdot", "&#x022D7;" },
2593     { "gtreqless",  "&#x022DB;" },
2594     { "gtreqqless", "&#x02A8C;" },
2595     { "gtrless",    "&#x02277;" },
2596     { "gtrsim", "&#x02273;" },
2597     { "gvertneqq",  "&#x02269;&#x0FE00;" },
2598     { "Hacek",  "&#x002C7;" },
2599     { "hbar",   "&#x0210F;" },
2600     { "heartsuit",  "&#x02665;" },
2601     { "HilbertSpace",   "&#x0210B;" },
2602     { "hksearow",   "&#x02925;" },
2603     { "hkswarow",   "&#x02926;" },
2604     { "hookleftarrow",  "&#x021A9;" },
2605     { "hookrightarrow", "&#x021AA;" },
2606     { "hslash", "&#x0210F;" },
2607     { "HumpDownHump",   "&#x0224E;" },
2608     { "HumpEqual",  "&#x0224F;" },
2609     { "iiiint", "&#x02A0C;" },
2610     { "iiint",  "&#x0222D;" },
2611     { "Im", "&#x02111;" },
2612     { "ImaginaryI", "&#x02148;" },
2613     { "imagline",   "&#x02110;" },
2614     { "imagpart",   "&#x02111;" },
2615     { "Implies",    "&#x021D2;" },
2616     { "in", "&#x02208;" },
2617     { "integers",   "&#x02124;" },
2618     { "Integral",   "&#x0222B;" },
2619     { "intercal",   "&#x022BA;" },
2620     { "Intersection",   "&#x022C2;" },
2621     { "intprod",    "&#x02A3C;" },
2622     { "InvisibleComma", "&#x02063;" },
2623     { "InvisibleTimes", "&#x02062;" },
2624     { "langle", "&#x02329;" },
2625     { "Laplacetrf", "&#x02112;" },
2626     { "lbrace", "&#x0007B;" },
2627     { "lbrack", "&#x0005B;" },
2628     { "LeftAngleBracket",   "&#x02329;" },
2629     { "LeftArrow",  "&#x02190;" },
2630     { "Leftarrow",  "&#x021D0;" },
2631     { "leftarrow",  "&#x02190;" },
2632     { "LeftArrowBar",   "&#x021E4;" },
2633     { "LeftArrowRightArrow",    "&#x021C6;" },
2634     { "leftarrowtail",  "&#x021A2;" },
2635     { "LeftCeiling",    "&#x02308;" },
2636     { "LeftDoubleBracket",  "&#x0301A;" },
2637     { "LeftDownVector", "&#x021C3;" },
2638     { "LeftFloor",  "&#x0230A;" },
2639     { "leftharpoondown",    "&#x021BD;" },
2640     { "leftharpoonup",  "&#x021BC;" },
2641     { "leftleftarrows", "&#x021C7;" },
2642     { "LeftRightArrow", "&#x02194;" },
2643     { "Leftrightarrow", "&#x021D4;" },
2644     { "leftrightarrow", "&#x02194;" },
2645     { "leftrightarrows",    "&#x021C6;" },
2646     { "leftrightharpoons",  "&#x021CB;" },
2647     { "leftrightsquigarrow",    "&#x021AD;" },
2648     { "LeftTee",    "&#x022A3;" },
2649     { "LeftTeeArrow",   "&#x021A4;" },
2650     { "leftthreetimes", "&#x022CB;" },
2651     { "LeftTriangle",   "&#x022B2;" },
2652     { "LeftTriangleEqual",  "&#x022B4;" },
2653     { "LeftUpVector",   "&#x021BF;" },
2654     { "LeftVector", "&#x021BC;" },
2655     { "leq",    "&#x02264;" },
2656     { "leqq",   "&#x02266;" },
2657     { "leqslant",   "&#x02A7D;" },
2658     { "lessapprox", "&#x02A85;" },
2659     { "lessdot",    "&#x022D6;" },
2660     { "lesseqgtr",  "&#x022DA;" },
2661     { "lesseqqgtr", "&#x02A8B;" },
2662     { "LessEqualGreater",   "&#x022DA;" },
2663     { "LessFullEqual",  "&#x02266;" },
2664     { "LessGreater",    "&#x02276;" },
2665     { "lessgtr",    "&#x02276;" },
2666     { "lesssim",    "&#x02272;" },
2667     { "LessSlantEqual", "&#x02A7D;" },
2668     { "LessTilde",  "&#x02272;" },
2669     { "ll", "&#x0226A;" },
2670     { "llcorner",   "&#x0231E;" },
2671     { "Lleftarrow", "&#x021DA;" },
2672     { "lmoustache", "&#x023B0;" },
2673     { "lnapprox",   "&#x02A89;" },
2674     { "lneq",   "&#x02A87;" },
2675     { "lneqq",  "&#x02268;" },
2676     { "LongLeftArrow",  "&#x027F5;" },
2677     { "Longleftarrow",  "&#x027F8;" },
2678     { "longleftarrow",  "&#x027F5;" },
2679     { "LongLeftRightArrow", "&#x027F7;" },
2680     { "Longleftrightarrow", "&#x027FA;" },
2681     { "longleftrightarrow", "&#x027F7;" },
2682     { "longmapsto", "&#x027FC;" },
2683     { "LongRightArrow", "&#x027F6;" },
2684     { "Longrightarrow", "&#x027F9;" },
2685     { "longrightarrow", "&#x027F6;" },
2686     { "looparrowleft",  "&#x021AB;" },
2687     { "looparrowright", "&#x021AC;" },
2688     { "LowerLeftArrow", "&#x02199;" },
2689     { "LowerRightArrow",    "&#x02198;" },
2690     { "lozenge",    "&#x025CA;" },
2691     { "lrcorner",   "&#x0231F;" },
2692     { "Lsh",    "&#x021B0;" },
2693     { "lvertneqq",  "&#x02268;&#x0FE00;" },
2694     { "maltese",    "&#x02720;" },
2695     { "mapsto", "&#x021A6;" },
2696     { "measuredangle",  "&#x02221;" },
2697     { "Mellintrf",  "&#x02133;" },
2698     { "MinusPlus",  "&#x02213;" },
2699     { "mp", "&#x02213;" },
2700     { "multimap",   "&#x022B8;" },
2701     { "napprox",    "&#x02249;" },
2702     { "natural",    "&#x0266E;" },
2703     { "naturals",   "&#x02115;" },
2704     { "nearrow",    "&#x02197;" },
2705     { "NegativeMediumSpace",    "&#x0200B;" },
2706     { "NegativeThickSpace", "&#x0200B;" },
2707     { "NegativeThinSpace",  "&#x0200B;" },
2708     { "NegativeVeryThinSpace",  "&#x0200B;" },
2709     { "NestedGreaterGreater",   "&#x0226B;" },
2710     { "NestedLessLess", "&#x0226A;" },
2711     { "nexists",    "&#x02204;" },
2712     { "ngeq",   "&#x02271;" },
2713     { "ngeqq",  "&#x02267;&#x00338;" },
2714     { "ngeqslant",  "&#x02A7E;&#x00338;" },
2715     { "ngtr",   "&#x0226F;" },
2716     { "nLeftarrow", "&#x021CD;" },
2717     { "nleftarrow", "&#x0219A;" },
2718     { "nLeftrightarrow",    "&#x021CE;" },
2719     { "nleftrightarrow",    "&#x021AE;" },
2720     { "nleq",   "&#x02270;" },
2721     { "nleqq",  "&#x02266;&#x00338;" },
2722     { "nleqslant",  "&#x02A7D;&#x00338;" },
2723     { "nless",  "&#x0226E;" },
2724     { "NonBreakingSpace",   "&#x000A0;" },
2725     { "NotCongruent",   "&#x02262;" },
2726     { "NotDoubleVerticalBar",   "&#x02226;" },
2727     { "NotElement", "&#x02209;" },
2728     { "NotEqual",   "&#x02260;" },
2729     { "NotEqualTilde",  "&#x02242;&#x00338;" },
2730     { "NotExists",  "&#x02204;" },
2731     { "NotGreater", "&#x0226F;" },
2732     { "NotGreaterEqual",    "&#x02271;" },
2733     { "NotGreaterFullEqual",    "&#x02266;&#x00338;" },
2734     { "NotGreaterGreater",  "&#x0226B;&#x00338;" },
2735     { "NotGreaterLess", "&#x02279;" },
2736     { "NotGreaterSlantEqual",   "&#x02A7E;&#x00338;" },
2737     { "NotGreaterTilde",    "&#x02275;" },
2738     { "NotHumpDownHump",    "&#x0224E;&#x00338;" },
2739     { "NotLeftTriangle",    "&#x022EA;" },
2740     { "NotLeftTriangleEqual",   "&#x022EC;" },
2741     { "NotLess",    "&#x0226E;" },
2742     { "NotLessEqual",   "&#x02270;" },
2743     { "NotLessGreater", "&#x02278;" },
2744     { "NotLessLess",    "&#x0226A;&#x00338;" },
2745     { "NotLessSlantEqual",  "&#x02A7D;&#x00338;" },
2746     { "NotLessTilde",   "&#x02274;" },
2747     { "NotPrecedes",    "&#x02280;" },
2748     { "NotPrecedesEqual",   "&#x02AAF;&#x00338;" },
2749     { "NotPrecedesSlantEqual",  "&#x022E0;" },
2750     { "NotReverseElement",  "&#x0220C;" },
2751     { "NotRightTriangle",   "&#x022EB;" },
2752     { "NotRightTriangleEqual",  "&#x022ED;" },
2753     { "NotSquareSubsetEqual",   "&#x022E2;" },
2754     { "NotSquareSupersetEqual", "&#x022E3;" },
2755     { "NotSubset",  "&#x02282;&#x020D2;" },
2756     { "NotSubsetEqual", "&#x02288;" },
2757     { "NotSucceeds",    "&#x02281;" },
2758     { "NotSucceedsEqual",   "&#x02AB0;&#x00338;" },
2759     { "NotSucceedsSlantEqual",  "&#x022E1;" },
2760     { "NotSuperset",    "&#x02283;&#x020D2;" },
2761     { "NotSupersetEqual",   "&#x02289;" },
2762     { "NotTilde",   "&#x02241;" },
2763     { "NotTildeEqual",  "&#x02244;" },
2764     { "NotTildeFullEqual",  "&#x02247;" },
2765     { "NotTildeTilde",  "&#x02249;" },
2766     { "NotVerticalBar", "&#x02224;" },
2767     { "nparallel",  "&#x02226;" },
2768     { "nprec",  "&#x02280;" },
2769     { "npreceq",    "&#x02AAF;&#x00338;" },
2770     { "nRightarrow",    "&#x021CF;" },
2771     { "nrightarrow",    "&#x0219B;" },
2772     { "nshortmid",  "&#x02224;" },
2773     { "nshortparallel", "&#x02226;" },
2774     { "nsimeq", "&#x02244;" },
2775     { "nsubset",    "&#x02282;&#x020D2;" },
2776     { "nsubseteq",  "&#x02288;" },
2777     { "nsubseteqq", "&#x02AC5;&#x0338;" },
2778     { "nsucc",  "&#x02281;" },
2779     { "nsucceq",    "&#x02AB0;&#x00338;" },
2780     { "nsupset",    "&#x02283;&#x020D2;" },
2781     { "nsupseteq",  "&#x02289;" },
2782     { "nsupseteqq", "&#x02AC6;&#x0338;" },
2783     { "ntriangleleft",  "&#x022EA;" },
2784     { "ntrianglelefteq",    "&#x022EC;" },
2785     { "ntriangleright", "&#x022EB;" },
2786     { "ntrianglerighteq",   "&#x022ED;" },
2787     { "nwarrow",    "&#x02196;" },
2788     { "oint",   "&#x0222E;" },
2789     { "OpenCurlyDoubleQuote",   "&#x0201C;" },
2790     { "OpenCurlyQuote", "&#x02018;" },
2791     { "orderof",    "&#x02134;" },
2792     { "parallel",   "&#x02225;" },
2793     { "PartialD",   "&#x02202;" },
2794     { "pitchfork",  "&#x022D4;" },
2795     { "PlusMinus",  "&#x000B1;" },
2796     { "pm", "&#x000B1;" },
2797     { "Poincareplane",  "&#x0210C;" },
2798     { "prec",   "&#x0227A;" },
2799     { "precapprox", "&#x02AB7;" },
2800     { "preccurlyeq",    "&#x0227C;" },
2801     { "Precedes",   "&#x0227A;" },
2802     { "PrecedesEqual",  "&#x02AAF;" },
2803     { "PrecedesSlantEqual", "&#x0227C;" },
2804     { "PrecedesTilde",  "&#x0227E;" },
2805     { "preceq", "&#x02AAF;" },
2806     { "precnapprox",    "&#x02AB9;" },
2807     { "precneqq",   "&#x02AB5;" },
2808     { "precnsim",   "&#x022E8;" },
2809     { "precsim",    "&#x0227E;" },
2810     { "primes", "&#x02119;" },
2811     { "Proportion", "&#x02237;" },
2812     { "Proportional",   "&#x0221D;" },
2813     { "propto", "&#x0221D;" },
2814     { "quaternions",    "&#x0210D;" },
2815     { "questeq",    "&#x0225F;" },
2816     { "rangle", "&#x0232A;" },
2817     { "rationals",  "&#x0211A;" },
2818     { "rbrace", "&#x0007D;" },
2819     { "rbrack", "&#x0005D;" },
2820     { "Re", "&#x0211C;" },
2821     { "realine",    "&#x0211B;" },
2822     { "realpart",   "&#x0211C;" },
2823     { "reals",  "&#x0211D;" },
2824     { "ReverseElement", "&#x0220B;" },
2825     { "ReverseEquilibrium", "&#x021CB;" },
2826     { "ReverseUpEquilibrium",   "&#x0296F;" },
2827     { "RightAngleBracket",  "&#x0232A;" },
2828     { "RightArrow", "&#x02192;" },
2829     { "Rightarrow", "&#x021D2;" },
2830     { "rightarrow", "&#x02192;" },
2831     { "RightArrowBar",  "&#x021E5;" },
2832     { "RightArrowLeftArrow",    "&#x021C4;" },
2833     { "rightarrowtail", "&#x021A3;" },
2834     { "RightCeiling",   "&#x02309;" },
2835     { "RightDoubleBracket", "&#x0301B;" },
2836     { "RightDownVector",    "&#x021C2;" },
2837     { "RightFloor", "&#x0230B;" },
2838     { "rightharpoondown",   "&#x021C1;" },
2839     { "rightharpoonup", "&#x021C0;" },
2840     { "rightleftarrows",    "&#x021C4;" },
2841     { "rightleftharpoons",  "&#x021CC;" },
2842     { "rightrightarrows",   "&#x021C9;" },
2843     { "rightsquigarrow",    "&#x0219D;" },
2844     { "RightTee",   "&#x022A2;" },
2845     { "RightTeeArrow",  "&#x021A6;" },
2846     { "rightthreetimes",    "&#x022CC;" },
2847     { "RightTriangle",  "&#x022B3;" },
2848     { "RightTriangleEqual", "&#x022B5;" },
2849     { "RightUpVector",  "&#x021BE;" },
2850     { "RightVector",    "&#x021C0;" },
2851     { "risingdotseq",   "&#x02253;" },
2852     { "rmoustache", "&#x023B1;" },
2853     { "Rrightarrow",    "&#x021DB;" },
2854     { "Rsh",    "&#x021B1;" },
2855     { "searrow",    "&#x02198;" },
2856     { "setminus",   "&#x02216;" },
2857     { "ShortDownArrow", "&#x02193;" },
2858     { "ShortLeftArrow", "&#x02190;" },
2859     { "shortmid",   "&#x02223;" },
2860     { "shortparallel",  "&#x02225;" },
2861     { "ShortRightArrow",    "&#x02192;" },
2862     { "ShortUpArrow",   "&#x02191;" },
2863     { "simeq",  "&#x02243;" },
2864     { "SmallCircle",    "&#x02218;" },
2865     { "smallsetminus",  "&#x02216;" },
2866     { "spadesuit",  "&#x02660;" },
2867     { "Sqrt",   "&#x0221A;" },
2868     { "sqsubset",   "&#x0228F;" },
2869     { "sqsubseteq", "&#x02291;" },
2870     { "sqsupset",   "&#x02290;" },
2871     { "sqsupseteq", "&#x02292;" },
2872     { "Square", "&#x025A1;" },
2873     { "SquareIntersection", "&#x02293;" },
2874     { "SquareSubset",   "&#x0228F;" },
2875     { "SquareSubsetEqual",  "&#x02291;" },
2876     { "SquareSuperset", "&#x02290;" },
2877     { "SquareSupersetEqual",    "&#x02292;" },
2878     { "SquareUnion",    "&#x02294;" },
2879     { "Star",   "&#x022C6;" },
2880     { "straightepsilon",    "&#x003B5;" },
2881     { "straightphi",    "&#x003D5;" },
2882     { "Subset", "&#x022D0;" },
2883     { "subset", "&#x02282;" },
2884     { "subseteq",   "&#x02286;" },
2885     { "subseteqq",  "&#x02AC5;" },
2886     { "SubsetEqual",    "&#x02286;" },
2887     { "subsetneq",  "&#x0228A;" },
2888     { "subsetneqq", "&#x02ACB;" },
2889     { "succ",   "&#x0227B;" },
2890     { "succapprox", "&#x02AB8;" },
2891     { "succcurlyeq",    "&#x0227D;" },
2892     { "Succeeds",   "&#x0227B;" },
2893     { "SucceedsEqual",  "&#x02AB0;" },
2894     { "SucceedsSlantEqual", "&#x0227D;" },
2895     { "SucceedsTilde",  "&#x0227F;" },
2896     { "succeq", "&#x02AB0;" },
2897     { "succnapprox",    "&#x02ABA;" },
2898     { "succneqq",   "&#x02AB6;" },
2899     { "succnsim",   "&#x022E9;" },
2900     { "succsim",    "&#x0227F;" },
2901     { "SuchThat",   "&#x0220B;" },
2902     { "Sum",    "&#x02211;" },
2903     { "Superset",   "&#x02283;" },
2904     { "SupersetEqual",  "&#x02287;" },
2905     { "Supset", "&#x022D1;" },
2906     { "supset", "&#x02283;" },
2907     { "supseteq",   "&#x02287;" },
2908     { "supseteqq",  "&#x02AC6;" },
2909     { "supsetneq",  "&#x0228B;" },
2910     { "supsetneqq", "&#x02ACC;" },
2911     { "swarrow",    "&#x02199;" },
2912     { "Therefore",  "&#x02234;" },
2913     { "therefore",  "&#x02234;" },
2914     { "thickapprox",    "&#x02248;" },
2915     { "thicksim",   "&#x0223C;" },
2916     { "ThinSpace",  "&#x02009;" },
2917     { "Tilde",  "&#x0223C;" },
2918     { "TildeEqual", "&#x02243;" },
2919     { "TildeFullEqual", "&#x02245;" },
2920     { "TildeTilde", "&#x02248;" },
2921     { "toea",   "&#x02928;" },
2922     { "tosa",   "&#x02929;" },
2923     { "triangle",   "&#x025B5;" },
2924     { "triangledown",   "&#x025BF;" },
2925     { "triangleleft",   "&#x025C3;" },
2926     { "trianglelefteq", "&#x022B4;" },
2927     { "triangleq",  "&#x0225C;" },
2928     { "triangleright",  "&#x025B9;" },
2929     { "trianglerighteq",    "&#x022B5;" },
2930     { "TripleDot",  "&#x020DB;" },
2931     { "twoheadleftarrow",   "&#x0219E;" },
2932     { "twoheadrightarrow",  "&#x021A0;" },
2933     { "ulcorner",   "&#x0231C;" },
2934     { "Union",  "&#x022C3;" },
2935     { "UnionPlus",  "&#x0228E;" },
2936     { "UpArrow",    "&#x02191;" },
2937     { "Uparrow",    "&#x021D1;" },
2938     { "uparrow",    "&#x02191;" },
2939     { "UpArrowDownArrow",   "&#x021C5;" },
2940     { "UpDownArrow",    "&#x02195;" },
2941     { "Updownarrow",    "&#x021D5;" },
2942     { "updownarrow",    "&#x02195;" },
2943     { "UpEquilibrium",  "&#x0296E;" },
2944     { "upharpoonleft",  "&#x021BF;" },
2945     { "upharpoonright", "&#x021BE;" },
2946     { "UpperLeftArrow", "&#x02196;" },
2947     { "UpperRightArrow",    "&#x02197;" },
2948     { "upsilon",    "&#x003C5;" },
2949     { "UpTee",  "&#x022A5;" },
2950     { "UpTeeArrow", "&#x021A5;" },
2951     { "upuparrows", "&#x021C8;" },
2952     { "urcorner",   "&#x0231D;" },
2953     { "varepsilon", "&#x0025B;" },
2954     { "varkappa",   "&#x003F0;" },
2955     { "varnothing", "&#x02205;" },
2956     { "varphi", "&#x003C6;" },
2957     { "varpi",  "&#x003D6;" },
2958     { "varpropto",  "&#x0221D;" },
2959     { "varrho", "&#x003F1;" },
2960     { "varsigma",   "&#x003C2;" },
2961     { "varsubsetneq",   "&#x0228A;&#x0FE00;" },
2962     { "varsubsetneqq",  "&#x02ACB;&#x0FE00;" },
2963     { "varsupsetneq",   "&#x0228B;&#x0FE00;" },
2964     { "varsupsetneqq",  "&#x02ACC;&#x0FE00;" },
2965     { "vartheta",   "&#x003D1;" },
2966     { "vartriangleleft",    "&#x022B2;" },
2967     { "vartriangleright",   "&#x022B3;" },
2968     { "Vee",    "&#x022C1;" },
2969     { "vee",    "&#x02228;" },
2970     { "Vert",   "&#x02016;" },
2971     { "vert",   "&#x0007C;" },
2972     { "VerticalBar",    "&#x02223;" },
2973     { "VerticalTilde",  "&#x02240;" },
2974     { "VeryThinSpace",  "&#x0200A;" },
2975     { "Wedge",  "&#x022C0;" },
2976     { "wedge",  "&#x02227;" },
2977     { "wp", "&#x02118;" },
2978     { "wr", "&#x02240;" },
2979     { "zeetrf", "&#x02128;" },
2980     { 0, 0 }
2981 };
2982 
2983 // *******************************************************************
2984 // QwtMmlDocument
2985 // *******************************************************************
2986 
fontName(QwtMathMLDocument::MmlFont type) const2987 QString QwtMmlDocument::fontName( QwtMathMLDocument::MmlFont type ) const
2988 {
2989     switch ( type )
2990     {
2991         case QwtMathMLDocument::NormalFont:
2992             return m_normal_font_name;
2993         case QwtMathMLDocument::FrakturFont:
2994             return m_fraktur_font_name;
2995         case QwtMathMLDocument::SansSerifFont:
2996             return m_sans_serif_font_name;
2997         case QwtMathMLDocument::ScriptFont:
2998             return m_script_font_name;
2999         case QwtMathMLDocument::MonospaceFont:
3000             return m_monospace_font_name;
3001         case QwtMathMLDocument::DoublestruckFont:
3002             return m_doublestruck_font_name;
3003     };
3004 
3005     return QString();
3006 }
3007 
setFontName(QwtMathMLDocument::MmlFont type,const QString & name)3008 void QwtMmlDocument::setFontName( QwtMathMLDocument::MmlFont type, const QString &name )
3009 {
3010     switch ( type )
3011     {
3012         case QwtMathMLDocument::NormalFont:
3013             m_normal_font_name = name;
3014             break;
3015         case QwtMathMLDocument::FrakturFont:
3016             m_fraktur_font_name = name;
3017             break;
3018         case QwtMathMLDocument::SansSerifFont:
3019             m_sans_serif_font_name = name;
3020             break;
3021         case QwtMathMLDocument::ScriptFont:
3022             m_script_font_name = name;
3023             break;
3024         case QwtMathMLDocument::MonospaceFont:
3025             m_monospace_font_name = name;
3026             break;
3027         case QwtMathMLDocument::DoublestruckFont:
3028             m_doublestruck_font_name = name;
3029             break;
3030     };
3031 }
3032 
domToQwtMmlNodeType(const QDomNode & dom_node)3033 QwtMml::NodeType domToQwtMmlNodeType( const QDomNode &dom_node )
3034 {
3035     QwtMml::NodeType mml_type = QwtMml::NoNode;
3036 
3037     switch ( dom_node.nodeType() )
3038     {
3039         case QDomNode::ElementNode:
3040         {
3041             QString tag = dom_node.nodeName();
3042             const QwtMmlNodeSpec *spec = mmlFindNodeSpec( tag );
3043 
3044             // treat urecognised tags as mrow
3045             if ( spec == 0 )
3046                 mml_type = QwtMml::UnknownNode;
3047             else
3048                 mml_type = spec->type;
3049 
3050             break;
3051         }
3052         case QDomNode::TextNode:
3053             mml_type = QwtMml::TextNode;
3054             break;
3055 
3056         case QDomNode::DocumentNode:
3057             mml_type = QwtMml::MrowNode;
3058             break;
3059 
3060         case QDomNode::EntityReferenceNode:
3061 //      qWarning("EntityReferenceNode: name=\"" + dom_node.nodeName() + "\" value=\"" + dom_node.nodeValue() + "\"");
3062             break;
3063 
3064         case QDomNode::AttributeNode:
3065         case QDomNode::CDATASectionNode:
3066         case QDomNode::EntityNode:
3067         case QDomNode::ProcessingInstructionNode:
3068         case QDomNode::CommentNode:
3069         case QDomNode::DocumentTypeNode:
3070         case QDomNode::DocumentFragmentNode:
3071         case QDomNode::NotationNode:
3072         case QDomNode::BaseNode:
3073         case QDomNode::CharacterDataNode:
3074             break;
3075     }
3076 
3077     return mml_type;
3078 }
3079 
3080 
QwtMmlDocument()3081 QwtMmlDocument::QwtMmlDocument()
3082 {
3083     m_root_node = 0;
3084 
3085     // Some defaults which happen to work on my computer,
3086     // but probably won't work on other's
3087 #if defined(Q_OS_WIN)
3088     m_normal_font_name = "Times New Roman";
3089 #else
3090     m_normal_font_name = "Century Schoolbook L";
3091 #endif
3092     m_fraktur_font_name = "Fraktur";
3093     m_sans_serif_font_name = "Luxi Sans";
3094     m_script_font_name = "Urw Chancery L";
3095     m_monospace_font_name = "Luxi Mono";
3096     m_doublestruck_font_name = "Doublestruck";
3097     m_base_font_point_size = 16;
3098     m_foreground_color = Qt::black;
3099     m_background_color = Qt::white;
3100 }
3101 
~QwtMmlDocument()3102 QwtMmlDocument::~QwtMmlDocument()
3103 {
3104     clear();
3105 }
3106 
clear()3107 void QwtMmlDocument::clear()
3108 {
3109     delete m_root_node;
3110     m_root_node = 0;
3111 }
3112 
dump() const3113 void QwtMmlDocument::dump() const
3114 {
3115     if ( m_root_node == 0 )
3116         return;
3117 
3118     QString indent;
3119     _dump( m_root_node, indent );
3120 }
3121 
_dump(const QwtMmlNode * node,QString & indent) const3122 void QwtMmlDocument::_dump( const QwtMmlNode *node, QString &indent ) const
3123 {
3124     if ( node == 0 ) return;
3125 
3126     qWarning() << indent + node->toStr();
3127 
3128     indent += "  ";
3129     const QwtMmlNode *child = node->firstChild();
3130     for ( ; child != 0; child = child->nextSibling() )
3131         _dump( child, indent );
3132     indent.truncate( indent.length() - 2 );
3133 }
3134 
setContent(QString text,QString * errorMsg,int * errorLine,int * errorColumn)3135 bool QwtMmlDocument::setContent( QString text, QString *errorMsg,
3136                                  int *errorLine, int *errorColumn )
3137 {
3138     clear();
3139 
3140     QString prefix = "<?xml version=\"2.0\"?>\n";
3141     prefix.append( entityDeclarations() );
3142 
3143     uint prefix_lines = 0;
3144     for ( int i = 0; i < prefix.length(); ++i )
3145     {
3146         if ( prefix.at( i ) == '\n' )
3147             ++prefix_lines;
3148     }
3149 
3150     QDomDocument dom;
3151     if ( !dom.setContent( prefix + text, false, errorMsg, errorLine, errorColumn ) )
3152     {
3153         if ( errorLine != 0 )
3154             *errorLine -= prefix_lines;
3155         return false;
3156     }
3157 
3158     // we don't have access to line info from now on
3159     if ( errorLine != 0 ) *errorLine = -1;
3160     if ( errorColumn != 0 ) *errorColumn = -1;
3161 
3162     bool ok;
3163     QwtMmlNode *root_node = domToMml( dom, &ok, errorMsg );
3164     if ( !ok )
3165         return false;
3166 
3167     if ( root_node == 0 )
3168     {
3169         if ( errorMsg != 0 )
3170             *errorMsg = "empty document";
3171         return false;
3172     }
3173 
3174     insertChild( 0, root_node, 0 );
3175     layout();
3176 
3177     /*    QFile of("/tmp/dump.xml");
3178         of.open(IO_WriteOnly);
3179         QTextStream os(&of);
3180         os.setEncoding(QTextStream::UnicodeUTF8);
3181         os << dom.toString(); */
3182 
3183     return true;
3184 }
3185 
layout()3186 void QwtMmlDocument::layout()
3187 {
3188     if ( m_root_node == 0 )
3189         return;
3190 
3191     m_root_node->layout();
3192     m_root_node->stretch();
3193 //    dump();
3194 }
3195 
insertChild(QwtMmlNode * parent,QwtMmlNode * new_node,QString * errorMsg)3196 bool QwtMmlDocument::insertChild( QwtMmlNode *parent, QwtMmlNode *new_node,
3197                                   QString *errorMsg )
3198 {
3199     if ( new_node == 0 )
3200         return true;
3201 
3202     Q_ASSERT( new_node->parent() == 0
3203               && new_node->nextSibling() == 0
3204               && new_node->previousSibling() == 0 );
3205 
3206     if ( parent != 0 )
3207     {
3208         if ( !mmlCheckChildType( parent->nodeType(), new_node->nodeType(), errorMsg ) )
3209             return false;
3210     }
3211 
3212     if ( parent == 0 )
3213     {
3214         if ( m_root_node == 0 )
3215             m_root_node = new_node;
3216         else
3217         {
3218             QwtMmlNode *n = m_root_node->lastSibling();
3219             n->m_next_sibling = new_node;
3220             new_node->m_previous_sibling = n;
3221         }
3222     }
3223     else
3224     {
3225         new_node->m_parent = parent;
3226         if ( parent->hasChildNodes() )
3227         {
3228             QwtMmlNode *n = parent->firstChild()->lastSibling();
3229             n->m_next_sibling = new_node;
3230             new_node->m_previous_sibling = n;
3231         }
3232         else parent->m_first_child = new_node;
3233     }
3234 
3235     return true;
3236 }
3237 
createNode(NodeType type,const QwtMmlAttributeMap & mml_attr,const QString & mml_value,QString * errorMsg)3238 QwtMmlNode *QwtMmlDocument::createNode( NodeType type,
3239                                      const QwtMmlAttributeMap &mml_attr,
3240                                      const QString &mml_value,
3241                                      QString *errorMsg )
3242 {
3243     Q_ASSERT( type != NoNode );
3244 
3245     QwtMmlNode *mml_node = 0;
3246 
3247     if ( !mmlCheckAttributes( type, mml_attr, errorMsg ) )
3248         return 0;
3249 
3250     switch ( type )
3251     {
3252         case MiNode:
3253             mml_node = new QwtMmlMiNode( this, mml_attr );
3254             break;
3255         case MnNode:
3256             mml_node = new QwtMmlMnNode( this, mml_attr );
3257             break;
3258         case MfracNode:
3259             mml_node = new QwtMmlMfracNode( this, mml_attr );
3260             break;
3261         case MrowNode:
3262             mml_node = new QwtMmlMrowNode( this, mml_attr );
3263             break;
3264         case MsqrtNode:
3265             mml_node = new QwtMmlMsqrtNode( this, mml_attr );
3266             break;
3267         case MrootNode:
3268             mml_node = new QwtMmlMrootNode( this, mml_attr );
3269             break;
3270         case MsupNode:
3271             mml_node = new QwtMmlMsupNode( this, mml_attr );
3272             break;
3273         case MsubNode:
3274             mml_node = new QwtMmlMsubNode( this, mml_attr );
3275             break;
3276         case MsubsupNode:
3277             mml_node = new QwtMmlMsubsupNode( this, mml_attr );
3278             break;
3279         case MoNode:
3280             mml_node = new QwtMmlMoNode( this, mml_attr );
3281             break;
3282         case MstyleNode:
3283             mml_node = new QwtMmlMstyleNode( this, mml_attr );
3284             break;
3285         case TextNode:
3286             mml_node = new QwtMmlTextNode( mml_value, this );
3287             break;
3288         case MphantomNode:
3289             mml_node = new QwtMmlMphantomNode( this, mml_attr );
3290             break;
3291         case MfencedNode:
3292             mml_node = new QwtMmlMfencedNode( this, mml_attr );
3293             break;
3294         case MtableNode:
3295             mml_node = new QwtMmlMtableNode( this, mml_attr );
3296             break;
3297         case MtrNode:
3298             mml_node = new QwtMmlMtrNode( this, mml_attr );
3299             break;
3300         case MtdNode:
3301             mml_node = new QwtMmlMtdNode( this, mml_attr );
3302             break;
3303         case MoverNode:
3304             mml_node = new QwtMmlMoverNode( this, mml_attr );
3305             break;
3306         case MunderNode:
3307             mml_node = new QwtMmlMunderNode( this, mml_attr );
3308             break;
3309         case MunderoverNode:
3310             mml_node = new QwtMmlMunderoverNode( this, mml_attr );
3311             break;
3312         case MalignMarkNode:
3313             mml_node = new QwtMmlMalignMarkNode( this );
3314             break;
3315         case MerrorNode:
3316             mml_node = new QwtMmlMerrorNode( this, mml_attr );
3317             break;
3318         case MtextNode:
3319             mml_node = new QwtMmlMtextNode( this, mml_attr );
3320             break;
3321         case MpaddedNode:
3322             mml_node = new QwtMmlMpaddedNode( this, mml_attr );
3323             break;
3324         case MspaceNode:
3325             mml_node = new QwtMmlMspaceNode( this, mml_attr );
3326             break;
3327         case UnknownNode:
3328             mml_node = new QwtMmlUnknownNode( this, mml_attr );
3329             break;
3330         case NoNode:
3331             mml_node = 0;
3332             break;
3333     }
3334 
3335     return mml_node;
3336 }
3337 
insertOperator(QwtMmlNode * node,const QString & text)3338 void QwtMmlDocument::insertOperator( QwtMmlNode *node, const QString &text )
3339 {
3340     QwtMmlNode *text_node = createNode( TextNode, QwtMmlAttributeMap(), text, 0 );
3341     QwtMmlNode *mo_node = createNode( MoNode, QwtMmlAttributeMap(), QString(), 0 );
3342 
3343     bool ok = insertChild( node, mo_node, 0 );
3344     Q_ASSERT( ok );
3345     ok = insertChild( mo_node, text_node, 0 );
3346     Q_ASSERT( ok );
3347 }
3348 
domToMml(const QDomNode & dom_node,bool * ok,QString * errorMsg)3349 QwtMmlNode *QwtMmlDocument::domToMml( const QDomNode &dom_node, bool *ok, QString *errorMsg )
3350 {
3351     // create the node
3352 
3353     Q_ASSERT( ok != 0 );
3354 
3355     NodeType mml_type = domToQwtMmlNodeType( dom_node );
3356 
3357     if ( mml_type == NoNode )
3358     {
3359         *ok = true;
3360         return 0;
3361     }
3362 
3363     QDomNamedNodeMap dom_attr = dom_node.attributes();
3364     QwtMmlAttributeMap mml_attr;
3365     for ( int i = 0; i < dom_attr.length(); ++i )
3366     {
3367         QDomNode attr_node = dom_attr.item( i );
3368         Q_ASSERT( !attr_node.nodeName().isNull() );
3369         Q_ASSERT( !attr_node.nodeValue().isNull() );
3370         mml_attr[attr_node.nodeName()] = attr_node.nodeValue();
3371     }
3372 
3373     QString mml_value;
3374     if ( mml_type == TextNode )
3375         mml_value = dom_node.nodeValue();
3376     QwtMmlNode *mml_node = createNode( mml_type, mml_attr, mml_value, errorMsg );
3377     if ( mml_node == 0 )
3378     {
3379         *ok = false;
3380         return 0;
3381     }
3382 
3383     // create the node's children according to the child_spec
3384 
3385     const QwtMmlNodeSpec *spec = mmlFindNodeSpec( mml_type );
3386     QDomNodeList dom_child_list = dom_node.childNodes();
3387     int child_cnt = dom_child_list.count();
3388     QwtMmlNode *mml_child = 0;
3389 
3390     QString separator_list;
3391     if ( mml_type == MfencedNode )
3392         separator_list = mml_node->explicitAttribute( "separators", "," );
3393 
3394     switch ( spec->child_spec )
3395     {
3396         case QwtMmlNodeSpec::ChildIgnore:
3397             break;
3398 
3399         case QwtMmlNodeSpec::ImplicitMrow:
3400 
3401             if ( child_cnt > 0 )
3402             {
3403                 mml_child = createImplicitMrowNode( dom_node, ok, errorMsg );
3404                 if ( !*ok )
3405                 {
3406                     delete mml_node;
3407                     return 0;
3408                 }
3409 
3410                 if ( !insertChild( mml_node, mml_child, errorMsg ) )
3411                 {
3412                     delete mml_node;
3413                     delete mml_child;
3414                     *ok = false;
3415                     return 0;
3416                 }
3417             }
3418 
3419             break;
3420 
3421         default:
3422             // exact ammount of children specified - check...
3423             if ( spec->child_spec != child_cnt )
3424             {
3425                 if ( errorMsg != 0 )
3426                     *errorMsg = QString( "element " )
3427                                 + spec->tag
3428                                 + " requires exactly "
3429                                 + QString::number( spec->child_spec )
3430                                 + " arguments, got "
3431                                 + QString::number( child_cnt );
3432                 delete mml_node;
3433                 *ok = false;
3434                 return 0;
3435             }
3436 
3437             // ...and continue just as in ChildAny
3438 #ifdef Q_FALLTHROUGH
3439             Q_FALLTHROUGH();
3440 #endif
3441 
3442         case QwtMmlNodeSpec::ChildAny:
3443             if ( mml_type == MfencedNode )
3444                 insertOperator( mml_node, mml_node->explicitAttribute( "open", "(" ) );
3445 
3446             for ( int i = 0; i < child_cnt; ++i )
3447             {
3448                 QDomNode dom_child = dom_child_list.item( i );
3449 
3450                 QwtMmlNode *mml_child = domToMml( dom_child, ok, errorMsg );
3451                 if ( !*ok )
3452                 {
3453                     delete mml_node;
3454                     return 0;
3455                 }
3456 
3457                 if ( mml_type == MtableNode && mml_child->nodeType() != MtrNode )
3458                 {
3459                     QwtMmlNode *mtr_node = createNode( MtrNode, QwtMmlAttributeMap(), QString(), 0 );
3460                     insertChild( mml_node, mtr_node, 0 );
3461                     if ( !insertChild( mtr_node, mml_child, errorMsg ) )
3462                     {
3463                         delete mml_node;
3464                         delete mml_child;
3465                         *ok = false;
3466                         return 0;
3467                     }
3468                 }
3469                 else if ( mml_type == MtrNode && mml_child->nodeType() != MtdNode )
3470                 {
3471                     QwtMmlNode *mtd_node = createNode( MtdNode, QwtMmlAttributeMap(), QString(), 0 );
3472                     insertChild( mml_node, mtd_node, 0 );
3473                     if ( !insertChild( mtd_node, mml_child, errorMsg ) )
3474                     {
3475                         delete mml_node;
3476                         delete mml_child;
3477                         *ok = false;
3478                         return 0;
3479                     }
3480                 }
3481                 else
3482                 {
3483                     if ( !insertChild( mml_node, mml_child, errorMsg ) )
3484                     {
3485                         delete mml_node;
3486                         delete mml_child;
3487                         *ok = false;
3488                         return 0;
3489                     }
3490                 }
3491 
3492                 if ( i < child_cnt - 1 && mml_type == MfencedNode && !separator_list.isEmpty() )
3493                 {
3494                     QChar separator;
3495                     if ( i >= ( int )separator_list.length() )
3496                         separator = separator_list.at( separator_list.length() - 1 );
3497                     else
3498                         separator = separator_list[i];
3499                     insertOperator( mml_node, QString( separator ) );
3500                 }
3501             }
3502 
3503             if ( mml_type == MfencedNode )
3504                 insertOperator( mml_node, mml_node->explicitAttribute( "close", ")" ) );
3505 
3506             break;
3507     }
3508 
3509     *ok = true;
3510     return mml_node;
3511 }
3512 
createImplicitMrowNode(const QDomNode & dom_node,bool * ok,QString * errorMsg)3513 QwtMmlNode *QwtMmlDocument::createImplicitMrowNode( const QDomNode &dom_node, bool *ok,
3514         QString *errorMsg )
3515 {
3516     QDomNodeList dom_child_list = dom_node.childNodes();
3517     int child_cnt = dom_child_list.count();
3518 
3519     if ( child_cnt == 0 )
3520     {
3521         *ok = true;
3522         return 0;
3523     }
3524 
3525     if ( child_cnt == 1 )
3526         return domToMml( dom_child_list.item( 0 ), ok, errorMsg );
3527 
3528     QwtMmlNode *mml_node = createNode( MrowNode, QwtMmlAttributeMap(),
3529                                     QString(), errorMsg );
3530     Q_ASSERT( mml_node != 0 ); // there is no reason in heaven or hell for this to fail
3531 
3532     for ( int i = 0; i < child_cnt; ++i )
3533     {
3534         QDomNode dom_child = dom_child_list.item( i );
3535 
3536         QwtMmlNode *mml_child = domToMml( dom_child, ok, errorMsg );
3537         if ( !*ok )
3538         {
3539             delete mml_node;
3540             return 0;
3541         }
3542 
3543         if ( !insertChild( mml_node, mml_child, errorMsg ) )
3544         {
3545             delete mml_node;
3546             delete mml_child;
3547             *ok = false;
3548             return 0;
3549         }
3550     }
3551 
3552     return mml_node;
3553 }
3554 
paint(QPainter * p,const QPoint & pos) const3555 void QwtMmlDocument::paint( QPainter *p, const QPoint &pos ) const
3556 {
3557     if ( m_root_node == 0 )
3558         return;
3559 
3560     /*    p->save();
3561         p->setPen(Qt::blue);
3562         p->drawLine(pos.x() - 5, pos.y(), pos.x() + 5, pos.y());
3563         p->drawLine(pos.x(), pos.y() - 5, pos.x(), pos.y() + 5);
3564         p->restore(); */
3565 
3566     QRect mr = m_root_node->myRect();
3567     m_root_node->setRelOrigin( pos - mr.topLeft() );
3568     m_root_node->paint( p );
3569 }
3570 
size() const3571 QSize QwtMmlDocument::size() const
3572 {
3573     if ( m_root_node == 0 )
3574         return QSize( 0, 0 );
3575     return m_root_node->deviceRect().size();
3576 }
3577 
3578 
3579 
3580 
3581 // *******************************************************************
3582 // QwtMmlNode
3583 // *******************************************************************
3584 
3585 
QwtMmlNode(NodeType type,QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)3586 QwtMmlNode::QwtMmlNode( NodeType type, QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
3587 {
3588     m_parent = 0;
3589     m_first_child = 0;
3590     m_next_sibling = 0;
3591     m_previous_sibling = 0;
3592 
3593     m_node_type = type;
3594     m_document = document;
3595     m_attribute_map = attribute_map;
3596 
3597     m_my_rect = m_parent_rect = QRect( 0, 0, 0, 0 );
3598     m_rel_origin = QPoint( 0, 0 );
3599     m_stretched = false;
3600 }
3601 
~QwtMmlNode()3602 QwtMmlNode::~QwtMmlNode()
3603 {
3604     QwtMmlNode *n = firstChild();
3605     while ( n != 0 )
3606     {
3607         QwtMmlNode *tmp = n->nextSibling();
3608         delete n;
3609         n = tmp;
3610     }
3611 }
3612 
rectToStr(const QRect & rect)3613 static QString rectToStr( const QRect &rect )
3614 {
3615     return QString( "[(%1, %2), %3x%4]" )
3616            .arg( rect.x() )
3617            .arg( rect.y() )
3618            .arg( rect.width() )
3619            .arg( rect.height() );
3620 }
3621 
toStr() const3622 QString QwtMmlNode::toStr() const
3623 {
3624     const QwtMmlNodeSpec *spec = mmlFindNodeSpec( nodeType() );
3625     Q_ASSERT( spec != 0 );
3626 
3627     return QString( "%1 %2 mr=%3 pr=%4 dr=%5 ro=(%7, %8) str=%9" )
3628            .arg( spec->type_str )
3629            .arg( ( quintptr )this, 0, 16 )
3630            .arg( rectToStr( myRect() ) )
3631            .arg( rectToStr( parentRect() ) )
3632            .arg( rectToStr( deviceRect() ) )
3633            .arg( m_rel_origin.x() )
3634            .arg( m_rel_origin.y() )
3635            .arg( ( int )isStretched() );
3636 }
3637 
interpretSpacing(const QString & value,bool * ok) const3638 int QwtMmlNode::interpretSpacing( const QString &value, bool *ok ) const
3639 {
3640     return ::interpretSpacing( value, em(), ex(), ok );
3641 }
3642 
basePos() const3643 int QwtMmlNode::basePos() const
3644 {
3645     QFontMetrics fm( font() );
3646     return fm.strikeOutPos();
3647 }
3648 
underlinePos() const3649 int QwtMmlNode::underlinePos() const
3650 {
3651     QFontMetrics fm( font() );
3652     return basePos() + fm.underlinePos();
3653 }
overlinePos() const3654 int QwtMmlNode::overlinePos() const
3655 {
3656     QFontMetrics fm( font() );
3657     return basePos() - fm.overlinePos();
3658 }
3659 
lastSibling() const3660 QwtMmlNode *QwtMmlNode::lastSibling() const
3661 {
3662     const QwtMmlNode *n = this;
3663     while ( !n->isLastSibling() )
3664         n = n->nextSibling();
3665     return const_cast<QwtMmlNode*>( n );
3666 }
3667 
firstSibling() const3668 QwtMmlNode *QwtMmlNode::firstSibling() const
3669 {
3670     const QwtMmlNode *n = this;
3671     while ( !n->isFirstSibling() )
3672         n = n->previousSibling();
3673     return const_cast<QwtMmlNode*>( n );
3674 }
3675 
em() const3676 int QwtMmlNode::em() const
3677 {
3678     return QFontMetrics( font() ).boundingRect( 'm' ).width();
3679 }
3680 
ex() const3681 int QwtMmlNode::ex() const
3682 {
3683     return QFontMetrics( font() ).boundingRect( 'x' ).height();
3684 }
3685 
scriptlevel(const QwtMmlNode *) const3686 int QwtMmlNode::scriptlevel( const QwtMmlNode * ) const
3687 {
3688     int parent_sl;
3689     const QwtMmlNode *p = parent();
3690     if ( p == 0 )
3691         parent_sl = 0;
3692     else
3693         parent_sl = p->scriptlevel( this );
3694 
3695     QString expl_sl_str = explicitAttribute( "scriptlevel" );
3696     if ( expl_sl_str.isNull() )
3697         return parent_sl;
3698 
3699     if ( expl_sl_str.startsWith( "+" ) || expl_sl_str.startsWith( "-" ) )
3700     {
3701         bool ok;
3702         int expl_sl = expl_sl_str.toInt( &ok );
3703         if ( ok )
3704         {
3705             return parent_sl + expl_sl;
3706         }
3707         else
3708         {
3709             qWarning() << "QwtMmlNode::scriptlevel(): bad value " + expl_sl_str;
3710             return parent_sl;
3711         }
3712     }
3713 
3714     bool ok;
3715     int expl_sl = expl_sl_str.toInt( &ok );
3716     if ( ok )
3717         return expl_sl;
3718 
3719 
3720     if ( expl_sl_str == "+" )
3721         return parent_sl + 1;
3722     else if ( expl_sl_str == "-" )
3723         return parent_sl - 1;
3724     else
3725     {
3726         qWarning() << "QwtMmlNode::scriptlevel(): could not parse value: \"" + expl_sl_str + "\"";
3727         return parent_sl;
3728     }
3729 }
3730 
devicePoint(const QPoint & p) const3731 QPoint QwtMmlNode::devicePoint( const QPoint &p ) const
3732 {
3733     QRect mr = myRect();
3734     QRect dr = deviceRect();
3735 
3736     if ( isStretched() )
3737         return dr.topLeft() + QPoint( ( p.x() - mr.left() ) * dr.width() / mr.width(),
3738                                       ( p.y() - mr.top() ) * dr.height() / mr.height() );
3739     else
3740         return dr.topLeft() + p - mr.topLeft();
3741 }
3742 
inheritAttributeFromMrow(const QString & name,const QString & def) const3743 QString QwtMmlNode::inheritAttributeFromMrow( const QString &name,
3744         const QString &def ) const
3745 {
3746     const QwtMmlNode *p = this;
3747     for ( ; p != 0; p = p->parent() )
3748     {
3749         if ( p == this || p->nodeType() == MstyleNode )
3750         {
3751             QString value = p->explicitAttribute( name );
3752             if ( !value.isNull() )
3753                 return value;
3754         }
3755     }
3756 
3757     return def;
3758 }
3759 
color() const3760 QColor QwtMmlNode::color() const
3761 {
3762     // If we are child of <merror> return red
3763     const QwtMmlNode *p = this;
3764     for ( ; p != 0; p = p->parent() )
3765     {
3766         if ( p->nodeType() == MerrorNode )
3767             return QColor( "red" );
3768     }
3769 
3770     QString value_str = inheritAttributeFromMrow( "mathcolor" );
3771     if ( value_str.isNull() )
3772         value_str = inheritAttributeFromMrow( "color" );
3773     if ( value_str.isNull() )
3774         return QColor();
3775 
3776     return QColor( value_str );
3777 }
3778 
background() const3779 QColor QwtMmlNode::background() const
3780 {
3781     QString value_str = inheritAttributeFromMrow( "mathbackground" );
3782     if ( value_str.isNull() )
3783         value_str = inheritAttributeFromMrow( "background" );
3784     if ( value_str.isNull() )
3785         return QColor();
3786 
3787     return QColor( value_str );
3788 }
3789 
updateFontAttr(QwtMmlAttributeMap & font_attr,const QwtMmlNode * n,const QString & name,const QString & preferred_name=QString ())3790 static void updateFontAttr( QwtMmlAttributeMap &font_attr, const QwtMmlNode *n,
3791                             const QString &name, const QString &preferred_name = QString() )
3792 {
3793     if ( font_attr.contains( preferred_name ) || font_attr.contains( name ) )
3794         return;
3795     QString value = n->explicitAttribute( name );
3796     if ( !value.isNull() )
3797         font_attr[name] = value;
3798 }
3799 
collectFontAttributes(const QwtMmlNode * node)3800 static QwtMmlAttributeMap collectFontAttributes( const QwtMmlNode *node )
3801 {
3802     QwtMmlAttributeMap font_attr;
3803 
3804     for ( const QwtMmlNode *n = node; n != 0; n = n->parent() )
3805     {
3806         if ( n == node || n->nodeType() == QwtMml::MstyleNode )
3807         {
3808             updateFontAttr( font_attr, n, "mathvariant" );
3809             updateFontAttr( font_attr, n, "mathsize" );
3810 
3811             // depreciated attributes
3812             updateFontAttr( font_attr, n, "fontsize", "mathsize" );
3813             updateFontAttr( font_attr, n, "fontweight", "mathvariant" );
3814             updateFontAttr( font_attr, n, "fontstyle", "mathvariant" );
3815             updateFontAttr( font_attr, n, "fontfamily", "mathvariant" );
3816         }
3817     }
3818 
3819     return font_attr;
3820 }
3821 
font() const3822 QFont QwtMmlNode::font() const
3823 {
3824     QFont fn( document()->fontName( QwtMathMLDocument::NormalFont ),
3825               document()->baseFontPointSize() );
3826 
3827     int ps = fn.pointSize();
3828     int sl = scriptlevel();
3829     if ( sl >= 0 )
3830     {
3831         for ( int i = 0; i < sl; ++i )
3832             ps = ( int )( ps * g_script_size_multiplier );
3833     }
3834     else
3835     {
3836         for ( int i = 0; i > sl; --i )
3837             ps = ( int )( ps / g_script_size_multiplier );
3838     }
3839     if ( ps < g_min_font_point_size )
3840         ps = g_min_font_point_size;
3841     fn.setPointSize( ps );
3842 
3843     int em = QFontMetrics( fn ).boundingRect( 'm' ).width();
3844     int ex = QFontMetrics( fn ).boundingRect( 'x' ).height();
3845 
3846     QwtMmlAttributeMap font_attr = collectFontAttributes( this );
3847 
3848     if ( font_attr.contains( "mathvariant" ) )
3849     {
3850         QString value = font_attr["mathvariant"];
3851 
3852         bool ok;
3853         uint mv = interpretMathVariant( value, &ok );
3854 
3855         if ( ok )
3856         {
3857             if ( mv & ScriptMV )
3858                 fn.setFamily( document()->fontName( QwtMathMLDocument::ScriptFont ) );
3859 
3860             if ( mv & FrakturMV )
3861                 fn.setFamily( document()->fontName( QwtMathMLDocument::FrakturFont ) );
3862 
3863             if ( mv & SansSerifMV )
3864                 fn.setFamily( document()->fontName( QwtMathMLDocument::SansSerifFont ) );
3865 
3866             if ( mv & MonospaceMV )
3867                 fn.setFamily( document()->fontName( QwtMathMLDocument::MonospaceFont ) );
3868 
3869             if ( mv & DoubleStruckMV )
3870                 fn.setFamily( document()->fontName( QwtMathMLDocument::DoublestruckFont ) );
3871 
3872             if ( mv & BoldMV )
3873                 fn.setBold( true );
3874 
3875             if ( mv & ItalicMV )
3876                 fn.setItalic( true );
3877         }
3878     }
3879 
3880     if ( font_attr.contains( "mathsize" ) )
3881     {
3882         QString value = font_attr["mathsize"];
3883         fn = interpretMathSize( value, fn, em, ex, 0 );
3884     }
3885 
3886     fn = interpretDepreciatedFontAttr( font_attr, fn, em, ex );
3887 
3888     if ( nodeType() == MiNode
3889             && !font_attr.contains( "mathvariant" )
3890             && !font_attr.contains( "fontstyle" ) )
3891     {
3892         const QwtMmlMiNode *mi_node = ( const QwtMmlMiNode* ) this;
3893         if ( mi_node->text().length() == 1 )
3894             fn.setItalic( true );
3895     }
3896 
3897     if ( nodeType() == MoNode )
3898     {
3899         fn.setItalic( false );
3900         fn.setBold( false );
3901     }
3902 
3903     return fn;
3904 }
3905 
explicitAttribute(const QString & name,const QString & def) const3906 QString QwtMmlNode::explicitAttribute( const QString &name, const QString &def ) const
3907 {
3908     QwtMmlAttributeMap::const_iterator it = m_attribute_map.find( name );
3909     if ( it != m_attribute_map.end() )
3910         return *it;
3911     return def;
3912 }
3913 
3914 
parentRect() const3915 QRect QwtMmlNode::parentRect() const
3916 {
3917     if ( isStretched() )
3918         return m_parent_rect;
3919 
3920     QRect mr = myRect();
3921     QPoint ro = relOrigin();
3922 
3923     return QRect( ro + mr.topLeft(), mr.size() );
3924 }
3925 
3926 
stretchTo(const QRect & rect)3927 void QwtMmlNode::stretchTo( const QRect &rect )
3928 {
3929     m_parent_rect = rect;
3930     m_stretched = true;
3931 }
3932 
setRelOrigin(const QPoint & rel_origin)3933 void QwtMmlNode::setRelOrigin( const QPoint &rel_origin )
3934 {
3935     m_rel_origin = rel_origin + QPoint( -myRect().left(), 0 );
3936     m_stretched = false;
3937 }
3938 
updateMyRect()3939 void QwtMmlNode::updateMyRect()
3940 {
3941     m_my_rect = symbolRect();
3942     QwtMmlNode *child = firstChild();
3943     for ( ; child != 0; child = child->nextSibling() )
3944         m_my_rect |= child->parentRect();
3945 }
3946 
layout()3947 void QwtMmlNode::layout()
3948 {
3949     m_parent_rect = QRect( 0, 0, 0, 0 );
3950     m_stretched = false;
3951     m_rel_origin = QPoint( 0, 0 );
3952 
3953     QwtMmlNode *child = firstChild();
3954     for ( ; child != 0; child = child->nextSibling() )
3955         child->layout();
3956 
3957     layoutSymbol();
3958 
3959     updateMyRect();
3960 
3961     if ( parent() == 0 )
3962         m_rel_origin = QPoint( 0, 0 );
3963 }
3964 
3965 
deviceRect() const3966 QRect QwtMmlNode::deviceRect() const
3967 {
3968     if ( parent() == 0 )
3969         return QRect( relOrigin() + myRect().topLeft(), myRect().size() );
3970 
3971     /*    if (!isStretched()) {
3972         QRect pdr = parent()->deviceRect();
3973         QRect pmr = parent()->myRect();
3974         QRect pr = parentRect();
3975         QRect mr = myRect();
3976         return QRect(pdr.left() + pr.left() - pmr.left(),
3977                 pdr.top()  + pr.top() - pmr.top(),
3978                 mr.width(), mr.height());
3979         }
3980     */
3981     QRect pdr = parent()->deviceRect();
3982     QRect pr = parentRect();
3983     QRect pmr = parent()->myRect();
3984 
3985     float scale_w = 0;
3986     if ( pmr.width() != 0 )
3987         scale_w = ( float )pdr.width() / pmr.width();
3988     float scale_h = 0;
3989     if ( pmr.height() != 0 )
3990         scale_h = ( float )pdr.height() / pmr.height();
3991 
3992     return QRect( pdr.left() + ROUND( ( pr.left() - pmr.left() ) * scale_w ),
3993                   pdr.top()  + ROUND( ( pr.top() - pmr.top() ) * scale_h ),
3994                   ROUND( ( pr.width() * scale_w ) ),
3995                   ROUND( ( pr.height() * scale_h ) ) );
3996 }
3997 
layoutSymbol()3998 void QwtMmlNode::layoutSymbol()
3999 {
4000     // default behaves like an mrow
4001 
4002     // now lay them out in a neat row, aligning their origins to my origin
4003     int w = 0;
4004     QwtMmlNode *child = firstChild();
4005     for ( ; child != 0; child = child->nextSibling() )
4006     {
4007         child->setRelOrigin( QPoint( w, 0 ) );
4008         w += child->parentRect().width() + 1;
4009     }
4010 }
4011 
paint(QPainter * p)4012 void QwtMmlNode::paint( QPainter *p )
4013 {
4014     if ( !myRect().isValid() )
4015         return;
4016     p->save();
4017 
4018     QColor fg = color();
4019     QColor bg = background();
4020     if ( bg.isValid() )
4021         p->fillRect( myRect(), bg );
4022     if ( fg.isValid() )
4023         p->setPen( QPen( color(), 0 ) );
4024 
4025     QwtMmlNode *child = firstChild();
4026     for ( ; child != 0; child = child->nextSibling() )
4027         child->paint( p );
4028 
4029     paintSymbol( p );
4030 
4031     p->restore();
4032 }
4033 
paintSymbol(QPainter * p) const4034 void QwtMmlNode::paintSymbol( QPainter *p ) const
4035 {
4036     if ( g_draw_frames && myRect().isValid() )
4037     {
4038         p->save();
4039         p->setPen( QPen( Qt::red, 0 ) );
4040         p->drawRect( m_my_rect );
4041         QPen pen = p->pen();
4042         pen.setStyle( Qt::DotLine );
4043         p->setPen( pen );
4044         p->drawLine( myRect().left(), 0, myRect().right(), 0 );
4045         p->restore();
4046     }
4047 }
4048 
stretch()4049 void QwtMmlNode::stretch()
4050 {
4051     QwtMmlNode *child = firstChild();
4052     for ( ; child != 0; child = child->nextSibling() )
4053         child->stretch();
4054 }
4055 
text() const4056 QString QwtMmlTokenNode::text() const
4057 {
4058     QString result;
4059 
4060     const QwtMmlNode *child = firstChild();
4061     for ( ; child != 0; child = child->nextSibling() )
4062     {
4063         if ( child->nodeType() != TextNode ) continue;
4064         if ( !result.isEmpty() )
4065             result += ' ';
4066         result += static_cast<const QwtMmlTextNode *>( child )->text();
4067     }
4068 
4069     return result;
4070 }
4071 
numerator() const4072 QwtMmlNode *QwtMmlMfracNode::numerator() const
4073 {
4074     QwtMmlNode *node = firstChild();
4075     Q_ASSERT( node != 0 );
4076     return node;
4077 }
4078 
denominator() const4079 QwtMmlNode *QwtMmlMfracNode::denominator() const
4080 {
4081     QwtMmlNode *node = numerator()->nextSibling();
4082     Q_ASSERT( node != 0 );
4083     return node;
4084 }
4085 
symbolRect() const4086 QRect QwtMmlMfracNode::symbolRect() const
4087 {
4088     int num_width = numerator()->myRect().width();
4089     int denom_width = denominator()->myRect().width();
4090     int my_width = qMax( num_width, denom_width ) + 4;
4091 
4092     return QRect( -my_width / 2, 0, my_width, 1 );
4093 }
4094 
layoutSymbol()4095 void QwtMmlMfracNode::layoutSymbol()
4096 {
4097     QwtMmlNode *num = numerator();
4098     QwtMmlNode *denom = denominator();
4099 
4100     QRect num_rect = num->myRect();
4101     QRect denom_rect = denom->myRect();
4102 
4103     int spacing = ( int )( g_mfrac_spacing * ( num_rect.height() + denom_rect.height() ) );
4104 
4105     num->setRelOrigin( QPoint( -num_rect.width() / 2, - spacing - num_rect.bottom() ) );
4106     denom->setRelOrigin( QPoint( -denom_rect.width() / 2, spacing - denom_rect.top() ) );
4107 }
4108 
zeroLineThickness(const QString & s)4109 static bool zeroLineThickness( const QString &s )
4110 {
4111     if ( s.length() == 0 || !s[0].isDigit() )
4112         return false;
4113 
4114     for ( int i = 0; i < s.length(); ++i )
4115     {
4116         QChar c = s.at( i );
4117         if ( c.isDigit() && c != '0' )
4118             return false;
4119     }
4120     return true;
4121 }
4122 
paintSymbol(QPainter * p) const4123 void QwtMmlMfracNode::paintSymbol( QPainter *p ) const
4124 {
4125     QString linethickness_str = inheritAttributeFromMrow( "linethickness", "1" );
4126 
4127     /* InterpretSpacing returns an int, which might be 0 even if the thickness
4128        is > 0, though very very small. That's ok, because the painter then paints
4129        a line of thickness 1. However, we have to run this check if the line
4130        thickness really is zero */
4131     if ( !zeroLineThickness( linethickness_str ) )
4132     {
4133         bool ok;
4134         int linethickness = interpretSpacing( linethickness_str, &ok );
4135         if ( !ok )
4136             linethickness = 1;
4137 
4138         p->save();
4139         QPen pen = p->pen();
4140         pen.setWidth( linethickness );
4141         p->setPen( pen );
4142         QSize s = myRect().size();
4143         p->drawLine( -s.width() / 2, 0, s.width() / 2, 0 );
4144         p->restore();
4145     }
4146 }
4147 
base() const4148 QwtMmlNode *QwtMmlRootBaseNode::base() const
4149 {
4150     QwtMmlNode *node = firstChild();
4151 //    Q_ASSERT(node != 0);
4152     return node;
4153 }
4154 
index() const4155 QwtMmlNode *QwtMmlRootBaseNode::index() const
4156 {
4157     QwtMmlNode *b = base();
4158     if ( b == 0 )
4159         return 0;
4160     return b->nextSibling();
4161 }
4162 
scriptlevel(const QwtMmlNode * child) const4163 int QwtMmlRootBaseNode::scriptlevel( const QwtMmlNode *child ) const
4164 {
4165     int sl = QwtMmlNode::scriptlevel();
4166 
4167     QwtMmlNode *i = index();
4168     if ( child != 0 && child == i )
4169         return sl + 1;
4170     else
4171         return sl;
4172 }
4173 
4174 
symbolRect() const4175 QRect QwtMmlRootBaseNode::symbolRect() const
4176 {
4177     QwtMmlNode *b = base();
4178     QRect base_rect;
4179     if ( b == 0 )
4180         base_rect = QRect( 0, 0, 1, 1 );
4181     else
4182         base_rect = base()->myRect();
4183 
4184     int margin = ( int )( g_mroot_base_margin * base_rect.height() );
4185     int tw = tailWidth();
4186 
4187     return QRect( -tw, base_rect.top() - margin, tw,
4188                   base_rect.height() + 2 * margin );
4189 }
4190 
tailWidth() const4191 int QwtMmlRootBaseNode::tailWidth() const
4192 {
4193     QFontMetrics fm( font() );
4194     return fm.boundingRect( g_radical_char ).width();
4195 }
4196 
layoutSymbol()4197 void QwtMmlRootBaseNode::layoutSymbol()
4198 {
4199     QwtMmlNode *b = base();
4200     QSize base_size;
4201     if ( b != 0 )
4202     {
4203         b->setRelOrigin( QPoint( 0, 0 ) );
4204         base_size = base()->myRect().size();
4205     }
4206     else
4207         base_size = QSize( 1, 1 );
4208 
4209     QwtMmlNode *i = index();
4210     if ( i != 0 )
4211     {
4212         int tw = tailWidth();
4213 
4214         QRect i_rect = i->myRect();
4215         i->setRelOrigin( QPoint( -tw / 2 - i_rect.width(),
4216                                  -i_rect.bottom() - 4 ) );
4217     }
4218 }
4219 
paintSymbol(QPainter * p) const4220 void QwtMmlRootBaseNode::paintSymbol( QPainter *p ) const
4221 {
4222     QFont fn = font();
4223 
4224     p->save();
4225 
4226     QRect sr = symbolRect();
4227 
4228     QRect r = sr;
4229     r.moveTopLeft( devicePoint( sr.topLeft() ) );
4230     p->setViewport( r );
4231     p->setWindow( QFontMetrics( fn ).boundingRect( g_radical_char ) );
4232     p->setFont( font() );
4233     p->drawText( 0, 0, QString( g_radical_char ) );
4234 
4235     p->restore();
4236 
4237     p->drawLine( sr.right(), sr.top(), myRect().right(), sr.top() );
4238 }
4239 
QwtMmlTextNode(const QString & text,QwtMmlDocument * document)4240 QwtMmlTextNode::QwtMmlTextNode( const QString &text, QwtMmlDocument *document )
4241     : QwtMmlNode( TextNode, document, QwtMmlAttributeMap() )
4242 {
4243     m_text = text;
4244     // Trim whitespace from ends, but keep nbsp and thinsp
4245     m_text.remove( QRegExp( "^[^\\S\\x00a0\\x2009]+" ) );
4246     m_text.remove( QRegExp( "[^\\S\\x00a0\\x2009]+$" ) );
4247 
4248     if ( m_text == QString( QChar( 0x62, 0x20 ) )    // &InvisibleTimes;
4249             || m_text == QString( QChar( 0x63, 0x20 ) ) // &InvisibleComma;
4250             || m_text == QString( QChar( 0x61, 0x20 ) ) ) // &ApplyFunction;
4251         m_text = "";
4252 }
4253 
toStr() const4254 QString QwtMmlTextNode::toStr() const
4255 {
4256     return QwtMmlNode::toStr() + ", text=\"" + m_text + "\"";
4257 }
4258 
paintSymbol(QPainter * p) const4259 void QwtMmlTextNode::paintSymbol( QPainter *p ) const
4260 {
4261     QwtMmlNode::paintSymbol( p );
4262 
4263     QFont fn = font();
4264 
4265     QFontInfo fi( fn );
4266 //    qWarning("MmlTextNode::paintSymbol(): requested: %s, used: %s, size=%d, italic=%d, bold=%d, text=\"%s\" sl=%d",
4267 //              fn.family().latin1(), fi.family().latin1(), fi.pointSize(), (int)fi.italic(), (int)fi.bold(), m_text.latin1(), scriptlevel());
4268 
4269     QFontMetrics fm( fn );
4270 
4271     p->save();
4272     p->setFont( fn );
4273 
4274     QPoint dPos = devicePoint( relOrigin() );
4275     p->drawText( dPos.x(), dPos.y() + fm.strikeOutPos(), m_text );
4276 
4277     p->restore();
4278 }
4279 
symbolRect() const4280 QRect QwtMmlTextNode::symbolRect() const
4281 {
4282     QFontMetrics fm( font() );
4283 
4284     QRect br = fm.tightBoundingRect( m_text );
4285     br.translate( 0, fm.strikeOutPos() );
4286 
4287     return br;
4288 }
4289 
base() const4290 QwtMmlNode *QwtMmlSubsupBaseNode::base() const
4291 {
4292     QwtMmlNode *b = firstChild();
4293     Q_ASSERT( b != 0 );
4294     return b;
4295 }
4296 
sscript() const4297 QwtMmlNode *QwtMmlSubsupBaseNode::sscript() const
4298 {
4299     QwtMmlNode *s = base()->nextSibling();
4300     Q_ASSERT( s != 0 );
4301     return s;
4302 }
4303 
scriptlevel(const QwtMmlNode * child) const4304 int QwtMmlSubsupBaseNode::scriptlevel( const QwtMmlNode *child ) const
4305 {
4306     int sl = QwtMmlNode::scriptlevel();
4307 
4308     QwtMmlNode *s = sscript();
4309     if ( child != 0 && child == s )
4310         return sl + 1;
4311     else
4312         return sl;
4313 }
4314 
layoutSymbol()4315 void QwtMmlMsupNode::layoutSymbol()
4316 {
4317     QwtMmlNode *b = base();
4318     QwtMmlNode *s = sscript();
4319 
4320     b->setRelOrigin( QPoint( -b->myRect().width(), 0 ) );
4321     s->setRelOrigin( QPoint( 0, b->myRect().top() ) );
4322 }
4323 
layoutSymbol()4324 void QwtMmlMsubNode::layoutSymbol()
4325 {
4326     QwtMmlNode *b = base();
4327     QwtMmlNode *s = sscript();
4328 
4329     b->setRelOrigin( QPoint( -b->myRect().width(), 0 ) );
4330     s->setRelOrigin( QPoint( 0, b->myRect().bottom() ) );
4331 }
4332 
base() const4333 QwtMmlNode *QwtMmlMsubsupNode::base() const
4334 {
4335     QwtMmlNode *b = firstChild();
4336     Q_ASSERT( b != 0 );
4337     return b;
4338 }
4339 
subscript() const4340 QwtMmlNode *QwtMmlMsubsupNode::subscript() const
4341 {
4342     QwtMmlNode *sub = base()->nextSibling();
4343     Q_ASSERT( sub != 0 );
4344     return sub;
4345 }
4346 
superscript() const4347 QwtMmlNode *QwtMmlMsubsupNode::superscript() const
4348 {
4349     QwtMmlNode *sup = subscript()->nextSibling();
4350     Q_ASSERT( sup != 0 );
4351     return sup;
4352 }
4353 
layoutSymbol()4354 void QwtMmlMsubsupNode::layoutSymbol()
4355 {
4356     QwtMmlNode *b = base();
4357     QwtMmlNode *sub = subscript();
4358     QwtMmlNode *sup = superscript();
4359 
4360     b->setRelOrigin( QPoint( -b->myRect().width(), 0 ) );
4361     sub->setRelOrigin( QPoint( 0, b->myRect().bottom() ) );
4362     sup->setRelOrigin( QPoint( 0, b->myRect().top() ) );
4363 }
4364 
scriptlevel(const QwtMmlNode * child) const4365 int QwtMmlMsubsupNode::scriptlevel( const QwtMmlNode *child ) const
4366 {
4367     int sl = QwtMmlNode::scriptlevel();
4368 
4369     QwtMmlNode *sub = subscript();
4370     QwtMmlNode *sup = superscript();
4371 
4372     if ( child != 0 && ( child == sup || child == sub ) )
4373         return sl + 1;
4374     else
4375         return sl;
4376 }
4377 
toStr() const4378 QString QwtMmlMoNode::toStr() const
4379 {
4380     return QwtMmlNode::toStr() + QString( " form=%1" ).arg( ( int )form() );
4381 }
4382 
layoutSymbol()4383 void QwtMmlMoNode::layoutSymbol()
4384 {
4385     QwtMmlNode *child = firstChild();
4386     if ( child == 0 )
4387         return;
4388 
4389     child->setRelOrigin( QPoint( 0, 0 ) );
4390 
4391     if ( m_oper_spec == 0 )
4392         m_oper_spec = mmlFindOperSpec( text(), form() );
4393 }
4394 
QwtMmlMoNode(QwtMmlDocument * document,const QwtMmlAttributeMap & attribute_map)4395 QwtMmlMoNode::QwtMmlMoNode( QwtMmlDocument *document, const QwtMmlAttributeMap &attribute_map )
4396     : QwtMmlTokenNode( MoNode, document, attribute_map )
4397 {
4398     m_oper_spec = 0;
4399 }
4400 
dictionaryAttribute(const QString & name) const4401 QString QwtMmlMoNode::dictionaryAttribute( const QString &name ) const
4402 {
4403     const QwtMmlNode *p = this;
4404     for ( ; p != 0; p = p->parent() )
4405     {
4406         if ( p == this || p->nodeType() == MstyleNode )
4407         {
4408             QString expl_attr = p->explicitAttribute( name );
4409             if ( !expl_attr.isNull() )
4410                 return expl_attr;
4411         }
4412     }
4413 
4414     return mmlDictAttribute( name, m_oper_spec );
4415 }
4416 
form() const4417 QwtMml::FormType QwtMmlMoNode::form() const
4418 {
4419     QString value_str = inheritAttributeFromMrow( "form" );
4420     if ( !value_str.isNull() )
4421     {
4422         bool ok;
4423         FormType value = interpretForm( value_str, &ok );
4424         if ( ok )
4425             return value;
4426         else
4427             qWarning( "Could not convert %s to form", value_str.toLatin1().data() );
4428 
4429     }
4430 
4431     // Default heuristic.
4432     if ( firstSibling() == ( QwtMmlNode* )this && lastSibling() != ( QwtMmlNode* )this )
4433         return PrefixForm;
4434     else if ( lastSibling() == ( QwtMmlNode* )this && firstSibling() != ( QwtMmlNode* )this )
4435         return PostfixForm;
4436     else return InfixForm;
4437 
4438 }
4439 
stretch()4440 void QwtMmlMoNode::stretch()
4441 {
4442     if ( parent() == 0 )
4443         return;
4444 
4445     if ( m_oper_spec == 0 )
4446         return;
4447 
4448     if ( m_oper_spec->stretch_dir == QwtMmlOperSpec::HStretch
4449             && parent()->nodeType() == MrowNode
4450             && ( nextSibling() != 0 || previousSibling() != 0 ) )
4451         return;
4452 
4453     QRect pmr = parent()->myRect();
4454     QRect pr = parentRect();
4455 
4456     switch ( m_oper_spec->stretch_dir )
4457     {
4458         case QwtMmlOperSpec::VStretch:
4459             stretchTo( QRect( pr.left(), pmr.top(), pr.width(), pmr.height() ) );
4460             break;
4461         case QwtMmlOperSpec::HStretch:
4462             stretchTo( QRect( pmr.left(), pr.top(), pmr.width(), pr.height() ) );
4463             break;
4464         case QwtMmlOperSpec::HVStretch:
4465             stretchTo( pmr );
4466             break;
4467         case QwtMmlOperSpec::NoStretch:
4468             break;
4469     }
4470 }
4471 
lspace() const4472 int QwtMmlMoNode::lspace() const
4473 {
4474     Q_ASSERT( m_oper_spec != 0 );
4475     if ( parent() == 0
4476             || ( parent()->nodeType() != MrowNode
4477                  && parent()->nodeType() != MfencedNode
4478                  && parent()->nodeType() != UnknownNode )
4479             || ( previousSibling() == 0 && nextSibling() == 0 ) )
4480         return 0;
4481     else
4482         return interpretSpacing( dictionaryAttribute( "lspace" ), 0 );
4483 }
4484 
rspace() const4485 int QwtMmlMoNode::rspace() const
4486 {
4487     Q_ASSERT( m_oper_spec != 0 );
4488     if ( parent() == 0
4489             || ( parent()->nodeType() != MrowNode
4490                  && parent()->nodeType() != MfencedNode
4491                  && parent()->nodeType() != UnknownNode )
4492             || ( previousSibling() == 0 && nextSibling() == 0 ) )
4493         return 0;
4494     else
4495         return interpretSpacing( dictionaryAttribute( "rspace" ), 0 );
4496 }
4497 
symbolRect() const4498 QRect QwtMmlMoNode::symbolRect() const
4499 {
4500     const QwtMmlNode *child = firstChild();
4501 
4502     if ( child == 0 )
4503         return QRect( 0, 0, 0, 0 );
4504 
4505     QRect cmr = child->myRect();
4506 
4507     return QRect( -lspace(), cmr.top(),
4508                   cmr.width() + lspace() + rspace(), cmr.height() );
4509 }
4510 
rowspacing() const4511 int QwtMmlMtableNode::rowspacing() const
4512 {
4513     QString value = explicitAttribute( "rowspacing" );
4514     if ( value.isNull() )
4515         return ex();
4516     bool ok;
4517     int r = interpretSpacing( value, &ok );
4518 
4519     if ( ok )
4520         return r;
4521     else
4522         return ex();
4523 }
4524 
columnspacing() const4525 int QwtMmlMtableNode::columnspacing() const
4526 {
4527     QString value = explicitAttribute( "columnspacing" );
4528     if ( value.isNull() )
4529         return ( int )( 0.8 * em() );
4530     bool ok;
4531     int r = interpretSpacing( value, &ok );
4532 
4533     if ( ok )
4534         return r;
4535     else
4536         return ( int )( 0.8 * em() );
4537 }
4538 
colWidthSum() const4539 uint QwtMmlMtableNode::CellSizeData::colWidthSum() const
4540 {
4541     uint w = 0;
4542     for ( int i = 0; i < col_widths.count(); ++i )
4543         w += col_widths[i];
4544     return w;
4545 }
4546 
rowHeightSum() const4547 uint QwtMmlMtableNode::CellSizeData::rowHeightSum() const
4548 {
4549     uint h = 0;
4550     for ( int i = 0; i < row_heights.count(); ++i )
4551         h += row_heights[i];
4552     return h;
4553 }
4554 
init(const QwtMmlNode * first_row)4555 void QwtMmlMtableNode::CellSizeData::init( const QwtMmlNode *first_row )
4556 {
4557     col_widths.clear();
4558     row_heights.clear();
4559 
4560     const QwtMmlNode *mtr = first_row;
4561     for ( ; mtr != 0; mtr = mtr->nextSibling() )
4562     {
4563 
4564         Q_ASSERT( mtr->nodeType() == MtrNode );
4565 
4566         int col_cnt = 0;
4567         const QwtMmlNode *mtd = mtr->firstChild();
4568         for ( ; mtd != 0; mtd = mtd->nextSibling(), ++col_cnt )
4569         {
4570 
4571             Q_ASSERT( mtd->nodeType() == MtdNode );
4572 
4573             QRect mtdmr = mtd->myRect();
4574 
4575             if ( col_cnt == col_widths.count() )
4576                 col_widths.append( mtdmr.width() );
4577             else
4578                 col_widths[col_cnt] = qMax( col_widths[col_cnt], mtdmr.width() );
4579         }
4580 
4581         row_heights.append( mtr->myRect().height() );
4582     }
4583 }
4584 
layoutSymbol()4585 void QwtMmlMtableNode::layoutSymbol()
4586 {
4587     // Obtain natural widths of columns
4588     m_cell_size_data.init( firstChild() );
4589 
4590     int col_spc = columnspacing();
4591     int row_spc = rowspacing();
4592     int frame_spc_hor = framespacing_hor();
4593     QString columnwidth_attr = explicitAttribute( "columnwidth", "auto" );
4594 
4595     // Is table width set by user? If so, set col_width_sum and never ever change it.
4596     int col_width_sum = m_cell_size_data.colWidthSum();
4597     bool width_set_by_user = false;
4598     QString width_str = explicitAttribute( "width", "auto" );
4599     if ( width_str != "auto" )
4600     {
4601         bool ok;
4602 
4603         int w = interpretSpacing( width_str, &ok );
4604         if ( ok )
4605         {
4606             col_width_sum = w
4607                             - col_spc * ( m_cell_size_data.numCols() - 1 )
4608                             - frame_spc_hor * 2;
4609             width_set_by_user = true;
4610         }
4611     }
4612 
4613     // Find out what kind of columns we are dealing with and set the widths of
4614     // statically sized columns.
4615     int fixed_width_sum = 0;          // sum of widths of statically sized set columns
4616     int auto_width_sum = 0;           // sum of natural widths of auto sized columns
4617     int relative_width_sum = 0;       // sum of natural widths of relatively sized columns
4618     double relative_fraction_sum = 0; // total fraction of width taken by relatively
4619     // sized columns
4620     int i;
4621     for ( i = 0; i < m_cell_size_data.numCols(); ++i )
4622     {
4623         QString value = interpretListAttr( columnwidth_attr, i, "auto" );
4624 
4625         // Is it an auto sized column?
4626         if ( value == "auto" || value == "fit" )
4627         {
4628             auto_width_sum += m_cell_size_data.col_widths[i];
4629             continue;
4630         }
4631 
4632         // Is it a statically sized column?
4633         bool ok;
4634         int w = interpretSpacing( value, &ok );
4635         if ( ok )
4636         {
4637             // Yup, sets its width to the user specified value
4638             m_cell_size_data.col_widths[i] = w;
4639             fixed_width_sum += w;
4640             continue;
4641         }
4642 
4643         // Is it a relatively sized column?
4644         if ( value.endsWith( "%" ) )
4645         {
4646             value.truncate( value.length() - 1 );
4647             double factor = value.toFloat( &ok );
4648             if ( ok && !value.isEmpty() )
4649             {
4650                 factor /= 100.0;
4651                 relative_width_sum += m_cell_size_data.col_widths[i];
4652                 relative_fraction_sum += factor;
4653                 if ( !width_set_by_user )
4654                 {
4655                     // If the table width was not set by the user, we are free to increase
4656                     // it so that the width of this column will be >= than its natural width
4657                     int min_col_width_sum = ROUND( m_cell_size_data.col_widths[i] / factor );
4658                     if ( min_col_width_sum > col_width_sum )
4659                         col_width_sum = min_col_width_sum;
4660                 }
4661                 continue;
4662             }
4663             else
4664                 qWarning( "MmlMtableNode::layoutSymbol(): could not parse value %s%%", value.toLatin1().data() );
4665         }
4666 
4667         // Relatively sized column, but we failed to parse the factor. Treat is like an auto
4668         // column.
4669         auto_width_sum += m_cell_size_data.col_widths[i];
4670     }
4671 
4672     // Work out how much space remains for the auto olumns, after allocating
4673     // the statically sized and the relatively sized columns.
4674     int required_auto_width_sum = col_width_sum
4675                                   - ROUND( relative_fraction_sum * col_width_sum )
4676                                   - fixed_width_sum;
4677 
4678     if ( !width_set_by_user && required_auto_width_sum < auto_width_sum )
4679     {
4680         if ( relative_fraction_sum < 1 )
4681             col_width_sum = ROUND( ( fixed_width_sum + auto_width_sum ) / ( 1 - relative_fraction_sum ) );
4682         else
4683             col_width_sum = fixed_width_sum + auto_width_sum + relative_width_sum;
4684         required_auto_width_sum = auto_width_sum;
4685     }
4686 
4687     // Ratio by which we have to shring/grow all auto sized columns to make it all fit
4688     double auto_width_scale = 1;
4689     if ( auto_width_sum > 0 )
4690         auto_width_scale = ( float )required_auto_width_sum / auto_width_sum;
4691 
4692     // Set correct sizes for the auto sized and the relatively sized columns.
4693     for ( i = 0; i < m_cell_size_data.numCols(); ++i )
4694     {
4695         QString value = interpretListAttr( columnwidth_attr, i, "auto" );
4696 
4697         // Is it a relatively sized column?
4698         if ( value.endsWith( "%" ) )
4699         {
4700             bool ok;
4701             int w = interpretPercentSpacing( value, col_width_sum, &ok );
4702             if ( ok )
4703                 m_cell_size_data.col_widths[i] = w;
4704             else
4705                 // We're treating parsing errors here as auto sized columns
4706                 m_cell_size_data.col_widths[i]
4707                 = ROUND( auto_width_scale * m_cell_size_data.col_widths[i] );
4708         }
4709         // Is it an auto sized column?
4710         else if ( value == "auto" )
4711         {
4712             m_cell_size_data.col_widths[i]
4713             = ROUND( auto_width_scale * m_cell_size_data.col_widths[i] );
4714         }
4715     }
4716 
4717     QString s;
4718     QList<int> &col_widths = m_cell_size_data.col_widths;
4719     for ( i = 0; i < col_widths.count(); ++i )
4720     {
4721         s += QString( "[w=%1 %2%%]" )
4722              .arg( col_widths[i] )
4723              .arg( 100 * col_widths[i] / m_cell_size_data.colWidthSum() );
4724     }
4725 //    qWarning(s);
4726 
4727     m_content_width = m_cell_size_data.colWidthSum()
4728                       + col_spc * ( m_cell_size_data.numCols() - 1 );
4729     m_content_height = m_cell_size_data.rowHeightSum()
4730                        + row_spc * ( m_cell_size_data.numRows() - 1 );
4731 
4732     int bottom = -m_content_height / 2;
4733     QwtMmlNode *child = firstChild();
4734     for ( ; child != 0; child = child->nextSibling() )
4735     {
4736         Q_ASSERT( child->nodeType() == MtrNode );
4737         QwtMmlMtrNode *row = ( QwtMmlMtrNode* ) child;
4738 
4739         row->layoutCells( m_cell_size_data.col_widths, col_spc );
4740         QRect rmr = row->myRect();
4741         row->setRelOrigin( QPoint( 0, bottom - rmr.top() ) );
4742         bottom += rmr.height() + row_spc;
4743     }
4744 }
4745 
symbolRect() const4746 QRect QwtMmlMtableNode::symbolRect() const
4747 {
4748     int frame_spc_hor = framespacing_hor();
4749     int frame_spc_ver = framespacing_ver();
4750 
4751     return QRect( -frame_spc_hor,
4752                   -m_content_height / 2 - frame_spc_ver,
4753                   m_content_width + 2 * frame_spc_hor,
4754                   m_content_height + 2 * frame_spc_ver );
4755 }
4756 
frame() const4757 QwtMml::FrameType QwtMmlMtableNode::frame() const
4758 {
4759     QString value = explicitAttribute( "frame", "none" );
4760     return interpretFrameType( value, 0, 0 );
4761 }
4762 
columnlines(int idx) const4763 QwtMml::FrameType QwtMmlMtableNode::columnlines( int idx ) const
4764 {
4765     QString value = explicitAttribute( "columnlines", "none" );
4766     return interpretFrameType( value, idx, 0 );
4767 }
4768 
rowlines(int idx) const4769 QwtMml::FrameType QwtMmlMtableNode::rowlines( int idx ) const
4770 {
4771     QString value = explicitAttribute( "rowlines", "none" );
4772     return interpretFrameType( value, idx, 0 );
4773 }
4774 
paintSymbol(QPainter * p) const4775 void QwtMmlMtableNode::paintSymbol( QPainter *p ) const
4776 {
4777     FrameType f = frame();
4778     if ( f != FrameNone )
4779     {
4780         p->save();
4781 
4782         QPen pen = p->pen();
4783         if ( f == FrameDashed )
4784             pen.setStyle( Qt::DashLine );
4785         else
4786             pen.setStyle( Qt::SolidLine );
4787         p->setPen( pen );
4788         p->drawRect( myRect() );
4789 
4790         p->restore();
4791     }
4792 
4793     p->save();
4794 
4795     int col_spc = columnspacing();
4796     int row_spc = rowspacing();
4797 
4798     QPen pen = p->pen();
4799     int col_offset = 0;
4800     int i;
4801     for ( i = 0; i < m_cell_size_data.numCols() - 1; ++i )
4802     {
4803         FrameType f = columnlines( i );
4804         col_offset += m_cell_size_data.col_widths[i];
4805 
4806         if ( f != FrameNone )
4807         {
4808             if ( f == FrameDashed )
4809                 pen.setStyle( Qt::DashLine );
4810             else if ( f == FrameSolid )
4811                 pen.setStyle( Qt::SolidLine );
4812 
4813             p->setPen( pen );
4814             int x = col_offset + col_spc / 2;
4815             p->drawLine( x, -m_content_height / 2, x, m_content_height / 2 );
4816         }
4817         col_offset += col_spc;
4818     }
4819 
4820     int row_offset = 0;
4821     for ( i = 0; i < m_cell_size_data.numRows() - 1; ++i )
4822     {
4823         FrameType f = rowlines( i );
4824         row_offset += m_cell_size_data.row_heights[i];
4825 
4826         if ( f != FrameNone )
4827         {
4828             if ( f == FrameDashed )
4829                 pen.setStyle( Qt::DashLine );
4830             else if ( f == FrameSolid )
4831                 pen.setStyle( Qt::SolidLine );
4832 
4833             p->setPen( pen );
4834             int y = row_offset + row_spc / 2 - m_content_height / 2;
4835             p->drawLine( 0, y, m_content_width, y );
4836         }
4837         row_offset += row_spc;
4838     }
4839 
4840     p->restore();
4841 }
4842 
framespacing_ver() const4843 int QwtMmlMtableNode::framespacing_ver() const
4844 {
4845     if ( frame() == FrameNone )
4846         return ( int )( 0.2 * em() );
4847 
4848     QString value = explicitAttribute( "framespacing", "0.4em 0.5ex" );
4849 
4850     bool ok;
4851     FrameSpacing fs = interpretFrameSpacing( value, em(), ex(), &ok );
4852     if ( ok )
4853         return fs.m_ver;
4854     else
4855         return ( int )( 0.5 * ex() );
4856 }
4857 
framespacing_hor() const4858 int QwtMmlMtableNode::framespacing_hor() const
4859 {
4860     if ( frame() == FrameNone )
4861         return ( int )( 0.2 * em() );
4862 
4863     QString value = explicitAttribute( "framespacing", "0.4em 0.5ex" );
4864 
4865     bool ok;
4866     FrameSpacing fs = interpretFrameSpacing( value, em(), ex(), &ok );
4867     if ( ok )
4868         return fs.m_hor;
4869     else
4870         return ( int )( 0.4 * em() );
4871 }
4872 
layoutCells(const QList<int> & col_widths,int col_spc)4873 void QwtMmlMtrNode::layoutCells( const QList<int> &col_widths,
4874                               int col_spc )
4875 {
4876     QRect mr = myRect();
4877 
4878     QwtMmlNode *child = firstChild();
4879     int col_offset = 0;
4880     uint colnum = 0;
4881     for ( ; child != 0; child = child->nextSibling(), ++colnum )
4882     {
4883         Q_ASSERT( child->nodeType() == MtdNode );
4884         QwtMmlMtdNode *mtd = ( QwtMmlMtdNode* ) child;
4885 
4886         QRect r = QRect( 0, mr.top(), col_widths[colnum], mr.height() );
4887         mtd->setMyRect( r );
4888         mtd->setRelOrigin( QPoint( col_offset, 0 ) );
4889         col_offset += col_widths[colnum] + col_spc;
4890     }
4891 
4892     updateMyRect();
4893 }
4894 
scriptlevel(const QwtMmlNode * child) const4895 int QwtMmlMtdNode::scriptlevel( const QwtMmlNode *child ) const
4896 {
4897     int sl = QwtMmlNode::scriptlevel();
4898     if ( child != 0 && child == firstChild() )
4899         return sl + m_scriptlevel_adjust;
4900     else
4901         return sl;
4902 }
4903 
setMyRect(const QRect & rect)4904 void QwtMmlMtdNode::setMyRect( const QRect &rect )
4905 {
4906     QwtMmlNode::setMyRect( rect );
4907     QwtMmlNode *child = firstChild();
4908     if ( child == 0 )
4909         return;
4910 
4911     if ( rect.width() < child->myRect().width() )
4912     {
4913         while ( rect.width() < child->myRect().width()
4914                 && child->font().pointSize() > g_min_font_point_size )
4915         {
4916 
4917 //          qWarning("MmlMtdNode::setMyRect(): rect.width()=%d, child()->myRect().width=%d sl=%d",
4918 //              rect.width(), child->myRect().width(), m_scriptlevel_adjust);
4919 
4920             ++m_scriptlevel_adjust;
4921             child->layout();
4922         }
4923 
4924 //      qWarning("MmlMtdNode::setMyRect(): rect.width()=%d, child()->myRect().width=%d sl=%d",
4925 //              rect.width(), child->myRect().width(), m_scriptlevel_adjust);
4926     }
4927 
4928     QRect mr = myRect();
4929     QRect cmr = child->myRect();
4930 
4931     QPoint child_rel_origin;
4932 
4933     switch ( columnalign() )
4934     {
4935         case ColAlignLeft:
4936             child_rel_origin.setX( 0 );
4937             break;
4938         case ColAlignCenter:
4939             child_rel_origin.setX( mr.left() + ( mr.width() - cmr.width() ) / 2 );
4940             break;
4941         case ColAlignRight:
4942             child_rel_origin.setX( mr.right() - cmr.width() );
4943             break;
4944     }
4945 
4946     switch ( rowalign() )
4947     {
4948         case RowAlignTop:
4949             child_rel_origin.setY( mr.top() - cmr.top() );
4950             break;
4951         case RowAlignCenter:
4952         case RowAlignBaseline:
4953             child_rel_origin.setY( mr.top() - cmr.top() + ( mr.height() - cmr.height() ) / 2 );
4954             break;
4955         case RowAlignBottom:
4956             child_rel_origin.setY( mr.bottom() - cmr.bottom() );
4957             break;
4958         case RowAlignAxis:
4959             child_rel_origin.setY( 0 );
4960             break;
4961     }
4962 
4963     child->setRelOrigin( child_rel_origin );
4964 }
4965 
colNum()4966 uint QwtMmlMtdNode::colNum()
4967 {
4968     QwtMmlNode *syb = previousSibling();
4969 
4970     uint i = 0;
4971     for ( ; syb != 0; syb = syb->previousSibling() )
4972         ++i;
4973 
4974     return i;
4975 }
4976 
rowNum()4977 uint QwtMmlMtdNode::rowNum()
4978 {
4979     QwtMmlNode *row = parent()->previousSibling();
4980 
4981     uint i = 0;
4982     for ( ; row != 0; row = row->previousSibling() )
4983         ++i;
4984 
4985     return i;
4986 }
4987 
columnalign()4988 QwtMmlMtdNode::ColAlign QwtMmlMtdNode::columnalign()
4989 {
4990     QString val = explicitAttribute( "columnalign" );
4991     if ( !val.isNull() )
4992         return interpretColAlign( val, 0, 0 );
4993 
4994     QwtMmlNode *node = parent(); // <mtr>
4995     if ( node == 0 )
4996         return ColAlignCenter;
4997 
4998     uint colnum = colNum();
4999     val = node->explicitAttribute( "columnalign" );
5000     if ( !val.isNull() )
5001         return interpretColAlign( val, colnum, 0 );
5002 
5003     node = node->parent(); // <mtable>
5004     if ( node == 0 )
5005         return ColAlignCenter;
5006 
5007     val = node->explicitAttribute( "columnalign" );
5008     if ( !val.isNull() )
5009         return interpretColAlign( val, colnum, 0 );
5010 
5011     return ColAlignCenter;
5012 }
5013 
rowalign()5014 QwtMmlMtdNode::RowAlign QwtMmlMtdNode::rowalign()
5015 {
5016     QString val = explicitAttribute( "rowalign" );
5017     if ( !val.isNull() )
5018         return interpretRowAlign( val, 0, 0 );
5019 
5020     QwtMmlNode *node = parent(); // <mtr>
5021     if ( node == 0 )
5022         return RowAlignAxis;
5023 
5024     uint rownum = rowNum();
5025     val = node->explicitAttribute( "rowalign" );
5026     if ( !val.isNull() )
5027         return interpretRowAlign( val, rownum, 0 );
5028 
5029     node = node->parent(); // <mtable>
5030     if ( node == 0 )
5031         return RowAlignAxis;
5032 
5033     val = node->explicitAttribute( "rowalign" );
5034     if ( !val.isNull() )
5035         return interpretRowAlign( val, rownum, 0 );
5036 
5037     return RowAlignAxis;
5038 }
5039 
layoutSymbol()5040 void QwtMmlMoverNode::layoutSymbol()
5041 {
5042     QwtMmlNode *base = firstChild();
5043     Q_ASSERT( base != 0 );
5044     QwtMmlNode *over = base->nextSibling();
5045     Q_ASSERT( over != 0 );
5046 
5047     QRect base_rect = base->myRect();
5048     QRect over_rect = over->myRect();
5049 
5050     int spacing = ( int )( g_mfrac_spacing * ( over_rect.height()
5051                            + base_rect.height() ) );
5052 
5053     base->setRelOrigin( QPoint( -base_rect.width() / 2, 0 ) );
5054     over->setRelOrigin( QPoint( -over_rect.width() / 2,
5055                                 base_rect.top() - spacing - over_rect.bottom() ) );
5056 }
5057 
scriptlevel(const QwtMmlNode * node) const5058 int QwtMmlMoverNode::scriptlevel( const QwtMmlNode *node ) const
5059 {
5060     QwtMmlNode *base = firstChild();
5061     Q_ASSERT( base != 0 );
5062     QwtMmlNode *over = base->nextSibling();
5063     Q_ASSERT( over != 0 );
5064 
5065     int sl = QwtMmlNode::scriptlevel();
5066     if ( node != 0 && node == over )
5067         return sl + 1;
5068     else
5069         return sl;
5070 }
5071 
layoutSymbol()5072 void QwtMmlMunderNode::layoutSymbol()
5073 {
5074     QwtMmlNode *base = firstChild();
5075     Q_ASSERT( base != 0 );
5076     QwtMmlNode *under = base->nextSibling();
5077     Q_ASSERT( under != 0 );
5078 
5079     QRect base_rect = base->myRect();
5080     QRect under_rect = under->myRect();
5081 
5082     int spacing = ( int )( g_mfrac_spacing * ( under_rect.height() + base_rect.height() ) );
5083 
5084     base->setRelOrigin( QPoint( -base_rect.width() / 2, 0 ) );
5085     under->setRelOrigin( QPoint( -under_rect.width() / 2, base_rect.bottom() + spacing - under_rect.top() ) );
5086 }
5087 
scriptlevel(const QwtMmlNode * node) const5088 int QwtMmlMunderNode::scriptlevel( const QwtMmlNode *node ) const
5089 {
5090     QwtMmlNode *base = firstChild();
5091     Q_ASSERT( base != 0 );
5092     QwtMmlNode *under = base->nextSibling();
5093     Q_ASSERT( under != 0 );
5094 
5095     int sl = QwtMmlNode::scriptlevel();
5096     if ( node != 0 && node == under )
5097         return sl + 1;
5098     else
5099         return sl;
5100 }
5101 
layoutSymbol()5102 void QwtMmlMunderoverNode::layoutSymbol()
5103 {
5104     QwtMmlNode *base = firstChild();
5105     Q_ASSERT( base != 0 );
5106     QwtMmlNode *under = base->nextSibling();
5107     Q_ASSERT( under != 0 );
5108     QwtMmlNode *over = under->nextSibling();
5109     Q_ASSERT( over != 0 );
5110 
5111     QRect base_rect = base->myRect();
5112     QRect under_rect = under->myRect();
5113     QRect over_rect = over->myRect();
5114 
5115     int spacing = ( int )( g_mfrac_spacing * (   base_rect.height()
5116                            + under_rect.height()
5117                            + over_rect.height() )   );
5118 
5119     base->setRelOrigin( QPoint( -base_rect.width() / 2, 0 ) );
5120     under->setRelOrigin( QPoint( -under_rect.width() / 2, base_rect.bottom() + spacing - under_rect.top() ) );
5121     over->setRelOrigin( QPoint( -over_rect.width() / 2, base_rect.top() - spacing - under_rect.bottom() ) );
5122 }
5123 
scriptlevel(const QwtMmlNode * node) const5124 int QwtMmlMunderoverNode::scriptlevel( const QwtMmlNode *node ) const
5125 {
5126     QwtMmlNode *base = firstChild();
5127     Q_ASSERT( base != 0 );
5128     QwtMmlNode *under = base->nextSibling();
5129     Q_ASSERT( under != 0 );
5130     QwtMmlNode *over = under->nextSibling();
5131     Q_ASSERT( over != 0 );
5132 
5133     int sl = QwtMmlNode::scriptlevel();
5134     if ( node != 0 && ( node == under || node == over ) )
5135         return sl + 1;
5136     else
5137         return sl;
5138 }
5139 
interpretSpacing(QString value,int base_value,bool * ok) const5140 int QwtMmlMpaddedNode::interpretSpacing( QString value, int base_value, bool *ok ) const
5141 {
5142     if ( ok != 0 )
5143         *ok = false;
5144 
5145     value.replace( ' ', "" );
5146 
5147     QString sign, factor_str, pseudo_unit;
5148     bool percent = false;
5149 
5150     // extract the sign
5151     int idx = 0;
5152     if ( idx < value.length() && ( value.at( idx ) == '+' || value.at( idx ) == '-' ) )
5153         sign = value.at( idx++ );
5154 
5155     // extract the factor
5156     while ( idx < value.length() && ( value.at( idx ).isDigit() || value.at( idx ) == '.' ) )
5157         factor_str.append( value.at( idx++ ) );
5158 
5159     // extract the % sign
5160     if ( idx < value.length() && value.at( idx ) == '%' )
5161     {
5162         percent = true;
5163         ++idx;
5164     }
5165 
5166     // extract the pseudo-unit
5167     pseudo_unit = value.mid( idx );
5168 
5169     bool float_ok;
5170     double factor = factor_str.toFloat( &float_ok );
5171     if ( !float_ok || factor < 0 )
5172     {
5173         qWarning( "MmlMpaddedNode::interpretSpacing(): could not parse \"%s\"", value.toLatin1().data() );
5174         return 0;
5175     }
5176 
5177     if ( percent )
5178         factor /= 100.0;
5179 
5180     QRect cr;
5181     if ( firstChild() == 0 )
5182         cr = QRect( 0, 0, 0, 0 );
5183     else
5184         cr = firstChild()->myRect();
5185 
5186     int unit_size;
5187 
5188     if ( pseudo_unit.isEmpty() )
5189         unit_size = base_value;
5190     else if ( pseudo_unit == "width" )
5191         unit_size = cr.width();
5192     else if ( pseudo_unit == "height" )
5193         unit_size = -cr.top();
5194     else if ( pseudo_unit == "depth" )
5195         unit_size = cr.bottom();
5196     else
5197     {
5198         bool unit_ok;
5199         unit_size = QwtMmlNode::interpretSpacing( "1" + pseudo_unit, &unit_ok );
5200         if ( !unit_ok )
5201         {
5202             qWarning( "MmlMpaddedNode::interpretSpacing(): could not parse \"%s\"", value.toLatin1().data() );
5203             return 0;
5204         }
5205     }
5206 
5207     if ( ok != 0 )
5208         *ok = true;
5209 
5210     if ( sign.isNull() )
5211         return ( int )( factor * unit_size );
5212     else if ( sign == "+" )
5213         return base_value + ( int )( factor * unit_size );
5214     else // sign == "-"
5215         return base_value - ( int )( factor * unit_size );
5216 }
5217 
lspace() const5218 int QwtMmlMpaddedNode::lspace() const
5219 {
5220     QString value = explicitAttribute( "lspace" );
5221 
5222     if ( value.isNull() )
5223         return 0;
5224 
5225     bool ok;
5226     int lspace = interpretSpacing( value, 0, &ok );
5227 
5228     if ( ok )
5229         return lspace;
5230 
5231     return 0;
5232 }
5233 
width() const5234 int QwtMmlMpaddedNode::width() const
5235 {
5236     int child_width = 0;
5237     if ( firstChild() != 0 )
5238         child_width = firstChild()->myRect().width();
5239 
5240     QString value = explicitAttribute( "width" );
5241     if ( value.isNull() )
5242         return child_width;
5243 
5244     bool ok;
5245     int w = interpretSpacing( value, child_width, &ok );
5246     if ( ok )
5247         return w;
5248 
5249     return child_width;
5250 }
5251 
height() const5252 int QwtMmlMpaddedNode::height() const
5253 {
5254     QRect cr;
5255     if ( firstChild() == 0 )
5256         cr = QRect( 0, 0, 0, 0 );
5257     else
5258         cr = firstChild()->myRect();
5259 
5260     QString value = explicitAttribute( "height" );
5261     if ( value.isNull() )
5262         return -cr.top();
5263 
5264     bool ok;
5265     int h = interpretSpacing( value, -cr.top(), &ok );
5266     if ( ok )
5267         return h;
5268 
5269     return -cr.top();
5270 }
5271 
depth() const5272 int QwtMmlMpaddedNode::depth() const
5273 {
5274     QRect cr;
5275     if ( firstChild() == 0 )
5276         cr = QRect( 0, 0, 0, 0 );
5277     else
5278         cr = firstChild()->myRect();
5279 
5280     QString value = explicitAttribute( "depth" );
5281     if ( value.isNull() )
5282         return cr.bottom();
5283 
5284     bool ok;
5285     int h = interpretSpacing( value, cr.bottom(), &ok );
5286     if ( ok )
5287         return h;
5288 
5289     return cr.bottom();
5290 }
5291 
layoutSymbol()5292 void QwtMmlMpaddedNode::layoutSymbol()
5293 {
5294     QwtMmlNode *child = firstChild();
5295     if ( child == 0 )
5296         return;
5297 
5298     child->setRelOrigin( QPoint( 0, 0 ) );
5299 }
5300 
5301 
symbolRect() const5302 QRect QwtMmlMpaddedNode::symbolRect() const
5303 {
5304     return QRect( -lspace(), -height(), lspace() + width(), height() + depth() );
5305 }
5306 
5307 // *******************************************************************
5308 // Static helper functions
5309 // *******************************************************************
5310 
entityDeclarations()5311 static QString entityDeclarations()
5312 {
5313     QString result = "<!DOCTYPE math [\n";
5314 
5315     const QwtMmlEntitySpec *ent = g_xml_entity_data;
5316     for ( ; ent->name != 0; ++ent )
5317     {
5318         result += "\t<!ENTITY " + QString( ent->name ) + " \"" + ent->value + "\">\n";
5319     }
5320 
5321     result += "]>\n";
5322 
5323     return result;
5324 }
5325 
interpretSpacing(QString value,int em,int ex,bool * ok)5326 static int interpretSpacing( QString value, int em, int ex, bool *ok )
5327 {
5328     if ( ok != 0 )
5329         *ok = true;
5330 
5331     if ( value == "thin" )
5332         return 1;
5333 
5334     if ( value == "medium" )
5335         return 2;
5336 
5337     if ( value == "thick" )
5338         return 3;
5339 
5340     struct HSpacingValue
5341     {
5342         const char *name;
5343         float factor;
5344     };
5345 
5346     static const HSpacingValue g_h_spacing_data[] =
5347     {
5348         { "veryverythinmathspace",  ( float ) 0.0555556   },
5349         { "verythinmathspace",      ( float ) 0.111111    },
5350         { "thinmathspace",              ( float ) 0.166667    },
5351         { "mediummathspace",        ( float ) 0.222222    },
5352         { "thickmathspace",         ( float ) 0.277778    },
5353         { "verythickmathspace",     ( float ) 0.333333    },
5354         { "veryverythickmathspace",     ( float ) 0.388889    },
5355         { 0,                        ( float ) 0           }
5356     };
5357 
5358     const HSpacingValue *v = g_h_spacing_data;
5359     for ( ; v->name != 0; ++v )
5360     {
5361         if ( value == v->name )
5362             return ( int )( em * v->factor );
5363     }
5364 
5365     if ( value.endsWith( "em" ) )
5366     {
5367         value.truncate( value.length() - 2 );
5368         bool float_ok;
5369         float factor = value.toFloat( &float_ok );
5370         if ( float_ok && factor >= 0 )
5371             return ( int )( em * factor );
5372         else
5373         {
5374             qWarning( "interpretSpacing(): could not parse \"%sem\"", value.toLatin1().data() );
5375             if ( ok != 0 )
5376                 *ok = false;
5377             return 0;
5378         }
5379     }
5380 
5381     if ( value.endsWith( "ex" ) )
5382     {
5383         value.truncate( value.length() - 2 );
5384         bool float_ok;
5385         float factor = value.toFloat( &float_ok );
5386         if ( float_ok && factor >= 0 )
5387             return ( int )( ex * factor );
5388         else
5389         {
5390             qWarning( "interpretSpacing(): could not parse \"%sex\"", value.toLatin1().data() );
5391             if ( ok != 0 )
5392                 *ok = false;
5393             return 0;
5394         }
5395     }
5396 
5397     if ( value.endsWith( "cm" ) )
5398     {
5399         value.truncate( value.length() - 2 );
5400         bool float_ok;
5401         float factor = value.toFloat( &float_ok );
5402         if ( float_ok && factor >= 0 )
5403         {
5404             Q_ASSERT( qApp->desktop() != 0 );
5405             QDesktopWidget *dw = qApp->desktop();
5406             Q_ASSERT( dw->width() != 0 );
5407             Q_ASSERT( dw->widthMM() != 0 );
5408             return ( int )( factor * 10 * dw->width() / dw->widthMM() );
5409         }
5410         else
5411         {
5412             qWarning( "interpretSpacing(): could not parse \"%scm\"", value.toLatin1().data() );
5413             if ( ok != 0 )
5414                 *ok = false;
5415             return 0;
5416         }
5417     }
5418 
5419     if ( value.endsWith( "mm" ) )
5420     {
5421         value.truncate( value.length() - 2 );
5422         bool float_ok;
5423         float factor = value.toFloat( &float_ok );
5424         if ( float_ok && factor >= 0 )
5425         {
5426             Q_ASSERT( qApp->desktop() != 0 );
5427             QDesktopWidget *dw = qApp->desktop();
5428             Q_ASSERT( dw->width() != 0 );
5429             Q_ASSERT( dw->widthMM() != 0 );
5430             return ( int )( factor * dw->width() / dw->widthMM() );
5431         }
5432         else
5433         {
5434             qWarning( "interpretSpacing(): could not parse \"%smm\"", value.toLatin1().data() );
5435             if ( ok != 0 )
5436                 *ok = false;
5437             return 0;
5438         }
5439     }
5440 
5441     if ( value.endsWith( "in" ) )
5442     {
5443         value.truncate( value.length() - 2 );
5444         bool float_ok;
5445         float factor = value.toFloat( &float_ok );
5446         if ( float_ok && factor >= 0 )
5447         {
5448             Q_ASSERT( qApp->desktop() != 0 );
5449             QDesktopWidget *dw = qApp->desktop();
5450             Q_ASSERT( dw->width() != 0 );
5451             Q_ASSERT( dw->widthMM() != 0 );
5452             return ( int )( factor * 10 * dw->width() / ( 2.54 * dw->widthMM() ) );
5453         }
5454         else
5455         {
5456             qWarning( "interpretSpacing(): could not parse \"%sin\"", value.toLatin1().data() );
5457             if ( ok != 0 )
5458                 *ok = false;
5459             return 0;
5460         }
5461     }
5462 
5463     if ( value.endsWith( "px" ) )
5464     {
5465         value.truncate( value.length() - 2 );
5466         bool float_ok;
5467         int i = ( int ) value.toFloat( &float_ok );
5468         if ( float_ok && i >= 0 )
5469             return i;
5470         else
5471         {
5472             qWarning( "interpretSpacing(): could not parse \"%spx\"", value.toLatin1().data() );
5473             if ( ok != 0 )
5474                 *ok = false;
5475             return 0;
5476         }
5477     }
5478 
5479     bool float_ok;
5480     int i = ( int )value.toFloat( &float_ok );
5481     if ( float_ok && i >= 0 )
5482         return i;
5483 
5484     qWarning( "interpretSpacing(): could not parse \"%s\"", value.toLatin1().data() );
5485     if ( ok != 0 )
5486         *ok = false;
5487     return 0;
5488 }
5489 
interpretPercentSpacing(QString value,int base,bool * ok)5490 static int interpretPercentSpacing( QString value, int base, bool *ok )
5491 {
5492     if ( !value.endsWith( "%" ) )
5493     {
5494         if ( ok != 0 )
5495             *ok = false;
5496         return 0;
5497     }
5498 
5499     value.truncate( value.length() - 1 );
5500     bool float_ok;
5501     float factor = value.toFloat( &float_ok );
5502     if ( float_ok && factor >= 0 )
5503     {
5504         if ( ok != 0 )
5505             *ok = true;
5506         return ( int )( base * factor / 100.0 );
5507     }
5508 
5509     qWarning( "interpretPercentSpacing(): could not parse \"%s%%\"", value.toLatin1().data() );
5510     if ( ok != 0 )
5511         *ok = false;
5512     return 0;
5513 }
5514 
interpretPointSize(QString value,bool * ok)5515 static int interpretPointSize( QString value, bool *ok )
5516 {
5517     if ( !value.endsWith( "pt" ) )
5518     {
5519         if ( ok != 0 )
5520             *ok = false;
5521         return 0;
5522     }
5523 
5524     value.truncate( value.length() - 2 );
5525     bool float_ok;
5526     int pt_size = ( int ) value.toFloat( &float_ok );
5527     if ( float_ok && pt_size > 0 )
5528     {
5529         if ( ok != 0 )
5530             *ok = true;
5531         return pt_size;
5532     }
5533 
5534     qWarning( "interpretPointSize(): could not parse \"%spt\"", value.toLatin1().data() );
5535     if ( ok != 0 )
5536         *ok = false;
5537     return 0;
5538 }
5539 
mmlFindNodeSpec(QwtMml::NodeType type)5540 static const QwtMmlNodeSpec *mmlFindNodeSpec( QwtMml::NodeType type )
5541 {
5542     const QwtMmlNodeSpec *spec = g_node_spec_data;
5543     for ( ; spec->type != QwtMml::NoNode; ++spec )
5544     {
5545         if ( type == spec->type ) return spec;
5546     }
5547     return 0;
5548 }
5549 
mmlFindNodeSpec(const QString & tag)5550 static const QwtMmlNodeSpec *mmlFindNodeSpec( const QString &tag )
5551 {
5552     const QwtMmlNodeSpec *spec = g_node_spec_data;
5553     for ( ; spec->type != QwtMml::NoNode; ++spec )
5554     {
5555         if ( tag == spec->tag ) return spec;
5556     }
5557     return 0;
5558 }
5559 
mmlCheckChildType(QwtMml::NodeType parent_type,QwtMml::NodeType child_type,QString * error_str)5560 static bool mmlCheckChildType( QwtMml::NodeType parent_type, QwtMml::NodeType child_type,
5561                                QString *error_str )
5562 {
5563     if ( parent_type == QwtMml::UnknownNode || child_type == QwtMml::UnknownNode )
5564         return true;
5565 
5566     const QwtMmlNodeSpec *child_spec = mmlFindNodeSpec( child_type );
5567     const QwtMmlNodeSpec *parent_spec = mmlFindNodeSpec( parent_type );
5568 
5569     Q_ASSERT( parent_spec != 0 );
5570     Q_ASSERT( child_spec != 0 );
5571 
5572     QString allowed_child_types( parent_spec->child_types );
5573     // null list means any child type is valid
5574     if ( allowed_child_types.isNull() )
5575         return true;
5576 
5577     QString child_type_str = QString( " " ) + child_spec->type_str + " ";
5578     if ( !allowed_child_types.contains( child_type_str ) )
5579     {
5580         if ( error_str != 0 )
5581             *error_str = QString( "illegal child " )
5582                          + child_spec->type_str
5583                          + " for parent "
5584                          + parent_spec->type_str;
5585         return false;
5586     }
5587 
5588     return true;
5589 }
5590 
mmlCheckAttributes(QwtMml::NodeType child_type,const QwtMmlAttributeMap & attr,QString * error_str)5591 static bool mmlCheckAttributes( QwtMml::NodeType child_type, const QwtMmlAttributeMap &attr,
5592                                 QString *error_str )
5593 {
5594     const QwtMmlNodeSpec *spec = mmlFindNodeSpec( child_type );
5595     Q_ASSERT( spec != 0 );
5596 
5597     QString allowed_attr( spec->attributes );
5598     // empty list means any attr is valid
5599     if ( allowed_attr.isEmpty() )
5600         return true;
5601 
5602     QwtMmlAttributeMap::const_iterator it = attr.begin(), end = attr.end();
5603     for ( ; it != end; ++it )
5604     {
5605         QString name = it.key();
5606 
5607         if ( name.indexOf( ':' ) != -1 )
5608             continue;
5609 
5610         QString padded_name = " " + name + " ";
5611         if ( !allowed_attr.contains( padded_name ) )
5612         {
5613             if ( error_str != 0 )
5614                 *error_str = QString( "illegal attribute " )
5615                              + name
5616                              + " in "
5617                              + spec->type_str;
5618             return false;
5619         }
5620     }
5621 
5622     return true;
5623 }
5624 
attributeIndex(const QString & name)5625 static int attributeIndex( const QString &name )
5626 {
5627     for ( unsigned i = 0; i < g_oper_spec_rows; ++i )
5628     {
5629         if ( name == g_oper_spec_names[i] )
5630             return i;
5631     }
5632     return -1;
5633 }
5634 
decodeEntityValue(QString literal)5635 static QString decodeEntityValue( QString literal )
5636 {
5637     QString result;
5638 
5639     while ( !literal.isEmpty() )
5640     {
5641 
5642         if ( !literal.startsWith( "&#" ) )
5643         {
5644             qWarning() << "decodeEntityValue(): bad entity literal: \"" + literal + "\"";
5645             return QString();
5646         }
5647 
5648         literal = literal.right( literal.length() - 2 );
5649 
5650         int i = literal.indexOf( ';' );
5651         if ( i == -1 )
5652         {
5653             qWarning() << "decodeEntityValue(): bad entity literal: \"" + literal + "\"";
5654             return QString();
5655         }
5656 
5657         QString char_code = literal.left( i );
5658         literal = literal.right( literal.length() - i - 1 );
5659 
5660         if ( char_code.isEmpty() )
5661         {
5662             qWarning() << "decodeEntityValue(): bad entity literal: \"" + literal + "\"";
5663             return QString();
5664         }
5665 
5666         if ( char_code.at( 0 ) == 'x' )
5667         {
5668             char_code = char_code.right( char_code.length() - 1 );
5669             bool ok;
5670             unsigned c = char_code.toUInt( &ok, 16 );
5671             if ( !ok )
5672             {
5673                 qWarning() << "decodeEntityValue(): bad entity literal: \"" + literal + "\"";
5674                 return QString();
5675             }
5676             result += QChar( c );
5677         }
5678         else
5679         {
5680             bool ok;
5681             unsigned c = char_code.toUInt( &ok, 10 );
5682             if ( !ok )
5683             {
5684                 qWarning() << "decodeEntityValue(): bad entity literal: \"" + literal + "\"";
5685                 return QString();
5686             }
5687             result += QChar( c );
5688         }
5689     }
5690 
5691     return result;
5692 }
5693 
searchEntitySpecData(const QString & value,const QwtMmlEntitySpec * from=0)5694 static const QwtMmlEntitySpec *searchEntitySpecData( const QString &value, const QwtMmlEntitySpec *from = 0 )
5695 {
5696     const QwtMmlEntitySpec *ent = from;
5697     if ( ent == 0 )
5698         ent = g_xml_entity_data;
5699     for ( ; ent->name != 0; ++ent )
5700     {
5701         QString ent_value = decodeEntityValue( ent->value );
5702         if ( value == ent_value )
5703             return ent;
5704     }
5705     return 0;
5706 }
5707 
5708 struct OperSpecSearchResult
5709 {
OperSpecSearchResultOperSpecSearchResult5710     OperSpecSearchResult() { prefix_form = infix_form = postfix_form = 0; }
5711 
5712     const QwtMmlOperSpec *prefix_form,
5713           *infix_form,
5714           *postfix_form;
5715 
5716     const QwtMmlOperSpec *&getForm( QwtMml::FormType f );
haveFormOperSpecSearchResult5717     bool haveForm( QwtMml::FormType f )
5718     { return getForm( f ) != 0; }
addFormOperSpecSearchResult5719     void addForm( const QwtMmlOperSpec *spec )
5720     { getForm( spec->form ) = spec; }
5721 };
5722 
getForm(QwtMml::FormType f)5723 const QwtMmlOperSpec *&OperSpecSearchResult::getForm( QwtMml::FormType f )
5724 {
5725     switch ( f )
5726     {
5727         case QwtMml::PrefixForm:
5728             return prefix_form;
5729         case QwtMml::InfixForm:
5730             return infix_form;
5731         case QwtMml::PostfixForm:
5732             return postfix_form;
5733     }
5734     return postfix_form; // just to avoid warning
5735 }
5736 
5737 /*
5738     Searches g_oper_spec_data and returns any instance of operator name. There may
5739     be more instances, but since the list is sorted, they will be next to each other.
5740 */
searchOperSpecData(const QString & name)5741 static const QwtMmlOperSpec *searchOperSpecData( const QString &name )
5742 {
5743     const char *name_latin1 = name.toLatin1().data();
5744 
5745     // binary search
5746     // establish invariant g_oper_spec_data[begin].name < name < g_oper_spec_data[end].name
5747 
5748     int cmp = qstrcmp( name_latin1, g_oper_spec_data[0].name );
5749     if ( cmp < 0 )
5750         return 0;
5751 
5752     if ( cmp == 0 )
5753         return g_oper_spec_data;
5754 
5755     uint begin = 0;
5756     uint end = g_oper_spec_count;
5757 
5758     // invariant holds
5759     while ( end - begin > 1 )
5760     {
5761         uint mid = ( begin + end ) / 2;
5762 
5763         const QwtMmlOperSpec *spec = g_oper_spec_data + mid;
5764         int cmp = qstrcmp( name_latin1, spec->name );
5765         if ( cmp < 0 )
5766             end = mid;
5767         else if ( cmp > 0 )
5768             begin = mid;
5769         else
5770             return spec;
5771     }
5772 
5773     return 0;
5774 }
5775 
5776 /*
5777     This searches g_oper_spec_data until at least one name in name_list is found with FormType form,
5778     or until name_list is exhausted. The idea here is that if we don't find the operator in the
5779     specified form, we still want to use some other available form of that operator.
5780 */
_mmlFindOperSpec(const QStringList & name_list,QwtMml::FormType form)5781 static OperSpecSearchResult _mmlFindOperSpec( const QStringList &name_list, QwtMml::FormType form )
5782 {
5783     OperSpecSearchResult result;
5784 
5785     QStringList::const_iterator it = name_list.begin();
5786     for ( ; it != name_list.end(); ++it )
5787     {
5788         const QString &name = *it;
5789 
5790         const QwtMmlOperSpec *spec = searchOperSpecData( name );
5791 
5792         if ( spec == 0 )
5793             continue;
5794 
5795         const char *name_latin1 = name.toLatin1().data();
5796 
5797         // backtrack to the first instance of name
5798         while ( spec > g_oper_spec_data && qstrcmp( ( spec - 1 )->name, name_latin1 ) == 0 )
5799             --spec;
5800 
5801         // iterate over instances of name until the instances are exhausted or until we
5802         // find an instance in the specified form.
5803         do
5804         {
5805             result.addForm( spec++ );
5806             if ( result.haveForm( form ) )
5807                 break;
5808         }
5809         while ( qstrcmp( spec->name, name_latin1 ) == 0 );
5810 
5811         if ( result.haveForm( form ) )
5812             break;
5813     }
5814 
5815     return result;
5816 }
5817 
5818 /*
5819     text is a string between <mo> and </mo>. It can be a character ('+'), an
5820     entity reference ("&infin;") or a character reference ("&#x0221E"). Our
5821     job is to find an operator spec in the operator dictionary (g_oper_spec_data)
5822     that matches text. Things are further complicated by the fact, that many
5823     operators come in several forms (prefix, infix, postfix).
5824 
5825     If available, this function returns an operator spec matching text in the specified
5826     form. If such operator is not available, returns an operator spec that matches
5827     text, but of some other form in the preference order specified by the MathML spec.
5828     If that's not available either, returns the default operator spec.
5829 */
mmlFindOperSpec(const QString & text,QwtMml::FormType form)5830 static const QwtMmlOperSpec *mmlFindOperSpec( const QString &text, QwtMml::FormType form )
5831 {
5832     QStringList name_list;
5833     name_list.append( text );
5834 
5835     // First, just try to find text in the operator dictionary.
5836     OperSpecSearchResult result = _mmlFindOperSpec( name_list, form );
5837 
5838     if ( !result.haveForm( form ) )
5839     {
5840         // Try to find other names for the operator represented by text.
5841 
5842         const QwtMmlEntitySpec *ent = 0;
5843         for ( ;; )
5844         {
5845             ent = searchEntitySpecData( text, ent );
5846             if ( ent == 0 )
5847                 break;
5848             name_list.append( '&' + QString( ent->name ) + ';' );
5849             ++ent;
5850         }
5851 
5852         result = _mmlFindOperSpec( name_list, form );
5853     }
5854 
5855     const QwtMmlOperSpec *spec = result.getForm( form );
5856     if ( spec != 0 )
5857         return spec;
5858 
5859     spec = result.getForm( QwtMml::InfixForm );
5860     if ( spec != 0 )
5861         return spec;
5862 
5863     spec = result.getForm( QwtMml::PostfixForm );
5864     if ( spec != 0 )
5865         return spec;
5866 
5867     spec = result.getForm( QwtMml::PrefixForm );
5868     if ( spec != 0 )
5869         return spec;
5870 
5871     return &g_oper_spec_defaults;
5872 }
5873 
mmlDictAttribute(const QString & name,const QwtMmlOperSpec * spec)5874 static QString mmlDictAttribute( const QString &name, const QwtMmlOperSpec *spec )
5875 {
5876     int i = attributeIndex( name );
5877     if ( i == -1 )
5878         return QString();
5879     else
5880         return spec->attributes[i];
5881 }
5882 
interpretMathVariant(const QString & value,bool * ok)5883 static uint interpretMathVariant( const QString &value, bool *ok )
5884 {
5885     struct MathVariantValue
5886     {
5887         const char *value;
5888         uint mv;
5889     };
5890 
5891     static const MathVariantValue g_mv_data[] =
5892     {
5893         { "normal",                     QwtMml::NormalMV },
5894         { "bold",                           QwtMml::BoldMV },
5895         { "italic",                         QwtMml::ItalicMV },
5896         { "bold-italic",                QwtMml::BoldMV | QwtMml::ItalicMV },
5897         { "double-struck",                  QwtMml::DoubleStruckMV },
5898         { "bold-fraktur",                   QwtMml::BoldMV | QwtMml::FrakturMV },
5899         { "script",                         QwtMml::ScriptMV },
5900         { "bold-script",                QwtMml::BoldMV | QwtMml::ScriptMV },
5901         { "fraktur",                        QwtMml::FrakturMV },
5902         { "sans-serif",                 QwtMml::SansSerifMV },
5903         { "bold-sans-serif",                QwtMml::BoldMV | QwtMml::SansSerifMV },
5904         { "sans-serif-italic",          QwtMml::SansSerifMV | QwtMml::ItalicMV },
5905         { "sans-serif-bold-italic",         QwtMml::SansSerifMV | QwtMml::ItalicMV | QwtMml::BoldMV },
5906         { "monospace",                  QwtMml::MonospaceMV },
5907         { 0,                            0 }
5908     };
5909 
5910     const MathVariantValue *v = g_mv_data;
5911     for ( ; v->value != 0; ++v )
5912     {
5913         if ( value == v->value )
5914         {
5915             if ( ok != 0 )
5916                 *ok = true;
5917             return v->mv;
5918         }
5919     }
5920 
5921     if ( ok != 0 )
5922         *ok = false;
5923 
5924     qWarning( "interpretMathVariant(): could not parse value: \"%s\"", value.toLatin1().data() );
5925 
5926     return QwtMml::NormalMV;
5927 }
5928 
interpretForm(const QString & value,bool * ok)5929 static QwtMml::FormType interpretForm( const QString &value, bool *ok )
5930 {
5931     if ( ok != 0 )
5932         *ok = true;
5933 
5934     if ( value == "prefix" )
5935         return QwtMml::PrefixForm;
5936     if ( value == "infix" )
5937         return QwtMml::InfixForm;
5938     if ( value == "postfix" )
5939         return QwtMml::PostfixForm;
5940 
5941     if ( ok != 0 )
5942         *ok = false;
5943 
5944     qWarning( "interpretForm(): could not parse value \"%s\"", value.toLatin1().data() );
5945     return QwtMml::InfixForm;
5946 }
5947 
interpretColAlign(const QString & value_list,uint colnum,bool * ok)5948 static QwtMml::ColAlign interpretColAlign( const QString &value_list, uint colnum, bool *ok )
5949 {
5950     QString value = interpretListAttr( value_list, colnum, "center" );
5951 
5952     if ( ok != 0 )
5953         *ok = true;
5954 
5955     if ( value == "left" )
5956         return QwtMml::ColAlignLeft;
5957     if ( value == "right" )
5958         return QwtMml::ColAlignRight;
5959     if ( value == "center" )
5960         return QwtMml::ColAlignCenter;
5961 
5962     if ( ok != 0 )
5963         *ok = false;
5964 
5965     qWarning( "interpretColAlign(): could not parse value \"%s\"", value.toLatin1().data() );
5966     return QwtMml::ColAlignCenter;
5967 }
5968 
interpretRowAlign(const QString & value_list,uint rownum,bool * ok)5969 static QwtMml::RowAlign interpretRowAlign( const QString &value_list, uint rownum, bool *ok )
5970 {
5971     QString value = interpretListAttr( value_list, rownum, "axis" );
5972 
5973     if ( ok != 0 )
5974         *ok = true;
5975 
5976     if ( value == "top" )
5977         return QwtMml::RowAlignTop;
5978     if ( value == "center" )
5979         return QwtMml::RowAlignCenter;
5980     if ( value == "bottom" )
5981         return QwtMml::RowAlignBottom;
5982     if ( value == "baseline" )
5983         return QwtMml::RowAlignBaseline;
5984     if ( value == "axis" )
5985         return QwtMml::RowAlignAxis;
5986 
5987     if ( ok != 0 )
5988         *ok = false;
5989 
5990     qWarning( "interpretRowAlign(): could not parse value \"%s\"", value.toLatin1().data() );
5991     return QwtMml::RowAlignAxis;
5992 }
5993 
interpretListAttr(const QString & value_list,int idx,const QString & def)5994 static QString interpretListAttr( const QString &value_list, int idx, const QString &def )
5995 {
5996     QStringList l = value_list.split( ' ' );
5997 
5998     if ( l.count() == 0 )
5999         return def;
6000 
6001     if ( l.count() <= idx )
6002         return l[l.count() - 1];
6003     else
6004         return l[idx];
6005 }
6006 
interpretFrameType(const QString & value_list,uint idx,bool * ok)6007 static QwtMml::FrameType interpretFrameType( const QString &value_list, uint idx, bool *ok )
6008 {
6009     if ( ok != 0 )
6010         *ok = true;
6011 
6012     QString value = interpretListAttr( value_list, idx, "none" );
6013 
6014     if ( value == "none" )
6015         return QwtMml::FrameNone;
6016     if ( value == "solid" )
6017         return QwtMml::FrameSolid;
6018     if ( value == "dashed" )
6019         return QwtMml::FrameDashed;
6020 
6021     if ( ok != 0 )
6022         *ok = false;
6023 
6024     qWarning( "interpretFrameType(): could not parse value \"%s\"", value.toLatin1().data() );
6025     return QwtMml::FrameNone;
6026 }
6027 
6028 
interpretFrameSpacing(const QString & value_list,int em,int ex,bool * ok)6029 static QwtMml::FrameSpacing interpretFrameSpacing( const QString &value_list, int em, int ex, bool *ok )
6030 {
6031     QwtMml::FrameSpacing fs;
6032 
6033     QStringList l = value_list.split( ' ' );
6034     if ( l.count() != 2 )
6035     {
6036         qWarning( "interpretFrameSpacing: could not parse value \"%s\"", value_list.toLatin1().data() );
6037         if ( ok != 0 )
6038             *ok = false;
6039         return QwtMml::FrameSpacing( ( int )( 0.4 * em ), ( int )( 0.5 * ex ) );
6040     }
6041 
6042     bool hor_ok, ver_ok;
6043     fs.m_hor = interpretSpacing( l[0], em, ex, &hor_ok );
6044     fs.m_ver = interpretSpacing( l[1], em, ex, &ver_ok );
6045 
6046     if ( ok != 0 )
6047         *ok = hor_ok && ver_ok;
6048 
6049     return fs;
6050 }
6051 
interpretDepreciatedFontAttr(const QwtMmlAttributeMap & font_attr,QFont & fn,int em,int ex)6052 static QFont interpretDepreciatedFontAttr( const QwtMmlAttributeMap &font_attr, QFont &fn, int em, int ex )
6053 {
6054     if ( font_attr.contains( "fontsize" ) )
6055     {
6056         QString value = font_attr["fontsize"];
6057 
6058         for ( ;; )
6059         {
6060 
6061             bool ok;
6062             int ptsize = interpretPointSize( value, &ok );
6063             if ( ok )
6064             {
6065                 fn.setPointSize( ptsize );
6066                 break;
6067             }
6068 
6069             ptsize = interpretPercentSpacing( value, fn.pointSize(), &ok );
6070             if ( ok )
6071             {
6072                 fn.setPointSize( ptsize );
6073                 break;
6074             }
6075 
6076             int size = interpretSpacing( value, em, ex, &ok );
6077             if ( ok )
6078             {
6079                 fn.setPixelSize( size );
6080                 break;
6081             }
6082 
6083             break;
6084         }
6085     }
6086 
6087     if ( font_attr.contains( "fontweight" ) )
6088     {
6089         QString value = font_attr["fontweight"];
6090         if ( value == "normal" )
6091             fn.setBold( false );
6092         else if ( value == "bold" )
6093             fn.setBold( true );
6094         else
6095             qWarning( "interpretDepreciatedFontAttr(): could not parse fontweight \"%s\"", value.toLatin1().data() );
6096     }
6097 
6098     if ( font_attr.contains( "fontstyle" ) )
6099     {
6100         QString value = font_attr["fontstyle"];
6101         if ( value == "normal" )
6102             fn.setItalic( false );
6103         else if ( value == "italic" )
6104             fn.setItalic( true );
6105         else
6106             qWarning( "interpretDepreciatedFontAttr(): could not parse fontstyle \"%s\"", value.toLatin1().data() );
6107     }
6108 
6109     if ( font_attr.contains( "fontfamily" ) )
6110     {
6111         QString value = font_attr["fontfamily"];
6112         fn.setFamily( value );
6113     }
6114 
6115     return fn;
6116 }
6117 
interpretMathSize(QString value,QFont & fn,int em,int ex,bool * ok)6118 static QFont interpretMathSize( QString value, QFont &fn, int em, int ex, bool *ok )
6119 {
6120     if ( ok != 0 )
6121         *ok = true;
6122 
6123     if ( value == "small" )
6124     {
6125         fn.setPointSize( ( int )( fn.pointSize() * 0.7 ) );
6126         return fn;
6127     }
6128 
6129     if ( value == "normal" )
6130         return fn;
6131 
6132     if ( value == "big" )
6133     {
6134         fn.setPointSize( ( int )( fn.pointSize() * 1.5 ) );
6135         return fn;
6136     }
6137 
6138     bool size_ok;
6139 
6140     int ptsize = interpretPointSize( value, &size_ok );
6141     if ( size_ok )
6142     {
6143         fn.setPointSize( ptsize );
6144         return fn;
6145     }
6146 
6147     int size = interpretSpacing( value, em, ex, &size_ok );
6148     if ( size_ok )
6149     {
6150         fn.setPixelSize( size );
6151         return fn;
6152     }
6153 
6154     if ( ok != 0 )
6155         *ok = false;
6156     qWarning( "interpretMathSize(): could not parse mathsize \"%s\"", value.toLatin1().data() );
6157     return fn;
6158 }
6159 
6160 /*!
6161     \class QwtMathMLDocument
6162 
6163     \brief The QwtMathMLDocument class renders mathematical formulas written in MathML 2.0.
6164 */
6165 
6166 /*!
6167   Constructs an empty MML document.
6168 */
QwtMathMLDocument()6169 QwtMathMLDocument::QwtMathMLDocument()
6170 {
6171     m_doc = new QwtMmlDocument;
6172 }
6173 
6174 /*!
6175   Destroys the MML document.
6176 */
~QwtMathMLDocument()6177 QwtMathMLDocument::~QwtMathMLDocument()
6178 {
6179     delete m_doc;
6180 }
6181 
6182 /*!
6183     Clears the contents of this MML document.
6184 */
clear()6185 void QwtMathMLDocument::clear()
6186 {
6187     m_doc->clear();
6188 }
6189 
6190 /*!
6191     Sets the MathML expression to be rendered. The expression is given
6192     in the string \a text. If the expression is successfully parsed,
6193     this method returns true; otherwise it returns false. If an error
6194     occured \a errorMsg is set to a diagnostic message, while \a
6195     errorLine and \a errorColumn contain the location of the error.
6196     Any of \a errorMsg, \a errorLine and \a errorColumn may be 0,
6197     in which case they are not set.
6198 
6199     \a text should contain MathML 2.0 presentation markup elements enclosed
6200     in a <math> element.
6201 */
setContent(QString text,QString * errorMsg,int * errorLine,int * errorColumn)6202 bool QwtMathMLDocument::setContent( QString text, QString *errorMsg,
6203                                     int *errorLine, int *errorColumn )
6204 {
6205     return m_doc->setContent( text, errorMsg, errorLine, errorColumn );
6206 }
6207 
6208 /*!
6209   Renders this MML document with the painter \a p at position \a pos.
6210 */
paint(QPainter * p,const QPoint & pos) const6211 void QwtMathMLDocument::paint( QPainter *p, const QPoint &pos ) const
6212 {
6213     m_doc->paint( p, pos );
6214 }
6215 
6216 /*!
6217     Returns the size of this MML document, as rendered, in pixels.
6218 */
size() const6219 QSize QwtMathMLDocument::size() const
6220 {
6221     return m_doc->size();
6222 }
6223 
6224 /*!
6225     Returns the name of the font used to render the font \a type.
6226 
6227     \sa setFontName()  setBaseFontPointSize() baseFontPointSize() QwtMathMLDocument::MmlFont
6228 */
fontName(QwtMathMLDocument::MmlFont type) const6229 QString QwtMathMLDocument::fontName( QwtMathMLDocument::MmlFont type ) const
6230 {
6231     return m_doc->fontName( type );
6232 }
6233 
6234 /*!
6235     Sets the name of the font used to render the font \a type to \a name.
6236 
6237     \sa fontName() setBaseFontPointSize() baseFontPointSize() QwtMathMLDocument::MmlFont
6238 */
setFontName(QwtMathMLDocument::MmlFont type,const QString & name)6239 void QwtMathMLDocument::setFontName( QwtMathMLDocument::MmlFont type, const QString &name )
6240 {
6241     m_doc->setFontName( type, name );
6242 }
6243 
6244 /*!
6245     Returns the point size of the font used to render expressions
6246     whose scriptlevel is 0.
6247 
6248     \sa setBaseFontPointSize() fontName() setFontName()
6249 */
baseFontPointSize() const6250 int QwtMathMLDocument::baseFontPointSize() const
6251 {
6252     return m_doc->baseFontPointSize();
6253 }
6254 
6255 /*!
6256     Sets the point \a size of the font used to render expressions
6257     whose scriptlevel is 0.
6258 
6259     \sa baseFontPointSize() fontName() setFontName()
6260 */
setBaseFontPointSize(int size)6261 void QwtMathMLDocument::setBaseFontPointSize( int size )
6262 {
6263     m_doc->setBaseFontPointSize( size );
6264 }
6265