org-mw.el 8.3 KB

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