org-export.el 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. ;;; org-export.el --- Export engine for Org
  2. ;;
  3. ;; Copyright 2008-2011 Free Software Foundation, Inc.
  4. ;;
  5. ;; Emacs Lisp Archive Entry
  6. ;; Filename: org-export.el
  7. ;; Version: 0.3
  8. ;; Author: Bastien <bzg AT altern DOT org>
  9. ;; Maintainer: Bastien <bzg AT altern DOT org>
  10. ;; Keywords:
  11. ;; Description:
  12. ;; URL: [Not distributed yet]
  13. ;;
  14. ;; This file is not part of GNU Emacs.
  15. ;;
  16. ;; This program is free software; you can redistribute it and/or modify
  17. ;; it under the terms of the GNU General Public License as published by
  18. ;; the Free Software Foundation; either version 3, or (at your option)
  19. ;; any later version.
  20. ;;
  21. ;; This program is distributed in the hope that it will be useful,
  22. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. ;; GNU General Public License for more details.
  25. ;;
  26. ;; You should have received a copy of the GNU General Public License
  27. ;; along with this program; if not, write to the Free Software
  28. ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  29. ;;
  30. ;;; Commentary:
  31. ;;
  32. ;; org-export.el implements a new experimental export engine for Org.
  33. ;;
  34. ;; Put this file into your load-path and the following into your ~/.emacs:
  35. ;; (require 'org-export)
  36. ;;
  37. ;;; Todo:
  38. ;;
  39. ;;; Code:
  40. (eval-when-compile
  41. (require 'cl))
  42. ;;; Preparation functions:
  43. ;; Currently needed for `org-export-preprocess-string'
  44. (require 'org-exp)
  45. (defvar org-export-structure nil)
  46. (defvar org-export-content nil)
  47. (defvar org-export-properties nil)
  48. (defun org-export-set-backend (suffix)
  49. "Set the backend functions names from SUFFIX."
  50. (setq org-export-structure
  51. `((header ,(intern (concat "org-" suffix "-export-header")))
  52. (first-lines ,(intern (concat "org-" suffix "-export-first-lines")))
  53. (section-beginning ,(intern (concat "org-" suffix "-export-section-beginning")))
  54. (heading ,(intern (concat "org-" suffix "-export-heading")))
  55. (section-end ,(intern (concat "org-" suffix "-export-section-end")))
  56. (footer ,(intern (concat "org-" suffix "-export-footer")))))
  57. (setq org-export-content
  58. `((fonts ,(intern (concat "org-" suffix "-export-fonts")))
  59. (links ,(intern (concat "org-" suffix "-export-links")))
  60. (lists ,(intern (concat "org-" suffix "-export-lists")))
  61. (envs ,(intern (concat "org-" suffix "-export-quote-verse-center")))
  62. (tables ,(intern (concat "org-" suffix "-export-tables"))))))
  63. ;;; Parsing functions:
  64. (defun org-export-parse (&optional level)
  65. "Recursively parse the current buffer.
  66. If LEVEL is set, do the parsing at that level of sectioning.
  67. Return a nested list containing the structure of the parsed
  68. buffer and information about each section, including its
  69. content."
  70. (let (output eos)
  71. (save-excursion
  72. (goto-char (point-min))
  73. (while (re-search-forward org-complex-heading-regexp nil t)
  74. (let ((heading (match-string 4))
  75. (properties (org-entry-properties)))
  76. (save-restriction
  77. (narrow-to-region (if (looking-at "\n") (1+ (point)) (point))
  78. (save-excursion
  79. (setq eos (org-end-of-subtree t t))))
  80. (setq output
  81. (append output
  82. (list
  83. (list :level (or level 1)
  84. :heading heading
  85. :properties properties
  86. :content (org-export-get-entry-content)
  87. :subtree (org-export-parse
  88. (if level (1+ level) 2)))))))
  89. (goto-char (1- eos)))))
  90. output))
  91. (defun org-export-get-entry-content ()
  92. "Extract the content of an entry.
  93. The content of a entry is the part before its first subtree or
  94. the end of the entry."
  95. (save-excursion
  96. (goto-char (point-min))
  97. ;; FIXME The following shouldn't be necessary since we are cleaning
  98. ;; up the buffer ith org-export-preprocess-string
  99. (while (or (looking-at org-property-drawer-re)
  100. (looking-at org-clock-drawer-re)
  101. (looking-at org-keyword-time-regexp))
  102. (move-beginning-of-line 1))
  103. (buffer-substring
  104. (point)
  105. (if (re-search-forward org-complex-heading-regexp nil t)
  106. (match-beginning 0) (point-max)))))
  107. ;;; Rendering functions:
  108. (defun org-export-render (&optional filter)
  109. "Render the current Org buffer and export it.
  110. First parse the buffer and return it as a nested list. If FILTER
  111. is set, use it to filter this list (see `org-export-filter') then
  112. export the (filtered) list with `org-export-render-structure'."
  113. (setq org-export-properties
  114. (org-combine-plists (org-default-export-plist)
  115. (org-infile-export-plist)))
  116. (let* (first-lines
  117. (bstring (buffer-string))
  118. (parsed-buffer
  119. (with-temp-buffer
  120. (org-mode)
  121. (insert (apply 'org-export-preprocess-string
  122. bstring org-export-properties))
  123. (goto-char (point-min))
  124. (setq first-lines (org-export-get-entry-content))
  125. (org-export-parse))))
  126. (switch-to-buffer (get-buffer-create "*Org export*"))
  127. (erase-buffer)
  128. (funcall (cadr (assoc 'header org-export-structure)))
  129. (funcall (cadr (assoc 'first-lines org-export-structure)) first-lines)
  130. (org-export-render-structure parsed-buffer filter)
  131. (funcall (cadr (assoc 'footer org-export-structure)))))
  132. (defun org-export-render-structure (parsed-buffer &optional filter)
  133. "Render PARSED-BUFFER.
  134. An optional argument FILTER specifies a filter to pass to the
  135. rendering engine."
  136. (mapc (lambda(s)
  137. (funcall (cadr (assoc 'section-beginning org-export-structure)) s)
  138. (funcall (cadr (assoc 'heading org-export-structure)) s)
  139. (insert (org-export-render-content s) "\n\n")
  140. (org-export-render-structure (plist-get s :subtree) filter)
  141. (funcall (cadr (assoc 'section-end org-export-structure)) s))
  142. (org-export-filter parsed-buffer filter)))
  143. (defun org-export-render-content (section)
  144. "Render SECTION.
  145. SECTION is either a string or a property list containing
  146. informations (including content) for a section."
  147. (with-temp-buffer
  148. (insert (if (listp section) (plist-get section :content) section))
  149. (mapc (lambda(e)
  150. (goto-char (point-min))
  151. (funcall (cadr (assoc e org-export-content))))
  152. '(fonts tables lists envs links))
  153. (buffer-string)))
  154. (defun org-export-filter (parsed-buffer filter)
  155. "Filter out PARSED-BUFFER with FILTER.
  156. PARSED-BUFFER is a nested list of sections and subsections, as
  157. produced by `org-export-parse'. FILTER is an alist of rules to
  158. apply to PARSED-BUFFER. For the syntax of a filter, please check
  159. the docstring of `org-export-latex-filter'."
  160. ;; FIXME where is org-export-latex-filter
  161. (delete
  162. nil
  163. (mapcar
  164. (lambda(s)
  165. (if (delete
  166. nil
  167. (mapcar
  168. (lambda(f)
  169. (let ((cnd (car f)) (re (cadr f)) prop-cnd)
  170. (or (and (eq cnd 'heading)
  171. (string-match re (plist-get s :heading)))
  172. (and (eq cnd 'content)
  173. (string-match re (plist-get s :content)))
  174. (and (setq prop-cnd
  175. (assoc cnd (plist-get s :properties)))
  176. (string-match re (cadr prop-cnd))))))
  177. filter))
  178. nil ;; return nil if the section is filtered out
  179. (progn (plist-put s :subtree
  180. (org-export-filter (plist-get s :subtree) filter))
  181. s))) ;; return the section if it isn't filtered out
  182. parsed-buffer)))
  183. (provide 'org-export)
  184. ;;; User Options, Variables
  185. ;;; org-export.el ends here