support specifying image size in preview

This commit is contained in:
Le Tan 2018-05-06 21:36:22 +08:00
parent 84437bcd97
commit dba154b2c3
6 changed files with 121 additions and 35 deletions

View File

@ -73,7 +73,15 @@ Notice that the sequence number is irrelevant. Markdown will change the sequence
### Images and Links ### Images and Links
```md ```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) [Link Text](/url/of/the/link)
``` ```
@ -81,6 +89,7 @@ Notice that the sequence number is irrelevant. Markdown will change the sequence
**Notes**: **Notes**:
- It is not recommended to use image links in reference format. VNote will not preview those images. - 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 ### Blockquotes
```md ```md
@ -164,6 +173,8 @@ VNote also supports displayed mathematics via fenced code block with language `m
Here is a `inline code`. 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 ### Strikethrough
```md ```md
Here is a ~~text~~ with strikethrough. Here is a ~~text~~ with strikethrough.

View File

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

View File

@ -37,7 +37,10 @@ extern VConfigManager *g_config;
QVector<QPair<QString, QString>> VUtils::s_availableLanguages; 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]*"); const QString VUtils::c_imageTitleRegExp = QString("[\\w\\(\\)@#%\\*\\-\\+=\\?<>\\,\\.\\s]*");

View File

@ -328,12 +328,16 @@ public:
static QPixmap pixmapFromFile(const QString &p_filePath); static QPixmap pixmapFromFile(const QString &p_filePath);
// Regular expression for image link. // 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): // Captured texts (need to be trimmed):
// 1. Image Alt Text (Title); // 1. Image Alt Text (Title);
// 2. Image URL; // 2. Image URL;
// 3. Image Optional Title with double quotes; // 3. Image Optional Title with double quotes or quotes;
// 4. Unused; // 4. Unused;
// 5. Unused;
// 6. Unused;
// 7. Width;
// 8. Height;
static const QString c_imageLinkRegExp; static const QString c_imageLinkRegExp;
// Regular expression for image title. // Regular expression for image title.

View File

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

View File

@ -101,7 +101,9 @@ private:
m_blockPos(-1), m_blockPos(-1),
m_blockNumber(-1), m_blockNumber(-1),
m_padding(0), 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_blockPos(p_blockPos),
m_blockNumber(p_blockNumber), m_blockNumber(p_blockNumber),
m_padding(p_padding), 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_startPos;
int m_endPos; int m_endPos;
@ -140,6 +160,12 @@ private:
// Whether it is an image block. // Whether it is an image block.
bool m_isBlock; 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. // Start to preview images according to image links.
@ -151,11 +177,10 @@ private:
QVector<ImageLinkInfo> &p_imageLinks); QVector<ImageLinkInfo> &p_imageLinks);
// Fetch the image link's URL if there is only one link. // 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. // Fetch the image's full path and size.
// @p_url: contains the short URL in ![](). void fetchImageInfoToPreview(const QString &p_text, ImageLinkInfo &p_info);
QString fetchImagePathToPreview(const QString &p_text, QString &p_url);
// Update the preview info of related blocks according to @p_imageLinks. // Update the preview info of related blocks according to @p_imageLinks.
void updateBlockPreviewInfo(TS p_timeStamp, const QVector<ImageLinkInfo> &p_imageLinks); void updateBlockPreviewInfo(TS p_timeStamp, const QVector<ImageLinkInfo> &p_imageLinks);