Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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: */