From 7e2c35324c54646f53f0fa14b7bce07e1da73c0b Mon Sep 17 00:00:00 2001 From: dante Date: Tue, 3 Nov 2020 18:51:19 +0100 Subject: 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 --- 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 ++++++++---------------------- 13 files changed, 704 insertions(+), 358 deletions(-) create mode 100644 starmath/inc/starmathdatabase.hxx create mode 100644 starmath/source/starmathdatabase.cxx (limited to 'starmath') 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 DoSum(); std::unique_ptr DoProduct(); std::unique_ptr DoSubSup(TG nActiveGroup, SmNode *pGivenNode); + std::unique_ptr DoSubSupEvaluate(SmNode *pGivenNode); std::unique_ptr DoOpSubSup(); std::unique_ptr DoPower(); std::unique_ptr DoBlank(); @@ -120,6 +121,7 @@ class SmParser std::unique_ptr DoColor(); std::unique_ptr DoBrace(); std::unique_ptr DoBracebody(bool bIsLeftRight); + std::unique_ptr DoEvaluate(); std::unique_ptr DoFunction(); std::unique_ptr DoBinom(); std::unique_ptr 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} - // 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 #include #include +#include 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 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 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 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 SmParser::DoSubSup(TG nActiveGroup, SmNode *pGivenNode) return pNode; } +std::unique_ptr SmParser::DoSubSupEvaluate(SmNode *pGivenNode) +{ + std::unique_ptr xGivenNode(pGivenNode); + DepthProtect aDepthGuard(m_nParseDepth); + if (aDepthGuard.TooDeep()) throw std::range_error("parser depth limit"); + + std::unique_ptr pNode(new SmSubSupNode(m_aCurToken)); + pNode->SetUseLimits(true); + + // initialize subnodes array + std::vector> 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(RSUB); break; + case TTO : nIndex = static_cast(RSUP); break; + default : + SAL_WARN( "starmath", "unknown case"); + } + nIndex++; + assert(1 <= nIndex && nIndex <= SUBSUP_NUM_ENTRIES); + + std::unique_ptr 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 xSNode; + xSNode = DoTerm(true); + + aSubNodes[nIndex] = std::move(xENode ? xENode : xSNode); + } + + pNode->SetSubNodes(buildNodeArray(aSubNodes)); + return pNode; +} + std::unique_ptr SmParser::DoOpSubSup() { DepthProtect aDepthGuard(m_nParseDepth); @@ -1613,6 +1640,8 @@ std::unique_ptr SmParser::DoTerm(bool bGroupNumberIdent) case TLEFT : return DoBrace(); + case TEVALUATE: + return DoEvaluate(); case TBLANK : case TSBLANK : @@ -2302,6 +2331,8 @@ std::unique_ptr 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 SmParser::DoBracebody(bool bIsLeftRight) return pBody; } +std::unique_ptr SmParser::DoEvaluate() +{ + + // Checkout depth and create node + DepthProtect aDepthGuard(m_nParseDepth); + if (aDepthGuard.TooDeep()) throw std::range_error("parser depth limit"); + std::unique_ptr 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 pBody = DoPower(); + SmToken bToken( TNONE, '\0', "", TG::LBrace, 5); + std::unique_ptr pLeft; + pLeft.reset(new SmMathSymbolNode(bToken)); + + // Mount nodes + std::unique_ptr 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 rSNode; + rSNode = DoSubSupEvaluate(xSNode.release()); + rSNode->GetToken().eType = TEVALUATE; + return rSNode; + } + + return xSNode; + +} + std::unique_ptr 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 + +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; -- cgit