/src/libreoffice/starmath/source/wordexportbase.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | */ |
9 | | |
10 | | #include "wordexportbase.hxx" |
11 | | #include <sal/log.hxx> |
12 | | #include <osl/diagnose.h> |
13 | | |
14 | | SmWordExportBase::SmWordExportBase(const SmNode* pIn) |
15 | 0 | : m_pTree(pIn) |
16 | 0 | { |
17 | 0 | } |
18 | | |
19 | 0 | SmWordExportBase::~SmWordExportBase() = default; |
20 | | |
21 | | void SmWordExportBase::HandleNode(const SmNode* pNode, int nLevel) |
22 | 0 | { |
23 | 0 | SAL_INFO("starmath.wordbase", |
24 | 0 | "Node: " << nLevel << " " << int(pNode->GetType()) << " " << pNode->GetNumSubNodes()); |
25 | 0 | switch (pNode->GetType()) |
26 | 0 | { |
27 | 0 | case SmNodeType::Attribute: |
28 | 0 | HandleAttribute(static_cast<const SmAttributeNode*>(pNode), nLevel); |
29 | 0 | break; |
30 | 0 | case SmNodeType::Text: |
31 | 0 | HandleText(pNode, nLevel); |
32 | 0 | break; |
33 | 0 | case SmNodeType::VerticalBrace: |
34 | 0 | HandleVerticalBrace(static_cast<const SmVerticalBraceNode*>(pNode), nLevel); |
35 | 0 | break; |
36 | 0 | case SmNodeType::Brace: |
37 | 0 | HandleBrace(static_cast<const SmBraceNode*>(pNode), nLevel); |
38 | 0 | break; |
39 | 0 | case SmNodeType::Oper: |
40 | 0 | HandleOperator(static_cast<const SmOperNode*>(pNode), nLevel); |
41 | 0 | break; |
42 | 0 | case SmNodeType::UnHor: |
43 | 0 | HandleUnaryOperation(static_cast<const SmUnHorNode*>(pNode), nLevel); |
44 | 0 | break; |
45 | 0 | case SmNodeType::BinHor: |
46 | 0 | HandleBinaryOperation(static_cast<const SmBinHorNode*>(pNode), nLevel); |
47 | 0 | break; |
48 | 0 | case SmNodeType::BinVer: |
49 | 0 | HandleFractions(pNode, nLevel, nullptr); |
50 | 0 | break; |
51 | 0 | case SmNodeType::Root: |
52 | 0 | HandleRoot(static_cast<const SmRootNode*>(pNode), nLevel); |
53 | 0 | break; |
54 | 0 | case SmNodeType::Special: |
55 | 0 | { |
56 | 0 | auto pText = static_cast<const SmTextNode*>(pNode); |
57 | | //if the token str and the result text are the same then this |
58 | | //is to be seen as text, else assume it's a mathchar |
59 | 0 | if (pText->GetText() == pText->GetToken().aText) |
60 | 0 | HandleText(pText, nLevel); |
61 | 0 | else |
62 | 0 | HandleMath(pText, nLevel); |
63 | 0 | break; |
64 | 0 | } |
65 | 0 | case SmNodeType::Math: |
66 | 0 | case SmNodeType::MathIdent: |
67 | 0 | HandleMath(pNode, nLevel); |
68 | 0 | break; |
69 | 0 | case SmNodeType::SubSup: |
70 | 0 | HandleSubSupScript(static_cast<const SmSubSupNode*>(pNode), nLevel); |
71 | 0 | break; |
72 | 0 | case SmNodeType::Expression: |
73 | 0 | HandleAllSubNodes(pNode, nLevel); |
74 | 0 | break; |
75 | 0 | case SmNodeType::Table: |
76 | | //Root Node, PILE equivalent, i.e. vertical stack |
77 | 0 | HandleTable(pNode, nLevel); |
78 | 0 | break; |
79 | 0 | case SmNodeType::Matrix: |
80 | 0 | HandleMatrix(static_cast<const SmMatrixNode*>(pNode), nLevel); |
81 | 0 | break; |
82 | 0 | case SmNodeType::Line: |
83 | 0 | { |
84 | | // TODO |
85 | 0 | HandleAllSubNodes(pNode, nLevel); |
86 | 0 | } |
87 | 0 | break; |
88 | | #if 0 |
89 | | case SmNodeType::Align: |
90 | | HandleMAlign(pNode,nLevel); |
91 | | break; |
92 | | #endif |
93 | 0 | case SmNodeType::Place: |
94 | | // explicitly do nothing, MSOffice treats that as a placeholder if item is missing |
95 | 0 | break; |
96 | 0 | case SmNodeType::Blank: |
97 | 0 | HandleBlank(); |
98 | 0 | break; |
99 | 0 | default: |
100 | 0 | HandleAllSubNodes(pNode, nLevel); |
101 | 0 | break; |
102 | 0 | } |
103 | 0 | } |
104 | | |
105 | | //Root Node, PILE equivalent, i.e. vertical stack |
106 | | void SmWordExportBase::HandleTable(const SmNode* pNode, int nLevel) |
107 | 0 | { |
108 | | //The root of the starmath is a table, if |
109 | | //we convert this them each iteration of |
110 | | //conversion from starmath to Word will |
111 | | //add an extra unnecessary level to the |
112 | | //Word output stack which would grow |
113 | | //without bound in a multi step conversion |
114 | 0 | if (nLevel || pNode->GetNumSubNodes() > 1) |
115 | 0 | HandleVerticalStack(pNode, nLevel); |
116 | 0 | else |
117 | 0 | HandleAllSubNodes(pNode, nLevel); |
118 | 0 | } |
119 | | |
120 | | void SmWordExportBase::HandleAllSubNodes(const SmNode* pNode, int nLevel) |
121 | 0 | { |
122 | 0 | int size = pNode->GetNumSubNodes(); |
123 | 0 | for (int i = 0; i < size; ++i) |
124 | 0 | { |
125 | | // TODO remove when all types of nodes are handled properly |
126 | 0 | if (pNode->GetSubNode(i) == nullptr) |
127 | 0 | { |
128 | 0 | SAL_WARN("starmath.wordbase", "Subnode is NULL, parent node not handled properly"); |
129 | 0 | continue; |
130 | 0 | } |
131 | 0 | HandleNode(pNode->GetSubNode(i), nLevel + 1); |
132 | 0 | } |
133 | 0 | } |
134 | | |
135 | | void SmWordExportBase::HandleUnaryOperation(const SmUnHorNode* pNode, int nLevel) |
136 | 0 | { |
137 | | // update HandleMath() when adding new items |
138 | 0 | SAL_INFO("starmath.wordbase", "Unary: " << int(pNode->GetToken().eType)); |
139 | | |
140 | 0 | HandleAllSubNodes(pNode, nLevel); |
141 | 0 | } |
142 | | |
143 | | void SmWordExportBase::HandleBinaryOperation(const SmBinHorNode* pNode, int nLevel) |
144 | 0 | { |
145 | 0 | SAL_INFO("starmath.wordbase", "Binary: " << int(pNode->Symbol()->GetToken().eType)); |
146 | | // update HandleMath() when adding new items |
147 | 0 | switch (pNode->Symbol()->GetToken().eType) |
148 | 0 | { |
149 | 0 | case TDIVIDEBY: |
150 | 0 | return HandleFractions(pNode, nLevel, "lin"); |
151 | 0 | default: |
152 | 0 | HandleAllSubNodes(pNode, nLevel); |
153 | 0 | break; |
154 | 0 | } |
155 | 0 | } |
156 | | |
157 | | void SmWordExportBase::HandleMath(const SmNode* pNode, int nLevel) |
158 | 0 | { |
159 | 0 | SAL_INFO("starmath.wordbase", "Math: " << int(pNode->GetToken().eType)); |
160 | 0 | switch (pNode->GetToken().eType) |
161 | 0 | { |
162 | 0 | case TDIVIDEBY: |
163 | 0 | case TACUTE: |
164 | 0 | OSL_ASSERT(false); |
165 | 0 | [[fallthrough]]; // the above are handled elsewhere, e.g. when handling BINHOR |
166 | 0 | default: |
167 | 0 | HandleText(pNode, nLevel); |
168 | 0 | break; |
169 | 0 | } |
170 | 0 | } |
171 | | |
172 | | void SmWordExportBase::HandleSubSupScript(const SmSubSupNode* pNode, int nLevel) |
173 | 0 | { |
174 | | // set flags to a bitfield of which sub/sup items exists |
175 | 0 | int flags = (pNode->GetSubSup(CSUB) != nullptr ? (1 << CSUB) : 0) |
176 | 0 | | (pNode->GetSubSup(CSUP) != nullptr ? (1 << CSUP) : 0) |
177 | 0 | | (pNode->GetSubSup(RSUB) != nullptr ? (1 << RSUB) : 0) |
178 | 0 | | (pNode->GetSubSup(RSUP) != nullptr ? (1 << RSUP) : 0) |
179 | 0 | | (pNode->GetSubSup(LSUB) != nullptr ? (1 << LSUB) : 0) |
180 | 0 | | (pNode->GetSubSup(LSUP) != nullptr ? (1 << LSUP) : 0); |
181 | 0 | HandleSubSupScriptInternal(pNode, nLevel, flags); |
182 | 0 | } |
183 | | |
184 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |