请教如何禁止 plantuml 多次执行


#1

我需要在 org files 里插入一些 plantuml 画 UML 。写好之后,如果多次 export 到 html ,则 plantuml 每次都会被执行一次,即使两次 export 之间并没有修改 plantuml 代码,而且, plantuml 执行太慢了。

我想到将 plantuml 代码写到单独的一个 org 文件里,然后 #+INCLUDE 进来,但是发布的时候仍然每次都要执行 plantuml 。

在我配置 emacs ,使得每次执行 C-x C-s (save-buffer) 都执行 export 之后,这个问题就更恼人了。 请问大家有没有好方法,要么不 export 被 include 的文件,要么有什么属性值,使得设置后 plantuml code block 不被 babel 执行?


#2

哈,刚在本站搜索了一下 plantuml ,在这里找到了解决方法:plantuml 代码块无法执行 添加 :noeval 即可。感谢 et2010


#3

你还可以写一个Makefile


#4

但是我不知道如何关联 org 中的 plantuml 代码和 plantuml 生成的 png 图片。比如第一次发布生成了 png 图片,但是后来我又修改了 plantuml 代码,怎么才能让 org 执行这段代码重新生成图片呢? 如果只是检测 org 文件变化了就重新生成图片,那么 org 文件里有多个 plantuml 代码片段,都要重新生成一次,还是慢。

虽然总得修改 :noeval ,但是我还算能接受。也许可以写一点 elisp 代码可以让这个过程更简便一点。


#5

如果写成多个 org 文件,就如同#4 楼所说,用 Makefile,只“编译”发生变化的文件。

如果是单个 org 文件,就得想办法来实现类似 Makefile 的效果。

我会采取这种方案:

;; 伪代码
(defun org-babel-execute-buffer-maybe (&optional arg)
  ;;  file: foo.org             dir: .foo.org
  ;; +--------------+          +--------------+
  ;; |   #block-1   |  ---->   | cache-file-1 |
  ;; |   #blcok-2   |  ---->   | cache-file-2 |
  ;; |   ...        |          | ...          |
  ;; |   #block-n   |  ---->   | cache-file-3 |
  ;; +--------------+          +--------------+
  (while (org-next-block)
    (let* ((block-name (get-name-of-current-block))
           (block-code (get-code-of-current-block))
           (cache-code (get-code-from-cache-file block-name)))
      (unless (string= block-code cache-code)
        (org-execute-current-block)
        (update-cache-file block-name block-code)))))

#6

谢谢! 我找时间试一试。