4

I would like to use org-publish to generate files for a website. I would prefer to do this using the ox-pandoc exporter rather than org-mode's own publishing exporters. But I can't quite seem to see how this is done.

The org-publish function requires a function (plist filename pub-dir) format

 (defun org-pandoc-publish-to-html (plist filename pub-dir)
 "Publish an org file to html using ox-pandoc. Return output file name."
 (org-publish-org-to 'org-pandoc-export-to-html filename ".html" plist pub-dir))

Not sure what's wrong with the above, but it doesn't work. Specifically, with :publishing-function (org-pandoc-publish-to-html) set I get the message: unknown "nil" back-end: Aborting export with no output.

Update: when I change the setting to :publishing-function (org-pandoc-export-to-html) I get a different message:

Publishing file /Users/Roambot/test/source/pubtest.org using `org-pandoc-export-to-html'
Initializing asynchronous export process
Publishing file /Users/Roambot/test/source/pubtest.org using `org-pandoc-export-to-html'
Process `org-export-process' exited abnormally

The Org Export Process buffer reads: Before first headline at position 1 in buffer *temp*. I'm not sure what this means.

Again, publishing works fine for other export functions like org-html-publish-to-html and ox-pandoc works independently of org-publish.

  • 1
    I'm using pandoc 1.17.0.2 (installed via the binary on OS X El Capitan) and ox-pandoc 1.151223 (installed via elpa). I should also say that ox-pandoc works perfectly for normal export. I just don't understand how to call it as a back-end for org-publish. – mclear May 24 '16 at 14:32
  • It would be nice if you could test whether my approach works for you. – Tobias Apr 24 at 9:46
2
+50

You misinterpreted the meaning of the first argument of org-publish-org-to. It is the export backend and not a function. Because of the special structure of the pandoc backend replacing org-pandoc-export-to-html with 'pandoc does not work. If you do that you only get the filtered org stuff in your output files. The final translation to html is missing. (That is quite reasonable since nothing tells Pandoc to export to HTML.)

Your second approach of using org-pandoc-export-to-html5 as publishing function does also not work since that function does not takes the optional arguments ASYNC SUBTREEP VISIBLE-ONLY BODY-ONLY and EXT-PLIST of org-export-to-file and not the required arguments PLIST FILENAME PUB-DIR for a publishing function.

I propose to define your own Org export backend that inherits most of its stuff from the pandoc backend. Only the final filter converts the Org stuff into HTML stuff via Pandoc.

In your project you can use the publishing function org-pandoc-publish-to-html as defined below. It calls org-publish-org-to with the specialized backend pandoc-html5.

(defun org-pandoc-html5-filter (contents _backend _info)
  "Convert Org CONTENTS into html5 output."
  (let ((backup-inhibited t)
    contents-filename
    process
    buffer)
    (unwind-protect
    ;; org-pandoc runs pandoc asynchronous.  We need to
    ;; synchronize pandoc for filtering.  `org-pandoc-run' returns
    ;; the process needed for synchronization.  Pityingly we need
    ;; to call `org-pandoc-run-to-buffer-or-file' which handles
    ;; additional options and special hooks.  Therefore we
    ;; temporarily advice `org-pandoc-run' to give us the process.
    (cl-letf* ((original-org-pandoc-run (symbol-function 'org-pandoc-run))
           ((symbol-function 'org-pandoc-run) (lambda (&rest a)
                            (setq process (apply original-org-pandoc-run a)))))
      (setq contents-filename (make-temp-file ".tmp" nil ".org" contents))
      (org-pandoc-run-to-buffer-or-file
       contents-filename
       'html5
       nil ;; not only the sub-tree
       t) ;; buffer
      (while (process-live-p process)
        (sit-for 0.5))
      (with-current-buffer (setq buffer (process-buffer process))
        (buffer-string)))
      (when (file-exists-p contents-filename)
    (delete-file contents-filename))
      (when (buffer-live-p buffer)
    (kill-buffer buffer))
      )))

(org-export-define-derived-backend
    'pandoc-html5
    'pandoc
  :filters-alist '((:filter-final-output . org-pandoc-html5-filter)))

(defun org-pandoc-publish-to-html (plist filename pub-dir)
  "Publish an org file to html using ox-pandoc. Return output file name."
  (let ((org-pandoc-format "html5"))
    (org-publish-org-to
     'pandoc-html5
     filename
     (concat "." (or (plist-get plist :html-extension)
             org-html-extension
             "html"))
     plist
     pub-dir)))
  • thanks - this seems to work well, though since I've asked the question I've moved on to another note system. Thanks for the explanation of the lisp though! – mclear Apr 24 at 16:41
  • @mclear Sounds sad. Could you please explain which note system you moved to and for what reason? (Just curious. I will not start a discussion on that.) – Tobias Apr 24 at 16:44
  • 1
    ha - not so sad really. I use ox-hugo, which also has a pandoc option for conversion. – mclear Apr 25 at 1:36
  • @mclear Thx for the info. Never heard of hugo. Looks promising.Maybe I try it someday. – Tobias Apr 25 at 3:32

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.