summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2019-10-21 15:14:53 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2019-10-24 20:58:44 +0200
commitd377d1f3a921488525f6e75c850632f559707747 (patch)
treee351fc46db44119a6499f1c4543084b1c83c27dd /src
parent5edf34848a51c7678031aeb9576b8f3b7b5fceab (diff)
Enforce QTextDocument::MarkdownFeature compatibility at compile time
We use md4c for parsing markdown. It provides flags to control the feature set that will be supported when parsing particular documents. QTextMarkdownImporter::Feature is a fine-grained set of flags that exactly match the md4c feature flags that we support in Qt so far. QTextMarkdownImporter is a private exported class (new in 5.14). We don't expect the corresponding flags in md4c to change in incompatible ways in the future: the md4c authors have as much respect for avoiding compatibility issues as we do, and likely will only add features, not remove them. We now enforce QTextMarkdownImporter::Features compatibility with QTextDocument::MarkdownFeatures by setting them directly. We check QTextMarkdownImporter::Features compatibility with md4c's #define'd feature flags using static asserts, so that any hypothetical incompatibility would be detected at compile time. The enum conversion from QTextDocument::MarkdownFeatures to QTextMarkdownImporter::Features is moved to a new QTextMarkdownImporter constructor; thus the conversions from QTextDocument::MarkdownFeatures to QTextMarkdownImporter::Features, and then to unsigned (in QTextMarkdownImporter::import()) are adjacent in the same private class implementation. If incompatibility ever occurred, we would need to replace one or both of those with another suitable conversion function. Change-Id: I0bf8a21eb7559df1d38406b948ef657f9060c67b Reviewed-by: Vitaly Fanaskov <vitaly.fanaskov@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/gui/text/qtextdocument.cpp2
-rw-r--r--src/gui/text/qtextdocument.h1
-rw-r--r--src/gui/text/qtextmarkdownimporter.cpp21
-rw-r--r--src/gui/text/qtextmarkdownimporter_p.h34
4 files changed, 40 insertions, 18 deletions
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 22c249d604..e94f635651 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -3420,7 +3420,7 @@ QString QTextDocument::toMarkdown(QTextDocument::MarkdownFeatures features) cons
#if QT_CONFIG(textmarkdownreader)
void QTextDocument::setMarkdown(const QString &markdown, QTextDocument::MarkdownFeatures features)
{
- QTextMarkdownImporter(static_cast<QTextMarkdownImporter::Features>(int(features))).import(this, markdown);
+ QTextMarkdownImporter(features).import(this, markdown);
}
#endif
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index 2fadc40cd2..7d46238257 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -152,7 +152,6 @@ public:
#endif
#if QT_CONFIG(textmarkdownwriter) || QT_CONFIG(textmarkdownreader)
- // Must be in sync with QTextMarkdownImporter::Features, should be in sync with #define MD_FLAG_* in md4c
enum MarkdownFeature {
MarkdownNoHTML = 0x0020 | 0x0040,
MarkdownDialectCommonMark = 0,
diff --git a/src/gui/text/qtextmarkdownimporter.cpp b/src/gui/text/qtextmarkdownimporter.cpp
index fe7e422923..87ade1f973 100644
--- a/src/gui/text/qtextmarkdownimporter.cpp
+++ b/src/gui/text/qtextmarkdownimporter.cpp
@@ -60,6 +60,22 @@ static const QChar Space = QLatin1Char(' ');
// TODO maybe eliminate the margins after all views recognize BlockQuoteLevel, CSS can format it, etc.
static const int BlockQuoteIndent = 40; // pixels, same as in QTextHtmlParserNode::initializeProperties
+Q_STATIC_ASSERT(int(QTextMarkdownImporter::FeatureCollapseWhitespace) == MD_FLAG_COLLAPSEWHITESPACE);
+Q_STATIC_ASSERT(int(QTextMarkdownImporter::FeaturePermissiveATXHeaders) == MD_FLAG_PERMISSIVEATXHEADERS);
+Q_STATIC_ASSERT(int(QTextMarkdownImporter::FeaturePermissiveURLAutoLinks) == MD_FLAG_PERMISSIVEURLAUTOLINKS);
+Q_STATIC_ASSERT(int(QTextMarkdownImporter::FeaturePermissiveMailAutoLinks) == MD_FLAG_PERMISSIVEEMAILAUTOLINKS);
+Q_STATIC_ASSERT(int(QTextMarkdownImporter::FeatureNoIndentedCodeBlocks) == MD_FLAG_NOINDENTEDCODEBLOCKS);
+Q_STATIC_ASSERT(int(QTextMarkdownImporter::FeatureNoHTMLBlocks) == MD_FLAG_NOHTMLBLOCKS);
+Q_STATIC_ASSERT(int(QTextMarkdownImporter::FeatureNoHTMLSpans) == MD_FLAG_NOHTMLSPANS);
+Q_STATIC_ASSERT(int(QTextMarkdownImporter::FeatureTables) == MD_FLAG_TABLES);
+Q_STATIC_ASSERT(int(QTextMarkdownImporter::FeatureStrikeThrough) == MD_FLAG_STRIKETHROUGH);
+Q_STATIC_ASSERT(int(QTextMarkdownImporter::FeaturePermissiveWWWAutoLinks) == MD_FLAG_PERMISSIVEWWWAUTOLINKS);
+Q_STATIC_ASSERT(int(QTextMarkdownImporter::FeaturePermissiveAutoLinks) == MD_FLAG_PERMISSIVEAUTOLINKS);
+Q_STATIC_ASSERT(int(QTextMarkdownImporter::FeatureTasklists) == MD_FLAG_TASKLISTS);
+Q_STATIC_ASSERT(int(QTextMarkdownImporter::FeatureNoHTML) == MD_FLAG_NOHTML);
+Q_STATIC_ASSERT(int(QTextMarkdownImporter::DialectCommonMark) == MD_DIALECT_COMMONMARK);
+Q_STATIC_ASSERT(int(QTextMarkdownImporter::DialectGitHub) == MD_DIALECT_GITHUB);
+
// --------------------------------------------------------
// MD4C callback function wrappers
@@ -122,6 +138,11 @@ QTextMarkdownImporter::QTextMarkdownImporter(QTextMarkdownImporter::Features fea
{
}
+QTextMarkdownImporter::QTextMarkdownImporter(QTextDocument::MarkdownFeatures features)
+ : QTextMarkdownImporter(static_cast<QTextMarkdownImporter::Features>(int(features)))
+{
+}
+
void QTextMarkdownImporter::import(QTextDocument *doc, const QString &markdown)
{
MD_PARSER callbacks = {
diff --git a/src/gui/text/qtextmarkdownimporter_p.h b/src/gui/text/qtextmarkdownimporter_p.h
index 35655aff8a..f450da5eb3 100644
--- a/src/gui/text/qtextmarkdownimporter_p.h
+++ b/src/gui/text/qtextmarkdownimporter_p.h
@@ -54,6 +54,7 @@
#include <QtGui/qfont.h>
#include <QtGui/qtguiglobal.h>
#include <QtGui/qpalette.h>
+#include <QtGui/qtextdocument.h>
#include <QtGui/qtextlist.h>
#include <QtCore/qstack.h>
@@ -67,27 +68,28 @@ class Q_GUI_EXPORT QTextMarkdownImporter
{
public:
enum Feature {
- // Must be kept in sync with MD_FLAG_* in md4c.h
- FeatureCollapseWhitespace = 0x0001, // MD_FLAG_COLLAPSEWHITESPACE
- FeaturePermissiveATXHeaders = 0x0002, // MD_FLAG_PERMISSIVEATXHEADERS
- FeaturePermissiveURLAutoLinks = 0x0004, // MD_FLAG_PERMISSIVEURLAUTOLINKS
- FeaturePermissiveMailAutoLinks = 0x0008, // MD_FLAG_PERMISSIVEEMAILAUTOLINKS
- FeatureNoIndentedCodeBlocks = 0x0010, // MD_FLAG_NOINDENTEDCODEBLOCKS
- FeatureNoHTMLBlocks = 0x0020, // MD_FLAG_NOHTMLBLOCKS
- FeatureNoHTMLSpans = 0x0040, // MD_FLAG_NOHTMLSPANS
- FeatureTables = 0x0100, // MD_FLAG_TABLES
- FeatureStrikeThrough = 0x0200, // MD_FLAG_STRIKETHROUGH
- FeaturePermissiveWWWAutoLinks = 0x0400, // MD_FLAG_PERMISSIVEWWWAUTOLINKS
- FeatureTasklists = 0x0800, // MD_FLAG_TASKLISTS
+ FeatureCollapseWhitespace = 0x0001,
+ FeaturePermissiveATXHeaders = 0x0002,
+ FeaturePermissiveURLAutoLinks = 0x0004,
+ FeaturePermissiveMailAutoLinks = 0x0008,
+ FeatureNoIndentedCodeBlocks = 0x0010,
+ FeatureNoHTMLBlocks = 0x0020,
+ FeatureNoHTMLSpans = 0x0040,
+ FeatureTables = 0x0100,
+ FeatureStrikeThrough = 0x0200,
+ FeaturePermissiveWWWAutoLinks = 0x0400,
+ FeatureTasklists = 0x0800,
// composite flags
- FeaturePermissiveAutoLinks = FeaturePermissiveMailAutoLinks | FeaturePermissiveURLAutoLinks | FeaturePermissiveWWWAutoLinks, // MD_FLAG_PERMISSIVEAUTOLINKS
- FeatureNoHTML = FeatureNoHTMLBlocks | FeatureNoHTMLSpans, // MD_FLAG_NOHTML
- DialectCommonMark = 0, // MD_DIALECT_COMMONMARK
- DialectGitHub = FeaturePermissiveAutoLinks | FeatureTables | FeatureStrikeThrough | FeatureTasklists // MD_DIALECT_GITHUB
+ FeaturePermissiveAutoLinks = FeaturePermissiveMailAutoLinks
+ | FeaturePermissiveURLAutoLinks | FeaturePermissiveWWWAutoLinks,
+ FeatureNoHTML = QTextDocument::MarkdownNoHTML,
+ DialectCommonMark = QTextDocument::MarkdownDialectCommonMark,
+ DialectGitHub = QTextDocument::MarkdownDialectGitHub
};
Q_DECLARE_FLAGS(Features, Feature)
QTextMarkdownImporter(Features features);
+ QTextMarkdownImporter(QTextDocument::MarkdownFeatures features);
void import(QTextDocument *doc, const QString &markdown);