bug-fix: add code block indentation in VTextBlockData to get a correct highlight

- Won't treat all the text to the end as code block once we add a new
line within a code block;
- Fix color column by adding the code block indentation bias.
This commit is contained in:
Le Tan 2018-01-01 16:08:26 +08:00
parent 968b674a50
commit 6ba12f7932
4 changed files with 64 additions and 6 deletions

View File

@ -5,7 +5,6 @@
#include "hgmarkdownhighlighter.h" #include "hgmarkdownhighlighter.h"
#include "vconfigmanager.h" #include "vconfigmanager.h"
#include "utils/vutils.h" #include "utils/vutils.h"
#include "vtextblockdata.h"
extern VConfigManager *g_config; extern VConfigManager *g_config;
@ -98,7 +97,7 @@ void HGMarkdownHighlighter::updateBlockUserData(int p_blockNum, const QString &p
{ {
Q_UNUSED(p_text); Q_UNUSED(p_text);
VTextBlockData *blockData = dynamic_cast<VTextBlockData *>(currentBlockUserData()); VTextBlockData *blockData = currentBlockData();
if (!blockData) { if (!blockData) {
blockData = new VTextBlockData(); blockData = new VTextBlockData();
setCurrentBlockUserData(blockData); setCurrentBlockUserData(blockData);
@ -109,6 +108,8 @@ void HGMarkdownHighlighter::updateBlockUserData(int p_blockNum, const QString &p
} else { } else {
m_possiblePreviewBlocks.insert(p_blockNum); m_possiblePreviewBlocks.insert(p_blockNum);
} }
blockData->setCodeBlockIndentation(-1);
} }
void HGMarkdownHighlighter::highlightBlock(const QString &text) void HGMarkdownHighlighter::highlightBlock(const QString &text)
@ -377,7 +378,9 @@ void HGMarkdownHighlighter::initBlockHighlihgtOne(unsigned long pos,
void HGMarkdownHighlighter::highlightCodeBlock(const QString &text) void HGMarkdownHighlighter::highlightCodeBlock(const QString &text)
{ {
static int startLeadingSpaces = -1; VTextBlockData *blockData = currentBlockData();
Q_ASSERT(blockData);
int length = 0; int length = 0;
int index = -1; int index = -1;
int preState = previousBlockState(); int preState = previousBlockState();
@ -393,14 +396,21 @@ void HGMarkdownHighlighter::highlightCodeBlock(const QString &text)
state = HighlightBlockState::CodeBlockStart; state = HighlightBlockState::CodeBlockStart;
// The leading spaces of code block start and end must be identical. // The leading spaces of code block start and end must be identical.
startLeadingSpaces = codeBlockStartExp.capturedTexts()[1].size(); int startLeadingSpaces = codeBlockStartExp.capturedTexts()[1].size();
blockData->setCodeBlockIndentation(startLeadingSpaces);
} else { } else {
// A normal block. // A normal block.
startLeadingSpaces = -1; blockData->setCodeBlockIndentation(-1);
return; return;
} }
} else { } else {
// Need to find a code block end. // Need to find a code block end.
int startLeadingSpaces = 0;
VTextBlockData *preBlockData = previousBlockData();
if (preBlockData) {
startLeadingSpaces = preBlockData->getCodeBlockIndentation();
}
index = codeBlockEndExp.indexIn(text); index = codeBlockEndExp.indexIn(text);
// The closing ``` should have the same indentation as the open ```. // The closing ``` should have the same indentation as the open ```.
@ -415,6 +425,8 @@ void HGMarkdownHighlighter::highlightCodeBlock(const QString &text)
length = text.length(); length = text.length();
state = HighlightBlockState::CodeBlock; state = HighlightBlockState::CodeBlock;
} }
blockData->setCodeBlockIndentation(startLeadingSpaces);
} }
setCurrentBlockState(state); setCurrentBlockState(state);
@ -428,6 +440,14 @@ void HGMarkdownHighlighter::highlightCodeBlockColorColumn(const QString &p_text)
return; return;
} }
VTextBlockData *blockData = currentBlockData();
Q_ASSERT(blockData);
int indent = blockData->getCodeBlockIndentation();
if (indent == -1) {
return;
}
cc += indent;
if (p_text.size() < cc) { if (p_text.size() < cc) {
return; return;
} }

View File

@ -8,6 +8,8 @@
#include <QSet> #include <QSet>
#include <QString> #include <QString>
#include "vtextblockdata.h"
extern "C" { extern "C" {
#include <pmh_parser.h> #include <pmh_parser.h>
} }
@ -255,6 +257,10 @@ private:
// Check if [p_pos, p_end) is a valid header. // Check if [p_pos, p_end) is a valid header.
bool isValidHeader(unsigned long p_pos, unsigned long p_end); bool isValidHeader(unsigned long p_pos, unsigned long p_end);
VTextBlockData *currentBlockData() const;
VTextBlockData *previousBlockData() const;
}; };
inline const QVector<VElementRegion> &HGMarkdownHighlighter::getHeaderRegions() const inline const QVector<VElementRegion> &HGMarkdownHighlighter::getHeaderRegions() const
@ -273,4 +279,19 @@ inline void HGMarkdownHighlighter::clearPossiblePreviewBlocks(const QVector<int>
m_possiblePreviewBlocks.remove(i); m_possiblePreviewBlocks.remove(i);
} }
} }
inline VTextBlockData *HGMarkdownHighlighter::currentBlockData() const
{
return static_cast<VTextBlockData *>(currentBlockUserData());
}
inline VTextBlockData *HGMarkdownHighlighter::previousBlockData() const
{
QTextBlock block = currentBlock().previous();
if (!block.isValid()) {
return NULL;
}
return static_cast<VTextBlockData *>(block.userData());
}
#endif #endif

View File

@ -3,7 +3,8 @@
#include <QDebug> #include <QDebug>
VTextBlockData::VTextBlockData() VTextBlockData::VTextBlockData()
: QTextBlockUserData() : QTextBlockUserData(),
m_codeBlockIndentation(-1)
{ {
} }

View File

@ -147,12 +147,19 @@ public:
// Return true if there have obsolete preview being deleted. // Return true if there have obsolete preview being deleted.
bool clearObsoletePreview(long long p_timeStamp, PreviewSource p_source); bool clearObsoletePreview(long long p_timeStamp, PreviewSource p_source);
int getCodeBlockIndentation() const;
void setCodeBlockIndentation(int p_indent);
private: private:
// Check the order of elements. // Check the order of elements.
bool checkOrder() const; bool checkOrder() const;
// Sorted by m_imageInfo.m_startPos, with no two element's position intersected. // Sorted by m_imageInfo.m_startPos, with no two element's position intersected.
QVector<VPreviewInfo *> m_previews; QVector<VPreviewInfo *> m_previews;
// Indentation of the this code block if this block is a fenced code block.
int m_codeBlockIndentation;
}; };
inline const QVector<VPreviewInfo *> &VTextBlockData::getPreviews() const inline const QVector<VPreviewInfo *> &VTextBlockData::getPreviews() const
@ -160,4 +167,13 @@ inline const QVector<VPreviewInfo *> &VTextBlockData::getPreviews() const
return m_previews; return m_previews;
} }
inline int VTextBlockData::getCodeBlockIndentation() const
{
return m_codeBlockIndentation;
}
inline void VTextBlockData::setCodeBlockIndentation(int p_indent)
{
m_codeBlockIndentation = p_indent;
}
#endif // VTEXTBLOCKDATA_H #endif // VTEXTBLOCKDATA_H