Cutelee  6.1.0
texthtmlbuilder.cpp
1 /*
2  This file is part of the Cutelee template system.
3 
4  Copyright (c) 2008 Stephen Kelly <steveire@gmail.com>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either version
9  2.1 of the Licence, 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  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library. If not, see <http://www.gnu.org/licenses/>.
18 
19 */
20 
21 #include "texthtmlbuilder.h"
22 
23 #include <QtCore/QList>
24 #include <QtGui/QTextDocument>
25 
26 namespace Cutelee
27 {
28 
30 {
31 public:
32  TextHTMLBuilderPrivate(TextHTMLBuilder *b) : q_ptr(b) {}
33 
34  QList<QTextListFormat::Style> currentListItemStyles;
35  QString m_text;
36 
37  TextHTMLBuilder *q_ptr;
38 
39  Q_DECLARE_PUBLIC(TextHTMLBuilder)
40 };
41 }
42 
43 using namespace Cutelee;
44 
45 TextHTMLBuilder::TextHTMLBuilder()
46  : AbstractMarkupBuilder(), d_ptr(new TextHTMLBuilderPrivate(this))
47 {
48 }
49 
50 TextHTMLBuilder::~TextHTMLBuilder() { delete d_ptr; }
51 
53 {
54  Q_D(TextHTMLBuilder);
55  ;
56  d->m_text.append(QStringLiteral("<strong>"));
57 }
58 
60 {
61  Q_D(TextHTMLBuilder);
62  d->m_text.append(QStringLiteral("</strong>"));
63 }
64 
66 {
67  Q_D(TextHTMLBuilder);
68  d->m_text.append(QStringLiteral("<em>"));
69 }
70 
72 {
73  Q_D(TextHTMLBuilder);
74  d->m_text.append(QStringLiteral("</em>"));
75 }
76 
78 {
79  Q_D(TextHTMLBuilder);
80  d->m_text.append(QStringLiteral("<u>"));
81 }
82 
84 {
85  Q_D(TextHTMLBuilder);
86  d->m_text.append(QStringLiteral("</u>"));
87 }
88 
90 {
91  Q_D(TextHTMLBuilder);
92  d->m_text.append(QStringLiteral("<s>"));
93 }
94 
96 {
97  Q_D(TextHTMLBuilder);
98  d->m_text.append(QStringLiteral("</s>"));
99 }
100 
101 void TextHTMLBuilder::beginForeground(const QBrush &brush)
102 {
103  Q_D(TextHTMLBuilder);
104  d->m_text.append(
105  QStringLiteral("<span style=\"color:%1;\">").arg(brush.color().name()));
106 }
107 
109 {
110  Q_D(TextHTMLBuilder);
111  d->m_text.append(QStringLiteral("</span>"));
112 }
113 
114 void TextHTMLBuilder::beginBackground(const QBrush &brush)
115 {
116  Q_D(TextHTMLBuilder);
117  d->m_text.append(QStringLiteral("<span style=\"background-color:%1;\">")
118  .arg(brush.color().name()));
119 }
120 
122 {
123  Q_D(TextHTMLBuilder);
124  d->m_text.append(QStringLiteral("</span>"));
125 }
126 
127 void TextHTMLBuilder::beginAnchor(const QString &href, const QString &name)
128 {
129  Q_D(TextHTMLBuilder);
130  if (!href.isEmpty()) {
131  if (!name.isEmpty()) {
132  d->m_text.append(
133  QStringLiteral("<a href=\"%1\" name=\"%2\">").arg(href, name));
134  } else {
135  d->m_text.append(QStringLiteral("<a href=\"%1\">").arg(href));
136  }
137  } else {
138  if (!name.isEmpty()) {
139  d->m_text.append(QStringLiteral("<a name=\"%1\">").arg(name));
140  }
141  }
142 }
143 
145 {
146  Q_D(TextHTMLBuilder);
147  d->m_text.append(QStringLiteral("</a>"));
148 }
149 
151 {
152  Q_D(TextHTMLBuilder);
153  d->m_text.append(
154  QStringLiteral("<span style=\"font-family:%1;\">").arg(family));
155 }
156 
158 {
159  Q_D(TextHTMLBuilder);
160  d->m_text.append(QStringLiteral("</span>"));
161 }
162 
164 {
165  Q_D(TextHTMLBuilder);
166  d->m_text.append(QStringLiteral("<span style=\"font-size:%1pt;\">")
167  .arg(QString::number(size)));
168 }
169 
171 {
172  Q_D(TextHTMLBuilder);
173  d->m_text.append(QStringLiteral("</span>"));
174 }
175 
176 void TextHTMLBuilder::beginParagraph(Qt::Alignment al, qreal topMargin,
177  qreal bottomMargin, qreal leftMargin,
178  qreal rightMargin)
179 {
180  Q_D(TextHTMLBuilder);
181  // Don't put paragraph tags inside li tags. Qt bug reported.
182  // if (currentListItemStyles.size() != 0)
183  // {
184  QString styleString;
185  if (topMargin != 0) {
186  styleString.append(QStringLiteral("margin-top:%1;").arg(topMargin));
187  }
188  if (bottomMargin != 0) {
189  styleString.append(QStringLiteral("margin-bottom:%1;").arg(bottomMargin));
190  }
191  if (leftMargin != 0) {
192  styleString.append(QStringLiteral("margin-left:%1;").arg(leftMargin));
193  }
194  if (rightMargin != 0) {
195  styleString.append(QStringLiteral("margin-right:%1;").arg(rightMargin));
196  }
197 
198  // Using == doesn't work here.
199  // Using bitwise comparison because an alignment can contain a vertical and
200  // a
201  // horizontal part.
202  if (al & Qt::AlignRight) {
203  d->m_text.append(QStringLiteral("<p align=\"right\" "));
204  } else if (al & Qt::AlignHCenter) {
205  d->m_text.append(QStringLiteral("<p align=\"center\" "));
206  } else if (al & Qt::AlignJustify) {
207  d->m_text.append(QStringLiteral("<p align=\"justify\" "));
208  } else if (al & Qt::AlignLeft) {
209  d->m_text.append(QStringLiteral("<p"));
210  } else {
211  d->m_text.append(QStringLiteral("<p"));
212  }
213 
214  if (!styleString.isEmpty()) {
215  d->m_text.append(QStringLiteral(" \"") + styleString + QLatin1Char('"'));
216  }
217  d->m_text.append(QLatin1Char('>'));
218  // }
219 }
220 
222 {
223  Q_D(TextHTMLBuilder);
224  switch (level) {
225  case 1:
226  d->m_text.append(QStringLiteral("<h1>"));
227  break;
228  case 2:
229  d->m_text.append(QStringLiteral("<h2>"));
230  break;
231  case 3:
232  d->m_text.append(QStringLiteral("<h3>"));
233  break;
234  case 4:
235  d->m_text.append(QStringLiteral("<h4>"));
236  break;
237  case 5:
238  d->m_text.append(QStringLiteral("<h5>"));
239  break;
240  case 6:
241  d->m_text.append(QStringLiteral("<h6>"));
242  break;
243  default:
244  break;
245  }
246 }
247 
249 {
250  Q_D(TextHTMLBuilder);
251  switch (level) {
252  case 1:
253  d->m_text.append(QStringLiteral("</h1>"));
254  break;
255  case 2:
256  d->m_text.append(QStringLiteral("</h2>"));
257  break;
258  case 3:
259  d->m_text.append(QStringLiteral("</h3>"));
260  break;
261  case 4:
262  d->m_text.append(QStringLiteral("</h4>"));
263  break;
264  case 5:
265  d->m_text.append(QStringLiteral("</h5>"));
266  break;
267  case 6:
268  d->m_text.append(QStringLiteral("</h6>"));
269  break;
270  default:
271  break;
272  }
273 }
274 
276 {
277  Q_D(TextHTMLBuilder);
278  d->m_text.append(QStringLiteral("</p>\n"));
279 }
280 
282 {
283  Q_D(TextHTMLBuilder);
284  d->m_text.append(QStringLiteral("<p>&nbsp;"));
285 }
286 
288 {
289  Q_D(TextHTMLBuilder);
290  if (width != -1) {
291  d->m_text.append(QStringLiteral("<hr width=\"%1\" />\n").arg(width));
292  }
293  d->m_text.append(QStringLiteral("<hr />\n"));
294 }
295 
296 void TextHTMLBuilder::insertImage(const QString &src, qreal width, qreal height)
297 {
298  Q_D(TextHTMLBuilder);
299  d->m_text.append(QStringLiteral("<img src=\"%1\" ").arg(src));
300  if (width != 0)
301  d->m_text.append(QStringLiteral("width=\"%2\" ").arg(width));
302  if (height != 0)
303  d->m_text.append(QStringLiteral("height=\"%2\" ").arg(height));
304  d->m_text.append(QStringLiteral("/>"));
305 }
306 
307 void TextHTMLBuilder::beginList(QTextListFormat::Style type)
308 {
309  Q_D(TextHTMLBuilder);
310  d->currentListItemStyles.append(type);
311  switch (type) {
312  case QTextListFormat::ListDisc:
313  d->m_text.append(QStringLiteral("<ul type=\"disc\">\n"));
314  break;
315  case QTextListFormat::ListCircle:
316  d->m_text.append(QStringLiteral("\n<ul type=\"circle\">\n"));
317  break;
318  case QTextListFormat::ListSquare:
319  d->m_text.append(QStringLiteral("\n<ul type=\"square\">\n"));
320  break;
321  case QTextListFormat::ListDecimal:
322  d->m_text.append(QStringLiteral("\n<ol type=\"1\">\n"));
323  break;
324  case QTextListFormat::ListLowerAlpha:
325  d->m_text.append(QStringLiteral("\n<ol type=\"a\">\n"));
326  break;
327  case QTextListFormat::ListUpperAlpha:
328  d->m_text.append(QStringLiteral("\n<ol type=\"A\">\n"));
329  break;
330  case QTextListFormat::ListLowerRoman:
331  d->m_text.append(QStringLiteral("\n<ol type=\"i\">\n"));
332  break;
333  case QTextListFormat::ListUpperRoman:
334  d->m_text.append(QStringLiteral("\n<ol type=\"I\">\n"));
335  break;
336  default:
337  break;
338  }
339 }
341 {
342  Q_D(TextHTMLBuilder);
343  switch (d->currentListItemStyles.last()) {
344  case QTextListFormat::ListDisc:
345  case QTextListFormat::ListCircle:
346  case QTextListFormat::ListSquare:
347  d->m_text.append(QStringLiteral("</ul>\n"));
348  break;
349  case QTextListFormat::ListDecimal:
350  case QTextListFormat::ListLowerAlpha:
351  case QTextListFormat::ListUpperAlpha:
352  case QTextListFormat::ListLowerRoman:
353  case QTextListFormat::ListUpperRoman:
354  d->m_text.append(QStringLiteral("</ol>\n"));
355  break;
356  default:
357  break;
358  }
359  d->currentListItemStyles.removeLast();
360 }
362 {
363  Q_D(TextHTMLBuilder);
364  d->m_text.append(QStringLiteral("<li>"));
365 }
366 
368 {
369  Q_D(TextHTMLBuilder);
370  d->m_text.append(QStringLiteral("</li>\n"));
371 }
372 
374 {
375  Q_D(TextHTMLBuilder);
376  d->m_text.append(QStringLiteral("<sup>"));
377 }
378 
380 {
381  Q_D(TextHTMLBuilder);
382  d->m_text.append(QStringLiteral("</sup>"));
383 }
384 
386 {
387  Q_D(TextHTMLBuilder);
388  d->m_text.append(QStringLiteral("<sub>"));
389 }
390 
392 {
393  Q_D(TextHTMLBuilder);
394  d->m_text.append(QStringLiteral("</sub>"));
395 }
396 
397 void TextHTMLBuilder::beginTable(qreal cellpadding, qreal cellspacing,
398  const QString &width)
399 {
400  Q_D(TextHTMLBuilder);
401  d->m_text.append(
402  QStringLiteral("<table cellpadding=\"%1\" cellspacing=\"%2\" "
403  "width=\"%3\" border=\"1\">")
404  .arg(cellpadding)
405  .arg(cellspacing)
406  .arg(width));
407 }
408 
410 {
411  Q_D(TextHTMLBuilder);
412  d->m_text.append(QStringLiteral("<tr>"));
413 }
414 
415 void TextHTMLBuilder::beginTableHeaderCell(const QString &width, int colspan,
416  int rowspan)
417 {
418  Q_D(TextHTMLBuilder);
419  d->m_text.append(
420  QStringLiteral("<th width=\"%1\" colspan=\"%2\" rowspan=\"%3\">")
421  .arg(width)
422  .arg(colspan)
423  .arg(rowspan));
424 }
425 
426 void TextHTMLBuilder::beginTableCell(const QString &width, int colspan,
427  int rowspan)
428 {
429  Q_D(TextHTMLBuilder);
430  d->m_text.append(
431  QStringLiteral("<td width=\"%1\" colspan=\"%2\" rowspan=\"%3\">")
432  .arg(width)
433  .arg(colspan)
434  .arg(rowspan));
435 }
436 
438 {
439  Q_D(TextHTMLBuilder);
440  d->m_text.append(QStringLiteral("</table>"));
441 }
442 
444 {
445  Q_D(TextHTMLBuilder);
446  d->m_text.append(QStringLiteral("</tr>"));
447 }
448 
450 {
451  Q_D(TextHTMLBuilder);
452  d->m_text.append(QStringLiteral("</th>"));
453 }
454 
456 {
457  Q_D(TextHTMLBuilder);
458  d->m_text.append(QStringLiteral("</td>"));
459 }
460 
462 {
463  Q_D(TextHTMLBuilder);
464  d->m_text.append(text.toHtmlEscaped());
465 }
466 
468 {
469  Q_D(TextHTMLBuilder);
470  d->m_text.append(text);
471 }
472 
474 {
475  Q_D(TextHTMLBuilder);
476  auto ret = d->m_text;
477  d->m_text.clear();
478  return ret;
479 }
Interface for creating marked-up text output.
The TextHTMLBuilder creates a clean html markup output.
void beginTableCell(const QString &width, int colspan, int rowspan) override
void beginTable(qreal cellpadding, qreal cellspacing, const QString &width) override
void appendRawText(const QString &text) override
void beginSubscript() override
void beginSuperscript() override
void endSuperscript() override
QString getResult() override
void beginAnchor(const QString &href={}, const QString &name={}) override
void beginForeground(const QBrush &brush) override
void beginBackground(const QBrush &brush) override
void appendLiteralText(const QString &text) override
void beginStrikeout() override
void beginHeader(int level) override
void endHeader(int level) override
void endTableHeaderCell() override
void beginTableHeaderCell(const QString &width, int colspan, int rowspan) override
void endStrikeout() override
void endFontPointSize() override
void insertHorizontalRule(int width=-1) override
void insertImage(const QString &src, qreal width, qreal height) override
void beginUnderline() override
void beginList(QTextListFormat::Style type) override
void beginFontFamily(const QString &family) override
void endUnderline() override
void beginFontPointSize(int size) override
void beginParagraph(Qt::Alignment al=Qt::AlignLeft, qreal topMargin=0.0, qreal bottomMargin=0.0, qreal leftMargin=0.0, qreal rightMargin=0.0) override
The Cutelee namespace holds all public Cutelee API.
Definition: Mainpage.dox:8