瀏覽代碼

support specifying image size in preview

Le Tan 7 年之前
父節點
當前提交
dba154b2c3

+ 12 - 1
src/resources/docs/markdown_guide_en.md

@@ -73,7 +73,15 @@ Notice that the sequence number is irrelevant. Markdown will change the sequence
 
 ### Images and Links
 ```md
-![Image Alt Text](/url/to/images.png)
+![Image Alt Text](/url/to/image.png "Optional Text")
+
+![Image Alt Text](/url/to/image.png "Image specified with width and height" =800x600)
+
+![Image Alt Text](/url/to/image.png =800x600)
+
+![Image Alt Text](/url/to/image.png "Image specified with width" =800x)
+
+![Image Alt Text](/url/to/image.png "Image specified with height" =x600)
 
 [Link Text](/url/of/the/link)
 ```
@@ -81,6 +89,7 @@ Notice that the sequence number is irrelevant. Markdown will change the sequence
 **Notes**:
 
 - It is not recommended to use image links in reference format. VNote will not preview those images.
+- Specifying size of image is supported only in **markdown-it**.
 
 ### Blockquotes
 ```md
@@ -164,6 +173,8 @@ VNote also supports displayed mathematics via fenced code block with language `m
 Here is a `inline code`.
 ```
 
+To insert one `` ` ``, you need to use two `` ` `` to enclose it, such as ``` `` ` `` ```. To insert two `` ` ``, you need to use three `` ` ``.
+
 ### Strikethrough
 ```md
 Here is a ~~text~~ with strikethrough.

+ 12 - 1
src/resources/docs/markdown_guide_zh.md

@@ -74,7 +74,15 @@ __This text will be bold__
 
 ### 图片和链接
 ```md
-![Image Alt Text](/url/to/images.png)
+![Image Alt Text](/url/to/image.png "Optional Text")
+
+![Image Alt Text](/url/to/image.png "Image specified with width and height" =800x600)
+
+![Image Alt Text](/url/to/image.png =800x600)
+
+![Image Alt Text](/url/to/image.png "Image specified with width" =800x)
+
+![Image Alt Text](/url/to/image.png "Image specified with height" =x600)
 
 [Link Text](/url/of/the/link)
 ```
@@ -82,6 +90,7 @@ __This text will be bold__
 **注意**:
 
 - VNote不推荐使用参考式的图片链接。VNote不会预览这些图片。
+- 声明图片尺寸只在 **markdown-it** 中支持。
 
 ### 块引用
 ```md
@@ -165,6 +174,8 @@ VNote也可以使用标明语言`mathjax`的代码块来实现块公式。使用
 Here is a `inline code`.
 ```
 
+如果想输入一个 `` ` ``,需要使用两个 `` ` `` 来括住它,例如 ``` `` ` `` ```。 要输入两个 `` ` ``,则需要使用三个 `` ` ``。
+
 ### 删除线
 ```md
 Here is a ~~text~~ with strikethrough.

+ 4 - 1
src/utils/vutils.cpp

@@ -37,7 +37,10 @@ extern VConfigManager *g_config;
 
 QVector<QPair<QString, QString>> VUtils::s_availableLanguages;
 
-const QString VUtils::c_imageLinkRegExp = QString("\\!\\[([^\\]]*)\\]\\(([^\\)\"]+)\\s*(\"(\\\\.|[^\"\\)])*\")?\\s*\\)");
+const QString VUtils::c_imageLinkRegExp = QString("\\!\\[([^\\]]*)\\]\\(([^\\)\"'\\s]+)\\s*"
+                                                  "((\"[^\"\\)\\n]*\")|('[^'\\)\\n]*'))?\\s*"
+                                                  "(=(\\d*)x(\\d*))?\\s*"
+                                                  "\\)");
 
 const QString VUtils::c_imageTitleRegExp = QString("[\\w\\(\\)@#%\\*\\-\\+=\\?<>\\,\\.\\s]*");
 

+ 6 - 2
src/utils/vutils.h

@@ -328,12 +328,16 @@ public:
     static QPixmap pixmapFromFile(const QString &p_filePath);
 
     // Regular expression for image link.
-    // ![image title]( http://github.com/tamlok/vnote.jpg "alt \" text" )
+    // ![image title]( http://github.com/tamlok/vnote.jpg "alt text" =200x100)
     // Captured texts (need to be trimmed):
     // 1. Image Alt Text (Title);
     // 2. Image URL;
-    // 3. Image Optional Title with double quotes;
+    // 3. Image Optional Title with double quotes or quotes;
     // 4. Unused;
+    // 5. Unused;
+    // 6. Unused;
+    // 7. Width;
+    // 8. Height;
     static const QString c_imageLinkRegExp;
 
     // Regular expression for image title.

+ 56 - 24
src/vpreviewmanager.cpp

@@ -158,31 +158,31 @@ void VPreviewManager::fetchImageLinksFromRegions(QVector<VElementRegion> p_image
                 || isAllSpaces(text, reg.m_endPos - blockStart, blockEnd - blockStart))) {
             // Image block.
             info.m_isBlock = true;
-            info.m_linkUrl = fetchImagePathToPreview(text, info.m_linkShortUrl);
+            fetchImageInfoToPreview(text, info);
         } else {
             // Inline image.
             info.m_isBlock = false;
-            info.m_linkUrl = fetchImagePathToPreview(text.mid(reg.m_startPos - blockStart,
-                                                              reg.m_endPos - reg.m_startPos),
-                                                     info.m_linkShortUrl);
+            fetchImageInfoToPreview(text.mid(reg.m_startPos - blockStart,
+                                             reg.m_endPos - reg.m_startPos),
+                                    info);
         }
 
-        if (info.m_linkUrl.isEmpty()) {
+        if (info.m_linkUrl.isEmpty() || info.m_linkShortUrl.isEmpty()) {
             continue;
         }
 
         p_imageLinks.append(info);
 
-        qDebug() << "image region" << i
-                 << info.m_startPos << info.m_endPos << info.m_blockNumber
-                 << info.m_linkShortUrl << info.m_linkUrl << info.m_isBlock;
+        qDebug() << "image region" << i << info.toString();
     }
 }
 
-QString VPreviewManager::fetchImageUrlToPreview(const QString &p_text)
+QString VPreviewManager::fetchImageUrlToPreview(const QString &p_text, int &p_width, int &p_height)
 {
     QRegExp regExp(VUtils::c_imageLinkRegExp);
 
+    p_width = p_height = -1;
+
     int index = regExp.indexIn(p_text);
     if (index == -1) {
         return QString();
@@ -193,30 +193,48 @@ QString VPreviewManager::fetchImageUrlToPreview(const QString &p_text)
         return QString();
     }
 
-    return regExp.capturedTexts()[2].trimmed();
+    QString tmp(regExp.cap(7));
+    if (!tmp.isEmpty()) {
+        p_width = tmp.toInt();
+        if (p_width <= 0) {
+            p_width = -1;
+        }
+    }
+
+    tmp = regExp.cap(8);
+    if (!tmp.isEmpty()) {
+        p_height = tmp.toInt();
+        if (p_height <= 0) {
+            p_height = -1;
+        }
+    }
+
+    return regExp.cap(2).trimmed();
 }
 
-QString VPreviewManager::fetchImagePathToPreview(const QString &p_text, QString &p_url)
+void VPreviewManager::fetchImageInfoToPreview(const QString &p_text, ImageLinkInfo &p_info)
 {
-    p_url = fetchImageUrlToPreview(p_text);
-    if (p_url.isEmpty()) {
-        return p_url;
+    QString surl = fetchImageUrlToPreview(p_text, p_info.m_width, p_info.m_height);
+    p_info.m_linkShortUrl = surl;
+    if (surl.isEmpty()) {
+        p_info.m_linkUrl = surl;
+        return;
     }
 
     const VFile *file = m_editor->getFile();
 
     QString imagePath;
-    QFileInfo info(file->fetchBasePath(), p_url);
+    QFileInfo info(file->fetchBasePath(), surl);
 
     if (info.exists()) {
         if (info.isNativePath()) {
             // Local file.
             imagePath = QDir::cleanPath(info.absoluteFilePath());
         } else {
-            imagePath = p_url;
+            imagePath = surl;
         }
     } else {
-        QString decodedUrl(p_url);
+        QString decodedUrl(surl);
         VUtils::decodeUrl(decodedUrl);
         QFileInfo dinfo(file->fetchBasePath(), decodedUrl);
         if (dinfo.exists()) {
@@ -224,10 +242,10 @@ QString VPreviewManager::fetchImagePathToPreview(const QString &p_text, QString
                 // Local file.
                 imagePath = QDir::cleanPath(dinfo.absoluteFilePath());
             } else {
-                imagePath = p_url;
+                imagePath = surl;
             }
         } else {
-            QUrl url(p_url);
+            QUrl url(surl);
             if (url.isLocalFile()) {
                 imagePath = url.toLocalFile();
             } else {
@@ -236,14 +254,16 @@ QString VPreviewManager::fetchImagePathToPreview(const QString &p_text, QString
         }
     }
 
-    return imagePath;
+    p_info.m_linkUrl = imagePath;
 }
 
 QString VPreviewManager::imageResourceName(const ImageLinkInfo &p_link)
 {
-    QString name = p_link.m_linkShortUrl;
-    if (m_editor->containsImage(name)
-        || name.isEmpty()) {
+    // Add size info to the name.
+    QString name = QString("%1_%2_%3").arg(p_link.m_linkShortUrl)
+                                      .arg(p_link.m_width)
+                                      .arg(p_link.m_height);
+    if (m_editor->containsImage(name)) {
         return name;
     }
 
@@ -263,7 +283,19 @@ QString VPreviewManager::imageResourceName(const ImageLinkInfo &p_link)
         return QString();
     }
 
-    m_editor->addImage(name, image);
+    // Resize the image.
+    if (p_link.m_width > 0) {
+        if (p_link.m_height > 0) {
+            m_editor->addImage(name, image.scaled(p_link.m_width, p_link.m_height));
+        } else {
+            m_editor->addImage(name, image.scaledToWidth(p_link.m_width));
+        }
+    } else if (p_link.m_height > 0) {
+        m_editor->addImage(name, image.scaledToHeight(p_link.m_height));
+    } else {
+        m_editor->addImage(name, image);
+    }
+
     return name;
 }
 

+ 31 - 6
src/vpreviewmanager.h

@@ -101,7 +101,9 @@ private:
               m_blockPos(-1),
               m_blockNumber(-1),
               m_padding(0),
-              m_isBlock(false)
+              m_isBlock(false),
+              m_width(-1),
+              m_height(-1)
         {
         }
 
@@ -115,10 +117,28 @@ private:
               m_blockPos(p_blockPos),
               m_blockNumber(p_blockNumber),
               m_padding(p_padding),
-              m_isBlock(false)
+              m_isBlock(false),
+              m_width(-1),
+              m_height(-1)
         {
         }
 
+        QString toString() const
+        {
+            return QString("ImageLinkInfo [%1,%2) block(%3,%4) padding %5 "
+                           "short %6 url %7 isBlock %8 width %9 height %10")
+                          .arg(m_startPos)
+                          .arg(m_endPos)
+                          .arg(m_blockNumber)
+                          .arg(m_blockPos)
+                          .arg(m_padding)
+                          .arg(m_linkShortUrl)
+                          .arg(m_linkUrl)
+                          .arg(m_isBlock)
+                          .arg(m_width)
+                          .arg(m_height);
+        }
+
         int m_startPos;
 
         int m_endPos;
@@ -140,6 +160,12 @@ private:
 
         // Whether it is an image block.
         bool m_isBlock;
+
+        // Image width, -1 for not specified.
+        int m_width;
+
+        // Image height, -1 for not specified.
+        int m_height;
     };
 
     // Start to preview images according to image links.
@@ -151,11 +177,10 @@ private:
                                     QVector<ImageLinkInfo> &p_imageLinks);
 
     // Fetch the image link's URL if there is only one link.
-    QString fetchImageUrlToPreview(const QString &p_text);
+    QString fetchImageUrlToPreview(const QString &p_text, int &p_width, int &p_height);
 
-    // Fetch teh image's full path if there is only one image link.
-    // @p_url: contains the short URL in ![]().
-    QString fetchImagePathToPreview(const QString &p_text, QString &p_url);
+    // Fetch the image's full path and size.
+    void fetchImageInfoToPreview(const QString &p_text, ImageLinkInfo &p_info);
 
     // Update the preview info of related blocks according to @p_imageLinks.
     void updateBlockPreviewInfo(TS p_timeStamp, const QVector<ImageLinkInfo> &p_imageLinks);