File indexing completed on 2024-05-19 05:21:47

0001 /*
0002    SPDX-FileCopyrightText: 2020-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 #include "abstractmarkupbuilder.h"
0009 #include "kpimtextedit_export.h"
0010 
0011 namespace KPIMTextEdit
0012 {
0013 class TextHTMLBuilderPrivate;
0014 
0015 /// @headerfile texthtmlbuilder.h grantlee/texthtmlbuilder.h
0016 
0017 /**
0018   @brief The TextHTMLBuilder creates a clean html markup output.
0019 
0020   This class creates html output which is as minimal as possible and restricted
0021   to the rich text features supported in %Qt.
0022   (https://doc.qt.io/qt-5/richtext-html-subset.html)
0023 
0024   The output contains only the body content, not the head element or other
0025   metadata.
0026 
0027   eg:
0028 
0029   @code
0030     <p>
0031       This is some <strong>formatted content</strong> in a paragraph.
0032     </p>
0033   @endcode
0034 
0035   instead of the content produced by %Qt:
0036 
0037   @code
0038     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"
0039   "http://www.w3.org/TR/REC-html40/strict.dtd">
0040     <html><head><meta name="qrichtext" content="1" /><meta
0041   http-equiv="Content-Type" content="text/html; charset=UTF-8" /><style
0042   type="text/css">
0043     p, li { white-space: pre-wrap; }
0044     </style></head><body style=" font-family:'Sans Serif'; font-size:10pt;
0045   font-weight:400; font-style:normal;">
0046     <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px;
0047   margin-right:0px; -qt-block-indent:0; text-indent:0px;">This is some <span
0048   style=" font-weight:600;">formatted content</span> in a paragraph.
0049   </p></body></html>
0050   @endcode
0051 
0052   Such tags should be created separately. For example:
0053 
0054   @code
0055     auto b = new TextHTMLBuilder();
0056     auto md = new MarkupDirector(b);
0057     md->constructContent();
0058     QString cleanHtml(
0059       "<head>\n<title>%1</title>\n</head>\n<body>%2</body>\n</html>")
0060                       .arg(document.metaInformation(QTextDocument::DocumentTitle))
0061                       .arg(b->getOutput());
0062     file.write(cleanHtml);
0063   @endcode
0064 
0065   Font formatting information on elements is represented by individual span
0066   elements.
0067 
0068   eg:
0069   @code
0070     <span style"color:blue;">
0071       <span style="background-color:red;">
0072         Blue text on red background
0073       </span>
0074     </span>
0075   @endcode
0076 
0077   instead of
0078 
0079   @code
0080     <span style="color:blue;background-color:red;">
0081       Blue text on red background
0082     </span>
0083   @endcode
0084 
0085   It my be possible to change this if necessary.
0086 
0087   @author Stephen Kelly <steveire@gmail.com>
0088 */
0089 class KPIMTEXTEDIT_EXPORT TextHTMLBuilder : virtual public KPIMTextEdit::AbstractMarkupBuilder
0090 {
0091 public:
0092     TextHTMLBuilder();
0093     ~TextHTMLBuilder() override;
0094 
0095     void beginStrong() override;
0096     void endStrong() override;
0097     void beginEmph() override;
0098     void endEmph() override;
0099     void beginUnderline() override;
0100     void endUnderline() override;
0101     void beginStrikeout() override;
0102     void endStrikeout() override;
0103     void beginForeground(const QBrush &brush) override;
0104     void endForeground() override;
0105     void beginBackground(const QBrush &brush) override;
0106     void endBackground() override;
0107     void beginAnchor(const QString &href = {}, const QString &name = {}) override;
0108     void endAnchor() override;
0109 
0110     // Maybe this stuff should just be added to a list, and then when I add
0111     // literal text,
0112     // add some kind of style attribute in one span instead of many.
0113     void beginFontFamily(const QString &family) override;
0114     void endFontFamily() override;
0115 
0116     /**
0117     Begin a new font point size
0118     @param size The new size to begin.
0119   */
0120     void beginFontPointSize(int size) override;
0121     void endFontPointSize() override;
0122 
0123     /**
0124     Begin a new paragraph
0125     @param al The new paragraph alignment
0126     @param topMargin The new paragraph topMargin
0127     @param bottomMargin The new paragraph bottomMargin
0128     @param leftMargin The new paragraph leftMargin
0129     @param rightMargin The new paragraph rightMargin
0130   */
0131     void beginParagraph(Qt::Alignment al = Qt::AlignLeft,
0132                         qreal topMargin = 0.0,
0133                         qreal bottomMargin = 0.0,
0134                         qreal leftMargin = 0.0,
0135                         qreal rightMargin = 0.0,
0136                         bool leftToRightText = false) override;
0137 
0138     /**
0139     Begin a new header element.
0140     @param level The new level to begin.
0141   */
0142     void beginHeader(int level) override;
0143 
0144     /**
0145     End a header element.
0146     @param level The new level to end.
0147   */
0148     void endHeader(int level) override;
0149 
0150     void endParagraph() override;
0151     void addNewline() override;
0152 
0153     void insertHorizontalRule(int width = -1) override;
0154 
0155     void insertImage(const QString &src, qreal width, qreal height) override;
0156 
0157     void beginList(QTextListFormat::Style type) override;
0158 
0159     void endList() override;
0160 
0161     void beginListItem() override;
0162     void endListItem() override;
0163 
0164     void beginSuperscript() override;
0165 
0166     void endSuperscript() override;
0167 
0168     void beginSubscript() override;
0169 
0170     void endSubscript() override;
0171 
0172     void beginTable(qreal cellpadding, qreal cellspacing, const QString &width) override;
0173 
0174     void beginTableRow() override;
0175     void beginTableHeaderCell(const QString &width, int colspan, int rowspan) override;
0176 
0177     void beginTableCell(const QString &width, int colspan, int rowspan) override;
0178 
0179     void endTable() override;
0180     void endTableRow() override;
0181     void endTableHeaderCell() override;
0182     void endTableCell() override;
0183 
0184     /**
0185     Reimplemented from AbstractMarkupBuilder.
0186 
0187     This implementation escapes the text before appending so that
0188 
0189     @verbatim
0190       A sample <b>bold</b> word.
0191     @endverbatim
0192 
0193     becomes
0194 
0195     @verbatim
0196       A sample &lt;b&gt;bold&lt;/b&gt; word.
0197     @endverbatim
0198   */
0199     void appendLiteralText(const QString &text) override;
0200 
0201     /**
0202     Append @p text without escaping.
0203 
0204     This is useful if extending MarkupDirector
0205   */
0206     void appendRawText(const QString &text) override;
0207 
0208     [[nodiscard]] QString getResult() override;
0209 
0210     void addSingleBreakLine() override;
0211 
0212 private:
0213     TextHTMLBuilderPrivate *d_ptr;
0214     Q_DECLARE_PRIVATE(TextHTMLBuilder)
0215 };
0216 
0217 }