From 7c7606460403e6495b860134f28e8d4d45c6c810 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 15 Jun 2021 16:50:44 +0200 Subject: Add QTextDocFragment::to/fromMarkdown() & QTextCursor::insertMarkdown() Also add the beginnings of an autotest for QTextCursor::insertHtml(), for comparison purposes. We can see that the block to be inserted is merged with an existing block by default rather than being inserted as a new one, with both HTML and Markdown insertions. So now we test for leading and trailing newlines in the markdown to be inserted, to determine whether we need a new block into which to insert, and to "hit enter" at the end of the insertion. QSKIP the toMarkdown() comparisons if GeneralFont is mono. This happens on Boot2Qt systems in CI. Task-number: QTBUG-76105 Task-number: QTBUG-94462 Task-number: QTBUG-100515 Task-number: QTBUG-103484 Change-Id: I51a05c6a7cd0be4f2817f4a922f45fa663982293 Reviewed-by: Allan Sandfeld Jensen --- src/gui/text/qtextcursor.cpp | 22 +++++++++++++ src/gui/text/qtextcursor.h | 7 +++-- src/gui/text/qtextdocumentfragment.cpp | 56 ++++++++++++++++++++++++++++++++-- src/gui/text/qtextdocumentfragment.h | 9 +++++- 4 files changed, 88 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index 8a8b2efaef..1480020410 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -2290,6 +2290,28 @@ void QTextCursor::insertHtml(const QString &html) #endif // QT_NO_TEXTHTMLPARSER +/*! + \since 6.4 + Inserts the \a markdown text at the current position(), + with the specified Markdown \a features. The default is GitHub dialect. +*/ + +#if QT_CONFIG(textmarkdownreader) + +void QTextCursor::insertMarkdown(const QString &markdown, QTextDocument::MarkdownFeatures features) +{ + if (!d || !d->priv) + return; + QTextDocumentFragment fragment = QTextDocumentFragment::fromMarkdown(markdown, features); + if (markdown.startsWith(QLatin1Char('\n'))) + insertBlock(fragment.d->doc->firstBlock().blockFormat()); + insertFragment(fragment); + if (!atEnd() && markdown.endsWith(QLatin1Char('\n'))) + insertText(QLatin1String("\n")); +} + +#endif // textmarkdownreader + /*! \overload \since 4.2 diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h index b33b05aacc..890712ab22 100644 --- a/src/gui/text/qtextcursor.h +++ b/src/gui/text/qtextcursor.h @@ -43,12 +43,11 @@ #include #include #include +#include #include QT_BEGIN_NAMESPACE - -class QTextDocument; class QTextCursorPrivate; class QTextDocumentFragment; class QTextCharFormat; @@ -201,6 +200,10 @@ public: #ifndef QT_NO_TEXTHTMLPARSER void insertHtml(const QString &html); #endif // QT_NO_TEXTHTMLPARSER +#if QT_CONFIG(textmarkdownreader) + void insertMarkdown(const QString &markdown, + QTextDocument::MarkdownFeatures features = QTextDocument::MarkdownDialectGitHub); +#endif // textmarkdownreader void insertImage(const QTextImageFormat &format, QTextFrameFormat::Position alignment); void insertImage(const QTextImageFormat &format); diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp index 348916dd04..47baa4229e 100644 --- a/src/gui/text/qtextdocumentfragment.cpp +++ b/src/gui/text/qtextdocumentfragment.cpp @@ -41,6 +41,12 @@ #include "qtextdocumentfragment_p.h" #include "qtextcursor_p.h" #include "qtextlist.h" +#if QT_CONFIG(textmarkdownreader) +#include "qtextmarkdownimporter_p.h" +#endif +#if QT_CONFIG(textmarkdownwriter) +#include "qtextmarkdownwriter_p.h" +#endif #include #include @@ -412,6 +418,26 @@ QString QTextDocumentFragment::toHtml() const #endif // QT_NO_TEXTHTMLPARSER +#if QT_CONFIG(textmarkdownwriter) + +/*! + \since 6.4 + + Returns the contents of the document fragment as Markdown, + with the specified \a features. The default is GitHub dialect. + + \sa toPlainText(), QTextDocument::toMarkdown() +*/ +QString QTextDocumentFragment::toMarkdown(QTextDocument::MarkdownFeatures features) const +{ + if (!d) + return QString(); + + return d->doc->toMarkdown(features); +} + +#endif // textmarkdownwriter + /*! Returns a document fragment that contains the given \a plainText. @@ -1277,9 +1303,6 @@ void QTextHtmlImporter::appendBlock(const QTextBlockFormat &format, QTextCharFor compressNextWhitespace = RemoveWhiteSpace; } -#endif // QT_NO_TEXTHTMLPARSER - -#ifndef QT_NO_TEXTHTMLPARSER /*! \fn QTextDocumentFragment QTextDocumentFragment::fromHtml(const QString &text, const QTextDocument *resourceProvider) \since 4.2 @@ -1305,4 +1328,31 @@ QTextDocumentFragment QTextDocumentFragment::fromHtml(const QString &html, const #endif // QT_NO_TEXTHTMLPARSER +#if QT_CONFIG(textmarkdownreader) + +/*! + \fn QTextDocumentFragment QTextDocumentFragment::fromMarkdown(const QString &markdown, QTextDocument::MarkdownFeatures features) + \since 6.4 + + Returns a QTextDocumentFragment based on the given \a markdown text with + the specified \a features. The default is GitHub dialect. + + The formatting is preserved as much as possible; for example, \c {**bold**} + will become a document fragment containing the text "bold" with a bold + character style. + + \note Loading external resources is not supported. +*/ +QTextDocumentFragment QTextDocumentFragment::fromMarkdown(const QString &markdown, QTextDocument::MarkdownFeatures features) +{ + QTextDocumentFragment res; + res.d = new QTextDocumentFragmentPrivate; + + QTextMarkdownImporter importer(features); + importer.import(res.d->doc, markdown); + return res; +} + +#endif // textmarkdownreader + QT_END_NAMESPACE diff --git a/src/gui/text/qtextdocumentfragment.h b/src/gui/text/qtextdocumentfragment.h index 37d7006ae6..3c23e403e0 100644 --- a/src/gui/text/qtextdocumentfragment.h +++ b/src/gui/text/qtextdocumentfragment.h @@ -41,13 +41,13 @@ #define QTEXTDOCUMENTFRAGMENT_H #include +#include #include QT_BEGIN_NAMESPACE class QTextStream; -class QTextDocument; class QTextDocumentFragmentPrivate; class QTextCursor; @@ -68,11 +68,18 @@ public: #ifndef QT_NO_TEXTHTMLPARSER QString toHtml() const; #endif // QT_NO_TEXTHTMLPARSER +#if QT_CONFIG(textmarkdownwriter) + QString toMarkdown(QTextDocument::MarkdownFeatures features = QTextDocument::MarkdownDialectGitHub) const; +#endif static QTextDocumentFragment fromPlainText(const QString &plainText); #ifndef QT_NO_TEXTHTMLPARSER static QTextDocumentFragment fromHtml(const QString &html, const QTextDocument *resourceProvider = nullptr); #endif // QT_NO_TEXTHTMLPARSER +#if QT_CONFIG(textmarkdownreader) + static QTextDocumentFragment fromMarkdown(const QString &markdown, + QTextDocument::MarkdownFeatures features = QTextDocument::MarkdownDialectGitHub); +#endif private: QTextDocumentFragmentPrivate *d; -- cgit v1.2.3