org: Advanced configuration

 
 12.15 Advanced configuration
 ============================
 
 Hooks
 -----
 
 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."
        (org-map-entries
         (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
 -------
 
 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 filters 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:
 
 bold                     babel-call               center-block
 clock                    code                     comment
 comment-block            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
 quote-section            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
                   'my-latex-filter-nobreaks)
 
    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’).
 
 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
      channel."
        (if (not (org-export-read-attribute :attr_ascii src-block :language))
          (org-export-with-backend 'ascii src-block contents info)
        (concat
         (format ",--[ %s ]--\n%s`----"
                 (org-element-property :language src-block)
                 (replace-regexp-in-string
                  "^" "| "
                  (org-element-normalize-string
                   (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.