diff options
Diffstat (limited to '')
-rw-r--r-- | starmath/source/wordexportbase.cxx | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/starmath/source/wordexportbase.cxx b/starmath/source/wordexportbase.cxx new file mode 100644 index 000000000..adf1a275c --- /dev/null +++ b/starmath/source/wordexportbase.cxx @@ -0,0 +1,184 @@ +/* -*- 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/. + */ + +#include "wordexportbase.hxx" +#include <sal/log.hxx> +#include <osl/diagnose.h> + +SmWordExportBase::SmWordExportBase(const SmNode* pIn) + : m_pTree(pIn) +{ +} + +SmWordExportBase::~SmWordExportBase() = default; + +void SmWordExportBase::HandleNode(const SmNode* pNode, int nLevel) +{ + SAL_INFO("starmath.wordbase", + "Node: " << nLevel << " " << int(pNode->GetType()) << " " << pNode->GetNumSubNodes()); + switch (pNode->GetType()) + { + case SmNodeType::Attribute: + HandleAttribute(static_cast<const SmAttributeNode*>(pNode), nLevel); + break; + case SmNodeType::Text: + HandleText(pNode, nLevel); + break; + case SmNodeType::VerticalBrace: + HandleVerticalBrace(static_cast<const SmVerticalBraceNode*>(pNode), nLevel); + break; + case SmNodeType::Brace: + HandleBrace(static_cast<const SmBraceNode*>(pNode), nLevel); + break; + case SmNodeType::Oper: + HandleOperator(static_cast<const SmOperNode*>(pNode), nLevel); + break; + case SmNodeType::UnHor: + HandleUnaryOperation(static_cast<const SmUnHorNode*>(pNode), nLevel); + break; + case SmNodeType::BinHor: + HandleBinaryOperation(static_cast<const SmBinHorNode*>(pNode), nLevel); + break; + case SmNodeType::BinVer: + HandleFractions(pNode, nLevel, nullptr); + break; + case SmNodeType::Root: + HandleRoot(static_cast<const SmRootNode*>(pNode), nLevel); + break; + case SmNodeType::Special: + { + auto pText = static_cast<const SmTextNode*>(pNode); + //if the token str and the result text are the same then this + //is to be seen as text, else assume it's a mathchar + if (pText->GetText() == pText->GetToken().aText) + HandleText(pText, nLevel); + else + HandleMath(pText, nLevel); + break; + } + case SmNodeType::Math: + case SmNodeType::MathIdent: + HandleMath(pNode, nLevel); + break; + case SmNodeType::SubSup: + HandleSubSupScript(static_cast<const SmSubSupNode*>(pNode), nLevel); + break; + case SmNodeType::Expression: + HandleAllSubNodes(pNode, nLevel); + break; + case SmNodeType::Table: + //Root Node, PILE equivalent, i.e. vertical stack + HandleTable(pNode, nLevel); + break; + case SmNodeType::Matrix: + HandleMatrix(static_cast<const SmMatrixNode*>(pNode), nLevel); + break; + case SmNodeType::Line: + { + // TODO + HandleAllSubNodes(pNode, nLevel); + } + break; +#if 0 + case SmNodeType::Align: + HandleMAlign(pNode,nLevel); + break; +#endif + case SmNodeType::Place: + // explicitly do nothing, MSOffice treats that as a placeholder if item is missing + break; + case SmNodeType::Blank: + HandleBlank(); + break; + default: + HandleAllSubNodes(pNode, nLevel); + break; + } +} + +//Root Node, PILE equivalent, i.e. vertical stack +void SmWordExportBase::HandleTable(const SmNode* pNode, int nLevel) +{ + //The root of the starmath is a table, if + //we convert this them each iteration of + //conversion from starmath to Word will + //add an extra unnecessary level to the + //Word output stack which would grow + //without bound in a multi step conversion + if (nLevel || pNode->GetNumSubNodes() > 1) + HandleVerticalStack(pNode, nLevel); + else + HandleAllSubNodes(pNode, nLevel); +} + +void SmWordExportBase::HandleAllSubNodes(const SmNode* pNode, int nLevel) +{ + int size = pNode->GetNumSubNodes(); + for (int i = 0; i < size; ++i) + { + // TODO remove when all types of nodes are handled properly + if (pNode->GetSubNode(i) == nullptr) + { + SAL_WARN("starmath.wordbase", "Subnode is NULL, parent node not handled properly"); + continue; + } + HandleNode(pNode->GetSubNode(i), nLevel + 1); + } +} + +void SmWordExportBase::HandleUnaryOperation(const SmUnHorNode* pNode, int nLevel) +{ + // update HandleMath() when adding new items + SAL_INFO("starmath.wordbase", "Unary: " << int(pNode->GetToken().eType)); + + HandleAllSubNodes(pNode, nLevel); +} + +void SmWordExportBase::HandleBinaryOperation(const SmBinHorNode* pNode, int nLevel) +{ + SAL_INFO("starmath.wordbase", "Binary: " << int(pNode->Symbol()->GetToken().eType)); + // update HandleMath() when adding new items + switch (pNode->Symbol()->GetToken().eType) + { + case TDIVIDEBY: + return HandleFractions(pNode, nLevel, "lin"); + default: + HandleAllSubNodes(pNode, nLevel); + break; + } +} + +void SmWordExportBase::HandleMath(const SmNode* pNode, int nLevel) +{ + SAL_INFO("starmath.wordbase", "Math: " << int(pNode->GetToken().eType)); + switch (pNode->GetToken().eType) + { + case TDIVIDEBY: + case TACUTE: + OSL_ASSERT(false); + [[fallthrough]]; // the above are handled elsewhere, e.g. when handling BINHOR + default: + HandleText(pNode, nLevel); + break; + } +} + +void SmWordExportBase::HandleSubSupScript(const SmSubSupNode* pNode, int nLevel) +{ + // set flags to a bitfield of which sub/sup items exists + int flags = (pNode->GetSubSup(CSUB) != nullptr ? (1 << CSUB) : 0) + | (pNode->GetSubSup(CSUP) != nullptr ? (1 << CSUP) : 0) + | (pNode->GetSubSup(RSUB) != nullptr ? (1 << RSUB) : 0) + | (pNode->GetSubSup(RSUP) != nullptr ? (1 << RSUP) : 0) + | (pNode->GetSubSup(LSUB) != nullptr ? (1 << LSUB) : 0) + | (pNode->GetSubSup(LSUP) != nullptr ? (1 << LSUP) : 0); + HandleSubSupScriptInternal(pNode, nLevel, flags); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |