使用换行符定义组织模式宏

Dro*_*ror 15 org-mode

可以在文件中定义宏,org如下所示:

#+MACRO: macroname <here comes the body of the macro>
Run Code Online (Sandbox Code Playgroud)

是否可以定义包含换行符的宏?即,类似于:

#+MACRO: macroname line 1 of macro
                   line 2 of macro
Run Code Online (Sandbox Code Playgroud)

特别是,这个宏将扩展到

line 1 of macro
line 2 of macro
Run Code Online (Sandbox Code Playgroud)

我的动机是将一个宏扩展为一个文本块,其中包含两个段落.

ema*_*ftw 10

这不仅可行,而且很容易做到.您只需要了解如何插入换行符.我利用Org Babel来破解宏.以下适用于我:

#+MACRO: newline   src_emacs-lisp[:results raw]{"\n"}
#+MACRO: macroname line 1 of macro {{{newline}}}line 2 of macro
Run Code Online (Sandbox Code Playgroud)

所以,鉴于此文件:

#+MACRO: newline    src_emacs-lisp[:results raw]{"\n"}
#+MACRO: macroname line 1 of macro {{{newline}}}line 2 of macro

{{{macroname}}}
Run Code Online (Sandbox Code Playgroud)

导出到组织模式提供以下内容

# Created 2015-11-03 Tue 15:27
#+TITLE: 
#+AUTHOR:
#+MACRO: newline    src_emacs-lisp[:results raw]{"\n"}
#+MACRO: macroname line 1 of macro {{{newline}}}line 2 of macro

line 1 of macro 
line 2 of macro
Run Code Online (Sandbox Code Playgroud)

您只需要知道一些导出格式在包装文本时将该换行符转换为单行.所以,你可能想要这样的东西得到两个段落:

#+MACRO: newline   src_emacs-lisp[:results raw]{"\n"}
#+MACRO: macroname line 1 of macro {{{newline}}} {{{newline}}}line 2 of macro
Run Code Online (Sandbox Code Playgroud)


小智 5

还有另一种似乎正常工作的解决方案.来自org-macro.el源代码:

;; VALUE starts with "(eval": it is a s-exp, `eval' it.
        (when (string-match "\\`(eval\\>" value)
          (setq value (eval (read value))))
Run Code Online (Sandbox Code Playgroud)

因此,您可以像这样定义宏:

#+MACRO: newline (eval "\n")
Run Code Online (Sandbox Code Playgroud)

也支持替代.宏

#+MACRO: img (eval "#+CAPTION: $1\nfile:$2")
Run Code Online (Sandbox Code Playgroud)

被称为

{{{img(hello world!, ./img1.jpg)}}}
Run Code Online (Sandbox Code Playgroud)

将被替换为:

#+CAPTION: hello world!
file:./img1.jpg
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这不再起作用,因为参数现在被替换为 sexps。这意味着 $1 将被替换为“arg”(包括引号)。你的建议可以改为`#+MACRO: img (eval (format "#+CAPTION: %1$s\nfile:%2$s" $1 $2))`。 (2认同)

abo*_*abo 3

目前使用标准工具是不可能的,因为 org-macro--collect-macros只能查看单行定义。

这是一个解决方法:

* Setup                                                                               :noexport:
#+begin_src elisp :exports results :results silent
(setq my-macros
      (mapcar
       (lambda (x)
         (string-match "\\*\\* \\([^\n]+\\)\n\\(.*\\)" x)
         (cons (match-string 1 x)
               (substring x (match-beginning 2))))
       (org-element-map (org-element-parse-buffer) 'headline
         (lambda (x)
           (and (= (org-element-property :level x) 2)
                (string=
                 (org-element-property
                  :raw-value
                  (org-element-property :parent x)) "Macros")
                (buffer-substring-no-properties
                 (org-element-property :begin x)
                 (org-element-property :end x)))))
       headings))

(defadvice org-macro--collect-macros (around add-macros activate)
  (let ((r ad-do-it))
    (setq ad-return-value
          (append my-macros r))))
#+end_src
* Macros
** foobar
line 1 of macro

line 2 of macro

** bar
line 1 of macro

line 2 of macro
line 3 of macro
* Test
{{{foobar}}}

{{{bar}}}
Run Code Online (Sandbox Code Playgroud)

这种方法有利于约定而不是自定义,因此每个宏都必须是名称为“Macros”的 1 级标题的 2 级子级。不需要额外的配置:简单的导出应该可以工作。

应将安装标题复制到您希望其工作的文件中。或者您可以将其添加defadvice到您的配置中,以便在任何地方都具有此行为。