mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
PegHighlighter: support fast parse
This commit is contained in:
parent
0e724635b3
commit
abee597812
@ -7,6 +7,19 @@
|
||||
#include "pegmarkdownhighlighter.h"
|
||||
#include "utils/vutils.h"
|
||||
|
||||
PegHighlighterFastResult::PegHighlighterFastResult()
|
||||
: m_timeStamp(0)
|
||||
{
|
||||
}
|
||||
|
||||
PegHighlighterFastResult::PegHighlighterFastResult(const PegMarkdownHighlighter *p_peg,
|
||||
const QSharedPointer<PegParseResult> &p_result)
|
||||
: m_timeStamp(p_result->m_timeStamp)
|
||||
{
|
||||
PegHighlighterResult::parseBlocksHighlights(m_blocksHighlights, p_peg, p_result);
|
||||
}
|
||||
|
||||
|
||||
PegHighlighterResult::PegHighlighterResult()
|
||||
: m_timeStamp(0),
|
||||
m_numOfBlocks(0),
|
||||
@ -25,7 +38,7 @@ PegHighlighterResult::PegHighlighterResult(const PegMarkdownHighlighter *p_peg,
|
||||
m_codeBlockStartExp = QRegExp(VUtils::c_fencedCodeBlockStartRegExp);
|
||||
m_codeBlockEndExp = QRegExp(VUtils::c_fencedCodeBlockEndRegExp);
|
||||
|
||||
parseBlocksHighlights(p_peg, p_result);
|
||||
parseBlocksHighlights(m_blocksHighlights, p_peg, p_result);
|
||||
|
||||
// Implicit sharing.
|
||||
m_imageRegions = p_result->m_imageRegions;
|
||||
@ -47,14 +60,16 @@ static bool compHLUnit(const HLUnit &p_a, const HLUnit &p_b)
|
||||
}
|
||||
}
|
||||
|
||||
void PegHighlighterResult::parseBlocksHighlights(const PegMarkdownHighlighter *p_peg,
|
||||
void PegHighlighterResult::parseBlocksHighlights(QVector<QVector<HLUnit>> &p_blocksHighlights,
|
||||
const PegMarkdownHighlighter *p_peg,
|
||||
const QSharedPointer<PegParseResult> &p_result)
|
||||
{
|
||||
m_blocksHighlights.resize(m_numOfBlocks);
|
||||
p_blocksHighlights.resize(p_result->m_numOfBlocks);
|
||||
if (p_result->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int offset = p_result->m_offset;
|
||||
const QTextDocument *doc = p_peg->getDocument();
|
||||
const QVector<HighlightingStyle> &styles = p_peg->getStyles();
|
||||
auto pmhResult = p_result->m_pmhElements;
|
||||
@ -71,20 +86,25 @@ void PegHighlighterResult::parseBlocksHighlights(const PegMarkdownHighlighter *p
|
||||
continue;
|
||||
}
|
||||
|
||||
parseBlocksHighlightOne(doc, elem_cursor->pos, elem_cursor->end, i);
|
||||
parseBlocksHighlightOne(p_blocksHighlights,
|
||||
doc,
|
||||
offset + elem_cursor->pos,
|
||||
offset + elem_cursor->end,
|
||||
i);
|
||||
elem_cursor = elem_cursor->next;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort m_blocksHighlights.
|
||||
for (int i = 0; i < m_blocksHighlights.size(); ++i) {
|
||||
if (m_blocksHighlights[i].size() > 1) {
|
||||
std::sort(m_blocksHighlights[i].begin(), m_blocksHighlights[i].end(), compHLUnit);
|
||||
// Sort p_blocksHighlights.
|
||||
for (int i = 0; i < p_blocksHighlights.size(); ++i) {
|
||||
if (p_blocksHighlights[i].size() > 1) {
|
||||
std::sort(p_blocksHighlights[i].begin(), p_blocksHighlights[i].end(), compHLUnit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PegHighlighterResult::parseBlocksHighlightOne(const QTextDocument *p_doc,
|
||||
void PegHighlighterResult::parseBlocksHighlightOne(QVector<QVector<HLUnit>> &p_blocksHighlights,
|
||||
const QTextDocument *p_doc,
|
||||
unsigned long p_pos,
|
||||
unsigned long p_end,
|
||||
int p_styleIndex)
|
||||
@ -121,7 +141,7 @@ void PegHighlighterResult::parseBlocksHighlightOne(const QTextDocument *p_doc,
|
||||
}
|
||||
unit.styleIndex = p_styleIndex;
|
||||
|
||||
m_blocksHighlights[blockNum].append(unit);
|
||||
p_blocksHighlights[blockNum].append(unit);
|
||||
|
||||
block = block.next();
|
||||
}
|
||||
|
@ -7,16 +7,41 @@
|
||||
class PegMarkdownHighlighter;
|
||||
class QTextDocument;
|
||||
|
||||
class PegHighlighterFastResult
|
||||
{
|
||||
public:
|
||||
PegHighlighterFastResult();
|
||||
|
||||
PegHighlighterFastResult(const PegMarkdownHighlighter *p_peg,
|
||||
const QSharedPointer<PegParseResult> &p_result);
|
||||
|
||||
bool matched(TimeStamp p_timeStamp) const
|
||||
{
|
||||
return m_timeStamp == p_timeStamp;
|
||||
}
|
||||
|
||||
TimeStamp m_timeStamp;
|
||||
|
||||
QVector<QVector<HLUnit>> m_blocksHighlights;
|
||||
};
|
||||
|
||||
|
||||
class PegHighlighterResult
|
||||
{
|
||||
public:
|
||||
PegHighlighterResult();
|
||||
|
||||
// TODO: handle p_result->m_offset.
|
||||
PegHighlighterResult(const PegMarkdownHighlighter *p_peg,
|
||||
const QSharedPointer<PegParseResult> &p_result);
|
||||
|
||||
bool matched(TimeStamp p_timeStamp) const;
|
||||
|
||||
// Parse highlight elements for all the blocks from parse results.
|
||||
static void parseBlocksHighlights(QVector<QVector<HLUnit>> &p_blocksHighlights,
|
||||
const PegMarkdownHighlighter *p_peg,
|
||||
const QSharedPointer<PegParseResult> &p_result);
|
||||
|
||||
TimeStamp m_timeStamp;
|
||||
|
||||
int m_numOfBlocks;
|
||||
@ -48,12 +73,9 @@ public:
|
||||
QVector<VMathjaxBlock> m_mathjaxBlocks;
|
||||
|
||||
private:
|
||||
// Parse highlight elements for all the blocks from parse results.
|
||||
void parseBlocksHighlights(const PegMarkdownHighlighter *p_peg,
|
||||
const QSharedPointer<PegParseResult> &p_result);
|
||||
|
||||
// Parse highlight elements for blocks from one parse result.
|
||||
void parseBlocksHighlightOne(const QTextDocument *p_doc,
|
||||
static void parseBlocksHighlightOne(QVector<QVector<HLUnit>> &p_blocksHighlights,
|
||||
const QTextDocument *p_doc,
|
||||
unsigned long p_pos,
|
||||
unsigned long p_end,
|
||||
int p_styleIndex);
|
||||
|
@ -49,6 +49,7 @@ void PegMarkdownHighlighter::init(const QVector<HighlightingStyle> &p_styles,
|
||||
m_colorColumnFormat.setBackground(QColor(g_config->getEditorColorColumnBg()));
|
||||
|
||||
m_result.reset(new PegHighlighterResult());
|
||||
m_fastResult.reset(new PegHighlighterFastResult());
|
||||
|
||||
m_parser = new PegParser(this);
|
||||
connect(m_parser, &PegParser::parseResultReady,
|
||||
@ -62,6 +63,24 @@ void PegMarkdownHighlighter::init(const QVector<HighlightingStyle> &p_styles,
|
||||
startParse();
|
||||
});
|
||||
|
||||
m_fastParseTimer = new QTimer(this);
|
||||
m_fastParseTimer->setSingleShot(true);
|
||||
m_fastParseTimer->setInterval(50);
|
||||
connect(m_fastParseTimer, &QTimer::timeout,
|
||||
this, [this]() {
|
||||
QSharedPointer<PegHighlighterFastResult> result(m_fastResult);
|
||||
if (!result->matched(m_timeStamp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QVector<QVector<HLUnit>> &hls = result->m_blocksHighlights;
|
||||
for (int i = 0; i < hls.size(); ++i) {
|
||||
if (!hls[i].isEmpty()) {
|
||||
rehighlightBlock(m_doc->findBlockByNumber(i));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_doc, &QTextDocument::contentsChange,
|
||||
this, &PegMarkdownHighlighter::handleContentsChange);
|
||||
}
|
||||
@ -71,9 +90,31 @@ void PegMarkdownHighlighter::highlightBlock(const QString &p_text)
|
||||
QSharedPointer<PegHighlighterResult> result(m_result);
|
||||
|
||||
int blockNum = currentBlock().blockNumber();
|
||||
if (result->m_blocksHighlights.size() > blockNum) {
|
||||
|
||||
highlightBlockOne(result->m_blocksHighlights, blockNum);
|
||||
|
||||
highlightBlockOne(m_fastResult->m_blocksHighlights, blockNum);
|
||||
|
||||
// Set current block's user data.
|
||||
updateBlockUserData(blockNum, p_text);
|
||||
|
||||
setCurrentBlockState(HighlightBlockState::Normal);
|
||||
|
||||
updateCodeBlockState(result, blockNum, p_text);
|
||||
|
||||
if (currentBlockState() == HighlightBlockState::CodeBlock) {
|
||||
highlightCodeBlock(result, blockNum, p_text);
|
||||
|
||||
highlightCodeBlockColorColumn(p_text);
|
||||
}
|
||||
}
|
||||
|
||||
void PegMarkdownHighlighter::highlightBlockOne(const QVector<QVector<HLUnit>> &p_highlights,
|
||||
int p_blockNum)
|
||||
{
|
||||
if (p_highlights.size() > p_blockNum) {
|
||||
// units are sorted by start position and length.
|
||||
const QVector<HLUnit> &units = result->m_blocksHighlights[blockNum];
|
||||
const QVector<HLUnit> &units = p_highlights[p_blockNum];
|
||||
if (!units.isEmpty()) {
|
||||
for (int i = 0; i < units.size(); ++i) {
|
||||
const HLUnit &unit = units[i];
|
||||
@ -102,19 +143,6 @@ void PegMarkdownHighlighter::highlightBlock(const QString &p_text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set current block's user data.
|
||||
updateBlockUserData(blockNum, p_text);
|
||||
|
||||
setCurrentBlockState(HighlightBlockState::Normal);
|
||||
|
||||
updateCodeBlockState(result, blockNum, p_text);
|
||||
|
||||
if (currentBlockState() == HighlightBlockState::CodeBlock) {
|
||||
highlightCodeBlock(result, blockNum, p_text);
|
||||
|
||||
highlightCodeBlockColorColumn(p_text);
|
||||
}
|
||||
}
|
||||
|
||||
void PegMarkdownHighlighter::handleContentsChange(int p_position, int p_charsRemoved, int p_charsAdded)
|
||||
@ -127,6 +155,8 @@ void PegMarkdownHighlighter::handleContentsChange(int p_position, int p_charsRem
|
||||
|
||||
++m_timeStamp;
|
||||
|
||||
startFastParse(p_position, p_charsRemoved, p_charsAdded);
|
||||
|
||||
// We still need a timer to start a complete parse.
|
||||
m_timer->start();
|
||||
}
|
||||
@ -142,6 +172,47 @@ void PegMarkdownHighlighter::startParse()
|
||||
m_parser->parseAsync(config);
|
||||
}
|
||||
|
||||
void PegMarkdownHighlighter::startFastParse(int p_position, int p_charsRemoved, int p_charsAdded)
|
||||
{
|
||||
// Get affected block range.
|
||||
int firstBlockNum, lastBlockNum;
|
||||
getFastParseBlockRange(p_position, p_charsRemoved, p_charsAdded, firstBlockNum, lastBlockNum);
|
||||
|
||||
QString text;
|
||||
QTextBlock block = m_doc->findBlockByNumber(firstBlockNum);
|
||||
int offset = block.position();
|
||||
while (block.isValid()) {
|
||||
int blockNum = block.blockNumber();
|
||||
if (blockNum > lastBlockNum) {
|
||||
break;
|
||||
} else if (blockNum == firstBlockNum) {
|
||||
text = block.text();
|
||||
} else {
|
||||
text = text + "\n" + block.text();
|
||||
}
|
||||
|
||||
block = block.next();
|
||||
}
|
||||
|
||||
QSharedPointer<PegParseConfig> config(new PegParseConfig());
|
||||
config->m_timeStamp = m_timeStamp;
|
||||
config->m_data = text.toUtf8();
|
||||
config->m_numOfBlocks = m_doc->blockCount();
|
||||
config->m_offset = offset;
|
||||
config->m_extensions = m_parserExts;
|
||||
config->m_fast = true;
|
||||
|
||||
QSharedPointer<PegParseResult> parseRes = m_parser->parse(config);
|
||||
processFastParseResult(parseRes);
|
||||
}
|
||||
|
||||
void PegMarkdownHighlighter::processFastParseResult(const QSharedPointer<PegParseResult> &p_result)
|
||||
{
|
||||
m_fastParseTimer->stop();
|
||||
m_fastResult.reset(new PegHighlighterFastResult(this, p_result));
|
||||
m_fastParseTimer->start();
|
||||
}
|
||||
|
||||
static bool compHLUnitStyle(const HLUnitStyle &a, const HLUnitStyle &b)
|
||||
{
|
||||
if (a.start < b.start) {
|
||||
@ -424,3 +495,97 @@ void PegMarkdownHighlighter::completeHighlight(QSharedPointer<PegHighlighterResu
|
||||
|
||||
emit highlightCompleted();
|
||||
}
|
||||
|
||||
void PegMarkdownHighlighter::getFastParseBlockRange(int p_position,
|
||||
int p_charsRemoved,
|
||||
int p_charsAdded,
|
||||
int &p_firstBlock,
|
||||
int &p_lastBlock) const
|
||||
{
|
||||
const int maxNumOfBlocks = 50;
|
||||
|
||||
int charsChanged = p_charsRemoved + p_charsAdded;
|
||||
QTextBlock firstBlock = m_doc->findBlock(p_position);
|
||||
|
||||
// May be an invalid block.
|
||||
QTextBlock lastBlock = m_doc->findBlock(qMax(0, p_position + charsChanged));
|
||||
if (!lastBlock.isValid()) {
|
||||
lastBlock = m_doc->lastBlock();
|
||||
}
|
||||
|
||||
int num = lastBlock.blockNumber() - firstBlock.blockNumber() + 1;
|
||||
|
||||
if (num >= maxNumOfBlocks) {
|
||||
p_firstBlock = firstBlock.blockNumber();
|
||||
p_lastBlock = p_firstBlock + maxNumOfBlocks - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Look up.
|
||||
// Find empty block.
|
||||
if (!VEditUtils::isEmptyBlock(firstBlock)) {
|
||||
while (firstBlock.isValid() && num < maxNumOfBlocks) {
|
||||
QTextBlock block = firstBlock.previous();
|
||||
if (block.isValid() && !VEditUtils::isEmptyBlock(block)) {
|
||||
firstBlock = block;
|
||||
++num;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cross code block.
|
||||
while (firstBlock.isValid() && num < maxNumOfBlocks) {
|
||||
int state = firstBlock.userState();
|
||||
if (state == HighlightBlockState::CodeBlock
|
||||
|| state == HighlightBlockState::CodeBlockEnd) {
|
||||
QTextBlock block = firstBlock.previous();
|
||||
if (block.isValid()) {
|
||||
firstBlock = block;
|
||||
++num;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Look down.
|
||||
// Find empty block.
|
||||
if (!VEditUtils::isEmptyBlock(lastBlock)) {
|
||||
while (lastBlock.isValid() && num < maxNumOfBlocks) {
|
||||
QTextBlock block = lastBlock.next();
|
||||
if (block.isValid() && !VEditUtils::isEmptyBlock(block)) {
|
||||
lastBlock = block;
|
||||
++num;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cross code block.
|
||||
while (lastBlock.isValid() && num < maxNumOfBlocks) {
|
||||
int state = lastBlock.userState();
|
||||
if (state == HighlightBlockState::CodeBlock
|
||||
|| state == HighlightBlockState::CodeBlockStart) {
|
||||
QTextBlock block = lastBlock.next();
|
||||
if (block.isValid()) {
|
||||
lastBlock = block;
|
||||
++num;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
p_firstBlock = firstBlock.blockNumber();
|
||||
p_lastBlock = lastBlock.blockNumber();
|
||||
if (p_lastBlock < p_firstBlock) {
|
||||
p_lastBlock = p_firstBlock;
|
||||
}
|
||||
}
|
||||
|
@ -74,6 +74,8 @@ private slots:
|
||||
private:
|
||||
void startParse();
|
||||
|
||||
void startFastParse(int p_position, int p_charsRemoved, int p_charsAdded);
|
||||
|
||||
void updateCodeBlocks(QSharedPointer<PegHighlighterResult> p_result);
|
||||
|
||||
// Set the user data of currentBlock().
|
||||
@ -99,6 +101,17 @@ private:
|
||||
|
||||
bool isMathJaxEnabled() const;
|
||||
|
||||
void getFastParseBlockRange(int p_position,
|
||||
int p_charsRemoved,
|
||||
int p_charsAdded,
|
||||
int &p_firstBlock,
|
||||
int &p_lastBlock) const;
|
||||
|
||||
void processFastParseResult(const QSharedPointer<PegParseResult> &p_result);
|
||||
|
||||
void highlightBlockOne(const QVector<QVector<HLUnit>> &p_highlights,
|
||||
int p_blockNum);
|
||||
|
||||
QTextDocument *m_doc;
|
||||
|
||||
TimeStamp m_timeStamp;
|
||||
@ -113,6 +126,8 @@ private:
|
||||
|
||||
QSharedPointer<PegHighlighterResult> m_result;
|
||||
|
||||
QSharedPointer<PegHighlighterFastResult> m_fastResult;
|
||||
|
||||
// Block number of those blocks which possible contains previewed image.
|
||||
QSet<int> m_possiblePreviewBlocks;
|
||||
|
||||
@ -121,6 +136,8 @@ private:
|
||||
|
||||
// Timer to trigger parse.
|
||||
QTimer *m_timer;
|
||||
|
||||
QTimer *m_fastParseTimer;
|
||||
};
|
||||
|
||||
inline const QVector<VElementRegion> &PegMarkdownHighlighter::getHeaderRegions() const
|
||||
|
@ -8,8 +8,12 @@ enum WorkerState
|
||||
Finished
|
||||
};
|
||||
|
||||
void PegParseResult::parse(QAtomicInt &p_stop)
|
||||
void PegParseResult::parse(QAtomicInt &p_stop, bool p_fast)
|
||||
{
|
||||
if (p_fast) {
|
||||
return;
|
||||
}
|
||||
|
||||
parseImageRegions(p_stop);
|
||||
|
||||
parseHeaderRegions(p_stop);
|
||||
@ -40,7 +44,7 @@ void PegParseResult::parseImageRegions(QAtomicInt &p_stop)
|
||||
return;
|
||||
}
|
||||
|
||||
m_imageRegions.push_back(VElementRegion(elem->pos, elem->end));
|
||||
m_imageRegions.push_back(VElementRegion(m_offset + elem->pos, m_offset + elem->end));
|
||||
elem = elem->next;
|
||||
}
|
||||
}
|
||||
@ -66,7 +70,7 @@ void PegParseResult::parseHeaderRegions(QAtomicInt &p_stop)
|
||||
return;
|
||||
}
|
||||
|
||||
m_headerRegions.push_back(VElementRegion(elem->pos, elem->end));
|
||||
m_headerRegions.push_back(VElementRegion(m_offset + elem->pos, m_offset + elem->end));
|
||||
elem = elem->next;
|
||||
}
|
||||
}
|
||||
@ -96,8 +100,9 @@ void PegParseResult::parseFencedCodeBlockRegions(QAtomicInt &p_stop)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_codeBlockRegions.contains(elem->pos)) {
|
||||
m_codeBlockRegions.insert(elem->pos, VElementRegion(elem->pos, elem->end));
|
||||
if (!m_codeBlockRegions.contains(m_offset + elem->pos)) {
|
||||
m_codeBlockRegions.insert(m_offset + elem->pos,
|
||||
VElementRegion(m_offset + elem->pos, m_offset + elem->end));
|
||||
}
|
||||
|
||||
elem = elem->next;
|
||||
@ -122,7 +127,7 @@ void PegParseResult::parseInlineEquationRegions(QAtomicInt &p_stop)
|
||||
return;
|
||||
}
|
||||
|
||||
m_inlineEquationRegions.push_back(VElementRegion(elem->pos, elem->end));
|
||||
m_inlineEquationRegions.push_back(VElementRegion(m_offset + elem->pos, m_offset + elem->end));
|
||||
elem = elem->next;
|
||||
}
|
||||
}
|
||||
@ -145,7 +150,7 @@ void PegParseResult::parseDisplayFormulaRegions(QAtomicInt &p_stop)
|
||||
return;
|
||||
}
|
||||
|
||||
m_displayFormulaRegions.push_back(VElementRegion(elem->pos, elem->end));
|
||||
m_displayFormulaRegions.push_back(VElementRegion(m_offset + elem->pos, m_offset + elem->end));
|
||||
elem = elem->next;
|
||||
}
|
||||
|
||||
@ -214,7 +219,7 @@ QSharedPointer<PegParseResult> PegParserWorker::parseMarkdown(const QSharedPoint
|
||||
return result;
|
||||
}
|
||||
|
||||
result->parse(p_stop);
|
||||
result->parse(p_stop, p_config->m_fast);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -228,13 +233,6 @@ PegParser::PegParser(QObject *p_parent)
|
||||
init();
|
||||
}
|
||||
|
||||
void PegParser::parseAsync(const QSharedPointer<PegParseConfig> &p_config)
|
||||
{
|
||||
m_pendingWork = p_config;
|
||||
|
||||
pickWorker();
|
||||
}
|
||||
|
||||
void PegParser::init()
|
||||
{
|
||||
for (int i = 0; i < NUM_OF_THREADS; ++i) {
|
||||
@ -267,6 +265,29 @@ PegParser::~PegParser()
|
||||
clear();
|
||||
}
|
||||
|
||||
void PegParser::parseAsync(const QSharedPointer<PegParseConfig> &p_config)
|
||||
{
|
||||
m_pendingWork = p_config;
|
||||
|
||||
pickWorker();
|
||||
}
|
||||
|
||||
QSharedPointer<PegParseResult> PegParser::parse(const QSharedPointer<PegParseConfig> &p_config)
|
||||
{
|
||||
QSharedPointer<PegParseResult> result(new PegParseResult(p_config));
|
||||
|
||||
if (p_config->m_data.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result->m_pmhElements = PegParser::parseMarkdownToElements(p_config);
|
||||
|
||||
QAtomicInt stop(0);
|
||||
result->parse(stop, p_config->m_fast);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PegParser::handleWorkerFinished(PegParserWorker *p_worker)
|
||||
{
|
||||
QSharedPointer<PegParseResult> result;
|
||||
@ -333,6 +354,7 @@ QVector<VElementRegion> PegParser::parseImageRegions(const QSharedPointer<PegPar
|
||||
return regs;
|
||||
}
|
||||
|
||||
int offset = p_config->m_offset;
|
||||
pmh_element *elem = res[pmh_IMAGE];
|
||||
while (elem != NULL) {
|
||||
if (elem->end <= elem->pos) {
|
||||
@ -340,7 +362,7 @@ QVector<VElementRegion> PegParser::parseImageRegions(const QSharedPointer<PegPar
|
||||
continue;
|
||||
}
|
||||
|
||||
regs.push_back(VElementRegion(elem->pos, elem->end));
|
||||
regs.push_back(VElementRegion(offset + elem->pos, offset + elem->end));
|
||||
elem = elem->next;
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,9 @@ struct PegParseConfig
|
||||
PegParseConfig()
|
||||
: m_timeStamp(0),
|
||||
m_numOfBlocks(0),
|
||||
m_extensions(pmh_EXT_NONE)
|
||||
m_offset(0),
|
||||
m_extensions(pmh_EXT_NONE),
|
||||
m_fast(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -26,8 +28,14 @@ struct PegParseConfig
|
||||
|
||||
int m_numOfBlocks;
|
||||
|
||||
// Offset of m_data in the document.
|
||||
int m_offset;
|
||||
|
||||
int m_extensions;
|
||||
|
||||
// Fast parse.
|
||||
bool m_fast;
|
||||
|
||||
QString toString() const
|
||||
{
|
||||
return QString("PegParseConfig ts %1 data %2 blocks %3").arg(m_timeStamp)
|
||||
@ -41,6 +49,7 @@ struct PegParseResult
|
||||
PegParseResult(const QSharedPointer<PegParseConfig> &p_config)
|
||||
: m_timeStamp(p_config->m_timeStamp),
|
||||
m_numOfBlocks(p_config->m_numOfBlocks),
|
||||
m_offset(p_config->m_offset),
|
||||
m_pmhElements(NULL)
|
||||
{
|
||||
}
|
||||
@ -74,12 +83,14 @@ struct PegParseResult
|
||||
}
|
||||
|
||||
// Parse m_pmhElements.
|
||||
void parse(QAtomicInt &p_stop);
|
||||
void parse(QAtomicInt &p_stop, bool p_fast);
|
||||
|
||||
TimeStamp m_timeStamp;
|
||||
|
||||
int m_numOfBlocks;
|
||||
|
||||
int m_offset;
|
||||
|
||||
pmh_element **m_pmhElements;
|
||||
|
||||
// All image link regions.
|
||||
@ -178,6 +189,8 @@ public:
|
||||
|
||||
~PegParser();
|
||||
|
||||
QSharedPointer<PegParseResult> parse(const QSharedPointer<PegParseConfig> &p_config);
|
||||
|
||||
void parseAsync(const QSharedPointer<PegParseConfig> &p_config);
|
||||
|
||||
static QVector<VElementRegion> parseImageRegions(const QSharedPointer<PegParseConfig> &p_config);
|
||||
|
@ -290,10 +290,10 @@ void VCodeBlockHighlightHelper::addToHighlightCache(const QString &p_text,
|
||||
const QVector<HLUnitPos> &p_units)
|
||||
{
|
||||
const int c_maxEntries = 100;
|
||||
const int c_maxTimeStampSpan = 3;
|
||||
const TimeStamp c_maxTimeStampSpan = 3;
|
||||
if (m_cache.size() >= c_maxEntries) {
|
||||
// Remove the oldest one.
|
||||
int ts = p_timeStamp - c_maxTimeStampSpan;
|
||||
TimeStamp ts = p_timeStamp - c_maxTimeStampSpan;
|
||||
for (auto it = m_cache.begin(); it != m_cache.end();) {
|
||||
if (it.value().m_timeStamp < ts) {
|
||||
it = m_cache.erase(it);
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "vpreviewmanager.h"
|
||||
|
||||
#include <QTextDocument>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QUrl>
|
||||
#include <QVector>
|
||||
@ -63,7 +62,6 @@ void VPreviewManager::imageDownloaded(const QByteArray &p_data, const QString &p
|
||||
|
||||
if (!image.isNull()) {
|
||||
m_editor->addImage(name, image);
|
||||
qDebug() << "downloaded image inserted in resource manager" << p_url << name;
|
||||
emit requestUpdateImageLinks();
|
||||
}
|
||||
}
|
||||
@ -172,8 +170,6 @@ void VPreviewManager::fetchImageLinksFromRegions(QVector<VElementRegion> p_image
|
||||
}
|
||||
|
||||
p_imageLinks.append(info);
|
||||
|
||||
qDebug() << "image region" << i << info.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -404,10 +400,6 @@ void VPreviewManager::updateBlockPreviewInfo(TS p_timeStamp,
|
||||
affectedBlocks.insert(link.m_blockNumber, QMapDummyValue());
|
||||
m_highlighter->addPossiblePreviewBlock(link.m_blockNumber);
|
||||
}
|
||||
|
||||
qDebug() << "block" << link.m_blockNumber
|
||||
<< imageCache(PreviewSource::ImageLink).size()
|
||||
<< blockData->toString();
|
||||
}
|
||||
|
||||
relayoutEditor(affectedBlocks);
|
||||
|
Loading…
x
Reference in New Issue
Block a user