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@collabora.co.uk>
diff --git a/compilerplugins/clang/sequentialassign.cxx b/compilerplugins/clang/sequentialassign.cxx
index 33b1afa..a89afea 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 99b94be..6b2fed0 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 5d75c87e..a63b506 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 f078383..020d22f 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 0000000..999b983f
--- /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 09b2b39..fb9fecc 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 6f81277..004e55a 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 caae616..d5f90ab 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 d71c872..6efd585 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 aa96a1e..ab9d723 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 821144a..f570ff5 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 db56d3c..587ba3c 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 598ec12..803f974 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 0000000..9b1dd65
--- /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 9b8ac0d..08f9d33 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 );
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( 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 );
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("[");
break;
case '{':
Append("lbrace");
break;
case ')':
Append(")");
break;
case ']':
Append("]");
break;
case '}':
Append("rbrace");
break;
case 0x0000:
case MS_NONE:
Append("none");
break;
case MS_NEG:
Append("neg");
case '{':
Append("{");
break;
case MS_PLUSMINUS:
Append("+-");
break;
case MS_FACT:
Append("fact");
case '}':
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 23186f6..f8cd9c9 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 a0019db..c3dcca0 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