如何在 Org-mode 中愉快地嵌入图片
对于经常用 emacs 的 Org-mode 写文章的朋友,常常会遇到的一个困扰就是如何在 Org-mode 中嵌入图片。俗话说一图胜千言,一篇令人印象深刻的文章总是少不了精致的图片,但是 Org-mode 自带的引入图片功能实在是有够简陋,往往只能通过 [[file:<path>]]
这种非常麻烦的方式,而一旦涉及到截图就更难受了。那么有没有什么办法能让 emacer 愉快地嵌入图片呢?当然有了,万能的开源社区往往早就解决了这类常见的痛点,那就是: org-download 。
使用 org-download 能实现什么样的功能?
首先,当我们想要在文章中引入一张图片,我们会怎么做呢? org-download 明确地将图片的来源作出了归类:
- 剪贴板
- 截屏
- 网络地址
- 直接从文件系统拖拽到 emacs 中
而无论你要用到的图片是从哪里来的, org-download
都可以轻松做到。
那么如何才能使用 org-download ?
安装
首先自然是安装,对于 doom-emacs
用户来说,只要在 package.el
文件中加入下面一行:
(package! org-download)
或者在原生 emacs 中使用 use-package
:
(use-package org-download)
配置
首先先贴上我现在在用的配置:
;;; org-download
(require 'org-download)
(setq org-download-screenshot-method "flameshot gui --raw >%s")
; (setq org-download-method 'directory)
(setq-default org-download-heading-lvl nil)
(setq-default org-download-image-dir "./images")
(defun dummy-org-download-annotate-function (link)
"")
(setq org-download-annotate-function
#'dummy-org-download-annotate-function)
或者用 use-package
配置:
(use-package org-download
:config
(setq-default org-download-heading-lvl nil)
(setq-default org-download-image-dir "./images")
(setq org-download-backend "wget")
(setq org-download-abbreviate-filename-function (lambda (fn) fn)) ; use original filename
(defun dummy-org-download-annotate-function (link)
"")
(setq org-download-annotate-function
#'dummy-org-download-annotate-function)
)
上述代码配置生效之后,你就可以愉快地使用了:先从复制图片开始,你可以从网络上随便点开一个页面,右键复制,然后在 Org 文档中执行 Alt-x org-download-clipboard
,很快,你想要的图片就被插入到文档中了。
至此,不关心配置细节的用户已经可以放心关闭这个网页去享受了,而如果你非常在意上面的配置起了什么作用,那就请继续往下滑。
-
(setq org-download-screenshot-method "flameshot gui --raw >%s")
这一行指定了 org-download 在执行截图时会调用的系统命令,我使用的是 flameshot ,但其实无关紧要,因为你几乎不会通过 org-download 去截屏,那样也太麻烦了,更快捷的方式是直接用你喜欢的截屏工具截图,然后将图片复制,然后和上面的流程那样插入图片。所以这一行其实并非必须。如果有和我一样是使用 flameshot 的用户,那么写一下也没什么关系。 -
接下来是被注释掉的
;(setq org-download-method 'directory)
。上面的文章其实隐藏了 org-download 的一个细节,那就是如何保存图片。它默认有两种方式,一种是作为附件,另一种是基于普通的文件夹。基于附件的并不常用,而且使用起来也非常别扭,因此 org-download 默认将存储为普通文件。 -
下面两行则设定了图片具体的保存位置。 org-download 默认有个非常别扭的行为,就是将图片保存到所在 headline 为文件夹名称的目录下,通过
(setq-default org-download-heading-lvl nil)
可以屏蔽这个行为;而后面一行则非常直观地设定了要保存的文件夹名称。另外你可能会疑惑为什么之前用的都是setq
怎么到这里就变成setq-default
了呢?那是因为这两个变量有 buffer 作用域和全局作用域之分,这样的好处是可以针对每不同的文件设定图片的保存路径。但是我并不需要这种功能,因此我将其全局设定。 -
配置的最后我自定了一个
dummy-org-download-annotate-fuction
函数,以及将对应的变量指向到这个函数中。这个函数的作用是返回一个空的字符串。为什么我要这么做你可以试试将这几行注释掉,就会发现你粘贴的图片上方多了一行莫名其妙的注释,#+DOWNLOAD...
,不知道别人怎么想,我是不需要这个功能的,因此我用自定义函数覆盖了这个特性。具体的讨论可以见这里。
针对文件夹设定不同的存储路径
有时候你可能想将图片存在不同的地方。比如对于我来说, org 文件分为两类,一种是只给自己看的笔记,其中的图片统一存放在 ~/Documents/org/images/
目录下,这样方便管理;另一种则是 hugo 博客文章,这个时候就应该将图片存放在相对目录下的 ./images/
文件夹中。
这种情景可以利用 .dir-local 来实现。
在想要定制的目录下创建 .dir-locals.el
文件,比如 hugo 的 content/
目录,写入如下内容:
(dir-locals-set-class-variables 'org-download-hugo-directory
'((org-mode . ((org-download-image-dir . "./images")))))
(dir-locals-set-directory-class
"~/Documents/Blog/content/" 'org-download-hugo-directory)
第一次使用时会出现安全提醒,按 !
忽略之后就可以使用了,或者使用:
(setq enable-local-variables :safe)
忽略所有安全提醒。