Merge branch 'master' of git+ssh://repo.or.cz/srv/git/org-mode
[org-mode.git] / EXPERIMENTAL / org-export.el
blob2261da3d45d5615bceff971aff23d1a7a27bc228
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]
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.
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.
28 ;;; Commentary:
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)
35 ;;; Code:
37 (eval-when-compile
38 (require 'cl))
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
46 its content."
47 (let (output eos)
48 (save-excursion
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)))
53 (save-restriction
54 (narrow-to-region (if (looking-at "\n") (1+ (point)) (point))
55 (save-excursion
56 (setq eos (org-end-of-subtree t t))))
57 (setq output
58 (append output
59 (list
60 (list :level (or level 1)
61 :heading heading
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)))))
68 output))
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."
73 (save-excursion
74 (goto-char (point-min))
75 (buffer-substring
76 (point)
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."
100 (save-excursion
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*"))
107 (erase-buffer)
108 (funcall (cdr (assoc 'header struct-backend)) props)
109 (funcall (cdr (assoc 'first-lines struct-backend))
110 first-lines props)
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
119 rendering engine."
120 (mapc (lambda(s)
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."
135 (with-temp-buffer
136 (insert (plist-get section :content))
137 (if (not (plist-get props :with-comment))
138 (funcall (cdr (assoc 'comment content-backend))))
139 (buffer-string)))
141 (defun org-export-strip-drawer ()
142 "Strip DRAWERS in the current buffer.
143 Stripped drawers are those matched by `org-drawer-regexp'."
144 (save-excursion
145 (while (re-search-forward org-drawer-regexp nil t)
146 (let ((beg (match-beginning 0))
147 (end (and (search-forward ":END:" nil t)
148 (match-end 0))))
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'."
159 (delete
160 nil
161 (mapcar
162 (lambda(s)
163 (if (delete
164 nil
165 (mapcar
166 (lambda(f)
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)))
172 (and (setq prop-cnd
173 (assoc cnd (plist-get s :properties)))
174 (string-match re (cadr prop-cnd))))))
175 filter))
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
180 parsed-buffer)))
182 (provide 'org-export)
184 ;;; User Options, Variables
186 ;;; org-export.el ends here