Define org mode macro with line breaks

泄露秘密 提交于 2020-01-01 08:19:10

问题


It is possible to define a macro in an org file as follow:

#+MACRO: macroname <here comes the body of the macro>

Is it possible to define a macro that contains line breaks? I.e., something like:

#+MACRO: macroname line 1 of macro
                   line 2 of macro

In particular, this macro will be expanded to

line 1 of macro
line 2 of macro

My motivation is to have a macro that expands to a block of text which contains, for instance, two paragraphs.


回答1:


Not only is this possible, it's quite easy to do. You just need to be creative about how you insert the newline. I make use of Org Babel to hack the macros. The following works for me:

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

So, given this document:

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

{{{macroname}}}

Exporting to Org mode gives the following

# 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

You just have to be aware that some export formats will transform that newline to a single line when it wraps the text. So, you probably want something like this to get two paragraphs:

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



回答2:


There is another solution which seems to work correctly. From org-macro.el source code:

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

Thus, you may define macro like this:

#+MACRO: newline (eval "\n")

Substitutions are also supported. The macro

#+MACRO: img (eval "#+CAPTION: $1\nfile:$2")

which is called as

{{{img(hello world!, ./img1.jpg)}}}

will be replaced with:

#+CAPTION: hello world!
file:./img1.jpg



回答3:


The best advice I can give you is: follow what's suggested by Nicolas Goaziou (i.e., don't use macros for your usage), and find another solution for which you're sure it'll work now and forever.

In this case, I'd either use YASnippets (if just an helper when typing) or Org Babel (if it needs to be customized after having written your document).




回答4:


Not possible with standard tools at the moment, as org-macro--collect-macros only looks at single line definitions.

Here's a work-around:

* 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}}}

This approach favors convention over customization, so each macro has to be a level 2 child of level 1 heading with name "Macros". No additional config necessary: a plain export should work.

The Setup heading should be copied to files where you want this to work. Or you can add the defadvice to your config to have this behavior everywhere.



来源:https://stackoverflow.com/questions/22132603/define-org-mode-macro-with-line-breaks

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!