summaryrefslogtreecommitdiffstats
path: root/src/gui/text/qtextmarkdownimporter_p.h
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2019-04-26 08:12:18 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2019-05-08 20:28:53 +0000
commit7dd71e812542c561a00dd792d314843a81c5687c (patch)
treef3b1c60d4d323f47786a206279e1468a16501aef /src/gui/text/qtextmarkdownimporter_p.h
parent82b26444a456d4d5ddf5f483b7766977659bee35 (diff)
Markdown: blockquotes, code blocks, and generalized nesting
Can now detect nested quotes and code blocks inside quotes, and can rewrite the markdown too. QTextHtmlParser sets hard-coded left and right margins, so we need to do the same to be able to read HTML and write markdown, or vice-versa, and to ensure that all views (QTextEdit, QTextBrowser, QML Text etc.) will render it with margins. But now we add a semantic memory too: BlockQuoteLevel is similar to HeadingLevel, which was added in 310daae53926628f80c08e4415b94b90ad525c8f to preserve H1..H6 heading levels, because detecting it via font size didn't make sense in QTextMarkdownWriter. Likewise detecting quote level by its margins didn't make sense; markdown supports nesting quotes; and indenting nested quotes via 40 pixels may be a bit too much, so we should consider it subject to change (and perhaps be able to change it via CSS later on). Since we're adding BlockQuoteLevel and depending on it in QTextMarkdownWriter, it's necessary to set it in QTextHtmlParser to enable HTML->markdown conversion. (But so far, nested blockquotes in HTML are not supported.) Quotes (and nested quotes) can contain indented code blocks, but it seems the reverse is not true (according to https://spec.commonmark.org/0.29/#example-201 ) Quotes can contain fenced code blocks. Quotes can contain lists. Nested lists can be interrupted with nested code blocks and nested quotes. So far the writer assumes all code blocks are the indented type. It will be necessary to add another attribute to remember whether the code block is indented or fenced (assuming that's necessary). Fenced code blocks would work better for writing inside block quotes and list items because the fence is less ambiguous than the indent. Postponing cursor->insertBlock() as long as possible helps with nesting. cursor->insertBlock() needs to be done "just in time" before inserting text that will go in the block. The block and char formats aren't necessarily known until that time. When a nested block (such as a nested quote) ends, the context reverts to the previous block format, which then needs to be re-determined and set before we insert text into the outer block; but if no text will be inserted, no new block is necessary. But we can't use QTextBlockFormat itself as storage, because for some reason bullets become very "sticky" and it becomes impossible to have plain continuation paragraphs inside list items: they all get bullets. Somehow QTextBlockFormat remembers, if we copy it. But we can create a new one each time and it's OK. Change-Id: Icd0529eb90d2b6a3cb57f0104bf78a7be81ede52 Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
Diffstat (limited to 'src/gui/text/qtextmarkdownimporter_p.h')
-rw-r--r--src/gui/text/qtextmarkdownimporter_p.h8
1 files changed, 8 insertions, 0 deletions
diff --git a/src/gui/text/qtextmarkdownimporter_p.h b/src/gui/text/qtextmarkdownimporter_p.h
index 8ab119d051..1716530b1d 100644
--- a/src/gui/text/qtextmarkdownimporter_p.h
+++ b/src/gui/text/qtextmarkdownimporter_p.h
@@ -100,25 +100,33 @@ public:
int cbText(int textType, const char* text, unsigned size);
private:
+ void insertBlock();
+
+private:
QTextDocument *m_doc = nullptr;
QTextCursor *m_cursor = nullptr;
QTextTable *m_currentTable = nullptr; // because m_cursor->currentTable() doesn't work
QString m_htmlAccumulator;
+ QString m_blockCodeLanguage;
QVector<int> m_nonEmptyTableCells; // in the current row
QStack<QTextList *> m_listStack;
QStack<QTextCharFormat> m_spanFormatStack;
QFont m_monoFont;
QPalette m_palette;
int m_htmlTagDepth = 0;
+ int m_blockQuoteDepth = 0;
int m_tableColumnCount = 0;
int m_tableRowCount = 0;
int m_tableCol = -1; // because relative cell movements (e.g. m_cursor->movePosition(QTextCursor::NextCell)) don't work
+ int m_paragraphMargin = 0;
Features m_features;
int m_blockType = 0;
bool m_emptyList = false; // true when the last thing we did was insertList
bool m_listItem = false;
bool m_emptyListItem = false;
+ bool m_codeBlock = false;
bool m_imageSpan = false;
+ bool m_needsInsertBlock = false;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QTextMarkdownImporter::Features)