html - 如何在 Emacs 的 Org 模式下在 Source Block 的“#+RESULTS”预览输出周围添加“#+ATTR_HTML”?
问题描述
我在 org 中使用 Plantuml,效果很好。但是,我试图通过在#+RESULTS输出标记之前自动添加一些HTML 标记来进行一些更改,这样可以获得漂亮的HTML 输出效果。
我的示例代码如下:
#+BEGIN_SRC plantuml :file test.png
@startuml
package "Some Group" {
HTTP - [First Component]
[Another Component]
}
node "Other Groups" {
FTP - [Second Component]
[First Component] --> FTP
}
cloud {
[Example 1]
}
database "MySql" {
folder "This is my folder" {
[Folder 3]
}
frame "Foo" {
[Frame 4]
}
}
[Another Component] --> [Example 1]
[Example 1] --> [Folder 3]
[Folder 3] --> [Frame 4]
@enduml
#+END_SRC
在 Plantuml 的“Cc Cc”之后,您将在 plantuml 代码块下方得到以下输出:
#+RESULTS:
[[file:test.png]]
但是,我希望它自动附加上面的#+RESULT标记,如下所示,这将显示在 Emacs 中的 plantuml 源代码块下方:
#+ATTR_HTML: :width 80%
#+ATTR_ORG: :width 80%
#+ATTR_HTML: :style background-color: white; border-radius: 8px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
#+RESULTS:
[[file:test.png]]
然后,我可以通过“Cc Ce h o”将 org 文件输出为 HTML,得到一个漂亮的 HTML。
我怎样才能做到?
谢谢 !
解决方案
标准技术是为源块命名:
#+NAME: foo
#+BEGIN_SRC plantuml :file test.png
@startuml
...
#+END_SRC
当你评估代码块时,它会产生一个#+RESULTS:
像这样的标题:
#+RESULTS: foo
[[file:test.png]]
现在您可以#+ATTR_*
在结果之前添加声明:
#+ATTR_HTML: :width 80%
#+ATTR_ORG: :width
#+ATTR_HTML: :style background-color: white; border-radius: 8px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
#+RESULTS: foo
[[file:test.png]]
重新运行代码块会将文件链接放在同一个位置,并且不会留下任何#+ATTR-*
东西。然后,您可以导出并获得“漂亮的 HTML”!
编辑:以上内容的主要目的是避免在未命名块时所需的手动工作:在每次重新评估源代码后,您必须不断将属性声明移动到新生成的 #+RESULTS: 部分块(并清理旧结果)。从我的 POV 来看,这是令人讨厌的部分,并且块的命名很好地处理了它。
然后添加属性声明成为我不特别希望自动化的一次性任务,主要是因为不同块的属性必然不同,所以我为一个块所做的任何事情都必须完全改变另一个:我宁愿手动完成一次性任务。
也就是说,您可以部分自动化属性插入,例如通过创建一个函数来执行插入并将其绑定到一个键:
(defun insert-attr-decls ()
(interactive)
(insert "#+ATTR_HTML: :width 80%\n")
(insert "#+ATTR_ORG: :width 80%\n")
(insert "#+ATTR_HTML: :style background-color: white; border-radius: 8px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);\n"))
(define-key org-mode-map [f10] 'insert-attr-decls)
然后在第一次评估后,将点放在#+RESULTS: foo
生成的线之前,然后按F10
。从我的 POV 来看,这就是我要停下来的地方(如果我走了这么远)。
下一步将是搜索插入应该去的地方,然后调用上面的函数——虽然我确信它可以改进:
(defun insert-attr-decls ()
(insert "#+ATTR_HTML: :width 80%\n")
(insert "#+ATTR_ORG: :width 80%\n")
(insert "#+ATTR_HTML: :style background-color: white; border-radius: 8px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);\n"))
(defun insert-attr-decls-at (s)
(let ((case-fold-search t))
(if (search-forward s nil t)
(progn
(search-backward s nil t)
(insert-attr-decls)))))
(defun insert-attr-decls-at-results ()
(interactive)
(save-excursion
(insert-attr-decls-at "#+RESULTS:")))
(define-key org-mode-map [f10] 'insert-attr-decls-at-results)
这已经是复杂性的巨大飞跃,它可能包含错误:例如,如果#+RESULTS:
缓冲区中没有字符串会发生什么?我没有测试过。所以如果其他人愿意花时间制作一个“完美”的功能,那么是的,也许我会接受并使用它。但除非这将成为我的主要工作,否则我宁愿把时间花在其他地方:如果确实证明它确实是一个时间槽,你总是可以在以后自动化它。
下一步(我不会这样做)将C-c C-c
评估块并添加属性声明。您可以通过添加insert-attr-decls-at-results
到org-babel-after-execute-hook
变量来做到这一点:
(add-hook 'org-babel-after-execute-hook 'insert-attr-decls-at-results)
这里的问题是,在每次求值时,你都会多添加一个属性声明块:你真的必须重写插入函数来检查是否已经有一个属性声明块,如果有,什么也不做。这留作练习。
AFAIAC 故事的寓意是:您可以使所有事情自动化,但并非所有事情都值得自动化。
推荐阅读
- python-3.x - 无法在第二个 Tkinter 帧中显示图像标签
- node.js - 如果我有 CSRF,我需要 JWT 身份验证吗?
- python - 有没有办法将 Tkinter 与 Google Colaboratory 一起使用?
- bazel - 有没有办法向 Bazel 添加原生规则?
- vb.net - 如何从列表框中获取每个项目并将其存储到 VB.NET 中的多个文本框中
- flutter - 如何防止颤振应用程序在 Dio 错误后崩溃?
- r - 如果字符串包含子集
- java - 如何生成授权:使用 RestAPI 的承载令牌?
- html - 如何避免重复的 SVG 代码,但又没有 defs/symbol/use 引起的 shadow DOM 问题?
- c# - C# 查找符合特定条件的对象的属性