org-export-freemind.el 6.7 KB

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