New experimental exporter from Org to MoinMoin by Puneeth Chaganti.
[org-mode.git] / EXPERIMENTAL / org-mm.el
1 ;;; org-mm.el --- MoinMoin backend for org-export.el
2 ;;
3 ;; Copyright 2010, 2011 Puneeth Chaganti
4 ;;
5 ;; Emacs Lisp Archive Entry
6 ;; Filename: org-mm.el
7 ;; Version: 0.2
8 ;; Author: Puneeth Chaganti <punchagan [at] gmail [dot] com>
9 ;; Keywords: MoinMoin Org export
10 ;; Description: MoinMoin exporter for Org
11 ;;
12 ;; This program is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; any later version.
16 ;;
17 ;; This program is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 ;; GNU General Public License for more details.
21 ;;
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with this program; if not, write to the Free Software
24 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 ;;
26 ;; A portion of this code is based on org-mw.el by Bastien Guerry.
27 ;;
28 ;;; Commentary:
29 ;;
30 ;; org-mm.el lets you convert Org files to MoinMoin files using
31 ;; the org-export.el experimental engine.
32 ;;
33 ;; Put this file into your load-path and the following into your ~/.emacs:
34 ;;   (require 'org-mm)
35 ;;
36 ;; You also need to fetch Org's git repository and add the EXPERIMENTAL/
37 ;; directory in your load path.
38 ;; 
39 ;; Fetch Org's git repository:
40 ;; 
41 ;; ~$ cd ~/install/git/
42 ;; ~$ git clone git://repo.or.cz/org-mode.git
43 ;;
44 ;; Put this in your .emacs.el:
45 ;; 
46 ;; (add-to-list 'load-path "~/install/git/org-mode/EXPERIMENTAL/")
47 ;;
48 ;; Export Org files to MoinMoin: M-x org-mm-export RET
49 ;;
50 ;;; Todo:
51 ;; 
52 ;; - handle radio links
53 ;; - support caption and attributes in tables
54 ;; - better handline of source code and examples
55 ;; - handle inline HTML
56 ;;
57 ;;; Code:
58
59 (require 'org-export)
60
61 (defvar org-mm-emphasis-alist
62   '(("*" "'''%s'''" nil)
63     ("/" "''%s''" nil)
64     ("_" "__%s__" nil)
65     ("+" "--%s--" nil)
66     ("=" "`%s`" nil))
67   "The list of fontification expressions for MoinMoin.")
68
69 (defvar org-mm-export-table-table-style "")
70 (defvar org-mm-export-table-header-style "")
71 (defvar org-mm-export-table-cell-style "")
72
73 (defun org-mm-export ()
74   "Export the current buffer to MoinMoin."
75   (interactive)
76   (setq org-export-current-backend 'mm)
77   (org-export-set-backend "mm")
78   ;; FIXME see the problem `org-mm-export-footnotes'
79   ;; (add-hook 'org-export-preprocess-final-hook 'org-mm-export-footnotes)
80   (add-hook 'org-export-preprocess-before-backend-specifics-hook
81             'org-mm-export-src-example)
82   (org-export-render)
83   ;; (remove-hook 'org-export-preprocess-final-hook 'org-mm-export-footnotes)
84   (remove-hook 'org-export-preprocess-before-backend-specifics-hook 
85                'org-mm-export-src-example))
86
87 (defun org-mm-export-header ()
88   "Export the header part."
89   (let* ((p (org-combine-plists (org-infile-export-plist)
90                                 org-export-properties))
91          (title (plist-get p :title))
92          (author (plist-get p :author))
93          (date (plist-get p :date))
94          (level (plist-get p :headline-levels)))
95     (insert (format "= %s by %s =\n\n" title author))
96     (if (plist-get p :table-of-contents)
97         (insert (format "<<TableOfContents(%s)>>\n" level)))))
98
99 (defun org-mm-export-first-lines (first-lines)
100   "Export first lines."
101   (insert (org-export-render-content first-lines) "\n")
102   (goto-char (point-max)))
103
104 (defun org-mm-export-heading (section-properties)
105   "Export MoinMoin heading"
106   (let* ((p section-properties)
107          (h (plist-get p :heading))
108          (s (make-string (1+ (plist-get p :level)) ?=)))
109     (insert (format "%s %s %s\n" s h s))))
110
111 (defun org-mm-export-quote-verse-center ()
112   "Export #+BEGIN_QUOTE/VERSE/CENTER environments."
113   (let (rpl e)
114     (while (re-search-forward "^[ \t]*ORG-\\([A-Z]+\\)-\\(START\\|END\\).*$" nil t)
115       (setq e (if (equal (match-string 2) "END") "/" "")) 
116       (setq rpl 
117             (cond ((equal (match-string 1) "BLOCKQUOTE") "blockquote>")
118                   ((equal (match-string 1) "VERSE") "pre>")
119                   ((equal (match-string 1) "CENTER") "center>")))
120       (replace-match (concat "<" e rpl) t))))
121
122 (defun org-mm-export-fonts ()
123   "Export fontification."
124   (while (re-search-forward org-emph-re nil t)
125     (let* ((emph (assoc (match-string 3) org-mm-emphasis-alist))
126            (beg (match-beginning 0))
127            (begs (match-string 1))
128            (end (match-end 0))
129            (ends (match-string 5))
130            (rpl (format (cadr emph) (match-string 4))))
131       (delete-region beg end)
132       (insert begs rpl ends))))
133
134 (defun org-mm-export-links ()
135   "Replace Org links with MoinMoin links."
136   ;; FIXME: This function could be more clever, of course.
137   (while (re-search-forward org-bracket-link-analytic-regexp nil t)
138     (cond ((and (equal (match-string 1) "file:")
139                 (save-match-data
140                   (string-match (org-image-file-name-regexp) (match-string 3))))
141            (replace-match 
142             (concat "{{" (file-name-nondirectory (match-string 3)) "}}")))
143           (t 
144            (replace-match 
145             (concat "[[\\1\\3|" (if (match-string 5) "\\5]]" "]]")))))))
146
147 ;; FIXME this function should test whether [1] is really a footnote.
148 ;; `org-footnote-normalize' should add properties to the normalized
149 ;; footnotes so that we can recognize them.
150 (defun org-mm-export-footnotes ()
151   "Export footnotes."
152   (goto-char (point-min))
153   (let (refpos rpl begnote begfullnote endnote)
154     (while (re-search-forward "\[[0-9]+\]" nil t)
155         (save-excursion
156           (save-match-data
157             (goto-char (point-max))
158             (search-backward (concat (match-string 0) " ") nil t)
159               (setq begfullnote (match-beginning 0))
160               (setq begnote (match-end 0))
161               (goto-char (match-end 0))
162               (re-search-forward "^\[[0-9]+\]\\|\\'" nil t)
163               (setq endnote (match-beginning 0))
164               (setq rpl (replace-regexp-in-string
165                          "\n" " " (buffer-substring endnote begnote)))
166               (setq rpl (replace-regexp-in-string "[ \t]+$" "" rpl))
167               (delete-region begfullnote endnote)))
168         (replace-match (concat "<ref>" rpl "</ref>")))))
169
170 (defun org-mm-export-src-example ()
171   "Export #+BEGIN_EXAMPLE and #+BEGIN_SRC."
172   (goto-char (point-min))
173   (let (start env)
174     (while (re-search-forward "^[ \t]*#\\+BEGIN_\\(EXAMPLE\\|SRC\\).*\n" nil t)
175       (setq env (match-string 1))
176       (replace-match "{{{\n")
177       (setq start (point))
178       (re-search-forward (concat "^[ \t]*#\\+END_" env ".*\n") nil t)
179       (replace-match "}}}\n"))))
180
181 (defun org-mm-export-lists ()
182   "Export lists to MoinMoin syntax."
183   (while (re-search-forward (org-item-beginning-re) nil t)
184     (move-beginning-of-line 1)
185     (insert (org-list-to-generic 
186              (org-list-parse-list t)
187              (org-combine-plists
188               '(:splice nil 
189                         :ostart "" :oend ""
190                         :ustart "" :uend ""
191                         :dstart "" :dend ""
192                         :dtstart "" :dtend " "
193                         :istart (concat (make-string (* 2 (1+ depth)) ?  )
194                                         (if (eq type 'unordered)
195                                             "* " "# "))
196                         :iend "\n"
197                         :icount nil
198                         :csep "\n"
199                         :cbon "[X]" :cboff "[ ]"
200                         :cbtrans "[-]"))))))
201
202
203 (defun org-mm-export-tables ()
204   "Convert tables in the current buffer to MoinMoin tables."
205   (while (re-search-forward "^\\([ \t]*\\)|" nil t)
206     (org-if-unprotected-at (1- (point))
207       (org-table-align)
208       (let* ((beg (org-table-begin))
209              (end (org-table-end))
210              (raw-table (buffer-substring beg end)) lines)
211         (setq lines (org-split-string raw-table "\n"))
212         (apply 'delete-region (list beg end))
213         (when org-export-table-remove-special-lines
214           (setq lines (org-table-clean-before-export lines 'maybe-quoted)))
215         (setq lines
216               (mapcar
217                (lambda(elem)
218                  (or (and (string-match "[ \t]*|-+" elem) 'hline)
219                      (org-split-string (org-trim elem) "|")))
220                lines))
221         (insert (orgtbl-to-mm lines nil))))))
222
223 (defun orgtbl-to-mm (table params)
224   "Convert TABLE into a MoinMoin table."
225   (let ((params2 (list
226                   :tstart (concat "" 
227                                   org-mm-export-table-table-style)
228                   :tend "\n"
229                   :lstart "||"
230                   :lend "||"
231                   :sep "||"
232                   :fmt (concat org-mm-export-table-cell-style " %s ")
233                   :hfmt (concat org-mm-export-table-cell-style "''' %s '''")
234                   :hlsep "||"
235                   )))
236     (orgtbl-to-generic table (org-combine-plists params2 params))))
237
238 ;; Various empty function for org-export.el to work:
239 (defun org-mm-export-footer () "")
240 (defun org-mm-export-section-beginning (section-properties) "")
241 (defun org-mm-export-section-end (section-properties) "")
242 (defun org-export-mm-preprocess (parameters)
243   "Do extra work for MoinMoin export."
244   nil)
245
246 (provide 'org-mm)