From 280d679c556ab8ead4748a627d7cd4c1950027fb Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 20 May 2019 11:50:26 +0200 Subject: [PATCH] QTextMarkdownWriter: fix some bad cases with word wrap If any non-breakable content (such as a link) already went past 80 columns, or if a word ended on column 80, it didn't wrap the rest of the paragraph following. Change-Id: I27dc0474f18892c34ee2514ea6d5070dae29424f Reviewed-by: Gatis Paeglis --- src/gui/text/qtextmarkdownwriter.cpp | 25 +++++++++++++++---- .../qtextmarkdownwriter/data/blockquotes.md | 3 ++- .../text/qtextmarkdownwriter/data/wordWrap.md | 13 ++++++++++ .../tst_qtextmarkdownwriter.cpp | 1 + 4 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 tests/auto/gui/text/qtextmarkdownwriter/data/wordWrap.md diff --git a/src/gui/text/qtextmarkdownwriter.cpp b/src/gui/text/qtextmarkdownwriter.cpp index f180098db2..02643acdca 100644 --- a/src/gui/text/qtextmarkdownwriter.cpp +++ b/src/gui/text/qtextmarkdownwriter.cpp @@ -212,10 +212,19 @@ QTextMarkdownWriter::ListInfo QTextMarkdownWriter::listInfo(QTextList *list) static int nearestWordWrapIndex(const QString &s, int before) { before = qMin(before, s.length()); - for (int i = before - 1; i >= 0; --i) { - if (s.at(i).isSpace()) - return i; + int fragBegin = qMax(before - 15, 0); + if (lcMDW().isDebugEnabled()) { + QString frag = s.mid(fragBegin, 30); + qCDebug(lcMDW) << frag << before; + qCDebug(lcMDW) << QString(before - fragBegin, Period) + QLatin1Char('<'); } + for (int i = before - 1; i >= 0; --i) { + if (s.at(i).isSpace()) { + qCDebug(lcMDW) << QString(i - fragBegin, Period) + QLatin1Char('^') << i; + return i; + } + } + qCDebug(lcMDW, "not possible"); return -1; } @@ -251,7 +260,7 @@ static void maybeEscapeFirstChar(QString &s) int QTextMarkdownWriter::writeBlock(const QTextBlock &block, bool wrap, bool ignoreFormat) { - int ColumnLimit = 80; + const int ColumnLimit = 80; QTextBlockFormat blockFmt = block.blockFormat(); bool indentedCodeBlock = false; if (block.textList()) { // it's a list-item @@ -419,12 +428,18 @@ int QTextMarkdownWriter::writeBlock(const QTextBlock &block, bool wrap, bool ign int fragLen = fragmentText.length(); bool breakingLine = false; while (i < fragLen) { + if (col >= ColumnLimit) { + m_stream << Newline << wrapIndentString; + col = m_wrappedLineIndent; + while (fragmentText[i].isSpace()) + ++i; + } int j = i + ColumnLimit - col; if (j < fragLen) { int wi = nearestWordWrapIndex(fragmentText, j); if (wi < 0) { j = fragLen; - } else { + } else if (wi >= i) { j = wi; breakingLine = true; } diff --git a/tests/auto/gui/text/qtextmarkdownwriter/data/blockquotes.md b/tests/auto/gui/text/qtextmarkdownwriter/data/blockquotes.md index f429fcc21b..44c198fdc5 100644 --- a/tests/auto/gui/text/qtextmarkdownwriter/data/blockquotes.md +++ b/tests/auto/gui/text/qtextmarkdownwriter/data/blockquotes.md @@ -13,7 +13,8 @@ MacFarlane writes: > > as readable as possible. The idea is that a Markdown-formatted document should > > be publishable as-is, as plain text, without looking like it's been marked up > > with tags or formatting instructions. ( -> > [http://daringfireball.net/projects/markdown/](http://daringfireball.net/projects/markdown/)) +> > [http://daringfireball.net/projects/markdown/](http://daringfireball.net/projects/markdown/) +> > ) > The point can be illustrated by comparing a sample of AsciiDoc with an > equivalent sample of Markdown. Here is a sample of AsciiDoc from the AsciiDoc diff --git a/tests/auto/gui/text/qtextmarkdownwriter/data/wordWrap.md b/tests/auto/gui/text/qtextmarkdownwriter/data/wordWrap.md new file mode 100644 index 0000000000..dacb0acf77 --- /dev/null +++ b/tests/auto/gui/text/qtextmarkdownwriter/data/wordWrap.md @@ -0,0 +1,13 @@ +[The CommonMark Specification](https://spec.commonmark.org/0.29/) is the +conservative formal specification of the Markdown format, while +[GitHub Flavored Markdown](https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown) +adds extra features such as task lists and tables. + +Qt owes thanks to the authors of the [MD4C parser](https://github.com/mity/md4c) +for making markdown import possible. The QTextMarkdownWriter class does not +have such dependencies, and also has not yet been tested as extensively, so we +do not yet guarantee that we are able to rewrite every Markdown document that +you are able to read and display with Text or QTextEdit. But you are free to +write [bugs](https://bugreports.qt.io) about any troublesome cases that you +encounter. + diff --git a/tests/auto/gui/text/qtextmarkdownwriter/tst_qtextmarkdownwriter.cpp b/tests/auto/gui/text/qtextmarkdownwriter/tst_qtextmarkdownwriter.cpp index b14e810430..acc74a9060 100644 --- a/tests/auto/gui/text/qtextmarkdownwriter/tst_qtextmarkdownwriter.cpp +++ b/tests/auto/gui/text/qtextmarkdownwriter/tst_qtextmarkdownwriter.cpp @@ -358,6 +358,7 @@ void tst_QTextMarkdownWriter::rewriteDocument_data() QTest::newRow("block quotes") << "blockquotes.md"; QTest::newRow("example") << "example.md"; QTest::newRow("list items after headings") << "headingsAndLists.md"; + QTest::newRow("word wrap") << "wordWrap.md"; } void tst_QTextMarkdownWriter::rewriteDocument()