1 ;;; org-export.el --- Export engine for Org
3 ;; Copyright 2008 Bastien Guerry
5 ;; Emacs Lisp Archive Entry
6 ;; Filename: org-export.el
8 ;; Author: Bastien <bzg AT altern DOT org>
9 ;; Maintainer: Bastien <bzg AT altern DOT org>
12 ;; URL: [Not distributed yet]
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)
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.
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.
30 ;; This is the export engine for Org.
32 ;; Put this file into your load-path and the following into your ~/.emacs:
33 ;; (require 'org-export)
40 ;;; Parsing functions:
42 (defun org-export-parse (&optional level
)
43 "Parse the current buffer.
44 Return a nested list reflecting the sectioning structure of the
45 file and containing all information about each section, including
49 (goto-char (point-min))
50 (while (re-search-forward org-complex-heading-regexp nil t
)
51 (let ((heading (match-string 4))
52 (properties (org-entry-properties)))
54 (narrow-to-region (if (looking-at "\n") (1+ (point)) (point))
56 (setq eos
(org-end-of-subtree t t
))))
60 (list :level
(or level
1)
62 :properties properties
63 :content
(org-export-parse-clean-content-string
64 (org-export-parse-content))
65 :subtree
(org-export-parse
66 (if level
(1+ level
) 2)))))))
67 (goto-char (1- eos
)))))
70 (defun org-export-parse-content ()
71 "Extract the content of a section.
72 The content of a section is the part before a subtree."
74 (goto-char (point-min))
77 (if (re-search-forward org-complex-heading-regexp nil t
)
78 (match-beginning 0) (point-max)))))
80 (defun org-export-parse-clean-content-string (s)
81 "From the content string S, remove stuff also captured by get-properties.
82 So this will remove the clock drawer, the property drawer, and the lines
83 with planning info (DEADLINE, SCHEDULED, CLOSED)."
84 (if (string-match org-property-drawer-re s
)
85 (setq s
(replace-match "" t t s
)))
86 (if (string-match org-clock-drawer-re s
)
87 (setq s
(replace-match "" t t s
)))
88 (while (string-match (concat org-keyword-time-regexp
".*\n?") s
)
89 (setq s
(replace-match "" t t s
)))
92 ;;; Rendering functions:
94 (defun org-export-buffer (filter struct-backend content-backend
)
95 "Render the current buffer.
96 It first parses the current buffer into a list. Then it filters
97 this list with FILTER. Finally it uses STRUCT-BACKEND and
98 CONTENT-BACKEND to render the structure of the buffer and the
99 content of each section."
101 (let* ((props (org-combine-plists
102 (org-default-export-plist)
103 (org-infile-export-plist)))
104 (first-lines (org-export-parse-content))
105 (parsed-buffer (org-export-parse)))
106 (switch-to-buffer (get-buffer-create "*Org export*"))
108 (funcall (cdr (assoc 'header struct-backend
)) props
)
109 (funcall (cdr (assoc 'first-lines struct-backend
))
111 (org-export-render-structure parsed-buffer props filter
112 struct-backend content-backend
)
113 (funcall (cdr (assoc 'footer struct-backend
)) props
))))
115 (defun org-export-render-structure
116 (parsed-buffer props filter struct-backend content-backend
)
117 "Render PARSED-BUFFER.
118 The optional argument FILTER specifies a filter to pass to the
121 (funcall (cdr (assoc 'section-beginning struct-backend
)) s
)
122 (funcall (cdr (assoc 'heading struct-backend
)) s
)
123 (insert (org-export-render-content s props content-backend
) "\n\n")
124 (org-export-render-structure (plist-get s
:subtree
) props
125 filter struct-backend content-backend
)
126 (funcall (cdr (assoc 'section-end struct-backend
)) s
))
127 (org-export-filter parsed-buffer filter
)))
129 (defun org-export-render-content (section props content-backend
)
130 "Render SECTION with PROPS. SECTION is the property list
131 defining the information for the section. PROPS is the property
132 list defining information for the current export.
133 CONTENT-BACKEND is an association list defining possible
134 exporting directive the content of this section."
136 (insert (plist-get section
:content
))
137 (if (not (plist-get props
:with-comment
))
138 (funcall (cdr (assoc 'comment content-backend
))))
141 (defun org-export-strip-drawer ()
142 "Strip DRAWERS in the current buffer.
143 Stripped drawers are those matched by `org-drawer-regexp'."
145 (while (re-search-forward org-drawer-regexp nil t
)
146 (let ((beg (match-beginning 0))
147 (end (and (search-forward ":END:" nil t
)
149 (delete-region beg end
)))))
151 ;;; Filtering functions:
153 (defun org-export-filter (parsed-buffer filter
)
154 "Filter out PARSED-BUFFER with FILTER.
155 PARSED-BUFFER is a nested list a sections and subsections, as
156 produced by `org-export-parse'. FILTER is an alist of rules to
157 apply to PARSED-BUFFER. For the syntax of a filter, please check
158 the docstring of `org-export-latex-filter'."
167 (let ((cnd (car f
)) (re (cadr f
)) prop-cnd
)
168 (or (and (eq cnd
'heading
)
169 (string-match re
(plist-get s
:heading
)))
170 (and (eq cnd
'content
)
171 (string-match re
(plist-get s
:content
)))
173 (assoc cnd
(plist-get s
:properties
)))
174 (string-match re
(cadr prop-cnd
))))))
176 nil
;; return nil if the section is filtered out
177 (progn (plist-put s
:subtree
178 (org-export-filter (plist-get s
:subtree
) filter
))
179 s
))) ;; return the section if it isn't filtered out
182 (provide 'org-export
)
184 ;;; User Options, Variables
186 ;;; org-export.el ends here