Intermediate state, I am just trying comiting now.
[org-mode.git] / CONTRIB / org-export-freemind.el
blob58791413a0619ec65ebc96c0c27d65585f4fa5b2
1 ;;; org-export-freemind - exporting utilities from org-mode to freemind
3 ;; Copyright (C) 2007 Marco Vezzoli
5 ;; Author: marco vezzoli <noise.otn@alice.it>
6 ;; Created:
7 ;; Version: 0.1.0
8 ;; Keywords: org-mode export freemind
9 ;; Commentary:
11 ;; This file is *not* part of GNU Emacs.
12 ;; This program is free software; you can redistribute it and/or
13 ;; modify it under the terms of the GNU General Public License as
14 ;; published by the Free Software Foundation; either version 2 of
15 ;; the License, or (at your option) any later version.
17 ;; This program is distributed in the hope that it will be
18 ;; useful, but WITHOUT ANY WARRANTY; without even the implied
19 ;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 ;; PURPOSE. See the GNU General Public License for more details.
22 ;; You should have received a copy of the GNU General Public
23 ;; License along with this program; if not, write to the Free
24 ;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301 USA
27 ;;; Code:
28 (defgroup org-export-freemind ()
29 "This group let you customize your own export into freemind format"
30 :group 'org-export)
32 (defcustom org-freemind-icons-alist
33 '(("TODO" . "button_cancel")
34 ("SPEC" . "pencil")
35 ("WIP" . "pencil")
36 ("TEST" . "xmag")
37 ("DONE" . "button_ok"))
38 "change the icon according to a regular expression"
39 :type '(alist :key-type regexp
40 :value-type string)
41 :group 'org-export-freemind)
43 (defcustom org-freemind-cloud-alist
44 '((":PROJECT:" . "ccffcc")
45 (":MEETING:" . "ccccff"))
46 "create a cloud with the defined color if title match a regexp"
47 :type '(alist :key-type regexp :value-type string)
48 :group 'org-export-freemind)
50 (defun org-export-as-freemind (&optional buffer outbuffer)
51 "Export the org buffer as FreeMind XML.
53 (interactive (list (current-buffer) ()))
54 ;; A quickie abstraction
56 ;; Output everything as FreeMind
57 (with-current-buffer (get-buffer buffer)
58 (goto-char (point-min)) ;; CD: beginning-of-buffer is not allowed.
59 (let* ((opt-plist (org-combine-plists (org-default-export-plist)
60 (org-infile-export-plist)))
61 (title (or (plist-get opt-plist :title)
62 (file-name-sans-extension
63 (file-name-nondirectory buffer-file-name))))
64 (filename (concat (file-name-as-directory
65 (org-export-directory :xoxo opt-plist))
66 title
67 ".mm"))
68 (out (if (bufferp outbuffer)
69 outbuffer
70 (find-file-noselect filename)))
71 (last-level 0)
72 (hanging-li nil))
74 ;; Check the output buffer is empty.
75 ;; Kick off the output
76 (unless (bufferp outbuffer)
77 (progn
78 (with-current-buffer out (erase-buffer))
79 (org-export-as-xoxo-insert-into out "<map version='0.8.0'>\n")))
80 (org-export-as-xoxo-insert-into out
81 "<node TEXT='" title "'"
82 (if (bufferp outbuffer)
83 " FOLDED='true'" "")
84 ">\n")
85 (if (bufferp outbuffer)
86 (org-export-as-xoxo-insert-into out "<cloud COLOR='#ccffff'/>\n"))
87 (while (re-search-forward "^\\(\\*+\\) \\(.+\\)" (point-max) 't)
88 (let* ((hd (match-string-no-properties 1))
89 (level (length hd))
90 (text (match-string-no-properties 2)))
91 (save-excursion
92 (goto-char (match-end 0))
93 (catch 'loop
94 (while 't
95 (forward-line)
96 (if (looking-at "^[ \t]\\(.*\\)")
98 (throw 'loop "")))))
100 ;; Handle level rendering
101 (cond
102 ((> level last-level)
103 (let ((rept (- level last-level 1))
104 (value ()))
105 (dotimes (i rept value)
106 (org-export-as-xoxo-insert-into out "<node FOLDED='false' TEXT='.'>\n")))
107 (org-export-as-xoxo-insert-into out "\n<node FOLDED='true' TEXT='"))
109 ((< level last-level)
110 (let ((rept (+ (- last-level level) 1))
111 (value ()))
112 (dotimes (i rept value)
113 (org-export-as-xoxo-insert-into out "</node>\n")))
114 (org-export-as-xoxo-insert-into out "<node FOLDED='true' TEXT='"))
116 ((equal level last-level)
117 (org-export-as-xoxo-insert-into out "</node>\n<node FOLDED='true' TEXT='")))
119 (setq last-level level)
121 ;; And output the new node
122 (let* ((heading
123 (concat "<html><h3>"
124 (replace-regexp-in-string
125 ":.*:"
126 (lambda (x)
127 (concat "<font color='red'>" x "</font>"))
128 text)
129 "</h3></html>"))
130 (html-quoted-heading (org-html-expand heading))
131 (exp-quote-heading (replace-regexp-in-string "'" "&quot;" html-quoted-heading)))
132 (org-export-as-xoxo-insert-into out exp-quote-heading "'>\n"))
134 (dolist (rule org-freemind-icons-alist)
135 (if (string-match (car rule) text)
136 (org-export-as-xoxo-insert-into out "<icon BUILTIN='" (cdr rule) "'/>\n")))
137 (dolist (rule org-freemind-cloud-alist)
138 (when (string-match (car rule) text)
139 (progn
140 (org-export-as-xoxo-insert-into out
141 "<cloud COLOR='#" (cdr rule) "'/>\n")
142 (message (cdr rule))
146 ;; Finally finish off the map
147 (let ((value ()))
148 (org-export-as-xoxo-insert-into out "\n")
149 (dotimes (i last-level value)
150 (org-export-as-xoxo-insert-into out "</node>\n")))
151 (org-export-as-xoxo-insert-into out "</node>\n")
153 ;; Finish the buffer off and clean it up.
154 (unless (bufferp outbuffer)
155 (progn
156 (org-export-as-xoxo-insert-into out "</map>\n")
157 (switch-to-buffer-other-window out)
158 (indent-region (point-min) (point-max) nil)
159 (save-buffer)
160 (goto-char (point-min))
161 )))))
163 (defun org-export-as-freemind-agenda-files ()
164 "Export all agenda files into Freemind format
165 each files is saved with .mm extension
166 into the XOXO publishing directory"
167 (interactive)
168 (dolist (file org-agenda-files)
169 (org-check-agenda-file file)
170 (set-buffer (org-get-agenda-file-buffer file))
171 (org-export-as-freemind (current-buffer))
174 (defun org-export-as-freemind-agenda-files-one-file (filename)
175 "Export all agenda files into FreeMind format.
176 All results are grouped in a single .mm file"
177 (interactive "FFile to save: ")
178 (let* ((title (file-name-sans-extension
179 (file-name-nondirectory filename)))
180 (out (find-file-noselect filename)))
181 (with-current-buffer out (erase-buffer))
182 (org-export-as-xoxo-insert-into out "<map version='0.8.0'><node TEXT='" title "'>\n")
183 (dolist (file org-agenda-files)
184 (org-check-agenda-file file)
185 (set-buffer (org-get-agenda-file-buffer file))
186 (org-export-as-freemind (current-buffer) out)
188 (org-export-as-xoxo-insert-into out "</node></map>\n")
189 (switch-to-buffer-other-window out)
190 (indent-region (point-min) (point-max) nil)
191 (save-buffer)
192 (goto-char (point-min))
195 (define-key org-mode-map "\C-c\C-xf" 'org-export-as-freemind)
196 ;;; org-export-freemind ends here