1 | // Copyright (C) 2019 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #ifndef QTEXTMARKDOWNIMPORTER_H |
5 | #define QTEXTMARKDOWNIMPORTER_H |
6 | |
7 | // |
8 | // W A R N I N G |
9 | // ------------- |
10 | // |
11 | // This file is not part of the Qt API. It exists purely as an |
12 | // implementation detail. This header file may change from version to |
13 | // version without notice, or even be removed. |
14 | // |
15 | // We mean it. |
16 | // |
17 | |
18 | #include <QtGui/qfont.h> |
19 | #include <QtGui/qtguiglobal.h> |
20 | #include <QtGui/qpalette.h> |
21 | #include <QtGui/qtextdocument.h> |
22 | #include <QtGui/qtextlist.h> |
23 | #include <QtCore/qpointer.h> |
24 | #include <QtCore/qstack.h> |
25 | #include <QtCore/private/qglobal_p.h> |
26 | |
27 | QT_BEGIN_NAMESPACE |
28 | |
29 | class QTextCursor; |
30 | class QTextDocument; |
31 | class QTextTable; |
32 | |
33 | class Q_GUI_EXPORT QTextMarkdownImporter |
34 | { |
35 | public: |
36 | enum Feature { |
37 | FeatureCollapseWhitespace = 0x0001, |
38 | = 0x0002, |
39 | FeaturePermissiveURLAutoLinks = 0x0004, |
40 | FeaturePermissiveMailAutoLinks = 0x0008, |
41 | FeatureNoIndentedCodeBlocks = 0x0010, |
42 | FeatureNoHTMLBlocks = 0x0020, |
43 | FeatureNoHTMLSpans = 0x0040, |
44 | FeatureTables = 0x0100, |
45 | FeatureStrikeThrough = 0x0200, |
46 | FeaturePermissiveWWWAutoLinks = 0x0400, |
47 | FeatureTasklists = 0x0800, |
48 | FeatureUnderline = 0x4000, |
49 | // composite flags |
50 | FeaturePermissiveAutoLinks = FeaturePermissiveMailAutoLinks |
51 | | FeaturePermissiveURLAutoLinks | FeaturePermissiveWWWAutoLinks, |
52 | FeatureNoHTML = QTextDocument::MarkdownNoHTML, |
53 | DialectCommonMark = QTextDocument::MarkdownDialectCommonMark, |
54 | DialectGitHub = QTextDocument::MarkdownDialectGitHub |
55 | }; |
56 | Q_DECLARE_FLAGS(Features, Feature) |
57 | |
58 | QTextMarkdownImporter(Features features); |
59 | QTextMarkdownImporter(QTextDocument::MarkdownFeatures features); |
60 | |
61 | void import(QTextDocument *doc, const QString &markdown); |
62 | |
63 | public: |
64 | // MD4C callbacks |
65 | int cbEnterBlock(int blockType, void* detail); |
66 | int cbLeaveBlock(int blockType, void* detail); |
67 | int cbEnterSpan(int spanType, void* detail); |
68 | int cbLeaveSpan(int spanType, void* detail); |
69 | int cbText(int textType, const char* text, unsigned size); |
70 | |
71 | private: |
72 | void insertBlock(); |
73 | |
74 | private: |
75 | QTextDocument *m_doc = nullptr; |
76 | QTextCursor *m_cursor = nullptr; |
77 | QTextTable *m_currentTable = nullptr; // because m_cursor->currentTable() doesn't work |
78 | #if QT_CONFIG(regularexpression) |
79 | QString m_htmlAccumulator; |
80 | #endif |
81 | QString m_blockCodeLanguage; |
82 | QList<int> m_nonEmptyTableCells; // in the current row |
83 | QStack<QPointer<QTextList>> m_listStack; |
84 | QStack<QTextCharFormat> m_spanFormatStack; |
85 | QFont m_monoFont; |
86 | QPalette m_palette; |
87 | #if QT_CONFIG(regularexpression) |
88 | int m_htmlTagDepth = 0; |
89 | #endif |
90 | int m_blockQuoteDepth = 0; |
91 | int m_tableColumnCount = 0; |
92 | int m_tableRowCount = 0; |
93 | int m_tableCol = -1; // because relative cell movements (e.g. m_cursor->movePosition(QTextCursor::NextCell)) don't work |
94 | int m_paragraphMargin = 0; |
95 | int m_blockType = 0; |
96 | char m_blockCodeFence = 0; |
97 | Features m_features; |
98 | QTextImageFormat m_imageFormat; |
99 | QTextListFormat m_listFormat; |
100 | QTextBlockFormat::MarkerType m_markerType = QTextBlockFormat::MarkerType::NoMarker; |
101 | bool m_needsInsertBlock = false; |
102 | bool m_needsInsertList = false; |
103 | bool m_listItem = false; // true from the beginning of LI to the end of the first P |
104 | bool m_codeBlock = false; |
105 | bool m_imageSpan = false; |
106 | }; |
107 | |
108 | Q_DECLARE_OPERATORS_FOR_FLAGS(QTextMarkdownImporter::Features) |
109 | |
110 | QT_END_NAMESPACE |
111 | |
112 | #endif // QTEXTMARKDOWNIMPORTER_H |
113 | |