摘要
https://wylu.github.io/posts/7bd83fc5/
在使用 Hexo + NexT 搭建個人博客的過程中一直有個問題沒有解決,直到今天才找到了解決方法。問題就是在展示同一張圖片中,caption出現了兩次,如圖:
問題分析
圖片正下方的 image-caption 是 NexT 給 fancybox 加上的;而圖片左下方的 figcaption 是因爲使用了 hexo-renderer-pandoc Markdown 渲染器導致的,hexo-renderer-pandoc 將 Markdown 文件渲染成 HTML 時,會對圖片進行渲染,然後生成一個 figcaption 的標籤。
很多人可能不會有這樣的問題,因爲 Hexo 默認的 Markdown 渲染器是 hexo-renderer-marked,hexo-renderer-marked 渲染圖片時不會生成 figcaption。
如果你使用的是 hexo-renderer-marked 渲染器,就不會有這樣的問題,但是相信很多人都是因爲需要使用 mathjax,所以都將默認的 Hexo 默認的 Markdown 渲染器換成了 hexo-renderer-pandoc,hexo-renderer-pandoc 功能強大(依賴與 pandoc 自身強大的功能),它對數學公式的渲染簡直可以說是吊打 hexo-renderer-marked,這也是我一直使用它的原因。
所以爲了在使用 hexo-renderer-pandoc 的同時,把圖片 caption 出現了兩次的問題解決,我提過 issue,查閱了許多資料,終於找到了解決的方法。
解決方法
編輯站點配置文件 _config.yml
,添加如下內容:
pandoc:
extensions:
- '-implicit_figures'
執行下列命令重新生成站點,展示效果如下:
$ hexo clean && hexo g && hexo s -o
隱藏 fancybox 的 caption
以 NexT v7.7.0 爲例,通過查看 hexo-theme-next/source/js/utils.js 源碼,發現 NexT 在使用 fancybox 時,如果圖片 title 或 alt 屬性不爲空時,就會 fancybox 添加一個子標籤展示圖片的 title 或 alt 屬性值。
var imageTitle = $image.attr('title') || $image.attr('alt');
if (imageTitle) {
$imageWrapLink.append(`<p class="image-caption">${imageTitle}</p>`);
// Make sure img title tag will show correctly in fancybox
$imageWrapLink.attr('title', imageTitle).attr('data-caption', imageTitle);
}
如果想通過配置支持選擇是否展示 caption,可以參考下方的方法(在 NexT v7.7.0 已測試過),其實不管 NexT 的版本如何,解決方法的思路基本是一致的。
首先修改主題配置文件 _config.yml
,找到 fancybox 的配置,將 fancybox 的配置改成如下所示內容:
# FancyBox is a tool that offers a nice and elegant way to add zooming functionality for images.
# For more information: https://fancyapps.com/fancybox
fancybox:
enable: true
caption: false
其中,enable 控制是否啓用 fancybox,而 caption 控制是否展示 caption (當然只有在 enable 爲 true 時,caption 配置纔有效),如果你不啓用 fancybox 自然也不會有 caption。
然後,編輯 hexo-theme-next/source/js/utils.js 文件,將上面的代碼修改成如下內容:
var imageTitle = $image.attr('title') || $image.attr('alt');
if (imageTitle) {
if (CONFIG.fancybox.caption) {
$imageWrapLink.append(`<p class="image-caption">${imageTitle}</p>`);
}
// Make sure img title tag will show correctly in fancybox
$imageWrapLink.attr('title', imageTitle).attr('data-caption', imageTitle);
}
接着,編輯 hexo-theme-next/source/js/next-boot.js 文件,將 CONFIG.fancybox && NexT.utils.wrapImageWithFancyBox();
替換成如下內容:
/**
* Register JS handlers by condition option.
* Need to add config option in Front-End at 'layout/_partials/head.swig' file.
*/
CONFIG.fancybox.enable && NexT.utils.wrapImageWithFancyBox();
相信你可以發現,我們這裏將 CONFIG.fancybox
替換成 CONFIG.fancybox.enable
,正是因爲我們自定義的配置是通過 fancybox 下的 enable 的值來確定是否啓用的。另外從源碼上方的註釋可以看到,CONFIG 下的配置項需要在前端文件 ‘layout/_partials/head.swig’ (實際上該文件在’layout/_partials/head/head.swig’)中加上。
所以最後,我們需要在 layout/_partials/head/head.swig
中修改一下上面我們所使用 CONFIG.fancybox.caption
配置。參照其它配置,這裏需要將 fancybox: {{ theme.fancybox }}
,修改成如下內容:
fancybox: {{ theme.fancybox | json }}
重新生成,效果如下: