Jelajahi Sumber

do not highlight verbatim code blocks

Le Tan 7 tahun lalu
induk
melakukan
2c527201b8
3 mengubah file dengan 63 tambahan dan 7 penghapusan
  1. 44 5
      src/hgmarkdownhighlighter.cpp
  2. 15 1
      src/hgmarkdownhighlighter.h
  3. 4 1
      src/vconstants.h

+ 44 - 5
src/hgmarkdownhighlighter.cpp

@@ -121,7 +121,8 @@ void HGMarkdownHighlighter::updateBlockUserData(int p_blockNum, const QString &p
 
 void HGMarkdownHighlighter::highlightBlock(const QString &text)
 {
-    int blockNum = currentBlock().blockNumber();
+    QTextBlock curBlock = currentBlock();
+    int blockNum = curBlock.blockNumber();
     if (m_blockHLResultReady && m_blockHighlights.size() > blockNum) {
         // units are sorted by start position and length.
         const QVector<HLUnit> &units = m_blockHighlights[blockNum];
@@ -161,14 +162,20 @@ void HGMarkdownHighlighter::highlightBlock(const QString &text)
     updateBlockUserData(blockNum, text);
 
     // If it is a block inside HTML comment, just skip it.
-    if (isBlockInsideCommentRegion(currentBlock())) {
+    if (isBlockInsideCommentRegion(curBlock)) {
         setCurrentBlockState(HighlightBlockState::Comment);
         goto exit;
     }
 
     // PEG Markdown Highlight does not handle the ``` code block correctly.
     setCurrentBlockState(HighlightBlockState::Normal);
-    highlightCodeBlock(text);
+    highlightCodeBlock(curBlock, text);
+
+    if (currentBlockState() == HighlightBlockState::Normal
+        && isVerbatimBlock(curBlock)) {
+        setCurrentBlockState(HighlightBlockState::Verbatim);
+        goto exit;
+    }
 
     // PEG Markdown Highlight does not handle links with spaces in the URL.
     // Links in the URL should be encoded to %20. We just let it be here and won't
@@ -328,6 +335,31 @@ void HGMarkdownHighlighter::initImageRegionsFromResult()
     emit imageLinksUpdated(m_imageRegions);
 }
 
+void HGMarkdownHighlighter::initVerbatimBlocksFromResult()
+{
+    m_verbatimBlocks.clear();
+    if (!result) {
+        return;
+    }
+
+    pmh_element *elem = result[pmh_VERBATIM];
+    while (elem != NULL) {
+        if (elem->end <= elem->pos) {
+            elem = elem->next;
+            continue;
+        }
+
+        // [firstBlock, lastBlock].
+        int firstBlock = document->findBlock(elem->pos).blockNumber();
+        int lastBlock = document->findBlock(elem->end - 1).blockNumber();
+        for (int i = firstBlock; i <= lastBlock; ++i) {
+            m_verbatimBlocks.insert(i);
+        }
+
+        elem = elem->next;
+    }
+}
+
 void HGMarkdownHighlighter::initHeaderRegionsFromResult()
 {
     // From Qt5.7, the capacity is preserved.
@@ -404,7 +436,7 @@ void HGMarkdownHighlighter::initBlockHighlihgtOne(unsigned long pos,
     }
 }
 
-void HGMarkdownHighlighter::highlightCodeBlock(const QString &text)
+void HGMarkdownHighlighter::highlightCodeBlock(const QTextBlock &p_block, const QString &text)
 {
     VTextBlockData *blockData = currentBlockData();
     Q_ASSERT(blockData);
@@ -418,7 +450,7 @@ void HGMarkdownHighlighter::highlightCodeBlock(const QString &text)
         && preState != HighlightBlockState::CodeBlockStart) {
         // Need to find a new code block start.
         index = codeBlockStartExp.indexIn(text);
-        if (index >= 0) {
+        if (index >= 0 && !isVerbatimBlock(p_block)) {
             // Start a new code block.
             length = text.length();
             state = HighlightBlockState::CodeBlockStart;
@@ -533,6 +565,8 @@ void HGMarkdownHighlighter::parse(bool p_fast)
         initImageRegionsFromResult();
 
         initHeaderRegionsFromResult();
+
+        initVerbatimBlocksFromResult();
     }
 
     if (result) {
@@ -630,6 +664,11 @@ bool HGMarkdownHighlighter::updateCodeBlocks()
     // Only handle complete codeblocks.
     QTextBlock block = document->firstBlock();
     while (block.isValid()) {
+        if (!inBlock && isVerbatimBlock(block)) {
+            block = block.next();
+            continue;
+        }
+
         QString text = block.text();
         if (inBlock) {
             item.m_text = item.m_text + "\n" + text;

+ 15 - 1
src/hgmarkdownhighlighter.h

@@ -232,6 +232,10 @@ private:
     // Sorted by start position.
     QVector<VElementRegion> m_headerRegions;
 
+    // All verbatim blocks (by parser) number.
+    // It may be a code block inside fenced code block.
+    QSet<int> m_verbatimBlocks;
+
     // Indexed by block number.
     QHash<int, HeaderBlockInfo> m_headerBlocks;
 
@@ -256,7 +260,7 @@ private:
     static const int initCapacity;
 
     void resizeBuffer(int newCap);
-    void highlightCodeBlock(const QString &text);
+    void highlightCodeBlock(const QTextBlock &p_block, const QString &text);
 
     // Highlight links using regular expression.
     // PEG Markdown Highlight treat URLs with spaces illegal. This function is
@@ -288,9 +292,15 @@ private:
     // Fetch all the header regions from parsing result.
     void initHeaderRegionsFromResult();
 
+    // Fetch all the verbatim blocks from parsing result.
+    void initVerbatimBlocksFromResult();
+
     // Whether @p_block is totally inside a HTML comment.
     bool isBlockInsideCommentRegion(const QTextBlock &p_block) const;
 
+    // Whether @p_block is a Verbatim block.
+    bool isVerbatimBlock(const QTextBlock &p_block) const;
+
     // Highlights have been changed. Try to signal highlightCompleted().
     void highlightChanged();
 
@@ -361,4 +371,8 @@ inline QVector<HighlightingStyle> &HGMarkdownHighlighter::getHighlightingStyles(
     return highlightingStyles;
 }
 
+inline bool HGMarkdownHighlighter::isVerbatimBlock(const QTextBlock &p_block) const
+{
+    return m_verbatimBlocks.contains(p_block.blockNumber());
+}
 #endif

+ 4 - 1
src/vconstants.h

@@ -118,7 +118,10 @@ enum HighlightBlockState
     CodeBlockEnd,
 
     // This block is inside a HTML comment region.
-    Comment
+    Comment,
+
+    // Verbatim code block.
+    Verbatim
 };
 
 // Pages to open on start up.