[Libreoffice-commits] core.git: compilerplugins/clang include/xmloff starmath/inc starmath/Library_sm.mk starmath/source xmloff/source

dante (via logerrit) logerrit at kemper.freedesktop.org
Tue Nov 10 06:59:53 UTC 2020


 compilerplugins/clang/sequentialassign.cxx |    1 
 include/xmloff/xmltoken.hxx                |    2 
 starmath/Library_sm.mk                     |    1 
 starmath/inc/parse.hxx                     |    2 
 starmath/inc/starmathdatabase.hxx          |   56 +++
 starmath/inc/strings.hrc                   |    4 
 starmath/inc/strings.hxx                   |    4 
 starmath/inc/token.hxx                     |   25 +
 starmath/inc/types.hxx                     |    1 
 starmath/source/ElementsDockingWindow.cxx  |    4 
 starmath/source/mathmlexport.cxx           |    2 
 starmath/source/mathmlimport.cxx           |   61 +++-
 starmath/source/parse.cxx                  |  122 ++++++--
 starmath/source/starmathdatabase.cxx       |  358 ++++++++++++++++++++++++
 starmath/source/visitors.cxx               |  422 +++++++----------------------
 xmloff/source/core/xmltoken.cxx            |    2 
 xmloff/source/token/tokens.txt             |    2 
 17 files changed, 711 insertions(+), 358 deletions(-)

New commits:
commit 7e2c35324c54646f53f0fa14b7bce07e1da73c0b
Author:     dante <dante19031999 at gmail.com>
AuthorDate: Tue Nov 3 18:51:19 2020 +0100
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Tue Nov 10 07:59:14 2020 +0100

    Evaluate command: tdf#109338
    
    Adds evaluate command.
    It's visible from UI as a bracket.
    Example: evaluate { {1} over {%sigma sqrt{2%pi} }func e^-{{(x-%mu)^2} over {2%sigma^2}} } from { -infinity } to { +infinity } = 0
    
    In order to make the mathml part, several changes had to be mad:
     - Allow mathml to correctly identify the math token for opperators
     - Allow mathml to correctly identify the math token for fences
       - Since improvements where made on token recognision, visitors to string can now be lighter ( removing long long switch )
     - Improving the import / export to mathm
     - LO says it mathml 2, but actually is something between 2 and 3
       - Allowing mfenced ( mathml 2.0 ) to stayl 3 adding the missing data ( prefix and postfix )
         - Be able to know if we are opening or closing brackets
       - lrline and lrdline commands hidden on UI.
         - They are they own open close
         - If prefix and postfix are missing meaning of the expression may change, however that's the user problem.
         - The problem resides in the fact that MS_VERTLINE is uses for lline and rline.
         - The problem resides in the fact that MS_DVERTLINE is uses for ldline and rdline.
     - Changing frac priority from 0 to 5, if not { frac 1 2 frac 1 2 } fails ( found while testing )
     - The mathml testing was made with highter standars than qa tests, however there are no guarantees.
     - Added xml tokens needed for math
     - Added starmathdatabase. Will grow in the future.
       The point is avoiding long lists and swtches inside code.
    
    Added it command for hidden or implicit product ( like ⁢ in mathml ). Oppens path for tdf#66200. Note that about this issue there is only one line on the parser. The mathml implementation will be made later when LO will allow chars with &charname;.
    
    Change-Id: If24b40c2420d39498693944f13a02985f997dd23
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105267
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/compilerplugins/clang/sequentialassign.cxx b/compilerplugins/clang/sequentialassign.cxx
index 33b1afa6852a..a89afea43438 100644
--- a/compilerplugins/clang/sequentialassign.cxx
+++ b/compilerplugins/clang/sequentialassign.cxx
@@ -118,6 +118,7 @@ public:
             || fn == SRCDIR "/starmath/source/cfgitem.cxx"
             || fn == SRCDIR "/ucb/source/ucp/ftp/ftpurl.cxx"
             || fn == SRCDIR "/starmath/source/node.cxx"
+            || fn == SRCDIR "/starmath/source/starmathdatabase.cxx"
             || fn == SRCDIR "/ucb/source/ucp/cmis/certvalidation_handler.cxx"
             || fn == SRCDIR "/reportdesign/source/ui/inspection/GeometryHandler.cxx"
             || fn == SRCDIR "/reportdesign/source/core/api/ReportDefinition.cxx"
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 99b94be7e2cc..6b2fed011a39 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -1477,6 +1477,8 @@ namespace xmloff::token {
         XML_POWER,
         XML_PRECISION_AS_SHOWN,
         XML_PREFIX,
+        XML_INFIX,
+        XML_POSTFIX,
         XML_PRESENTATION,
         XML_PRESENTATION_ORGCHART,
         XML_PRESENTATION_OUTLINE,
diff --git a/starmath/Library_sm.mk b/starmath/Library_sm.mk
index 5d75c87eb58f..a63b506783e1 100644
--- a/starmath/Library_sm.mk
+++ b/starmath/Library_sm.mk
@@ -98,6 +98,7 @@ $(eval $(call gb_Library_add_exception_objects,sm,\
         starmath/source/view \
         starmath/source/visitors \
         starmath/source/wordexportbase \
+        starmath/source/starmathdatabase \
 ))
 
 
diff --git a/starmath/inc/parse.hxx b/starmath/inc/parse.hxx
index f0783835fe21..020d22fb37b4 100644
--- a/starmath/inc/parse.hxx
+++ b/starmath/inc/parse.hxx
@@ -104,6 +104,7 @@ class SmParser
     std::unique_ptr<SmNode> DoSum();
     std::unique_ptr<SmNode> DoProduct();
     std::unique_ptr<SmNode> DoSubSup(TG nActiveGroup, SmNode *pGivenNode);
+    std::unique_ptr<SmNode> DoSubSupEvaluate(SmNode *pGivenNode);
     std::unique_ptr<SmNode> DoOpSubSup();
     std::unique_ptr<SmNode> DoPower();
     std::unique_ptr<SmBlankNode> DoBlank();
@@ -120,6 +121,7 @@ class SmParser
     std::unique_ptr<SmStructureNode> DoColor();
     std::unique_ptr<SmStructureNode> DoBrace();
     std::unique_ptr<SmBracebodyNode> DoBracebody(bool bIsLeftRight);
+    std::unique_ptr<SmNode> DoEvaluate();
     std::unique_ptr<SmTextNode> DoFunction();
     std::unique_ptr<SmTableNode> DoBinom();
     std::unique_ptr<SmBinVerNode> DoFrac();
diff --git a/starmath/inc/starmathdatabase.hxx b/starmath/inc/starmathdatabase.hxx
new file mode 100644
index 000000000000..999b983f06b3
--- /dev/null
+++ b/starmath/inc/starmathdatabase.hxx
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "token.hxx"
+#include "types.hxx"
+
+namespace starmathdatabase
+{
+/**
+      * Identifies operator chars tokens for importing mathml.
+      * Identifies from char cChar
+      * @param cChar
+      * @return closing fences' token
+      */
+SmToken Identify_SmXMLOperatorContext_Impl(sal_Unicode cChar, bool bIsStretchy = true);
+
+/**
+      * Identifies opening / closing brace tokens for importing mathml.
+      * Identifies from char cChar
+      * @param cChar
+      * @return closing fences' token
+      */
+SmToken Identify_PrefixPostfix_SmXMLOperatorContext_Impl(sal_Unicode cChar);
+
+/**
+      * Identifies opening brace tokens for importing mathml.
+      * Identifies from char cChar
+      * @param cChar
+      * @return closing fences' token
+      */
+SmToken Identify_Prefix_SmXMLOperatorContext_Impl(sal_Unicode cChar);
+
+/**
+      * Identifies closing brace tokens for importing mathml.
+      * Identifies from char cChar
+      * @param cChar
+      * @return closing fences' token
+      */
+SmToken Identify_Postfix_SmXMLOperatorContext_Impl(sal_Unicode cChar);
+}
diff --git a/starmath/inc/strings.hrc b/starmath/inc/strings.hrc
index 09b2b394c619..fb9fecc8e4b5 100644
--- a/starmath/inc/strings.hrc
+++ b/starmath/inc/strings.hrc
@@ -229,6 +229,10 @@
 #define RID_XEVALUATEDATY_HELP              NC_("RID_XEVALUATEDATY_HELP", "Evaluated At" )
 #define RID_XOVERBRACEY_HELP                NC_("RID_XOVERBRACEY_HELP", "Braces Top (Scalable)" )
 #define RID_XUNDERBRACEY_HELP               NC_("RID_XUNDERBRACEY_HELP", "Braces Bottom (Scalable)" )
+#define RID_EVALUATEX_HELP                  NC_("RID_EVALUATEX_HELP", "Evaluate" )
+#define RID_EVALUATE_FROMX_HELP             NC_("RID_EVALUATE_FROMX_HELP", "Evaluate Subscript Bottom" )
+#define RID_EVALUATE_TOX_HELP               NC_("RID_EVALUATE_TOX_HELP", "Evaluate Superscript Top" )
+#define RID_EVALUATE_FROMTOX_HELP           NC_("RID_EVALUATE_FROMTOX_HELP", "Evaluate Sup/Sub script" )
 #define RID_RSUBX_HELP                      NC_("RID_RSUBX_HELP", "Subscript Right" )
 #define RID_RSUPX_HELP                      NC_("RID_RSUPX_HELP", "Power" )
 #define RID_LSUBX_HELP                      NC_("RID_LSUBX_HELP", "Subscript Left" )
diff --git a/starmath/inc/strings.hxx b/starmath/inc/strings.hxx
index 6f81277d1a3e..004e55a8f170 100644
--- a/starmath/inc/strings.hxx
+++ b/starmath/inc/strings.hxx
@@ -221,6 +221,10 @@
 #define RID_XEVALUATEDATY   "left none {<?>} right rline_{<?>} "
 #define RID_XOVERBRACEY     "{<?>} overbrace {<?>} "
 #define RID_XUNDERBRACEY    "{<?>} underbrace {<?>} "
+#define RID_EVALX           "evaluate <?> "
+#define RID_EVAL_FROMX      "evaluate {<?>} from{<?>} "
+#define RID_EVAL_TOX        "evaluate {<?>} to{<?>} "
+#define RID_EVAL_FROMTOX    "evaluate {<?>} from{<?>} to{<?>} "
 #define RID_RSUBX           "<?>_{<?>}"
 #define RID_RSUPX           "<?>^{<?>}"
 #define RID_LSUBX           "<?> lsub{<?>} "
diff --git a/starmath/inc/token.hxx b/starmath/inc/token.hxx
index caae616e475a..d5f90abcada4 100644
--- a/starmath/inc/token.hxx
+++ b/starmath/inc/token.hxx
@@ -66,7 +66,7 @@ enum SmTokenType
     TEND,           TSPECIAL,       TNONE,          TESCAPE,        TUNKNOWN,
     TBLANK,         TSBLANK,        TPLACE,         TNOSPACE,       TDOTSDOWN,
     TNEWLINE,       TDOTSAXIS,      TDOTSLOW,       TDOTSVERT,      TBACKEPSILON,
-    TDOTSDIAG,      TDOTSUP,        TFRAC,
+    TDOTSDIAG,      TDOTSUP,        TERROR,
     // Basic
     TPLUS,          TMINUS,         TMULTIPLY,      TDIVIDEBY,      // +-*/
     TGT,            TLT,            TGE,            TLE,            // > < >= <=
@@ -78,6 +78,7 @@ enum SmTokenType
     TLIM,           TLIMSUP,        TLIMINF,        TTOWARD,        // Limits
     TOVER,          TTIMES,         TCDOT,          TDIV,           // Product type
     TSLASH,         TBACKSLASH,     TWIDESLASH,     TWIDEBACKSLASH, //Slash
+    TFRAC,          TIT,                                            // mathml related
     // Structure
     TMATRIX,         TPOUND,        TDPOUND,        TSTACK,         TBINOM,
     // Logic
@@ -119,8 +120,8 @@ enum SmTokenType
     TLBRACKET,      TRBRACKET,      TLDBRACKET,     TRDBRACKET,     // Bracket x1 & x2
     TLCEIL,         TRCEIL,         TLFLOOR,        TRFLOOR,        // Reals -> Wholes
     TLANGLE,        TRANGLE,        TLBRACE,        TRBRACE,        // <x> {x}
-    // Brackets Lines
-    TLLINE,         TRLINE,         TLDLINE,        TRDLINE,        TMLINE,
+    TLLINE,         TRLINE,         TLDLINE,        TRDLINE,        // Lines x1 x2
+    TMLINE,         TEVALUATE,      TLRLINE,        TLRDLINE,       // Custom
     // Differential calculus
     TNABLA,         TPARTIAL,       TFOURIER,       TLAPLACE,       // Derivative, Transformation
     TINTD,          TINT,           TIINT,          TIIINT,         // Integral
@@ -156,12 +157,26 @@ struct SmToken
     sal_Int32      nRow; // 1-based
     sal_Int32      nCol; // 1-based
 
-    SmToken();
+    SmToken()
+        : eType(TUNKNOWN)
+        , cMathChar('\0')
+        , nGroup(TG::NONE)
+        , nLevel(0)
+        , nRow(0)
+        , nCol(0) {}
+
     SmToken(SmTokenType eTokenType,
             sal_Unicode cMath,
             const char* pText,
             TG nTokenGroup = TG::NONE,
-            sal_uInt16 nTokenLevel = 0);
+            sal_uInt16 nTokenLevel = 0)
+        : aText(OUString::createFromAscii(pText))
+        , eType(eTokenType)
+        , cMathChar(cMath)
+        , nGroup(nTokenGroup)
+        , nLevel(nTokenLevel)
+        , nRow(0)
+        , nCol(0){}
 };
 
 struct SmTokenTableEntry
diff --git a/starmath/inc/types.hxx b/starmath/inc/types.hxx
index d71c87214a4f..6efd585fb28d 100644
--- a/starmath/inc/types.hxx
+++ b/starmath/inc/types.hxx
@@ -32,6 +32,7 @@ enum SmPrintSize { PRINT_SIZE_NORMAL, PRINT_SIZE_SCALED, PRINT_SIZE_ZOOMED };
 //! Note: not listed here does not(!) mean "not used"
 //!     (see %alpha ... %gamma for example)
 
+sal_Unicode const MS_NONE = '\0';
 sal_Unicode const MS_FACT = 0x0021;
 sal_Unicode const MS_INFINITY = 0x221E;
 sal_Unicode const MS_SLASH = 0x002F;
diff --git a/starmath/source/ElementsDockingWindow.cxx b/starmath/source/ElementsDockingWindow.cxx
index aa96a1e0bb7f..ab9d72343be2 100644
--- a/starmath/source/ElementsDockingWindow.cxx
+++ b/starmath/source/ElementsDockingWindow.cxx
@@ -209,9 +209,11 @@ const SmElementDescr SmElementsControl::m_aBracketsList[] =
     {RID_SLRANGLEX, RID_SLRANGLEX_HELP}, {RID_SLMRANGLEXY, RID_SLMRANGLEXY_HELP},
     {RID_SLRCEILX, RID_SLRCEILX_HELP}, {RID_SLRFLOORX, RID_SLRFLOORX_HELP},
     {RID_SLRLINEX, RID_SLRLINEX_HELP}, {RID_SLRDLINEX, RID_SLRDLINEX_HELP},
-    {RID_XEVALUATEDATY, RID_XEVALUATEDATY_HELP},
     {nullptr, nullptr},
     {RID_XOVERBRACEY, RID_XOVERBRACEY_HELP}, {RID_XUNDERBRACEY, RID_XUNDERBRACEY_HELP},
+    {nullptr, nullptr},
+    {RID_EVALX, RID_EVALUATEX_HELP}, {RID_EVAL_FROMX, RID_EVALUATE_FROMX_HELP},
+    {RID_EVAL_TOX, RID_EVALUATE_TOX_HELP}, {RID_EVAL_FROMTOX, RID_EVALUATE_FROMTOX_HELP},
 };
 
 const SmElementDescr SmElementsControl::m_aFormatsList[] =
diff --git a/starmath/source/mathmlexport.cxx b/starmath/source/mathmlexport.cxx
index 821144aa6a62..f570ff561552 100644
--- a/starmath/source/mathmlexport.cxx
+++ b/starmath/source/mathmlexport.cxx
@@ -998,6 +998,7 @@ void SmXMLExport::ExportBrace(const SmNode *pNode, int nLevel)
     if (pLeft && (pLeft->GetToken().eType != TNONE))
     {
         AddAttribute(XML_NAMESPACE_MATH, XML_FENCE, XML_TRUE);
+        AddAttribute(XML_NAMESPACE_MATH, XML_FORM, XML_PREFIX);
         if (pNode->GetScaleMode() == SmScaleMode::Height)
             AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_TRUE);
         else
@@ -1018,6 +1019,7 @@ void SmXMLExport::ExportBrace(const SmNode *pNode, int nLevel)
     if (pRight && (pRight->GetToken().eType != TNONE))
     {
         AddAttribute(XML_NAMESPACE_MATH, XML_FENCE, XML_TRUE);
+        AddAttribute(XML_NAMESPACE_MATH, XML_FORM, XML_POSTFIX);
         if (pNode->GetScaleMode() == SmScaleMode::Height)
             AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_TRUE);
         else
diff --git a/starmath/source/mathmlimport.cxx b/starmath/source/mathmlimport.cxx
index db56d3ced2da..587ba3ca6458 100644
--- a/starmath/source/mathmlimport.cxx
+++ b/starmath/source/mathmlimport.cxx
@@ -72,6 +72,7 @@ one go*/
 #include <unomodel.hxx>
 #include <utility.hxx>
 #include <visitors.hxx>
+#include <starmathdatabase.hxx>
 
 using namespace ::com::sun::star::beans;
 using namespace ::com::sun::star::container;
@@ -1043,11 +1044,13 @@ class SmXMLFencedContext_Impl : public SmXMLRowContext_Impl
 protected:
     sal_Unicode cBegin;
     sal_Unicode cEnd;
+    bool bIsStretchy;
 
 public:
     SmXMLFencedContext_Impl(SmXMLImport &rImport)
-        : SmXMLRowContext_Impl(rImport),
-        cBegin('('), cEnd(')') {}
+        : SmXMLRowContext_Impl(rImport)
+        , cBegin('('), cEnd(')')
+        , bIsStretchy(false) {}
 
     void SAL_CALL startFastElement(sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList > & xAttrList ) override;
     void SAL_CALL endFastElement(sal_Int32 nElement) override;
@@ -1070,6 +1073,9 @@ void SmXMLFencedContext_Impl::startFastElement(sal_Int32 /*nElement*/, const uno
             case XML_CLOSE:
                 cEnd = sValue[0];
                 break;
+            case XML_STRETCHY:
+                bIsStretchy = sValue == GetXMLToken(XML_TRUE);
+                break;
             default:
                 XMLOFF_WARN_UNKNOWN("starmath", aIter);
                 /*Go to superclass*/
@@ -1086,18 +1092,18 @@ void SmXMLFencedContext_Impl::endFastElement(sal_Int32 /*nElement*/)
     aToken.aText = ",";
     aToken.nLevel = 5;
 
-    aToken.eType = TLPARENT;
-    aToken.cMathChar = cBegin;
     std::unique_ptr<SmStructureNode> pSNode(new SmBraceNode(aToken));
+    if( bIsStretchy ) aToken = starmathdatabase::Identify_PrefixPostfix_SmXMLOperatorContext_Impl( cBegin );
+    else aToken = starmathdatabase::Identify_Prefix_SmXMLOperatorContext_Impl( cBegin );
+    if( aToken.eType == TERROR  ) aToken = SmToken( TLPARENT, MS_LPARENT, "(", TG::LBrace, 5 );
     std::unique_ptr<SmNode> pLeft(new SmMathSymbolNode(aToken));
-
-    aToken.cMathChar = cEnd;
-    aToken.eType = TRPARENT;
+    if( bIsStretchy ) aToken = starmathdatabase::Identify_PrefixPostfix_SmXMLOperatorContext_Impl( cEnd );
+    else aToken = starmathdatabase::Identify_Postfix_SmXMLOperatorContext_Impl( cEnd );
+    if( aToken.eType == TERROR  ) aToken = SmToken( TRPARENT, MS_RPARENT, ")", TG::LBrace, 5 );
     std::unique_ptr<SmNode> pRight(new SmMathSymbolNode(aToken));
 
     SmNodeArray aRelationArray;
     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
-
     aToken.cMathChar = '\0';
     aToken.eType = TIDENT;
 
@@ -1120,6 +1126,8 @@ void SmXMLFencedContext_Impl::endFastElement(sal_Int32 /*nElement*/)
 
 
     pSNode->SetSubNodes(std::move(pLeft), std::move(pBody), std::move(pRight));
+    // mfenced is always scalable. Stretchy keyword is not official, but in case of been in there
+    // can be used as a hint.
     pSNode->SetScaleMode(SmScaleMode::Height);
     GetSmImport().GetNodeStack().push_front(std::move(pSNode));
 }
@@ -1375,6 +1383,10 @@ class SmXMLOperatorContext_Impl : public SmXMLImportContext
 {
     SmXMLTokenAttrHelper maTokenAttrHelper;
     bool bIsStretchy;
+    bool bIsFenced;
+    bool isPrefix;
+    bool isInfix;
+    bool isPostfix;
     SmToken aToken;
 
 public:
@@ -1382,6 +1394,10 @@ public:
         : SmXMLImportContext(rImport)
         , maTokenAttrHelper(*this)
         , bIsStretchy(false)
+        , bIsFenced(false)
+        , isPrefix(false)
+        , isInfix(false)
+        , isPostfix(false)
     {
         aToken.eType = TSPECIAL;
         aToken.nLevel = 5;
@@ -1397,6 +1413,25 @@ public:
 void SmXMLOperatorContext_Impl::TCharacters(const OUString &rChars)
 {
     aToken.cMathChar = rChars[0];
+    SmToken bToken;
+    if( bIsFenced ){
+        if( bIsStretchy )
+        {
+            if( isPrefix ) bToken = starmathdatabase::Identify_Prefix_SmXMLOperatorContext_Impl( aToken.cMathChar );
+            else if( isInfix ) bToken = SmToken( TMLINE, MS_VERTLINE, "mline", TG::NONE, 0 );
+            else if( isPostfix ) bToken = starmathdatabase::Identify_Postfix_SmXMLOperatorContext_Impl( aToken.cMathChar );
+            else bToken = starmathdatabase::Identify_PrefixPostfix_SmXMLOperatorContext_Impl( aToken.cMathChar );
+        }
+        else
+        {
+            if( isPrefix ) bToken = starmathdatabase::Identify_Prefix_SmXMLOperatorContext_Impl( aToken.cMathChar );
+            else if( isInfix ) bToken = SmToken( TMLINE, MS_VERTLINE, "mline", TG::NONE, 0 );
+            else if( isPostfix ) bToken = starmathdatabase::Identify_Postfix_SmXMLOperatorContext_Impl( aToken.cMathChar );
+            else bToken = starmathdatabase::Identify_PrefixPostfix_SmXMLOperatorContext_Impl( aToken.cMathChar );
+        }
+    }
+    else bToken = starmathdatabase::Identify_SmXMLOperatorContext_Impl( aToken.cMathChar, bIsStretchy );
+    if( bToken.eType != TERROR ) aToken = bToken;
 }
 
 void SmXMLOperatorContext_Impl::endFastElement(sal_Int32 )
@@ -1428,6 +1463,14 @@ void SmXMLOperatorContext_Impl::startFastElement(sal_Int32 /*nElement*/, const u
             case XML_STRETCHY:
                 bIsStretchy = sValue == GetXMLToken(XML_TRUE);
                 break;
+            case XML_FENCE:
+                bIsFenced   = sValue == GetXMLToken(XML_TRUE);
+                break;
+            case XML_FORM:
+                isPrefix    = sValue == GetXMLToken(XML_PREFIX);    // <
+                isInfix     = sValue == GetXMLToken(XML_INFIX);     // |
+                isPostfix   = sValue == GetXMLToken(XML_POSTFIX);   // >
+                break;
             default:
                 XMLOFF_WARN_UNKNOWN("starmath", aIter);
                 break;
@@ -2229,12 +2272,14 @@ void SmXMLRowContext_Impl::endFastElement(sal_Int32 )
         aToken.cMathChar = MS_LBRACE;
         aToken.nLevel = 5;
         aToken.eType = TLGROUP;
+        aToken.nGroup = TG::NONE;
         aToken.aText = "{";
         aRelationArray[0] = new SmLineNode(aToken);
 
         aToken.cMathChar = MS_RBRACE;
         aToken.nLevel = 0;
         aToken.eType = TRGROUP;
+        aToken.nGroup = TG::NONE;
         aToken.aText = "}";
         aRelationArray[1] = new SmLineNode(aToken);
     }
diff --git a/starmath/source/parse.cxx b/starmath/source/parse.cxx
index 598ec121611b..803f97425a6d 100644
--- a/starmath/source/parse.cxx
+++ b/starmath/source/parse.cxx
@@ -38,32 +38,6 @@
 
 using namespace ::com::sun::star::i18n;
 
-
-SmToken::SmToken()
-    : eType(TUNKNOWN)
-    , cMathChar('\0')
-    , nGroup(TG::NONE)
-    , nLevel(0)
-    , nRow(0)
-    , nCol(0)
-{
-}
-
-SmToken::SmToken(SmTokenType eTokenType,
-                 sal_Unicode cMath,
-                 const char* pText,
-                 TG nTokenGroup,
-                 sal_uInt16 nTokenLevel)
-    : aText(OUString::createFromAscii(pText))
-    , eType(eTokenType)
-    , cMathChar(cMath)
-    , nGroup(nTokenGroup)
-    , nLevel(nTokenLevel)
-    , nRow(0)
-    , nCol(0)
-{
-}
-
 //Definition of math keywords
 const SmTokenTableEntry aTokenTable[] =
 {
@@ -123,6 +97,7 @@ const SmTokenTableEntry aTokenTable[] =
     { "drarrow" , TDRARROW, MS_DRARROW, TG::Standalone, 5},
     { "emptyset" , TEMPTYSET, MS_EMPTYSET, TG::Standalone, 5},
     { "equiv", TEQUIV, MS_EQUIV, TG::Relation, 0},
+    { "evaluate", TEVALUATE, '\0', TG::NONE, 0},
     { "exists", TEXISTS, MS_EXISTS, TG::Standalone, 5},
     { "exp", TEXP, '\0', TG::Function, 5},
     { "fact", TFACT, MS_FACT, TG::UnOper, 5},
@@ -130,7 +105,7 @@ const SmTokenTableEntry aTokenTable[] =
     { "font", TFONT, '\0', TG::FontAttr, 5},
     { "forall", TFORALL, MS_FORALL, TG::Standalone, 5},
     { "fourier", TFOURIER, MS_FOURIER, TG::Standalone, 5},
-    { "frac", TFRAC, '\0', TG::NONE, 0},
+    { "frac", TFRAC, '\0', TG::NONE, 5},
     { "from", TFROM, '\0', TG::Limit, 0},
     { "func", TFUNC, '\0', TG::Function, 5},
     { "ge", TGE, MS_GE, TG::Relation, 0},
@@ -150,6 +125,7 @@ const SmTokenTableEntry aTokenTable[] =
     { "int", TINT, MS_INT, TG::Oper, 5},
     { "intd", TINTD, MS_INT, TG::Oper, 5},
     { "intersection", TINTERSECT, MS_INTERSECT, TG::Product, 0},
+    { "it", TIT, '\0', TG::Product, 0},
     { "ital", TITALIC, '\0', TG::FontAttr, 5},
     { "italic", TITALIC, '\0', TG::FontAttr, 5},
     { "lambdabar" , TLAMBDABAR, MS_LAMBDABAR, TG::Standalone, 5},
@@ -174,6 +150,8 @@ const SmTokenTableEntry aTokenTable[] =
     { "lllint", TLLLINT, MS_LLLINT, TG::Oper, 5},
     { "ln", TLN, '\0', TG::Function, 5},
     { "log", TLOG, '\0', TG::Function, 5},
+    { "lrline", TLRLINE, MS_VERTLINE, TG::LBrace | TG::RBrace, 5},
+    { "lrdline", TLRDLINE, MS_VERTLINE, TG::LBrace | TG::RBrace, 5},
     { "lsub", TLSUB, '\0', TG::Power, 0},
     { "lsup", TLSUP, '\0', TG::Power, 0},
     { "lt", TLT, MS_LT, TG::Relation, 0},
@@ -1513,6 +1491,55 @@ std::unique_ptr<SmNode> SmParser::DoSubSup(TG nActiveGroup, SmNode *pGivenNode)
     return pNode;
 }
 
+std::unique_ptr<SmNode> SmParser::DoSubSupEvaluate(SmNode *pGivenNode)
+{
+    std::unique_ptr<SmNode> xGivenNode(pGivenNode);
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep()) throw std::range_error("parser depth limit");
+
+    std::unique_ptr<SmSubSupNode> pNode(new SmSubSupNode(m_aCurToken));
+    pNode->SetUseLimits(true);
+
+    // initialize subnodes array
+    std::vector<std::unique_ptr<SmNode>> aSubNodes(1 + SUBSUP_NUM_ENTRIES);
+    aSubNodes[0] = std::move(xGivenNode);
+
+    // process all sub-/supscripts
+    int  nIndex = 0;
+    while (TokenInGroup(TG::Limit))
+    {
+        SmTokenType  eType (m_aCurToken.eType);
+
+        switch (eType)
+        {
+            case TFROM :    nIndex = static_cast<int>(RSUB);    break;
+            case TTO   :    nIndex = static_cast<int>(RSUP);    break;
+            default :
+                SAL_WARN( "starmath", "unknown case");
+        }
+        nIndex++;
+        assert(1 <= nIndex  &&  nIndex <= SUBSUP_NUM_ENTRIES);
+
+        std::unique_ptr<SmNode> xENode;
+        if (aSubNodes[nIndex]) // if already occupied at earlier iteration
+        {
+            // forget the earlier one, remember an error instead
+            aSubNodes[nIndex].reset();
+            xENode = DoError(SmParseError::DoubleSubsupscript); // this also skips current token.
+        }
+        else NextToken(); // skip sub-/supscript token
+
+        // get sub-/supscript node
+        std::unique_ptr<SmNode> xSNode;
+        xSNode = DoTerm(true);
+
+        aSubNodes[nIndex] = std::move(xENode ? xENode : xSNode);
+    }
+
+    pNode->SetSubNodes(buildNodeArray(aSubNodes));
+    return pNode;
+}
+
 std::unique_ptr<SmNode> SmParser::DoOpSubSup()
 {
     DepthProtect aDepthGuard(m_nParseDepth);
@@ -1613,6 +1640,8 @@ std::unique_ptr<SmNode> SmParser::DoTerm(bool bGroupNumberIdent)
 
         case TLEFT :
             return DoBrace();
+                   case TEVALUATE:
+            return DoEvaluate();
 
         case TBLANK :
         case TSBLANK :
@@ -2302,6 +2331,8 @@ std::unique_ptr<SmStructureNode> SmParser::DoBrace()
             case TLANGLE :      eExpectedType = TRANGLE;    break;
             case TLFLOOR :      eExpectedType = TRFLOOR;    break;
             case TLCEIL :       eExpectedType = TRCEIL;     break;
+            case TLRLINE :      eExpectedType = TLRLINE;    break;
+            case TLRDLINE :     eExpectedType = TLRDLINE;   break;
             default :
                 SAL_WARN("starmath", "unknown case");
             }
@@ -2376,6 +2407,43 @@ std::unique_ptr<SmBracebodyNode> SmParser::DoBracebody(bool bIsLeftRight)
     return pBody;
 }
 
+std::unique_ptr<SmNode> SmParser::DoEvaluate()
+{
+
+    // Checkout depth and create node
+    DepthProtect aDepthGuard(m_nParseDepth);
+    if (aDepthGuard.TooDeep()) throw std::range_error("parser depth limit");
+    std::unique_ptr<SmStructureNode> xSNode(new SmBraceNode(m_aCurToken));
+    SmToken aToken( TRLINE, MS_VERTLINE, "evaluate", TG::RBrace, 5);
+    aToken.nRow = m_aCurToken.nRow;
+    aToken.nCol = m_aCurToken.nCol;
+
+    // Parse body && left none
+    NextToken();
+    std::unique_ptr<SmNode> pBody = DoPower();
+    SmToken bToken( TNONE, '\0', "", TG::LBrace, 5);
+    std::unique_ptr<SmNode> pLeft;
+    pLeft.reset(new SmMathSymbolNode(bToken));
+
+    // Mount nodes
+    std::unique_ptr<SmNode> pRight;
+    pRight.reset(new SmMathSymbolNode(aToken));
+    xSNode->SetSubNodes(std::move(pLeft), std::move(pBody), std::move(pRight));
+    xSNode->SetScaleMode(SmScaleMode::Height); // scalable line
+
+    // Parse from to
+    if ( m_aCurToken.nGroup == TG::Limit )
+    {
+        std::unique_ptr<SmNode> rSNode;
+        rSNode = DoSubSupEvaluate(xSNode.release());
+        rSNode->GetToken().eType = TEVALUATE;
+        return rSNode;
+    }
+
+    return xSNode;
+
+}
+
 std::unique_ptr<SmTextNode> SmParser::DoFunction()
 {
     DepthProtect aDepthGuard(m_nParseDepth);
diff --git a/starmath/source/starmathdatabase.cxx b/starmath/source/starmathdatabase.cxx
new file mode 100644
index 000000000000..9b1dd659bef5
--- /dev/null
+++ b/starmath/source/starmathdatabase.cxx
@@ -0,0 +1,358 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <starmathdatabase.hxx>
+
+SmToken starmathdatabase::Identify_SmXMLOperatorContext_Impl(sal_Unicode cChar, bool bIsStretchy)
+{
+    switch (cChar)
+    {
+        case MS_COPROD:
+            return SmToken(TCOPROD, MS_COPROD, "coprod", TG::Oper, 5);
+        case MS_IIINT:
+            return SmToken(TIIINT, MS_IIINT, "iiint", TG::Oper, 5);
+        case MS_IINT:
+            return SmToken(TIINT, MS_IINT, "iint", TG::Oper, 5);
+        case MS_INT:
+            if (bIsStretchy)
+                return SmToken(TINTD, MS_INT, "intd", TG::Oper, 5);
+            else
+                return SmToken(TINT, MS_INT, "int", TG::Oper, 5);
+        case MS_LINT:
+            return SmToken(TLINT, MS_LINT, "lint", TG::Oper, 5);
+        case MS_LLINT:
+            return SmToken(TLLINT, MS_LLINT, "llint", TG::Oper, 5);
+        case MS_LLLINT:
+            return SmToken(TLLLINT, MS_LLLINT, "lllint", TG::Oper, 5);
+        case MS_PROD:
+            return SmToken(TPROD, MS_PROD, "prod", TG::Oper, 5);
+        case MS_SUM:
+            return SmToken(TSUM, MS_SUM, "sum", TG::Oper, 5);
+        case MS_FACT:
+            return SmToken(TFACT, MS_FACT, "!", TG::UnOper, 5);
+        case MS_NEG:
+            return SmToken(TNEG, MS_NEG, "neg", TG::UnOper, 5);
+        case MS_OMINUS:
+            return SmToken(TOMINUS, MS_OMINUS, "ominus", TG::Sum, 0);
+        case MS_OPLUS:
+            return SmToken(TOPLUS, MS_OPLUS, "oplus", TG::Sum, 0);
+        case MS_UNION:
+            return SmToken(TUNION, MS_UNION, "union", TG::Sum, 0);
+        case MS_OR:
+            return SmToken(TOR, MS_OR, "|", TG::Sum, 5);
+        case MS_PLUSMINUS:
+            return SmToken(TPLUSMINUS, MS_PLUSMINUS, "+-", TG::Sum | TG::UnOper, 5);
+        case MS_MINUSPLUS:
+            return SmToken(TMINUSPLUS, MS_MINUSPLUS, "-+", TG::Sum | TG::UnOper, 5);
+        case 0xe083:
+        case MS_PLUS:
+            return SmToken(TPLUS, MS_PLUS, "+", TG::Sum | TG::UnOper, 5);
+        case MS_MINUS:
+            return SmToken(TMINUS, MS_MINUS, "-", TG::Sum | TG::UnOper, 5);
+        case 0x2022:
+        case MS_CDOT:
+            return SmToken(TCDOT, MS_CDOT, "cdot", TG::Product, 0);
+        case MS_DIV:
+            return SmToken(TDIV, MS_DIV, "div", TG::Product, 0);
+        case MS_TIMES:
+            return SmToken(TTIMES, MS_TIMES, "times", TG::Product, 0);
+        case MS_INTERSECT:
+            return SmToken(TINTERSECT, MS_INTERSECT, "intersection", TG::Product, 0);
+        case MS_ODIVIDE:
+            return SmToken(TODIVIDE, MS_ODIVIDE, "odivide", TG::Product, 0);
+        case MS_ODOT:
+            return SmToken(TODOT, MS_ODOT, "odot", TG::Product, 0);
+        case MS_OTIMES:
+            return SmToken(TOTIMES, MS_OTIMES, "otimes", TG::Product, 0);
+        case MS_AND:
+            return SmToken(TAND, MS_AND, "&", TG::Product, 0);
+        case MS_MULTIPLY:
+            return SmToken(TMULTIPLY, MS_MULTIPLY, "*", TG::Product, 0);
+        case MS_SLASH:
+            if (bIsStretchy)
+                return SmToken(TWIDESLASH, MS_SLASH, "wideslash", TG::Product, 0);
+            else
+                return SmToken(TSLASH, MS_SLASH, "slash", TG::Product, 0);
+        case MS_BACKSLASH:
+            if (bIsStretchy)
+                return SmToken(TWIDEBACKSLASH, MS_BACKSLASH, "bslash", TG::Product, 0);
+            else
+                return SmToken(TBACKSLASH, MS_BACKSLASH, "slash", TG::Product, 0);
+        case MS_DEF:
+            return SmToken(TDEF, MS_DEF, "def", TG::Relation, 0);
+        case MS_LINE:
+            return SmToken(TDIVIDES, MS_LINE, "divides", TG::Relation, 0);
+        case MS_EQUIV:
+            return SmToken(TEQUIV, MS_EQUIV, "equiv", TG::Relation, 0);
+        case MS_GE:
+            return SmToken(TGE, MS_GE, ">=", TG::Relation, 0);
+        case MS_GESLANT:
+            return SmToken(TGESLANT, MS_GESLANT, "geslant", TG::Relation, 0);
+        case MS_GG:
+            return SmToken(TGG, MS_GG, ">>", TG::Relation, 0);
+        case MS_GT:
+            return SmToken(TGT, MS_GT, ">", TG::Relation, 0);
+        case MS_IN:
+            return SmToken(TIN, MS_IN, "in", TG::Relation, 0);
+        case MS_LE:
+            return SmToken(TLE, MS_LE, "<=", TG::Relation, 0);
+        case MS_LESLANT:
+            return SmToken(TLESLANT, MS_LESLANT, "leslant", TG::Relation, 0);
+        case MS_LL:
+            return SmToken(TLL, MS_LL, "<<", TG::Relation, 0);
+        case MS_LT:
+            return SmToken(TLT, MS_LT, "<", TG::Relation, 0);
+        case MS_NDIVIDES:
+            return SmToken(TNDIVIDES, MS_NDIVIDES, "ndivides", TG::Relation, 0);
+        case MS_NEQ:
+            return SmToken(TNEQ, MS_NEQ, "<>", TG::Relation, 0);
+        case MS_NOTIN:
+            return SmToken(TNOTIN, MS_NOTIN, "notin", TG::Relation, 0);
+        case MS_NOTPRECEDES:
+            return SmToken(TNOTPRECEDES, MS_NOTPRECEDES, "nprec", TG::Relation, 0);
+        case MS_NSUBSET:
+            return SmToken(TNSUBSET, MS_NSUBSET, "nsubset", TG::Relation, 0);
+        case MS_NSUBSETEQ:
+            return SmToken(TNSUBSETEQ, MS_NSUBSETEQ, "nsubseteq", TG::Relation, 0);
+        case MS_NOTSUCCEEDS:
+            return SmToken(TNOTSUCCEEDS, MS_NOTSUCCEEDS, "nsucc", TG::Relation, 0);
+        case MS_NSUPSET:
+            return SmToken(TNSUPSET, MS_NSUPSET, "nsupset", TG::Relation, 0);
+        case MS_NSUPSETEQ:
+            return SmToken(TNSUPSETEQ, MS_NSUPSETEQ, "nsupseteq", TG::Relation, 0);
+        case MS_ORTHO:
+            return SmToken(TORTHO, MS_ORTHO, "ortho", TG::Relation, 0);
+        case MS_NI:
+            return SmToken(TNI, MS_NI, "owns", TG::Relation, 0);
+        case MS_DLINE:
+            return SmToken(TPARALLEL, MS_DLINE, "parallel", TG::Relation, 0);
+        case MS_PRECEDES:
+            return SmToken(TPRECEDES, MS_PRECEDES, "prec", TG::Relation, 0);
+        case MS_PRECEDESEQUAL:
+            return SmToken(TPRECEDESEQUAL, MS_PRECEDESEQUAL, "preccurlyeq", TG::Relation, 0);
+        case MS_PRECEDESEQUIV:
+            return SmToken(TPRECEDESEQUIV, MS_PRECEDESEQUIV, "precsim", TG::Relation, 0);
+        case MS_PROP:
+            return SmToken(TPROP, MS_PROP, "prop", TG::Relation, 0);
+        case MS_SIM:
+            return SmToken(TSIM, MS_SIM, "sim", TG::Relation, 0);
+        case 0x2245:
+        case MS_SIMEQ:
+            return SmToken(TSIMEQ, MS_SIMEQ, "simeq", TG::Relation, 0);
+        case MS_SUBSET:
+            return SmToken(TSUBSET, MS_SUBSET, "subset", TG::Relation, 0);
+        case MS_SUBSETEQ:
+            return SmToken(TSUBSETEQ, MS_SUBSETEQ, "subseteq", TG::Relation, 0);
+        case MS_SUCCEEDS:
+            return SmToken(TSUCCEEDS, MS_SUCCEEDS, "succ", TG::Relation, 0);
+        case MS_SUCCEEDSEQUAL:
+            return SmToken(TSUCCEEDSEQUAL, MS_SUCCEEDSEQUAL, "succcurlyeq", TG::Relation, 0);
+        case MS_SUCCEEDSEQUIV:
+            return SmToken(TSUCCEEDSEQUIV, MS_SUCCEEDSEQUIV, "succsim", TG::Relation, 0);
+        case MS_SUPSET:
+            return SmToken(TSUPSET, MS_SUPSET, "supset", TG::Relation, 0);
+        case MS_SUPSETEQ:
+            return SmToken(TSUPSETEQ, MS_SUPSETEQ, "supseteq", TG::Relation, 0);
+        case MS_RIGHTARROW:
+            return SmToken(TTOWARD, MS_RIGHTARROW, "toward", TG::Relation, 0);
+        case MS_TRANSL:
+            return SmToken(TTRANSL, MS_TRANSL, "transl", TG::Relation, 0);
+        case MS_TRANSR:
+            return SmToken(TTRANSR, MS_TRANSR, "transr", TG::Relation, 0);
+        case MS_ASSIGN:
+            return SmToken(TASSIGN, MS_ASSIGN, "=", TG::Relation, 0);
+        case MS_LANGLE:
+            return SmToken(TLANGLE, MS_LMATHANGLE, "langle", TG::LBrace, 5);
+        case MS_LMATHANGLE:
+            return SmToken(TLANGLE, MS_LMATHANGLE, "langle", TG::LBrace, 5);
+        case MS_LBRACE:
+            return SmToken(TLBRACE, MS_LBRACE, "lbrace", TG::LBrace, 5);
+        case MS_LCEIL:
+            return SmToken(TLCEIL, MS_LCEIL, "lceil", TG::LBrace, 5);
+        case MS_LFLOOR:
+            return SmToken(TLFLOOR, MS_LFLOOR, "lfloor", TG::LBrace, 5);
+        case MS_LDBRACKET:
+            return SmToken(TLDBRACKET, MS_LDBRACKET, "ldbracket", TG::LBrace, 5);
+        case MS_LBRACKET:
+            return SmToken(TLBRACKET, MS_LBRACKET, "[", TG::LBrace, 5);
+        case MS_LPARENT:
+            return SmToken(TLPARENT, MS_LPARENT, "(", TG::LBrace, 5);
+        case MS_RANGLE:
+            return SmToken(TRANGLE, MS_RMATHANGLE, "rangle", TG::RBrace, 5);
+        case MS_RMATHANGLE:
+            return SmToken(TRANGLE, MS_RMATHANGLE, "rangle", TG::RBrace, 5);
+        case MS_RBRACE:
+            return SmToken(TRBRACE, MS_RBRACE, "rbrace", TG::RBrace, 5);
+        case MS_RCEIL:
+            return SmToken(TRCEIL, MS_RCEIL, "rceil", TG::RBrace, 5);
+        case MS_RFLOOR:
+            return SmToken(TRFLOOR, MS_RFLOOR, "rfloor", TG::RBrace, 5);
+        case MS_RDBRACKET:
+            return SmToken(TRDBRACKET, MS_RDBRACKET, "rdbracket", TG::RBrace, 5);
+        case MS_RBRACKET:
+            return SmToken(TRBRACKET, MS_RBRACKET, "]", TG::RBrace, 5);
+        case MS_RPARENT:
+            return SmToken(TRPARENT, MS_RPARENT, ")", TG::RBrace, 5);
+        case MS_NONE:
+            return SmToken(TNONE, MS_NONE, "none", TG::RBrace | TG::LBrace, 5);
+        default:
+            return SmToken(TERROR, MS_NONE, "", TG::NONE, SAL_MAX_UINT16);
+    }
+}
+
+SmToken starmathdatabase::Identify_Prefix_SmXMLOperatorContext_Impl(sal_Unicode cChar)
+{
+    switch (cChar)
+    {
+        case MS_VERTLINE:
+            return SmToken(TLLINE, MS_VERTLINE, "lline", TG::LBrace, 5);
+        case MS_DVERTLINE:
+            return SmToken(TLDLINE, MS_DVERTLINE, "ldline", TG::LBrace, 5);
+        case MS_LANGLE:
+            return SmToken(TLANGLE, MS_LMATHANGLE, "langle", TG::LBrace, 5);
+        case MS_LMATHANGLE:
+            return SmToken(TLANGLE, MS_LMATHANGLE, "langle", TG::LBrace, 5);
+        case MS_LBRACE:
+            return SmToken(TLBRACE, MS_LBRACE, "lbrace", TG::LBrace, 5);
+        case MS_LCEIL:
+            return SmToken(TLCEIL, MS_LCEIL, "lceil", TG::LBrace, 5);
+        case MS_LFLOOR:
+            return SmToken(TLFLOOR, MS_LFLOOR, "lfloor", TG::LBrace, 5);
+        case MS_LDBRACKET:
+            return SmToken(TLDBRACKET, MS_LDBRACKET, "ldbracket", TG::LBrace, 5);
+        case MS_LBRACKET:
+            return SmToken(TLBRACKET, MS_LBRACKET, "[", TG::LBrace, 5);
+        case MS_LPARENT:
+            return SmToken(TLPARENT, MS_LPARENT, "(", TG::LBrace, 5);
+        case MS_RANGLE:
+            return SmToken(TRANGLE, MS_RMATHANGLE, "rangle", TG::RBrace, 5);
+        case MS_RMATHANGLE:
+            return SmToken(TRANGLE, MS_RMATHANGLE, "rangle", TG::RBrace, 5);
+        case MS_RBRACE:
+            return SmToken(TRBRACE, MS_RBRACE, "rbrace", TG::RBrace, 5);
+        case MS_RCEIL:
+            return SmToken(TRCEIL, MS_RCEIL, "rceil", TG::RBrace, 5);
+        case MS_RFLOOR:
+            return SmToken(TRFLOOR, MS_RFLOOR, "rfloor", TG::RBrace, 5);
+        case MS_RDBRACKET:
+            return SmToken(TRDBRACKET, MS_RDBRACKET, "rdbracket", TG::RBrace, 5);
+        case MS_RBRACKET:
+            return SmToken(TRBRACKET, MS_RBRACKET, "]", TG::RBrace, 5);
+        case MS_RPARENT:
+            return SmToken(TRPARENT, MS_RPARENT, ")", TG::RBrace, 5);
+        case MS_NONE:
+            return SmToken(TNONE, MS_NONE, "none", TG::LBrace | TG::RBrace, 5);
+        default:
+            return SmToken(TERROR, MS_NONE, "", TG::NONE, SAL_MAX_UINT16);
+    }
+}
+
+SmToken starmathdatabase::Identify_Postfix_SmXMLOperatorContext_Impl(sal_Unicode cChar)
+{
+    switch (cChar)
+    {
+        case MS_VERTLINE:
+            return SmToken(TRLINE, MS_VERTLINE, "rline", TG::RBrace, 5);
+        case MS_DVERTLINE:
+            return SmToken(TRDLINE, MS_DVERTLINE, "rdline", TG::RBrace, 5);
+        case MS_LANGLE:
+            return SmToken(TLANGLE, MS_LMATHANGLE, "langle", TG::LBrace, 5);
+        case MS_LMATHANGLE:
+            return SmToken(TLANGLE, MS_LMATHANGLE, "langle", TG::LBrace, 5);
+        case MS_LBRACE:
+            return SmToken(TLBRACE, MS_LBRACE, "lbrace", TG::LBrace, 5);
+        case MS_LCEIL:
+            return SmToken(TLCEIL, MS_LCEIL, "lceil", TG::LBrace, 5);
+        case MS_LFLOOR:
+            return SmToken(TLFLOOR, MS_LFLOOR, "lfloor", TG::LBrace, 5);
+        case MS_LDBRACKET:
+            return SmToken(TLDBRACKET, MS_LDBRACKET, "ldbracket", TG::LBrace, 5);
+        case MS_LBRACKET:
+            return SmToken(TLBRACKET, MS_LBRACKET, "[", TG::LBrace, 5);
+        case MS_LPARENT:
+            return SmToken(TLPARENT, MS_LPARENT, "(", TG::LBrace, 5);
+        case MS_RANGLE:
+            return SmToken(TRANGLE, MS_RMATHANGLE, "rangle", TG::RBrace, 5);
+        case MS_RMATHANGLE:
+            return SmToken(TRANGLE, MS_RMATHANGLE, "rangle", TG::RBrace, 5);
+        case MS_RBRACE:
+            return SmToken(TRBRACE, MS_RBRACE, "rbrace", TG::RBrace, 5);
+        case MS_RCEIL:
+            return SmToken(TRCEIL, MS_RCEIL, "rceil", TG::RBrace, 5);
+        case MS_RFLOOR:
+            return SmToken(TRFLOOR, MS_RFLOOR, "rfloor", TG::RBrace, 5);
+        case MS_RDBRACKET:
+            return SmToken(TRDBRACKET, MS_RDBRACKET, "rdbracket", TG::RBrace, 5);
+        case MS_RBRACKET:
+            return SmToken(TRBRACKET, MS_RBRACKET, "]", TG::RBrace, 5);
+        case MS_RPARENT:
+            return SmToken(TRPARENT, MS_RPARENT, ")", TG::RBrace, 5);
+        case MS_NONE:
+            return SmToken(TNONE, MS_NONE, "none", TG::LBrace | TG::RBrace, 5);
+        default:
+            return SmToken(TERROR, MS_NONE, "", TG::NONE, SAL_MAX_UINT16);
+    }
+}
+
+SmToken starmathdatabase::Identify_PrefixPostfix_SmXMLOperatorContext_Impl(sal_Unicode cChar)
+{
+    switch (cChar)
+    {
+        case MS_VERTLINE:
+            return SmToken(TLRLINE, MS_VERTLINE, "lrline", TG::LBrace | TG::RBrace, 5);
+        case MS_DVERTLINE:
+            return SmToken(TLRDLINE, MS_DVERTLINE, "lrdline", TG::LBrace | TG::RBrace, 5);
+        case MS_LANGLE:
+            return SmToken(TLANGLE, MS_LMATHANGLE, "langle", TG::LBrace, 5);
+        case MS_LMATHANGLE:
+            return SmToken(TLANGLE, MS_LMATHANGLE, "langle", TG::LBrace, 5);
+        case MS_LBRACE:
+            return SmToken(TLBRACE, MS_LBRACE, "lbrace", TG::LBrace, 5);
+        case MS_LCEIL:
+            return SmToken(TLCEIL, MS_LCEIL, "lceil", TG::LBrace, 5);
+        case MS_LFLOOR:
+            return SmToken(TLFLOOR, MS_LFLOOR, "lfloor", TG::LBrace, 5);
+        case MS_LDBRACKET:
+            return SmToken(TLDBRACKET, MS_LDBRACKET, "ldbracket", TG::LBrace, 5);
+        case MS_LBRACKET:
+            return SmToken(TLBRACKET, MS_LBRACKET, "[", TG::LBrace, 5);
+        case MS_LPARENT:
+            return SmToken(TLPARENT, MS_LPARENT, "(", TG::LBrace, 5);
+        case MS_RANGLE:
+            return SmToken(TRANGLE, MS_RMATHANGLE, "rangle", TG::RBrace, 5);
+        case MS_RMATHANGLE:
+            return SmToken(TRANGLE, MS_RMATHANGLE, "rangle", TG::RBrace, 5);
+        case MS_RBRACE:
+            return SmToken(TRBRACE, MS_RBRACE, "rbrace", TG::RBrace, 5);
+        case MS_RCEIL:
+            return SmToken(TRCEIL, MS_RCEIL, "rceil", TG::RBrace, 5);
+        case MS_RFLOOR:
+            return SmToken(TRFLOOR, MS_RFLOOR, "rfloor", TG::RBrace, 5);
+        case MS_RDBRACKET:
+            return SmToken(TRDBRACKET, MS_RDBRACKET, "rdbracket", TG::RBrace, 5);
+        case MS_RBRACKET:
+            return SmToken(TRBRACKET, MS_RBRACKET, "]", TG::RBrace, 5);
+        case MS_RPARENT:
+            return SmToken(TRPARENT, MS_RPARENT, ")", TG::RBrace, 5);
+        case MS_NONE:
+            return SmToken(TNONE, MS_NONE, "none", TG::LBrace | TG::RBrace, 5);
+        default:
+            return SmToken(TERROR, MS_NONE, "", TG::NONE, SAL_MAX_UINT16);
+    }
+}
diff --git a/starmath/source/visitors.cxx b/starmath/source/visitors.cxx
index 9b8ac0d855aa..08f9d33e024f 100644
--- a/starmath/source/visitors.cxx
+++ b/starmath/source/visitors.cxx
@@ -1967,23 +1967,32 @@ void SmNodeToTextVisitor::Visit( SmTableNode* pNode )
 
 void SmNodeToTextVisitor::Visit( SmBraceNode* pNode )
 {
-    SmNode *pLeftBrace  = pNode->OpeningBrace(),
-           *pBody       = pNode->Body(),
-           *pRightBrace = pNode->ClosingBrace();
-    //Handle special case where it's absolute function
-    if( pNode->GetToken( ).eType == TABS ) {
-        Append( "abs" );
-        LineToText( pBody );
-    } else {
-        if( pNode->GetScaleMode( ) == SmScaleMode::Height )
-            Append( "left " );
-        pLeftBrace->Accept( this );
-        Separate( );
+    if ( pNode->GetToken().eType == TEVALUATE )
+    {
+        SmNode *pBody = pNode->Body();
+        Append( "evaluate { " );
         pBody->Accept( this );
-        Separate( );
-        if( pNode->GetScaleMode( ) == SmScaleMode::Height )
-            Append( "right " );
-        pRightBrace->Accept( this );
+        Append("} ");
+    }
+    else{
+        SmNode *pLeftBrace  = pNode->OpeningBrace(),
+               *pBody       = pNode->Body(),
+               *pRightBrace = pNode->ClosingBrace();
+        //Handle special case where it's absolute function
+        if( pNode->GetToken( ).eType == TABS ) {
+            Append( "abs" );
+            LineToText( pBody );
+        } else {
+            if( pNode->GetScaleMode( ) == SmScaleMode::Height )
+                Append( "left " );
+            pLeftBrace->Accept( this );
+            Separate( );
+            pBody->Accept( this );
+            Separate( );
+            if( pNode->GetScaleMode( ) == SmScaleMode::Height )
+                Append( "right " );
+            pRightBrace->Accept( this );
+        }
     }
 }
 
@@ -2313,48 +2322,71 @@ void SmNodeToTextVisitor::Visit( SmBinDiagonalNode* pNode )
 
 void SmNodeToTextVisitor::Visit( SmSubSupNode* pNode )
 {
-    LineToText( pNode->GetBody( ) );
-    SmNode *pChild = pNode->GetSubSup( LSUP );
-    if( pChild ) {
-        Separate( );
-        Append( "lsup " );
-        LineToText( pChild );
-    }
-    pChild = pNode->GetSubSup( LSUB );
-    if( pChild ) {
-        Separate( );
-        Append( "lsub " );
-        LineToText( pChild );
-    }
-    pChild = pNode->GetSubSup( RSUP );
-    if( pChild ) {
-        Separate( );
-        Append( "^ " );
-        LineToText( pChild );
-    }
-    pChild = pNode->GetSubSup( RSUB );
-    if( pChild ) {
-        Separate( );
-        Append( "_ " );
-        LineToText( pChild );
-    }
-    pChild = pNode->GetSubSup( CSUP );
-    if( pChild ) {
-        Separate( );
-        if (pNode->IsUseLimits())
-            Append( "to " );
-        else
-            Append( "csup " );
-        LineToText( pChild );
+    if( pNode->GetToken().eType == TEVALUATE )
+    {
+        Append("evaluate { ");
+        pNode->GetSubNode( 0 )->GetSubNode( 1 )->Accept(this);
+        Append("} ");
+        SmNode* pChild = pNode->GetSubSup( RSUP );
+        if( pChild ) {
+            Separate( );
+            Append( "to { " );
+            LineToText( pChild );
+            Append( "} " );
+        }
+        pChild = pNode->GetSubSup( RSUB );
+        if( pChild ) {
+            Separate( );
+            Append( "from { " );
+            LineToText( pChild );
+            Append( "} " );
+        }
     }
-    pChild = pNode->GetSubSup( CSUB );
-    if( pChild ) {
-        Separate( );
-        if (pNode->IsUseLimits())
-            Append( "from " );
-        else
-            Append( "csub " );
-        LineToText( pChild );
+    else
+    {
+        LineToText( pNode->GetBody( ) );
+        SmNode *pChild = pNode->GetSubSup( LSUP );
+        if( pChild ) {
+            Separate( );
+            Append( "lsup " );
+            LineToText( pChild );
+        }
+        pChild = pNode->GetSubSup( LSUB );
+        if( pChild ) {
+            Separate( );
+            Append( "lsub " );
+            LineToText( pChild );
+        }
+        pChild = pNode->GetSubSup( RSUP );
+        if( pChild ) {
+            Separate( );
+            Append( "^ " );
+            LineToText( pChild );
+        }
+        pChild = pNode->GetSubSup( RSUB );
+        if( pChild ) {
+            Separate( );
+            Append( "_ " );
+            LineToText( pChild );
+        }
+        pChild = pNode->GetSubSup( CSUP );
+        if( pChild ) {
+            Separate( );
+            if (pNode->IsUseLimits())
+                Append( "to " );
+            else
+                Append( "csup " );
+            LineToText( pChild );
+        }
+        pChild = pNode->GetSubSup( CSUB );
+        if( pChild ) {
+            Separate( );
+            if (pNode->IsUseLimits())
+                Append( "from " );
+            else
+                Append( "csub " );
+            LineToText( pChild );
+        }
     }
 }
 
@@ -2418,39 +2450,6 @@ void SmNodeToTextVisitor::Visit( SmSpecialNode* pNode )
 {
     SmTokenType type = pNode->GetToken().eType;
     switch(type){
-        case TINTD:
-            Append("intd ");
-            break;
-        case TINT:
-            Append("int ");
-            break;
-        case TSUM:
-            Append("sum ");
-            break;
-        case TIINT:
-            Append("iint ");
-            break;
-        case TIIINT:
-            Append("iiint ");
-            break;
-        case TLINT:
-            Append("lint ");
-            break;
-        case TLLINT:
-            Append("llint ");
-            break;
-        case TLLLINT:
-            Append("lllint ");
-            break;
-        case TCOPROD:
-            Append("coprod ");
-            break;
-        case TPROD:
-            Append("prod ");
-            break;
-        case TLIM:
-            Append("lim ");
-            break;
         case TLIMSUP:
             Append("lim sup ");
             break;
@@ -2475,54 +2474,35 @@ void SmNodeToTextVisitor::Visit( SmGlyphSpecialNode* pNode )
 //TODO to improve this it is required to improve mathmlimport.
 void SmNodeToTextVisitor::Visit( SmMathSymbolNode* pNode )
 {
+    if (    ( pNode->GetToken().nGroup & TG::LBrace )
+         || ( pNode->GetToken().nGroup & TG::RBrace )
+         || ( pNode->GetToken().nGroup & TG::Sum )
+         || ( pNode->GetToken().nGroup & TG::Product )
+         || ( pNode->GetToken().nGroup & TG::Relation )
+         || ( pNode->GetToken().nGroup & TG::UnOper )
+         || ( pNode->GetToken().nGroup & TG::Oper )
+    ) {
+        Append( pNode->GetToken().aText );
+        return;
+    }
     sal_Unicode cChar = pNode->GetToken().cMathChar;
     Separate( );
     switch(cChar){
-        case '(':
-            Append("(");
-            break;
-        case '[':
-            Append("[");
+        case MS_NONE:
+            Append("none");
             break;
         case '{':
-            Append("lbrace");
-            break;
-        case ')':
-            Append(")");
-            break;
-        case ']':
-            Append("]");
+            Append("{");
             break;
         case '}':
-            Append("rbrace");
-            break;
-        case 0x0000:
-            Append("none");
-            break;
-        case MS_NEG:
-            Append("neg");
-            break;
-        case MS_PLUSMINUS:
-            Append("+-");
-            break;
-        case MS_FACT:
-            Append("fact");
+            Append("}");
             break;
         case MS_VERTLINE:
-            if( pNode->GetToken().eType == TLLINE ) Append("lline");
-            else if( pNode->GetToken().eType == TRLINE ) Append("rline");
-            else Append("mline");
+            Append("mline");
             break;
         case MS_TILDE:
             Append("\"~\"");
             break;
-        case MS_SIM:
-            Append("sim");
-            break;
-        case MS_DVERTLINE:
-            if( pNode->GetToken().eType == TLDLINE ) Append("ldline");
-            else Append("rdline");
-            break;
         case MS_RIGHTARROW:
             if( pNode->GetToken().eType == TTOWARD ) Append("toward");
             else Append("rightarrow");
@@ -2536,30 +2516,12 @@ void SmNodeToTextVisitor::Visit( SmMathSymbolNode* pNode )
         case MS_DOWNARROW:
             Append("downarrow");
             break;
-        case MS_NDIVIDES:
-            Append("ndivides");
-            break;
-        case MS_DLINE:
-            Append("parallel");
-            break;
-        case MS_TIMES:
-            Append("times");
-            break;
-        case MS_DIV:
-            Append("div");
-            break;
         case MS_LAMBDABAR:
             Append("lambdabar");
             break;
         case MS_DOTSLOW:
             Append("dotslow");
             break;
-        case 0x2022:
-            Append("cdot");
-            break;
-        case MS_CDOT:
-            Append("cdot");
-            break;
         case MS_SETC:
             Append("setC");
             break;
@@ -2623,157 +2585,15 @@ void SmNodeToTextVisitor::Visit( SmMathSymbolNode* pNode )
         case MS_NABLA:
             Append("nabla");
             break;
-        case MS_IN:
-            Append("in");
-            break;
-        case MS_NI:
-            Append("owns");
-            break;
-        case MS_NOTIN:
-            Append("notin");
-            break;
         case MS_BACKEPSILON:
             Append("backepsilon");
             break;
-        case MS_PROD:
-            Append("prod");
-            break;
-        case MS_COPROD:
-            Append("coprod");
-            break;
-        case MS_SUM:
-            Append("sum");
-            break;
-        case MS_MINUS:
-            Append("-");
-            break;
-        case MS_MINUSPLUS:
-            Append("-+");
-            break;
-        case MS_MULTIPLY:
-            Append("*");
-            break;
         case MS_CIRC:
             Append("circ");
             break;
-        case MS_PROP:
-            Append("prop");
-            break;
         case MS_INFINITY:
             Append("infinity");
             break;
-        case MS_AND:
-            Append("and");
-            break;
-        case MS_OR:
-            Append("or");
-            break;
-        case MS_INTERSECT:
-            Append("intersection");
-            break;
-        case MS_UNION:
-            Append("union");
-            break;
-        case MS_LINE:
-            Append("divides");
-            break;
-        case MS_INT:
-            if (pNode->GetScaleMode() == SmScaleMode::Height) Append("intd");
-            else Append("int");
-            break;
-        case MS_IINT:
-            Append("iint");
-            break;
-        case MS_IIINT:
-            Append("iiint");
-            break;
-        case MS_LINT:
-            Append("lint");
-            break;
-        case MS_LLINT:
-            Append("llint");
-            break;
-        case MS_LLLINT:
-            Append("lllint");
-            break;
-        case 0x2245:
-            Append("simeq");
-            break;
-        case MS_SIMEQ:
-            Append("simeq");
-            break;
-        case MS_BACKSLASH:
-            Append("setminus");
-            break;
-        case MS_APPROX:
-            Append("approx");
-            break;
-        case MS_NEQ:
-            Append("<>");
-            break;
-        case MS_EQUIV:
-            Append("equiv");
-            break;
-        case MS_LE:
-            Append("<=");
-            break;
-        case MS_GE:
-            Append(">=");
-            break;
-        case MS_LESLANT:
-            Append("leslant");
-            break;
-        case MS_GESLANT:
-            Append("geslant");
-            break;
-        case MS_PRECEDES:
-            Append("prec");
-            break;
-        case MS_SUCCEEDS:
-            Append("succ");
-            break;
-        case MS_PRECEDESEQUAL:
-            Append("preccurlyeq");
-            break;
-        case MS_SUCCEEDSEQUAL:
-            Append("succcurlyeq");
-            break;
-        case MS_PRECEDESEQUIV:
-            Append("precsim");
-            break;
-        case MS_SUCCEEDSEQUIV:
-            Append("succsim");
-            break;
-        case MS_NOTPRECEDES:
-            Append("nprec");
-            break;
-        case MS_NOTSUCCEEDS:
-            Append("nsucc");
-            break;
-        case MS_SUBSET:
-            Append("subset");
-            break;
-        case MS_SUPSET:
-            Append("supset");
-            break;
-        case MS_NSUBSET:
-            Append("nsubset");
-            break;
-        case MS_NSUPSET:
-            Append("nsupset");
-            break;
-        case MS_SUBSETEQ:
-            Append("subseteq");
-            break;
-        case MS_SUPSETEQ:
-            Append("supseteq");
-            break;
-        case MS_NSUBSETEQ:
-            Append("nsubseteq");
-            break;
-        case MS_NSUPSETEQ:
-            Append("nsupseteq");
-            break;
         case 0x22b2: // NORMAL SUBGROUP OF
             Append(OUStringChar(cChar));
             break;
@@ -2795,32 +2615,6 @@ void SmNodeToTextVisitor::Visit( SmMathSymbolNode* pNode )
         case MS_DOTSDOWN:
             Append("dotsdown");
             break;
-        case MS_LANGLE:
-        case MS_LMATHANGLE:
-            Append("langle");
-            break;
-        case MS_RANGLE:
-        case MS_RMATHANGLE:
-            Append("rangle");
-            break;
-        case 0x301a:
-            Append("ldbracket");
-            break;
-        case 0x301b:
-            Append("rdbracket");
-            break;
-        case MS_LDBRACKET:
-            Append("ldbracket");
-            break;
-        case MS_RDBRACKET:
-            Append("rdbracket");
-            break;
-        case 0xe083:
-            Append("+");
-            break;
-        case MS_PLUS:
-            Append("+");
-            break;
         case '^':
             Append("^");
             break;
@@ -2833,12 +2627,6 @@ void SmNodeToTextVisitor::Visit( SmMathSymbolNode* pNode )
         case 0xe098:
             Append("widevec");
             break;
-        case 0xE421:
-            Append("geslant");
-            break;
-        case 0xE425:
-            Append("leslant");
-            break;
         case 0xeb01:    //no space
         case 0xeb08:    //normal space
             break;
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 23186f625a75..f8cd9c9315c7 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -1483,6 +1483,8 @@ namespace xmloff::token {
         TOKEN( "power",                           XML_POWER ),
         TOKEN( "precision-as-shown",              XML_PRECISION_AS_SHOWN ),
         TOKEN( "prefix",                          XML_PREFIX ),
+        TOKEN( "infix",                           XML_INFIX ),
+        TOKEN( "postfix",                         XML_POSTFIX ),
         TOKEN( "presentation",                    XML_PRESENTATION ),
         TOKEN( "orgchart",                        XML_PRESENTATION_ORGCHART ),
         TOKEN( "outline",                         XML_PRESENTATION_OUTLINE ),
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index a0019db4bf85..c3dcca040340 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -1393,6 +1393,8 @@ oblique
 power
 precision-as-shown
 prefix
+infix
+postfix
 presentation
 orgchart
 outline


More information about the Libreoffice-commits mailing list