org-export.el 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. ;;; org-export.el --- Export engine for Org
  2. ;;
  3. ;; Copyright 2008 Bastien Guerry
  4. ;;
  5. ;; Emacs Lisp Archive Entry
  6. ;; Filename: org-export.el
  7. ;; Version: 0.1a
  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 program is free software; you can redistribute it and/or modify
  15. ;; it under the terms of the GNU General Public License as published by
  16. ;; the Free Software Foundation; either version 3, or (at your option)
  17. ;; any later version.
  18. ;;
  19. ;; This program is distributed in the hope that it will be useful,
  20. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. ;; GNU General Public License for more details.
  23. ;;
  24. ;; You should have received a copy of the GNU General Public License
  25. ;; along with this program; if not, write to the Free Software
  26. ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  27. ;;
  28. ;;; Commentary:
  29. ;;
  30. ;; This is the export engine for Org.
  31. ;;
  32. ;; Put this file into your load-path and the following into your ~/.emacs:
  33. ;; (require 'org-export)
  34. ;;
  35. ;;; Code:
  36. (eval-when-compile
  37. (require 'cl))
  38. ;;; Parsing functions:
  39. (defun org-export-parse (&optional level)
  40. "Parse the current buffer.
  41. Return a nested list reflecting the sectioning structure of the
  42. file and containing all information about each section, including
  43. its content."
  44. (let (output eos)
  45. (save-excursion
  46. (goto-char (point-min))
  47. (while (re-search-forward org-complex-heading-regexp nil t)
  48. (let ((heading (match-string 4))
  49. (properties (org-entry-properties)))
  50. (save-restriction
  51. (narrow-to-region (if (looking-at "\n") (1+ (point)) (point))
  52. (save-excursion
  53. (setq eos (org-end-of-subtree t t))))
  54. (setq output
  55. (append output
  56. (list
  57. (list :level (or level 1)
  58. :heading heading
  59. :properties properties
  60. :content (org-export-parse-clean-content-string
  61. (org-export-parse-content))
  62. :subtree (org-export-parse
  63. (if level (1+ level) 2)))))))
  64. (goto-char (1- eos)))))
  65. output))
  66. (defun org-export-parse-content ()
  67. "Extract the content of a section.
  68. The content of a section is the part before a subtree."
  69. (save-excursion
  70. (goto-char (point-min))
  71. (buffer-substring
  72. (point)
  73. (if (re-search-forward org-complex-heading-regexp nil t)
  74. (match-beginning 0) (point-max)))))
  75. (defun org-export-parse-clean-content-string (s)
  76. "From the content string S, remove stuff also captured by get-properties.
  77. So this will remove the clock drawer, the property drawer, and the lines
  78. with planning info (DEADLINE, SCHEDULED, CLOSED)."
  79. (if (string-match org-property-drawer-re s)
  80. (setq s (replace-match "" t t s)))
  81. (if (string-match org-clock-drawer-re s)
  82. (setq s (replace-match "" t t s)))
  83. (while (string-match (concat org-keyword-time-regexp ".*\n?") s)
  84. (setq s (replace-match "" t t s)))
  85. s)
  86. ;;; Rendering functions:
  87. (defun org-export-buffer (filter struct-backend content-backend)
  88. "Render the current buffer.
  89. It first parses the current buffer into a list. Then it filters
  90. this list with FILTER. Finally it uses STRUCT-BACKEND and
  91. CONTENT-BACKEND to render the structure of the buffer and the
  92. content of each section."
  93. (save-excursion
  94. (let* ((props (org-combine-plists
  95. (org-default-export-plist)
  96. (org-infile-export-plist)))
  97. (first-lines (org-export-parse-content))
  98. (parsed-buffer (org-export-parse)))
  99. (switch-to-buffer (get-buffer-create "*Org export*"))
  100. (erase-buffer)
  101. (funcall (cdr (assoc 'header struct-backend)) props)
  102. (funcall (cdr (assoc 'first-lines struct-backend))
  103. first-lines props)
  104. (org-export-render-structure parsed-buffer props filter
  105. struct-backend content-backend)
  106. (funcall (cdr (assoc 'footer struct-backend)) props))))
  107. (defun org-export-render-structure
  108. (parsed-buffer props filter struct-backend content-backend)
  109. "Render PARSED-BUFFER.
  110. The optional argument FILTER specifies a filter to pass to the
  111. rendering engine."
  112. (mapc (lambda(s)
  113. (funcall (cdr (assoc 'section-beginning struct-backend)) s)
  114. (funcall (cdr (assoc 'heading struct-backend)) s)
  115. (insert (org-export-render-content s props content-backend) "\n\n")
  116. (org-export-render-structure (plist-get s :subtree) props
  117. filter struct-backend content-backend)
  118. (funcall (cdr (assoc 'section-end struct-backend)) s))
  119. (org-export-filter parsed-buffer filter)))
  120. (defun org-export-render-content (section props content-backend)
  121. "Render SECTION with PROPS. SECTION is the property list
  122. defining the information for the section. PROPS is the property
  123. list defining information for the current export.
  124. CONTENT-BACKEND is an association list defining possible
  125. exporting directive the content of this section."
  126. (with-temp-buffer
  127. (insert (plist-get section :content))
  128. (if (not (plist-get props :with-comment))
  129. (funcall (cdr (assoc 'comment content-backend))))
  130. (buffer-string)))
  131. (defun org-export-strip-drawer ()
  132. "Strip DRAWERS in the current buffer.
  133. Stripped drawers are those matched by `org-drawer-regexp'."
  134. (save-excursion
  135. (while (re-search-forward org-drawer-regexp nil t)
  136. (let ((beg (match-beginning 0))
  137. (end (and (search-forward ":END:" nil t)
  138. (match-end 0))))
  139. (delete-region beg end)))))
  140. ;;; Filtering functions:
  141. (defun org-export-filter (parsed-buffer filter)
  142. "Filter out PARSED-BUFFER with FILTER.
  143. PARSED-BUFFER is a nested list a sections and subsections, as
  144. produced by `org-export-parse'. FILTER is an alist of rules to
  145. apply to PARSED-BUFFER. For the syntax of a filter, please check
  146. the docstring of `org-export-latex-filter'."
  147. (delete
  148. nil
  149. (mapcar
  150. (lambda(s)
  151. (if (delete
  152. nil
  153. (mapcar
  154. (lambda(f)
  155. (let ((cnd (car f)) (re (cadr f)) prop-cnd)
  156. (or (and (eq cnd 'heading)
  157. (string-match re (plist-get s :heading)))
  158. (and (eq cnd 'content)
  159. (string-match re (plist-get s :content)))
  160. (and (setq prop-cnd
  161. (assoc cnd (plist-get s :properties)))
  162. (string-match re (cadr prop-cnd))))))
  163. filter))
  164. nil ;; return nil if the section is filtered out
  165. (progn (plist-put s :subtree
  166. (org-export-filter (plist-get s :subtree) filter))
  167. s))) ;; return the section if it isn't filtered out
  168. parsed-buffer)))
  169. (provide 'org-export)
  170. ;;; User Options, Variables
  171. ;;; org-export.el ends here