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_fastResult.reset(new PegHighlighterFastResult());
|
||||
|
||||
m_fastParseBlocks = QPair<int, int>(-1, -1);
|
||||
|
||||
m_parser = new PegParser(this);
|
||||
connect(m_parser, &PegParser::parseResultReady,
|
||||
this, &PegMarkdownHighlighter::handleParseResult);
|
||||
@ -78,15 +80,10 @@ void PegMarkdownHighlighter::init(const QVector<HighlightingStyle> &p_styles,
|
||||
return;
|
||||
}
|
||||
|
||||
const QVector<QVector<HLUnit>> &hls = result->m_blocksHighlights;
|
||||
for (int i = 0; i < hls.size(); ++i) {
|
||||
if (!hls[i].isEmpty()) {
|
||||
for (int i = m_fastParseBlocks.first; i <= m_fastParseBlocks.second; ++i) {
|
||||
QTextBlock block = m_doc->findBlockByNumber(i);
|
||||
if (PegMarkdownHighlighter::blockTimeStamp(block) != m_timeStamp) {
|
||||
rehighlightBlock(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
m_rehighlightTimer = new QTimer(this);
|
||||
@ -135,14 +132,16 @@ void PegMarkdownHighlighter::highlightBlock(const QString &p_text)
|
||||
|
||||
highlightBlockOne(result->m_blocksHighlights, blockNum, cacheValid ? cache : NULL);
|
||||
} 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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
@ -288,6 +287,9 @@ void PegMarkdownHighlighter::startFastParse(int p_position, int p_charsRemoved,
|
||||
block = block.next();
|
||||
}
|
||||
|
||||
m_fastParseBlocks.first = firstBlockNum;
|
||||
m_fastParseBlocks.second = lastBlockNum;
|
||||
|
||||
QSharedPointer<PegParseConfig> config(new PegParseConfig());
|
||||
config->m_timeStamp = m_timeStamp;
|
||||
config->m_data = text.toUtf8();
|
||||
@ -671,85 +673,65 @@ void PegMarkdownHighlighter::getFastParseBlockRange(int p_position,
|
||||
}
|
||||
|
||||
int num = lastBlock.blockNumber() - firstBlock.blockNumber() + 1;
|
||||
if (num >= maxNumOfBlocks) {
|
||||
if (num > maxNumOfBlocks) {
|
||||
p_firstBlock = p_lastBlock = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Look up.
|
||||
// Find empty block.
|
||||
// When firstBlock is an empty block at first, we should always skip it.
|
||||
while (firstBlock.isValid() && num < maxNumOfBlocks) {
|
||||
QTextBlock block = firstBlock.previous();
|
||||
if (block.isValid() && !VEditUtils::isEmptyBlock(block)) {
|
||||
firstBlock = block;
|
||||
++num;
|
||||
} else {
|
||||
QTextBlock preBlock = firstBlock.previous();
|
||||
if (!preBlock.isValid()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Cross code block.
|
||||
while (firstBlock.isValid() && num < maxNumOfBlocks) {
|
||||
// Check code block.
|
||||
int state = firstBlock.userState();
|
||||
if (state == HighlightBlockState::CodeBlock
|
||||
|| state == HighlightBlockState::CodeBlockEnd) {
|
||||
QTextBlock block = firstBlock.previous();
|
||||
if (block.isValid()) {
|
||||
firstBlock = block;
|
||||
++num;
|
||||
} else {
|
||||
break;
|
||||
goto goup;
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
|
||||
// Till the block with 0 indentation to handle contents in list.
|
||||
while (firstBlock.isValid() && num < maxNumOfBlocks) {
|
||||
if (VEditUtils::fetchIndentation(firstBlock) == 0
|
||||
&& !VEditUtils::isEmptyBlock(firstBlock)) {
|
||||
break;
|
||||
} else {
|
||||
QTextBlock block = firstBlock.previous();
|
||||
if (block.isValid()) {
|
||||
firstBlock = block;
|
||||
goup:
|
||||
firstBlock = preBlock;
|
||||
++num;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Look down.
|
||||
// Find empty block.
|
||||
// If lastBlock is an empty block at first, we should always skip it.
|
||||
while (lastBlock.isValid() && num < maxNumOfBlocks) {
|
||||
QTextBlock block = lastBlock.next();
|
||||
if (block.isValid() && !VEditUtils::isEmptyBlock(block)) {
|
||||
lastBlock = block;
|
||||
++num;
|
||||
} else {
|
||||
QTextBlock nextBlock = lastBlock.next();
|
||||
if (!nextBlock.isValid()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Cross code block.
|
||||
while (lastBlock.isValid() && num < maxNumOfBlocks) {
|
||||
// Check code block.
|
||||
int state = lastBlock.userState();
|
||||
if (state == HighlightBlockState::CodeBlock
|
||||
|| state == HighlightBlockState::CodeBlockStart) {
|
||||
QTextBlock block = lastBlock.next();
|
||||
if (block.isValid()) {
|
||||
lastBlock = block;
|
||||
if (state == HighlightBlockState::CodeBlockStart
|
||||
|| state == HighlightBlockState::CodeBlock) {
|
||||
goto godown;
|
||||
}
|
||||
|
||||
// Empty block.
|
||||
if (VEditUtils::isEmptyBlock(nextBlock)) {
|
||||
break;
|
||||
}
|
||||
|
||||
godown:
|
||||
lastBlock = nextBlock;
|
||||
++num;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
p_firstBlock = firstBlock.blockNumber();
|
||||
|
@ -131,6 +131,8 @@ private:
|
||||
|
||||
TimeStamp nextCodeBlockTimeStamp();
|
||||
|
||||
bool isFastParseBlock(int p_blockNum) const;
|
||||
|
||||
static VTextBlockData *getBlockData(const QTextBlock &p_block);
|
||||
|
||||
static bool isEmptyCodeBlockHighlights(const QVector<QVector<HLUnitStyle>> &p_highlights);
|
||||
@ -163,6 +165,9 @@ private:
|
||||
|
||||
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.
|
||||
QSet<int> m_possiblePreviewBlocks;
|
||||
|
||||
@ -318,4 +323,9 @@ inline TimeStamp PegMarkdownHighlighter::nextCodeBlockTimeStamp()
|
||||
{
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user