This is the official manual for the latest Org-mode release.

Table of Contents

Next: , Previous: Other built-in back-ends, Up: Exporting

12.17 Advanced configuration


Two hooks are run during the first steps of the export process. The first one, org-export-before-processing-hook is called before expanding macros, Babel code and include keywords in the buffer. The second one, org-export-before-parsing-hook, as its name suggests, happens just before parsing the buffer. Their main use is for heavy duties, that is duties involving structural modifications of the document. For example, one may want to remove every headline in the buffer during export. The following code can achieve this:

     (defun my-headline-removal (backend)
       "Remove all headlines in the current buffer.
     BACKEND is the export back-end being used, as a symbol."
        (lambda () (delete-region (point) (progn (forward-line) (point))))))
     (add-hook 'org-export-before-parsing-hook 'my-headline-removal)

Note that functions used in these hooks require a mandatory argument, a symbol representing the back-end used.


Filters are lists of functions applied on a specific part of the output from a given back-end. More explicitly, each time a back-end transforms an Org object or element into another language, all functions within a given filter type are called in turn on the string produced. The string returned by the last function will be the one used in the final output.

There are filter sets for each type of element or object, for plain text, for the parse tree, for the export options and for the final output. They are all named after the same scheme: org-export-filter-TYPE-functions, where TYPE is the type targeted by the filter. Valid types are:

body bold babel-call
center-block clock code
diary-sexp drawer dynamic-block
entity example-block export-block
export-snippet final-output fixed-width
footnote-definition footnote-reference headline
horizontal-rule inline-babel-call inline-src-block
inlinetask italic item
keyword latex-environment latex-fragment
line-break link node-property
options paragraph parse-tree
plain-list plain-text planning
property-drawer quote-block radio-target
section special-block src-block
statistics-cookie strike-through subscript
superscript table table-cell
table-row target timestamp
underline verbatim verse-block

For example, the following snippet allows me to use non-breaking spaces in the Org buffer and get them translated into LaTeX without using the \nbsp macro (where _ stands for the non-breaking space):

     (defun my-latex-filter-nobreaks (text backend info)
       "Ensure \"_\" are properly handled in LaTeX export."
       (when (org-export-derived-backend-p backend 'latex)
             (replace-regexp-in-string "_" "~" text)))
     (add-to-list 'org-export-filter-plain-text-functions

Three arguments must be provided to a filter: the code being changed, the back-end used, and some information about the export process. You can safely ignore the third argument for most purposes. Note the use of org-export-derived-backend-p, which ensures that the filter will only be applied when using latex back-end or any other back-end derived from it (e.g., beamer).

Defining filters for individual files

You can customize the export for just a specific file by binding export filter variables using #+BIND. Here is an example where we introduce two filters, one to remove brackets from time stamps, and one to entirely remove any strike-through text. The functions doing the filtering are defined in an src block that allows the filter function definitions to exist in the file itself and ensures that the functions will be there when needed.

     #+BIND: org-export-filter-timestamp-functions (tmp-f-timestamp)
     #+BIND: org-export-filter-strike-through-functions (tmp-f-strike-through)
     #+begin_src emacs-lisp :exports results :results none
       (defun tmp-f-timestamp (s backend info)
         (replace-regexp-in-string "&[lg]t;\\|[][]" "" s))
       (defun tmp-f-strike-through (s backend info) "")

Extending an existing back-end

This is obviously the most powerful customization, since the changes happen at the parser level. Indeed, some export back-ends are built as extensions of other ones (e.g., Markdown back-end an extension of HTML back-end).

Extending a back-end means that if an element type is not transcoded by the new back-end, it will be handled by the original one. Hence you can extend specific parts of a back-end without too much work.

As an example, imagine we want the ascii back-end to display the language used in a source block, when it is available, but only when some attribute is non-nil, like the following:

     #+ATTR_ASCII: :language t

Because that back-end is lacking in that area, we are going to create a new back-end, my-ascii that will do the job.

     (defun my-ascii-src-block (src-block contents info)
       "Transcode a SRC-BLOCK element from Org to ASCII.
     CONTENTS is nil.  INFO is a plist used as a communication
       (if (not (org-export-read-attribute :attr_ascii src-block :language))
         (org-export-with-backend 'ascii src-block contents info)
        (format ",--[ %s ]--\n%s`----"
                (org-element-property :language src-block)
                 "^" "| "
                  (org-export-format-code-default src-block info)))))))
     (org-export-define-derived-backend 'my-ascii 'ascii
       :translate-alist '((src-block . my-ascii-src-block)))

The my-ascii-src-block function looks at the attribute above the element. If it isn't true, it gives hand to the ascii back-end. Otherwise, it creates a box around the code, leaving room for the language. A new back-end is then created. It only changes its behavior when translating src-block type element. Now, all it takes to use the new back-end is calling the following from an Org buffer:

     (org-export-to-buffer 'my-ascii "*Org MY-ASCII Export*")

It is obviously possible to write an interactive function for this, install it in the export dispatcher menu, and so on.