我们编写的 org 文件有时候并不是在一个特定的项目中的,org-publish 系列的函数常常不满足需求。
因此我在 org-dispatch
的基础上,以一种相对简单清晰的方式,编写了一个能指定特定导出目录的 memacs/org-dispatch
:
(defvar memacs--org-export-directory (expand-file-name "~/Desktop"))
(defun memacs/org-export-dispatch (&optional arg)
"Change exported destination to the special path."
(interactive "P")
;; 选择导出文件夹目录
(let ((dest (read-directory-name "Export to Directory: "
nil default-directory nil)))
(setq memacs--org-export-directory dest)
(org-export-dispatch))
)
;; 一个在 org-add-export-dir 执行前的切面
(defadvice org-export-output-file-name (before org-add-export-dir activate)
"Modifies org-export to place exported files in a different directory"
(when (not pub-dir)
(setq pub-dir memacs--org-export-directory)
(when (not (file-directory-p pub-dir))
(make-directory pub-dir))))
虽然以上代码能将 html 导出到指定目录,但是 org 文件中的图片链接不会被修改,因此导出的 html 文件都无法正确显示图片。
我的解决方式是:创建一个自己的 link type ,自定义它的导出函数。 以下是代码:
;; 链接点击事件
(defun memacs-img--custom-link-img-follow (path)
"Click event of custom link img."
(org-open-file-with-emacs path))
;; 根据链接里的路径求算出绝对路径,并将图片文件拷贝到导出目录的 statics 文件夹下面
;; 返回新的相对地址
(defun memacs-img//copy-to-destination-statics-dir (path desc format)
"A aspect for copy src file to statics dir in destination."
(let ((uri-slices (split-string path "/"))
(abs-path (expand-file-name path))
(statics-dir (concat memacs--org-export-directory "statics/")))
(if (not (file-exists-p abs-path))
;; return nil if image does not exist
nil
;; modify url and copy image file if image exists
(unless (file-exists-p statics-dir)
(make-directory statics-dir))
(let ((dest (concat statics-dir (nth (- (length uri-slices) 1) uri-slices)))
(relative-path (concat "./statics/" (nth (- (length uri-slices) 1) uri-slices))))
(unless (file-exists-p dest)
(copy-file abs-path dest))
relative-path)))
)
;; 修改链接为网络资源地址,该导出函数用于我的blog发布
(defun memacs-img//export-to-Internet (path desc format)
"A aspect for change path to url in the internet."
(let ((index (string-match "statics/" path)))
(if (not index)
;; index is nil
(concat custom-link-img-export-host "/statics/not_found.png")
;; index is the offset of "statics/"
(concat custom-link-img-export-host "/" (substring path index))
)
)
)
;; 设置默认导出函数
(setq memacs-img/before-export-aspect #'memacs-img//copy-to-destination-statics-dir)
(defun memacs-img--custom-link-img-export (path desc format)
"export event of custom link img."
;; concat custom img host and final two section of the path
(let ((url (funcall memacs-img/before-export-aspect path desc format)))
(cond
((eq format 'html)
(format "<img src=\"%s\" alt=\"%s\"/>" (url-encode-url url) desc))
((eq format 'md)
(format "![%s](%s)" desc (url-encode-url url)))
)
)
)
;;;; Init
;; 自定义link类型
(defun memacs-img--link-init ()
"Add link type 'img'."
(org-add-link-type "img" 'memacs-img--custom-link-img-follow 'memacs-img--custom-link-img-export)
(message "Add Custom Link 'img'.")
)
(memacs-img--link-init)
当然,这个方案兼容性不好,本身指定义 link 类型就与其他人的 org-mode 不兼容了,buffer中显示图片、 org-download
配置 都需要一定修改。后者比较简单,前者有点糟糕:
我的思路是在仿照 org-toggle-inline-images
提供一套自定义的 , 不是很优雅,不再赘述,有兴趣的可以看源码 memacs-org-ext
欢迎各位探讨学习。