Markdown: deal with horizontal rules (thematic breaks)

Change-Id: I14d4bcfe1a6c3bd87d1328f0abb81b2138545e4e
Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
This commit is contained in:
Shawn Rutledge 2019-04-26 08:29:07 +02:00
parent 040dd7fe26
commit 76716c4a9a
6 changed files with 69 additions and 2 deletions

View File

@ -273,7 +273,8 @@ int QTextMarkdownImporter::cbEnterBlock(int blockType, void *det)
m_currentTable = m_cursor->insertTable(1, 1); // we don't know the dimensions yet
break;
case MD_BLOCK_HR: {
QTextBlockFormat blockFmt = m_cursor->blockFormat();
qCDebug(lcMD, "HR");
QTextBlockFormat blockFmt;
blockFmt.setProperty(QTextFormat::BlockTrailingHorizontalRulerWidth, 1);
m_cursor->insertBlock(blockFmt, QTextCharFormat());
} break;

View File

@ -309,6 +309,9 @@ int QTextMarkdownWriter::writeBlock(const QTextBlock &block, bool wrap, bool ign
prefix += QLatin1String(bullet) + Space;
}
m_stream << prefix;
} else if (block.blockFormat().hasProperty(QTextFormat::BlockTrailingHorizontalRulerWidth)) {
m_stream << "- - -\n"; // unambiguous horizontal rule, not an underline under a heading
return 0;
} else if (!block.blockFormat().indent()) {
m_wrappedLineIndent = 0;
}

View File

@ -0,0 +1,17 @@
Heading
-------
***
stars
- bullet
** not a bullet or a rule, just two stars
- [ ] unchecked
--- indented too far, so not a rule
* * *
stars with tabs between
***
stars with whitespace after
---
hyphens with whitespace after
_____
underscores with whitespace after

View File

@ -2,6 +2,7 @@ CONFIG += testcase
TARGET = tst_qtextmarkdownimporter
QT += core-private gui-private testlib
SOURCES += tst_qtextmarkdownimporter.cpp
TESTDATA += data/headingBulletsContinuations.md
TESTDATA += \
data/thematicBreaks.md \
DEFINES += SRCDIR=\\\"$$PWD\\\"

View File

@ -52,6 +52,7 @@ class tst_QTextMarkdownImporter : public QObject
private slots:
void headingBulletsContinuations();
void thematicBreaks();
};
void tst_QTextMarkdownImporter::headingBulletsContinuations()
@ -117,5 +118,46 @@ void tst_QTextMarkdownImporter::headingBulletsContinuations()
#endif
}
void tst_QTextMarkdownImporter::thematicBreaks()
{
int horizontalRuleCount = 0;
int textLinesCount = 0;
QFile f(QFINDTESTDATA("data/thematicBreaks.md"));
QVERIFY(f.open(QFile::ReadOnly | QIODevice::Text));
QString md = QString::fromUtf8(f.readAll());
f.close();
QTextDocument doc;
QTextMarkdownImporter(QTextMarkdownImporter::DialectGitHub).import(&doc, md);
QTextFrame::iterator iterator = doc.rootFrame()->begin();
QTextFrame *currentFrame = iterator.currentFrame();
int i = 0;
while (!iterator.atEnd()) {
// There are no child frames
QCOMPARE(iterator.currentFrame(), currentFrame);
// Check whether the block is text or a horizontal rule
QTextBlock block = iterator.currentBlock();
if (block.blockFormat().hasProperty(QTextFormat::BlockTrailingHorizontalRulerWidth))
++horizontalRuleCount;
else if (!block.text().isEmpty())
++textLinesCount;
qCDebug(lcTests) << i << (block.blockFormat().hasProperty(QTextFormat::BlockTrailingHorizontalRulerWidth) ? QLatin1String("- - -") : block.text());
++iterator;
++i;
}
QCOMPARE(horizontalRuleCount, 5);
QCOMPARE(textLinesCount, 9);
#ifdef DEBUG_WRITE_HTML
{
QFile out("/tmp/thematicBreaks.html");
out.open(QFile::WriteOnly);
out.write(doc.toHtml().toLatin1());
out.close();
}
#endif
}
QTEST_MAIN(tst_QTextMarkdownImporter)
#include "tst_qtextmarkdownimporter.moc"

View File

@ -398,6 +398,9 @@ void tst_QTextMarkdownWriter::fromHtml_data()
QTest::newRow("nested ordered list items with continuations") <<
"<ol><li>item<p>continuation paragraph</p></li><li>another item<br/>continuation line</li><ol><li>item<p>continuation paragraph</p></li><li>another item<br/>continuation line</li></ol><li>another</li><li>another</li></ol>" <<
"1. item\n\n continuation paragraph\n\n2. another item\n continuation line\n\n 1. item\n\n continuation paragraph\n\n 2. another item\n continuation line\n\n3. another\n4. another\n";
QTest::newRow("thematic break") <<
"something<hr/>something else" <<
"something\n\n- - -\nsomething else\n\n";
// TODO
// QTest::newRow("escaped number and paren after double newline") <<
// "<p>(The first sentence of this paragraph is a line, the next paragraph has a number</p>13) but that's not part of an ordered list" <<