1 /* This file is part of the KDE project
2
3 Copyright (C) 2013 Inge Wallin <inge@lysator.liu.se>
4 Copyright (C) 2013 Mojtaba Shahi Senobari <mojtaba.shahi3000@gmail.com>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20 */
21
22
23 // Own
24 #include "OdtReaderWikiBackend.h"
25
26 // Calligra
27 #include <KoXmlReader.h>
28
29 #include <KoOdfStyleManager.h>
30 #include <KoOdfStyle.h>
31 #include <KoOdfListStyle.h>
32 #include <KoOdfStyleProperties.h>
33
34 // This filter
35 #include "OdfReaderWikiContext.h"
36 #include "WikiExportDebug.h"
37
38
39 #if 1
40 #define DEBUG_BACKEND() \
41 debugWiki << (reader.isStartElement() ? "start": (reader.isEndElement() ? "end" : "other")) \
42 << reader.qualifiedName().toString()
43 #else
44 #define DEBUG_BACKEND() \
45 //NOTHING
46 #endif
47
48
49 // ================================================================
50 // class OdtReaderWikiBackend
51
52
OdtReaderWikiBackend()53 OdtReaderWikiBackend::OdtReaderWikiBackend()
54 : OdfTextReaderBackend()
55 {
56 }
57
~OdtReaderWikiBackend()58 OdtReaderWikiBackend::~OdtReaderWikiBackend()
59 {
60 }
61
62
63 // ----------------------------------------------------------------
64 // Text level functions: paragraphs, headings, sections, frames, objects, etc
65
66
elementTextH(KoXmlStreamReader & reader,OdfReaderContext * context)67 void OdtReaderWikiBackend::elementTextH(KoXmlStreamReader &reader,
68 OdfReaderContext *context)
69 {
70 DEBUG_BACKEND();
71 OdfReaderWikiContext *wikiContext = dynamic_cast<OdfReaderWikiContext*>(context);
72 if (!wikiContext) {
73 return;
74 }
75
76 if (reader.isStartElement()) {
77 wikiContext->outlineLevel = reader.attributes().value("text:outline-level").toString().toInt();
78 outputHeadingLevel(wikiContext);
79 }
80 else {
81 outputHeadingLevel(wikiContext);
82 wikiContext->outStream << "\n";
83
84 wikiContext->outlineLevel = 0;
85 }
86 }
87
elementTextP(KoXmlStreamReader & reader,OdfReaderContext * context)88 void OdtReaderWikiBackend::elementTextP(KoXmlStreamReader &reader,
89 OdfReaderContext *context)
90 {
91 DEBUG_BACKEND();
92 OdfReaderWikiContext *wikiContext = dynamic_cast<OdfReaderWikiContext*>(context);
93 if (!wikiContext) {
94 return;
95 }
96
97 if (reader.isStartElement()) {
98 QString stylename = reader.attributes().value("text:style-name").toString();
99
100 KoOdfStyle *style = wikiContext->styleManager()->style(stylename, "paragraph");
101 //Push style to stack
102 wikiContext->pushStyle(style);
103 outputTextStyle(reader, wikiContext);
104 } else {
105 outputTextStyle(reader, wikiContext);
106 wikiContext->popStyle();
107
108 // At the end of a paragraph, output two newlines.
109 wikiContext->outStream << "\n";
110 }
111 }
112
113 // ----------------------------------------------------------------
114 // Paragraph level functions: spans, annotations, notes, text content itself, etc.
115
elementTextSpan(KoXmlStreamReader & reader,OdfReaderContext * context)116 void OdtReaderWikiBackend::elementTextSpan(KoXmlStreamReader &reader,
117 OdfReaderContext *context)
118 {
119 DEBUG_BACKEND();
120 OdfReaderWikiContext *wikiContext = dynamic_cast<OdfReaderWikiContext*>(context);
121 if (!wikiContext) {
122 return;
123 }
124
125 if (reader.isStartElement()) {
126 QString stylename = reader.attributes().value("text:style-name").toString();
127 KoOdfStyle *style = wikiContext->styleManager()->style(stylename, "text");
128 //Push style to stack
129 wikiContext->pushStyle(style);
130
131 outputTextStyle(reader, wikiContext);
132 }
133 else {
134 outputTextStyle(reader, wikiContext);
135 wikiContext->popStyle();
136 }
137 }
138
elementTextList(KoXmlStreamReader & reader,OdfReaderContext * context)139 void OdtReaderWikiBackend::elementTextList(KoXmlStreamReader &reader, OdfReaderContext *context)
140 {
141 DEBUG_BACKEND();
142 OdfReaderWikiContext *wikiContext = dynamic_cast<OdfReaderWikiContext*>(context);
143 if (!wikiContext) {
144 return;
145 }
146
147 if (reader.isStartElement()) {
148 QString stylename = reader.attributes().value("text:style-name").toString();
149 KoOdfListStyle *listStyle = wikiContext->styleManager()->listStyle(stylename);
150 if (listStyle) {
151 wikiContext->pushListStyle(listStyle);
152 }
153 wikiContext->listLevelCounter++;
154 }
155 else {
156 if (wikiContext->listLevelCounter == wikiContext->listStyleStack.count()) {
157 wikiContext->popListStyle();
158 }
159 wikiContext->listLevelCounter--;
160 }
161 }
162
elementTextS(KoXmlStreamReader & reader,OdfReaderContext * context)163 void OdtReaderWikiBackend::elementTextS(KoXmlStreamReader &reader,
164 OdfReaderContext *context)
165 {
166 DEBUG_BACKEND();
167 OdfReaderWikiContext *wikiContext = dynamic_cast<OdfReaderWikiContext*>(context);
168 if (!wikiContext) {
169 return;
170 }
171
172 // Find out number of spaces.
173 QString dummy = reader.attributes().value("text:c").toString();
174 bool ok;
175 quint32 numSpaces = dummy.toUInt(&ok);
176 if (!ok)
177 numSpaces = 1;
178
179 // Output the required number of spaces.
180 for (quint32 i = 0; i < numSpaces; ++i) {
181 wikiContext->outStream << ' ';
182 }
183 }
184
elementTextListItem(KoXmlStreamReader & reader,OdfReaderContext * context)185 void OdtReaderWikiBackend::elementTextListItem(KoXmlStreamReader &reader,
186 OdfReaderContext *context)
187 {
188 DEBUG_BACKEND();
189 OdfReaderWikiContext *wikiContext = dynamic_cast<OdfReaderWikiContext*>(context);
190 if (!wikiContext) {
191 return;
192 }
193
194 if (reader.isStartElement()) {
195 KoOdfListStyle *listStyle = wikiContext->popListStyle();
196 char symbol;
197 if (listStyle->listLevelStyleType() == "text:list-level-style-bullet") {
198 symbol = '*';
199 }
200 else if (listStyle->listLevelStyleType() == "text:list-level-style-number") {
201 symbol = '#';
202 }
203 wikiContext->pushListStyle(listStyle);
204
205 for (int level = 0; level < wikiContext->listLevelCounter; ++level) {
206 wikiContext->outStream << symbol;
207 }
208 wikiContext->outStream << ' ';
209 }
210 else {
211 wikiContext->outStream << '\n';
212 }
213
214 }
215
characterData(KoXmlStreamReader & reader,OdfReaderContext * context)216 void OdtReaderWikiBackend::characterData(KoXmlStreamReader &reader, OdfReaderContext *context)
217 {
218 DEBUG_BACKEND();
219 OdfReaderWikiContext *wikiContext = dynamic_cast<OdfReaderWikiContext*>(context);
220 if (!wikiContext) {
221 return;
222 }
223
224 wikiContext->outStream << reader.text().toString();
225 }
226
227
228 // ----------------------------------------------------------------
229 // private functions
230
231
outputTextStyle(KoXmlStreamReader & reader,OdfReaderWikiContext * wikiContext)232 void OdtReaderWikiBackend::outputTextStyle(KoXmlStreamReader &reader,
233 OdfReaderWikiContext *wikiContext)
234 {
235 KoOdfStyle *style = wikiContext->popStyle();
236 KoOdfStyleProperties *styleProperties = style->properties().value("style:text-properties");
237 if (!styleProperties) {
238 wikiContext->pushStyle(style);
239 return;
240 }
241
242 // Output italic and bold.
243 QString fontWeightProperty = "fo:font-weight";
244 QString fontStyleProperty = "fo:font-style";
245 if ((styleProperties->attribute(fontWeightProperty) == "bold")
246 && (styleProperties->attribute(fontStyleProperty) == "italic"))
247 {
248 wikiContext->outStream << "'''''";
249 } else if (styleProperties->attribute(fontWeightProperty) == "bold") {
250 wikiContext->outStream << "'''";
251 } else if (styleProperties->attribute(fontStyleProperty) == "italic") {
252 wikiContext->outStream << "''";
253 }
254
255 QString textPositionProperty = "style:text-position";
256 QString textLineThroughProperty = "style:text-line-through-style";
257 if (reader.isStartElement()) {
258 // Output strikeout text.
259 if (styleProperties->attribute(textLineThroughProperty) == "solid") {
260 wikiContext->outStream << "<s>";
261 }
262 // Output sub and super script.
263 if (styleProperties->attribute(textPositionProperty) == "sub") {
264 wikiContext->outStream << "<sub>";
265 }
266 else if (styleProperties->attribute(textPositionProperty) == "super") {
267 wikiContext->outStream << "<sup>";
268 }
269 }
270 else {
271 if (styleProperties->attribute(textLineThroughProperty)== "solid") {
272 wikiContext->outStream << "</s>";
273 }
274 if (styleProperties->attribute(textPositionProperty) == "sub") {
275 wikiContext->outStream << "</sub>";
276 }
277 else if (styleProperties->attribute(textPositionProperty) == "super") {
278 wikiContext->outStream << "</sup>";
279 }
280 }
281 wikiContext->pushStyle(style);
282 }
283
outputHeadingLevel(OdfReaderWikiContext * wikiContext)284 void OdtReaderWikiBackend::outputHeadingLevel(OdfReaderWikiContext *wikiContext)
285 {
286 int level = wikiContext->outlineLevel;
287 if (level == 1) {
288 wikiContext->outStream << "==";
289 }
290 else if (level == 2) {
291 wikiContext->outStream << "===";
292 }
293 else if (level == 3) {
294 wikiContext->outStream << "====";
295 }
296 }
297