diff options
Diffstat (limited to 'src/gui/text/qtextmarkdownimporter.cpp')
-rw-r--r-- | src/gui/text/qtextmarkdownimporter.cpp | 96 |
1 files changed, 52 insertions, 44 deletions
diff --git a/src/gui/text/qtextmarkdownimporter.cpp b/src/gui/text/qtextmarkdownimporter.cpp index 8c80a3f0c7..b96acba0e6 100644 --- a/src/gui/text/qtextmarkdownimporter.cpp +++ b/src/gui/text/qtextmarkdownimporter.cpp @@ -151,25 +151,16 @@ int QTextMarkdownImporter::cbEnterBlock(int blockType, void *det) m_blockType = blockType; switch (blockType) { case MD_BLOCK_P: - if (m_listStack.isEmpty()) { - m_needsInsertBlock = true; + if (!m_listStack.isEmpty()) + qCDebug(lcMD, m_listItem ? "P of LI at level %d" : "P continuation inside LI at level %d", m_listStack.count()); + else qCDebug(lcMD, "P"); - } else { - if (m_emptyListItem) { - qCDebug(lcMD, "LI text block at level %d -> BlockIndent %d", - m_listStack.count(), m_cursor->blockFormat().indent()); - m_emptyListItem = false; - } else { - qCDebug(lcMD, "P inside LI at level %d", m_listStack.count()); - m_needsInsertBlock = true; - } - } + m_needsInsertBlock = true; break; - case MD_BLOCK_QUOTE: { + case MD_BLOCK_QUOTE: ++m_blockQuoteDepth; qCDebug(lcMD, "QUOTE level %d", m_blockQuoteDepth); break; - } case MD_BLOCK_CODE: { MD_BLOCK_CODE_DETAIL *detail = static_cast<MD_BLOCK_CODE_DETAIL *>(det); m_codeBlock = true; @@ -194,51 +185,40 @@ int QTextMarkdownImporter::cbEnterBlock(int blockType, void *det) qCDebug(lcMD, "H%d", detail->level); } break; case MD_BLOCK_LI: { - m_needsInsertBlock = false; - MD_BLOCK_LI_DETAIL *detail = static_cast<MD_BLOCK_LI_DETAIL *>(det); - QTextList *list = m_listStack.top(); - QTextBlockFormat bfmt = list->item(list->count() - 1).blockFormat(); - bfmt.setMarker(detail->is_task ? - (detail->task_mark == ' ' ? QTextBlockFormat::Unchecked : QTextBlockFormat::Checked) : - QTextBlockFormat::NoMarker); - if (!m_emptyList) { - m_cursor->insertBlock(bfmt, QTextCharFormat()); - list->add(m_cursor->block()); - } - m_cursor->setBlockFormat(bfmt); - qCDebug(lcMD) << (m_emptyList ? "LI (first in list)" : "LI"); - m_emptyList = false; // Avoid insertBlock for the first item (because insertList already did that) + m_needsInsertBlock = true; m_listItem = true; - m_emptyListItem = true; + MD_BLOCK_LI_DETAIL *detail = static_cast<MD_BLOCK_LI_DETAIL *>(det); + m_markerType = detail->is_task ? + (detail->task_mark == ' ' ? QTextBlockFormat::Unchecked : QTextBlockFormat::Checked) : + QTextBlockFormat::NoMarker; + qCDebug(lcMD) << "LI"; } break; case MD_BLOCK_UL: { MD_BLOCK_UL_DETAIL *detail = static_cast<MD_BLOCK_UL_DETAIL *>(det); - QTextListFormat fmt; - fmt.setIndent(m_listStack.count() + 1); + m_listFormat = QTextListFormat(); + m_listFormat.setIndent(m_listStack.count() + 1); switch (detail->mark) { case '*': - fmt.setStyle(QTextListFormat::ListCircle); + m_listFormat.setStyle(QTextListFormat::ListCircle); break; case '+': - fmt.setStyle(QTextListFormat::ListSquare); + m_listFormat.setStyle(QTextListFormat::ListSquare); break; default: // including '-' - fmt.setStyle(QTextListFormat::ListDisc); + m_listFormat.setStyle(QTextListFormat::ListDisc); break; } qCDebug(lcMD, "UL %c level %d", detail->mark, m_listStack.count()); - m_listStack.push(m_cursor->insertList(fmt)); - m_emptyList = true; + m_needsInsertList = true; } break; case MD_BLOCK_OL: { MD_BLOCK_OL_DETAIL *detail = static_cast<MD_BLOCK_OL_DETAIL *>(det); - QTextListFormat fmt; - fmt.setIndent(m_listStack.count() + 1); - fmt.setNumberSuffix(QChar::fromLatin1(detail->mark_delimiter)); - fmt.setStyle(QTextListFormat::ListDecimal); + m_listFormat = QTextListFormat(); + m_listFormat.setIndent(m_listStack.count() + 1); + m_listFormat.setNumberSuffix(QChar::fromLatin1(detail->mark_delimiter)); + m_listFormat.setStyle(QTextListFormat::ListDecimal); qCDebug(lcMD, "OL xx%d level %d", detail->mark_delimiter, m_listStack.count()); - m_listStack.push(m_cursor->insertList(fmt)); - m_emptyList = true; + m_needsInsertList = true; } break; case MD_BLOCK_TD: { MD_BLOCK_TD_DETAIL *detail = static_cast<MD_BLOCK_TD_DETAIL *>(det); @@ -299,6 +279,9 @@ int QTextMarkdownImporter::cbLeaveBlock(int blockType, void *detail) { Q_UNUSED(detail) switch (blockType) { + case MD_BLOCK_P: + m_listItem = false; + break; case MD_BLOCK_UL: case MD_BLOCK_OL: qCDebug(lcMD, "list at level %d ended", m_listStack.count()); @@ -525,19 +508,32 @@ int QTextMarkdownImporter::cbText(int textType, const char *text, unsigned size) return 0; // no error } +/*! + Insert a new block based on stored state. + + m_cursor cannot store the state for the _next_ block ahead of time, because + m_cursor->setBlockFormat() controls the format of the block that the cursor + is already in; so cbLeaveBlock() cannot call setBlockFormat() without + altering the block that was just added. Therefore cbLeaveBlock() and the + following cbEnterBlock() set variables to remember what formatting should + come next, and insertBlock() is called just before the actual text + insertion, to create a new block with the right formatting. +*/ void QTextMarkdownImporter::insertBlock() { QTextCharFormat charFormat; if (!m_spanFormatStack.isEmpty()) charFormat = m_spanFormatStack.top(); QTextBlockFormat blockFormat; + if (!m_listStack.isEmpty() && !m_needsInsertList && m_listItem) { + QTextList *list = m_listStack.top(); + blockFormat = list->item(list->count() - 1).blockFormat(); + } if (m_blockQuoteDepth) { blockFormat.setProperty(QTextFormat::BlockQuoteLevel, m_blockQuoteDepth); blockFormat.setLeftMargin(BlockQuoteIndent * m_blockQuoteDepth); blockFormat.setRightMargin(BlockQuoteIndent); } - if (m_listStack.count()) - blockFormat.setIndent(m_listStack.count()); if (m_codeBlock) { blockFormat.setProperty(QTextFormat::BlockCodeLanguage, m_blockCodeLanguage); charFormat.setFont(m_monoFont); @@ -545,7 +541,19 @@ void QTextMarkdownImporter::insertBlock() blockFormat.setTopMargin(m_paragraphMargin); blockFormat.setBottomMargin(m_paragraphMargin); } + if (m_markerType == QTextBlockFormat::NoMarker) + blockFormat.clearProperty(QTextFormat::BlockMarker); + else + blockFormat.setMarker(m_markerType); + if (!m_listStack.isEmpty()) + blockFormat.setIndent(m_listStack.count()); m_cursor->insertBlock(blockFormat, charFormat); + if (m_needsInsertList) { + m_listStack.push(m_cursor->createList(m_listFormat)); + } else if (!m_listStack.isEmpty() && m_listItem) { + m_listStack.top()->add(m_cursor->block()); + } + m_needsInsertList = false; m_needsInsertBlock = false; } |