mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
PegMarkdownHighlight: refine fast parse
This commit is contained in:
parent
bfac189cb7
commit
284cba698f
@ -56,6 +56,8 @@ void PegMarkdownHighlighter::init(const QVector<HighlightingStyle> &p_styles,
|
|||||||
m_result.reset(new PegHighlighterResult());
|
m_result.reset(new PegHighlighterResult());
|
||||||
m_fastResult.reset(new PegHighlighterFastResult());
|
m_fastResult.reset(new PegHighlighterFastResult());
|
||||||
|
|
||||||
|
m_fastParseBlocks = QPair<int, int>(-1, -1);
|
||||||
|
|
||||||
m_parser = new PegParser(this);
|
m_parser = new PegParser(this);
|
||||||
connect(m_parser, &PegParser::parseResultReady,
|
connect(m_parser, &PegParser::parseResultReady,
|
||||||
this, &PegMarkdownHighlighter::handleParseResult);
|
this, &PegMarkdownHighlighter::handleParseResult);
|
||||||
@ -78,15 +80,10 @@ void PegMarkdownHighlighter::init(const QVector<HighlightingStyle> &p_styles,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QVector<QVector<HLUnit>> &hls = result->m_blocksHighlights;
|
for (int i = m_fastParseBlocks.first; i <= m_fastParseBlocks.second; ++i) {
|
||||||
for (int i = 0; i < hls.size(); ++i) {
|
|
||||||
if (!hls[i].isEmpty()) {
|
|
||||||
QTextBlock block = m_doc->findBlockByNumber(i);
|
QTextBlock block = m_doc->findBlockByNumber(i);
|
||||||
if (PegMarkdownHighlighter::blockTimeStamp(block) != m_timeStamp) {
|
|
||||||
rehighlightBlock(block);
|
rehighlightBlock(block);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
m_rehighlightTimer = new QTimer(this);
|
m_rehighlightTimer = new QTimer(this);
|
||||||
@ -135,14 +132,16 @@ void PegMarkdownHighlighter::highlightBlock(const QString &p_text)
|
|||||||
|
|
||||||
highlightBlockOne(result->m_blocksHighlights, blockNum, cacheValid ? cache : NULL);
|
highlightBlockOne(result->m_blocksHighlights, blockNum, cacheValid ? cache : NULL);
|
||||||
} else {
|
} else {
|
||||||
if (preHighlightSingleFormatBlock(m_fastResult->m_blocksHighlights, blockNum, p_text)) {
|
// If fast result cover this block, we do not need to use the outdated one.
|
||||||
|
if (isFastParseBlock(blockNum)) {
|
||||||
|
preHighlightSingleFormatBlock(m_fastResult->m_blocksHighlights, blockNum, p_text);
|
||||||
|
highlightBlockOne(m_fastResult->m_blocksHighlights, blockNum, NULL);
|
||||||
|
cacheValid = false;
|
||||||
|
} else {
|
||||||
|
if (preHighlightSingleFormatBlock(result->m_blocksHighlights, blockNum, p_text)) {
|
||||||
cacheValid = false;
|
cacheValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If fast result cover this block, we do not need to use the outdated one.
|
|
||||||
if (highlightBlockOne(m_fastResult->m_blocksHighlights, blockNum, NULL)) {
|
|
||||||
cacheValid = false;
|
|
||||||
} else {
|
|
||||||
highlightBlockOne(result->m_blocksHighlights, blockNum, cacheValid ? cache : NULL);
|
highlightBlockOne(result->m_blocksHighlights, blockNum, cacheValid ? cache : NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -288,6 +287,9 @@ void PegMarkdownHighlighter::startFastParse(int p_position, int p_charsRemoved,
|
|||||||
block = block.next();
|
block = block.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_fastParseBlocks.first = firstBlockNum;
|
||||||
|
m_fastParseBlocks.second = lastBlockNum;
|
||||||
|
|
||||||
QSharedPointer<PegParseConfig> config(new PegParseConfig());
|
QSharedPointer<PegParseConfig> config(new PegParseConfig());
|
||||||
config->m_timeStamp = m_timeStamp;
|
config->m_timeStamp = m_timeStamp;
|
||||||
config->m_data = text.toUtf8();
|
config->m_data = text.toUtf8();
|
||||||
@ -671,85 +673,65 @@ void PegMarkdownHighlighter::getFastParseBlockRange(int p_position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int num = lastBlock.blockNumber() - firstBlock.blockNumber() + 1;
|
int num = lastBlock.blockNumber() - firstBlock.blockNumber() + 1;
|
||||||
if (num >= maxNumOfBlocks) {
|
if (num > maxNumOfBlocks) {
|
||||||
p_firstBlock = p_lastBlock = -1;
|
p_firstBlock = p_lastBlock = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look up.
|
// Look up.
|
||||||
// Find empty block.
|
|
||||||
// When firstBlock is an empty block at first, we should always skip it.
|
|
||||||
while (firstBlock.isValid() && num < maxNumOfBlocks) {
|
while (firstBlock.isValid() && num < maxNumOfBlocks) {
|
||||||
QTextBlock block = firstBlock.previous();
|
QTextBlock preBlock = firstBlock.previous();
|
||||||
if (block.isValid() && !VEditUtils::isEmptyBlock(block)) {
|
if (!preBlock.isValid()) {
|
||||||
firstBlock = block;
|
|
||||||
++num;
|
|
||||||
} else {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Cross code block.
|
// Check code block.
|
||||||
while (firstBlock.isValid() && num < maxNumOfBlocks) {
|
|
||||||
int state = firstBlock.userState();
|
int state = firstBlock.userState();
|
||||||
if (state == HighlightBlockState::CodeBlock
|
if (state == HighlightBlockState::CodeBlock
|
||||||
|| state == HighlightBlockState::CodeBlockEnd) {
|
|| state == HighlightBlockState::CodeBlockEnd) {
|
||||||
QTextBlock block = firstBlock.previous();
|
goto goup;
|
||||||
if (block.isValid()) {
|
|
||||||
firstBlock = block;
|
|
||||||
++num;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
// Empty block.
|
||||||
|
if (VEditUtils::isEmptyBlock(firstBlock)) {
|
||||||
|
goto goup;
|
||||||
|
}
|
||||||
|
|
||||||
|
int indent = VEditUtils::fetchIndentation(firstBlock);
|
||||||
|
if (indent == 0) {
|
||||||
|
// If previous block is empty, then we could stop now.
|
||||||
|
if (VEditUtils::isEmptyBlock(preBlock)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Till the block with 0 indentation to handle contents in list.
|
goup:
|
||||||
while (firstBlock.isValid() && num < maxNumOfBlocks) {
|
firstBlock = preBlock;
|
||||||
if (VEditUtils::fetchIndentation(firstBlock) == 0
|
|
||||||
&& !VEditUtils::isEmptyBlock(firstBlock)) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
QTextBlock block = firstBlock.previous();
|
|
||||||
if (block.isValid()) {
|
|
||||||
firstBlock = block;
|
|
||||||
++num;
|
++num;
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look down.
|
// Look down.
|
||||||
// Find empty block.
|
|
||||||
// If lastBlock is an empty block at first, we should always skip it.
|
|
||||||
while (lastBlock.isValid() && num < maxNumOfBlocks) {
|
while (lastBlock.isValid() && num < maxNumOfBlocks) {
|
||||||
QTextBlock block = lastBlock.next();
|
QTextBlock nextBlock = lastBlock.next();
|
||||||
if (block.isValid() && !VEditUtils::isEmptyBlock(block)) {
|
if (!nextBlock.isValid()) {
|
||||||
lastBlock = block;
|
|
||||||
++num;
|
|
||||||
} else {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Cross code block.
|
// Check code block.
|
||||||
while (lastBlock.isValid() && num < maxNumOfBlocks) {
|
|
||||||
int state = lastBlock.userState();
|
int state = lastBlock.userState();
|
||||||
if (state == HighlightBlockState::CodeBlock
|
if (state == HighlightBlockState::CodeBlockStart
|
||||||
|| state == HighlightBlockState::CodeBlockStart) {
|
|| state == HighlightBlockState::CodeBlock) {
|
||||||
QTextBlock block = lastBlock.next();
|
goto godown;
|
||||||
if (block.isValid()) {
|
}
|
||||||
lastBlock = block;
|
|
||||||
|
// Empty block.
|
||||||
|
if (VEditUtils::isEmptyBlock(nextBlock)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
godown:
|
||||||
|
lastBlock = nextBlock;
|
||||||
++num;
|
++num;
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p_firstBlock = firstBlock.blockNumber();
|
p_firstBlock = firstBlock.blockNumber();
|
||||||
|
@ -131,6 +131,8 @@ private:
|
|||||||
|
|
||||||
TimeStamp nextCodeBlockTimeStamp();
|
TimeStamp nextCodeBlockTimeStamp();
|
||||||
|
|
||||||
|
bool isFastParseBlock(int p_blockNum) const;
|
||||||
|
|
||||||
static VTextBlockData *getBlockData(const QTextBlock &p_block);
|
static VTextBlockData *getBlockData(const QTextBlock &p_block);
|
||||||
|
|
||||||
static bool isEmptyCodeBlockHighlights(const QVector<QVector<HLUnitStyle>> &p_highlights);
|
static bool isEmptyCodeBlockHighlights(const QVector<QVector<HLUnitStyle>> &p_highlights);
|
||||||
@ -163,6 +165,9 @@ private:
|
|||||||
|
|
||||||
QSharedPointer<PegHighlighterFastResult> m_fastResult;
|
QSharedPointer<PegHighlighterFastResult> m_fastResult;
|
||||||
|
|
||||||
|
// Block range of fast parse, inclusive.
|
||||||
|
QPair<int, int> m_fastParseBlocks;
|
||||||
|
|
||||||
// Block number of those blocks which possible contains previewed image.
|
// Block number of those blocks which possible contains previewed image.
|
||||||
QSet<int> m_possiblePreviewBlocks;
|
QSet<int> m_possiblePreviewBlocks;
|
||||||
|
|
||||||
@ -318,4 +323,9 @@ inline TimeStamp PegMarkdownHighlighter::nextCodeBlockTimeStamp()
|
|||||||
{
|
{
|
||||||
return ++m_codeBlockTimeStamp;
|
return ++m_codeBlockTimeStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool PegMarkdownHighlighter::isFastParseBlock(int p_blockNum) const
|
||||||
|
{
|
||||||
|
return p_blockNum >= m_fastParseBlocks.first && p_blockNum <= m_fastParseBlocks.second;
|
||||||
|
}
|
||||||
#endif // PEGMARKDOWNHIGHLIGHTER_H
|
#endif // PEGMARKDOWNHIGHLIGHTER_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user