Browse Source

use HGMarkdownParser to fetch image links from Markdown file

Le Tan 8 years ago
parent
commit
cdcab4884a
4 changed files with 55 additions and 7 deletions
  1. 1 1
      src/hgmarkdownhighlighter.cpp
  2. 45 5
      src/utils/vutils.cpp
  3. 4 1
      src/utils/vutils.h
  4. 5 0
      src/vmdedit.h

+ 1 - 1
src/hgmarkdownhighlighter.cpp

@@ -483,7 +483,7 @@ void HGMarkdownHighlighter::parseInternal()
     QString text = document->toPlainText();
     QByteArray ba = text.toUtf8();
     const char *data = (const char *)ba.data();
-   int len = ba.size();
+    int len = ba.size();
 
     if (result) {
         pmh_free_elements(result);

+ 45 - 5
src/utils/vutils.cpp

@@ -25,6 +25,7 @@
 #include "vfile.h"
 #include "vnote.h"
 #include "vnotebook.h"
+#include "hgmarkdownhighlighter.h"
 
 extern VConfigManager *g_config;
 
@@ -165,7 +166,7 @@ QString VUtils::basePathFromPath(const QString &p_path)
 QVector<ImageLink> VUtils::fetchImagesFromMarkdownFile(VFile *p_file,
                                                        ImageLink::ImageLinkType p_type)
 {
-    V_ASSERT(p_file->getDocType() == DocType::Markdown);
+    Q_ASSERT(p_file->getDocType() == DocType::Markdown);
     QVector<ImageLink> images;
 
     bool isOpened = p_file->isOpened();
@@ -182,10 +183,14 @@ QVector<ImageLink> VUtils::fetchImagesFromMarkdownFile(VFile *p_file,
         return images;
     }
 
+    QVector<VElementRegion> regions = fetchImageRegionsUsingParser(text);
     QRegExp regExp(c_imageLinkRegExp);
     QString basePath = p_file->fetchBasePath();
-    int pos = 0;
-    while (pos < text.size() && (pos = regExp.indexIn(text, pos)) != -1) {
+    for (int i = 0; i < regions.size(); ++i) {
+        const VElementRegion &reg = regions[i];
+        QString linkText = text.mid(reg.m_startPos, reg.m_endPos - reg.m_startPos);
+        bool matched = regExp.exactMatch(linkText);
+        Q_ASSERT(matched);
         QString imageUrl = regExp.capturedTexts()[2].trimmed();
 
         ImageLink link;
@@ -215,8 +220,6 @@ QVector<ImageLink> VUtils::fetchImagesFromMarkdownFile(VFile *p_file,
             images.push_back(link);
             qDebug() << "fetch one image:" << link.m_type << link.m_path;
         }
-
-        pos += regExp.matchedLength();
     }
 
     if (!isOpened) {
@@ -816,3 +819,40 @@ bool VUtils::deleteFile(const VNotebook *p_notebook,
         return true;
     }
 }
+
+QVector<VElementRegion> VUtils::fetchImageRegionsUsingParser(const QString &p_content)
+{
+    Q_ASSERT(!p_content.isEmpty());
+    QVector<VElementRegion> regs;
+
+    QByteArray ba = p_content.toUtf8();
+    const char *data = (const char *)ba.data();
+    int len = ba.size();
+
+    pmh_element **result = NULL;
+    char *content = new char[len + 1];
+    memcpy(content, data, len);
+    content[len] = '\0';
+
+    pmh_markdown_to_elements(content, pmh_EXT_NONE, &result);
+
+    if (!result) {
+        return regs;
+    }
+
+    pmh_element *elem = result[pmh_IMAGE];
+    while (elem != NULL) {
+        if (elem->end <= elem->pos) {
+            elem = elem->next;
+            continue;
+        }
+
+        regs.push_back(VElementRegion(elem->pos, elem->end));
+
+        elem = elem->next;
+    }
+
+    pmh_free_elements(result);
+
+    return regs;
+}

+ 4 - 1
src/utils/vutils.h

@@ -64,7 +64,7 @@ public:
     // /home/tamlok/abc, /home/tamlok/abc/ will both return /home/tamlok.
     static QString basePathFromPath(const QString &p_path);
 
-    // Fetch all the image links (including those in code blocks) in markdown file p_file.
+    // Fetch all the image links in markdown file p_file.
     // @p_type to filter the links returned.
     // Need to open p_file and will close it if it is originally closed.
     static QVector<ImageLink> fetchImagesFromMarkdownFile(VFile *p_file,
@@ -184,6 +184,9 @@ private:
 
     static void initAvailableLanguage();
 
+    // Use HGMarkdownParser to parse @p_content to get all image link regions.
+    static QVector<VElementRegion> fetchImageRegionsUsingParser(const QString &p_content);
+
     // <value, name>
     static QVector<QPair<QString, QString>> s_availableLanguages;
 };

+ 5 - 0
src/vmdedit.h

@@ -83,7 +83,12 @@ private:
         int m_endPos;
     };
 
+    // Get the initial images from file before edit.
     void initInitImages();
+
+    // Clear two kind of images according to initial images and current images:
+    // 1. Newly inserted images which are deleted later;
+    // 2. Initial images which are deleted;
     void clearUnusedImages();
 
     // There is a QChar::ObjectReplacementCharacter (and maybe some spaces)