emacs-使用pandoc导出当前org-buffer为docx
1. 合法化化buffer名
Windows下,如果直接使用buffer名作为文件名,有时会有非法字符,需要清理。
(defun my/sanitize-windows-filename (filename)
"Sanitize FILENAME to be a valid Windows filename."
;; Replace invalid characters with an underscore
(replace-regexp-in-string "[<>:\\\"\/\|\?\*]+" "_" filename))
2. 将当前buffer内容放至TEMP文件夹内某文件并返回路径
(defun seq-replacer (input)
(dolist (pair input)
(goto-char (point-min))
(while (re-search-forward (car pair) nil t)
(replace-match (cadr pair)))))
(defun my/pandoc-line-breaker ()
"pandoc格式化"
(interactive)
(seq-replacer '(("\n\n*" "\n")
("\n" "\n\n")
)))
(defun my/save-buffer-to-temp-org ()
"Save the current buffer content to a file in the system's temporary directory.
The file name will be the same as the buffer name, but with a '.org' extension.
Return the path of the saved file."
(interactive)
(let* ((buffer-name (buffer-name))
(file-name (concat (my/sanitize-windows-filename buffer-name) ".org"))
(temp-dir (if (eq system-type 'windows-nt)
(expand-file-name (getenv "TEMP"))
(expand-file-name (getenv "TMPDIR"))))
(full-path (expand-file-name file-name temp-dir)))
;; Write buffer content to the file
;; (write-region (point-min) (point-max) full-path)
(with-temp-file full-path
(insert-buffer-substring buffer-name)
(my/pandoc-line-breaker))
;; Return the full path of the file
full-path))
这里用 getenv
做了一个不同系统兼容。Windows的临时文件为 TEMP
,而MacOS的临时文件为 TMPDIR
。
由于pandoc需要两个换行符才会转换为一个分段,故通过 my/pandoc-line-breaker
函数调节生成的临时文件,以确保换行正确。
3. 利用pandoc转换临时文件并保存到桌面
(defun my/org-buffer-export-docx ()
(interactive)
(let ((docx-file (concat (getenv "UserProfile") "\\desktop\\" (my/sanitize-windows-filename (buffer-name)) ".docx"))
(template-file (concat (file-truename "~/.emacs.d/org") "/template.docx")))
(shell-command (format "pandoc %s --from org+east_asian_line_breaks -o %s --reference-doc=%s" (my/save-buffer-to-temp-org) docx-file template-file))
(message "Convert finish: %s" docx-file)))
docx-file
指定保存路径为桌面;
template-file
是pandoc转换docx文件参考的模板,具体设置请查看pandoc官方文档;
这里的 --from org+east_asian_line_breaks
意味启用东亚换行设置,东亚文字间的换行不会被转换为空格,参考这篇博客的解说。