[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [O] Tutorial to create a new exporter ?
From: |
Robert Klein |
Subject: |
Re: [O] Tutorial to create a new exporter ? |
Date: |
Mon, 08 Jun 2015 18:06:07 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 |
Hi,
I once tried to write a tutorial for creating a derived backend, but
didn't find the time to finish it. I put the material so far below.
When I began writing my ox-blog exporter (github.com/roklein/ox-blog) I
think I began with the s5 exporter in org's source contrib/lisp/ox-s5.el.
If you need to export to a format an existing exporter already provides
(at least in part) you will want to create a derived exporter (using the
`org-export-define-derived-backend'). For a totally new format (e.g.
rtf) you' want to write an independent exporter using
`org-export-define-backend'.
Comprehensive documentation for both functions is provided in the source
code (lisp/ox.el)
The non-derived exporters for html and latex (lisp/ox-html.el and
lisp/ox-latex.el) are also very good as examples.
Best regards
Robert
* Minimal derived exporter
A minimal derived exporter providing capabilities of the HTML
exporter.
Please compare the code to the =org-export-define-backend= call in
=org-mode/lisp/ox-html.el=. The =:menu-entry= part is very similar,
in fact I copied the code for the menu entries from the =:menu-entry=
line downward omitting the =?h= and =?o= entries. The other change is
the key =2= instead of =h= for the original HTML exporter.
#+begin_src emacs-lisp :tangle ox-html-2.el
(require 'ox-html)
(org-export-define-derived-backend
'html-2 'html
:menu-entry
'(?2 "Export w/ minimal derived HTML"
((?H "To temporary buffer" org-html-export-as-html))))
(provide 'ox-html-2)
#+end_src
The derived back-end in the example calls the same exporting function
as the HTML back-end does for exporting to a temporary buffer,
=org-html-export-as-html=.
The minimal derived exporter is a new name and a menu entry for
calling the new exporter.
This exporter offers nothing the HTML exporter doesn't.
In the next example we will “write” an exporting function of our own
--- well, copy, rename, and adapt the =org-html-export-as-html=
function from =org-mode/lisp/ox-html.el=.
* Defining export for an org-mode element
In this example we will look at a derived backend which produces the
content of a weblog post in a temporary buffer.
Blogs at e.g. wordpress.com allow syntax highliging using the Syntax
Highlighter written by Alex Gorbatchev.
Our derived exporter will create the text of the blog post and source
code blocks will be marked up for Syntax Highlighter instead of
org-mode's internal mark-up.
You will have to copy the export in the temporary buffer and paste it
into the wordpress blog editor, though.[fn:: We will come back to
weblog exporting again, later. You might want to write a derived
exporter in this style for something you need every one in a while,
where you don't mind a bit of additional effort. For daily tasks you
will want something more elaborate. In web log exporting this would
include the exporter posting to the weblog.]
** Defining the derived backend.
At first we define the backend again. In comparison to the html-2
backend above the options to export to file and export to file and
open are removed.
In addition we have one entry in the =:translate-alist=: for exporting
source blocks the function =wp-dot-com-src-block= will be used.
#+begin_src emacs-lisp :tangle wp-dot-com-buffer.el
(require 'ox-html)
(org-export-define-derived-backend
'wp-dot-com-buffer 'html
:menu-entry
'(?3 "Export w/ minimal derived HTML"
((?H "To temporary buffer" org-wp-dot-com-export-as-html)))
:translate-alist
'((src-block . wp-dot-com-src-block)))
#+end_src
** language identifier mapping
The Syntax Highlighter uses sometimes other language identifiers for
source blocks than org-mode. For example, where org-mode uses =sh=,
Syntax Highlighter uses =bash=.
We're putting the mappings in an alist for later use.
#+begin_src emacs-lisp :tangle wp-dot-com-buffer.el
(defconst wp-dot-com-language-terms
'(("R" . "r")
("emacs-lisp" . "lisp")
("elisp" . "lisp")
("sh" . "bash")))
; (cdr (assoc "sh" wp-dot-com-language-terms))
; (cdr (assoc (org-element-property :language src-block)
wp-dot-com-language-terms)
#+end_src
** exporting source code blocks
The source code exporting function, =wp-dot-com-src-block=, is
modelled on =org-html-src-block= in =org-mode/lisp/ox-html.el=.
To keep things simple, the caption and label code is deleted. The
language identifier is mapped using the mapping defined in the alist
above. The HTML-formatting of the source code is removed, instead of
=org-html-format-code= we use =org-export-unravel-code=. At last the
=pre= formatting in angles is changed to =code= in brackets.
#+begin_src emacs-lisp :tangle wp-dot-com-buffer.el
(defun wp-dot-com-src-block (src-block contents info)
"Transcode a SRC-BLOCK element from Org to HTML.
CONTENTS holds the contents of the item. INFO is a plist holding
contextual information."
(if (org-export-read-attribute :attr_html src-block :textarea)
(org-html--textarea-block src-block)
(let ((language-term
(or (cdr (assoc (org-element-property :language src-block)
wp-dot-com-language-terms))
(org-element-property :language src-block)))
(code (car (org-export-unravel-code src-block))))
(if (not language-term) (format "<pre
class=\"example\"%s>\n%s</pre>" label code)
(format
"<div class=\"org-src-container\">\n%s\n</div>"
(format "\n[code lang=\"%s\"]%s[/code]" language-term code))))))
#+end_src
** export function for the derived backend
At the end of this example we define the export function
=org-wp-dot-com-export-as-html=.
- mostly a copy of org-html-export-as-html
- instead of passing 'body-only to org-export-as pass t, as we only
need the body for the web log
#+begin_src emacs-lisp :tangle wp-dot-com-buffer.el
(defun org-wp-dot-com-export-as-html
(&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to an HTML buffer.
If narrowing is active in the current buffer, only export its
narrowed part.
If a region is active, export that region.
A non-nil optional argument ASYNC means the process should happen
asynchronously. The resulting buffer should be accessible
through the `org-export-stack' interface.
When optional argument SUBTREEP is non-nil, export the sub-tree
at point, extracting information from the headline properties
first.
When optional argument VISIBLE-ONLY is non-nil, don't export
contents of hidden elements.
When optional argument BODY-ONLY is non-nil, only write code
between \"<body>\" and \"</body>\" tags.
EXT-PLIST, when provided, is a property list with external
parameters overriding Org default settings, but still inferior to
file-local settings.
Export is done in a buffer named \"*Org HTML Export*\", which
will be displayed when `org-export-show-temporary-export-buffer'
is non-nil."
(interactive)
(if async
(org-export-async-start
(lambda (output)
(with-current-buffer (get-buffer-create "*Org HTML Export*")
(erase-buffer)
(insert output)
(goto-char (point-min))
(set-auto-mode t)
(org-export-add-to-stack (current-buffer)
'wp-dot-com-buffer)))
`(org-export-as 'wp-dot-com-buffer ,subtreep ,visible-only ,t
',ext-plist))
(let ((outbuf (org-export-to-buffer
'wp-dot-com-buffer "*Org HTML Export*"
subtreep visible-only body-only ext-plist)))
;; Set major mode.
(with-current-buffer outbuf (set-auto-mode t))
(when org-export-show-temporary-export-buffer
(switch-to-buffer-other-window outbuf)))))
(provide 'ox-wp-dot-com-buffer)
#+end_src
* Using our own attributes
#+BEGIN_EXAMPLE
#+ATTR_MYEXPORTER
#+END_EXAMPLE
#+begin_src elisp
(org-export-read-attribute :attr_myexporter :background)
#+end_src
On 06/08/2015 12:33 PM, Xavier wrote:
> Hello,
>
> I am tracking my running workouts in a orgmode managed file. I'd like to
> export these entries to an online service (dailymile).
> I am looking for a good starter kit to create this exporter. Do you have
> something ?
>
> Regards
>