In an elisp program, I am trying to convert strings from org syntax to (say) html. For that, I use org-html-convert-region-to-html with a temporary buffer, and everything is fine:

(defun tv/org-string-to-html (string &optional macros)
  (if (or (not string) (string-empty-p string)) ""
      (insert string)
      (set-mark (point-min))
      (goto-char (point-max))
      (when macros (setq org-macro-templates macros)) ;; not working
       (buffer-substring-no-properties (point-min) (point-max))
       4 -5))))

;; ELISP> (tv/org-string-to-html "This is [[file:test][a link]], this is *bold*, and this is /italic/")
;; "This is <a href=\"test\">a link</a>, this is <b>bold</b>, and this is <i>italic</i>"

However, it does not work if the string I am trying to convert has a macro, because my temporary buffer does not know about this macro.

I have tried to pass the content of the org-macro-templates variable to my converter function in the function above, but it doesn't appear to work, the macro is still not recognized.

Examining org-macro-expand with edebug, it appears that the macro templates are overwritten by org -- which makes sense. And the org-macro-templates variable does warn not to set it directly, but to use #+MACRO: lines instead.

Now, the obvious solution would be to collect all the macros in the org buffer and insert them in the temporary buffer, or to simply use the current org buffer instead of a temporary buffer. Neither option is really nice...

Is there a proper way to achieve what I want?


I don't know if this is proper, but here is a version that seems close. The idea is to use a copy of the buffer to insert it, and convert it to html. There result seems to get wrapped in <p></p>, but maybe you can use a substring to get rid of these.

(defun tv/org-string-to-html (string &optional macros)
  (if (or (not string) (string-empty-p string)) ""
     (let ((start (goto-char (point-max))))
       (insert string)
       (narrow-to-region start (point-max))
       (with-current-buffer (org-html-export-as-html nil nil t t)
  • Thanks. The <p></p> are a problem I had already, hence the substring in my function above. This appears to work on a simple example, but not on the full size file: it fails with "invalid number of arguments" apparently referring to the whole body of the defun, and the "HTML export" buffer contains something which has nothing to do with my string. I guess that expanding other macros and includes in the buffer messes up the end? My strings are short enough that it's probably safe to insert at the beginning, I will play around and see what I can do. – T. Verron Oct 29 '19 at 13:11
  • The indentation of the last line is suspicious, did you intend the (buffer-string) to be in the with-current-buffer? – T. Verron Oct 29 '19 at 13:12
  • yes it should be within with-current-buffer, because you want the contents of the buffer that (org-html-export-as-html nil nil t t) outputs. I am not sure what would cause it to fail, it works for me with other macros around. – John Kitchin Oct 29 '19 at 16:34
  • Okay, so after a restart it's working. One of the problem I had was context (the current buffer was not what I thinked it was, at the time of calling), but the "invalid number of arguments" thing will probably forever be a mystery. – T. Verron Nov 4 '19 at 10:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.