Export: Enable new export switches in org-mtags.el.
[org-mode/org-tableheadings.git] / contrib / lisp / org-mtags.el
blob62fca9e5c2531ca44b5bccc011e4a3294013be9d
1 ;;; org-mtags.el --- Muse-like tags in Org-mode
2 ;; Copyright (C) 2008 Free Software Foundation, Inc.
3 ;;
4 ;; Author: Carsten Dominik <carsten at orgmode dot org>
5 ;; Keywords: outlines, hypermedia, calendar, wp
6 ;; Homepage: http://orgmode.org
7 ;; Version: 0.01
8 ;;
9 ;; This file is not yet part of GNU Emacs.
11 ;; GNU Emacs is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; any later version.
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the
23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 ;; Boston, MA 02110-1301, USA.
25 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27 ;;; Commentary:
29 ;; This modules implements some of the formatting tags available in
30 ;; Emacs Muse. This is not a way if adding new functionality, but just
31 ;; a different way to write some formatting directives. The advantage is
32 ;; that files written in this way can be read by Muse reasonably well,
33 ;; and that this provides an alternative way of writing formatting
34 ;; directives in Org, a way that some might find more pleasant to type
35 ;; and look at that the Org's #+BEGIN..#+END notation.
37 ;; The goal of this development is to make it easier for people to
38 ;; move between both worlds as they see fit for different tasks.
40 ;; The following muse tags will be translated during export into their
41 ;; native Org equivalents:
43 ;; <br>
44 ;; Needs to be at the end of a line. Will be translated to "\\".
46 ;; <example switches="-n -r">
47 ;; Needs to be on a line by itself, similarly the </example> tag.
48 ;; Will be translated into Org's #+BEGIN_EXAMPLE construct.
50 ;; <quote>
51 ;; Needs to be on a line by itself, similarly the </quote> tag.
52 ;; Will be translated into Org's #+BEGIN_QUOTE construct.
54 ;; <comment>
55 ;; Needs to be on a line by itself, similarly the </comment> tag.
56 ;; Will be translated into Org's #+BEGIN_COMMENT construct.
58 ;; <verse>
59 ;; Needs to be on a line by itself, similarly the </verse> tag.
60 ;; Will be translated into Org's #+BEGIN_VERSE construct.
62 ;; <contents>
63 ;; This gets translated into "[TABLE-OF-CONTENTS]". It will not
64 ;; trigger the production of a table of contents - that is done
65 ;; in Org with the "#+OPTIONS: toc:t" setting. But it will define
66 ;; the location where the TOC will be placed.
68 ;; <literal style="STYLE"> ;; only latex and html supported in Org
69 ;; Needs to be on a line by itself, similarly the </literal> tag.
71 ;; <src lang="LANG" switches="-n -r">
72 ;; Needs to be on a line by itself, similarly the </src> tag.
73 ;; Will be translated into Org's BEGIN_SRC construct.
75 ;; <include file="FILE" markup="MARKUP" lang="LANG" prefix="str" prefix1="str">
76 ;; Needs to be on a line by itself.
77 ;; Will be translated into Org's #+INCLUDE construct.
79 ;; The lisp/perl/ruby/python tags can be implemented using the
80 ;; `org-eval.el' module, which see.
82 (require 'org)
84 ;;; Customization
86 (defgroup org-mtags nil
87 "Options concerning Muse tags in Org mode."
88 :tag "Org Muse Tags"
89 :group 'org)
91 (defface org-mtags ; similar to shadow
92 (org-compatible-face 'shadow
93 '((((class color grayscale) (min-colors 88) (background light))
94 (:foreground "grey50"))
95 (((class color grayscale) (min-colors 88) (background dark))
96 (:foreground "grey70"))
97 (((class color) (min-colors 8) (background light))
98 (:foreground "green"))
99 (((class color) (min-colors 8) (background dark))
100 (:foreground "yellow"))))
101 "Face for Muse-like tags in Org."
102 :group 'org-mtags
103 :group 'org-faces)
105 (defcustom org-mtags-prefer-muse-templates t
106 "Non-nil means, prefere Muse tags for structure elements.
107 This is relevane when expanding the templates defined in the variable
108 `org-structure-templates'."
109 :group 'org-mtags
110 :type 'boolean)
112 (defconst org-mtags-supported-tags
113 '("example" "quote" "comment" "verse" "contents" "literal" "src" "include")
114 "The tags that are supported by org-mtags.el for conversion.
115 In addition to this list, the <br> tag is supported as well.")
117 (defconst org-mtags-fontification-re
118 (concat
119 "^[ \t]*</?\\("
120 (mapconcat 'identity org-mtags-supported-tags "\\|")
121 "\\)\\>[^>]*>\\|<br>[ \t]*$")
122 "Regular expression used for fontifying muse tags.")
124 (defun org-mtags-replace ()
125 "Replace Muse-like tags with the appropriate Org constructs.
126 The is done in the entire buffer."
127 (interactive) ;; FIXME
128 (let ((re (concat "^[ \t]*\\(</?\\("
129 (mapconcat 'identity org-mtags-supported-tags "\\|")
130 "\\)\\>\\)"))
131 info tag rpl style markup lang file prefix prefix1 switches)
132 ;; First, do the <br> tag
133 (goto-char (point-min))
134 (while (re-search-forward "<br>[ \t]*$" nil t)
135 (replace-match "\\\\" t t))
136 ;; Now, all the other tags
137 (goto-char (point-min))
138 (while (re-search-forward re nil t)
139 (goto-char (match-beginning 1))
140 (setq info (org-mtags-get-tag-and-attributes))
141 (if (not info)
142 (end-of-line 1)
143 (setq tag (plist-get info :tag))
144 (cond
145 ((equal tag "contents")
146 (setq rpl "[TABLE-OF-CONTENTS]")
147 ;; FIXME: also trigger TOC in options-plist?????
149 ((member tag '("quote" "comment" "verse"))
150 (if (plist-get info :closing)
151 (setq rpl (format "#+END_%s" (upcase tag)))
152 (setq rpl (format "#+BEGIN_%s" (upcase tag)))))
153 ((equal tag "literal")
154 (setq style (plist-get info :style))
155 (and style (setq style (downcase style)))
156 (if (plist-get info :closing)
157 (setq rpl (cond
158 ((member style '("latex"))
159 "#+END_LaTeX")
160 ((member style '("html"))
161 "#+END_HTML")
162 ((member style '("ascii"))
163 "#+END_ASCII")))
164 (setq rpl (cond
165 ((member style '("latex"))
166 "#+BEGIN_LaTeX")
167 ((member style '("html"))
168 "#+BEGIN_HTML")
169 ((member style '("ascii"))
170 "#+BEGIN_ASCII")))))
171 ((equal tag "example")
172 (if (plist-get info :closing)
173 (setq rpl "#+END_EXAMPLE")
174 (setq rpl "#+BEGIN_EXAMPLE")
175 (when (setq switches (plist-get info :switches))
176 (setq rpl (concat rpl " " switches)))))
177 ((equal tag "src")
178 (if (plist-get info :closing)
179 (setq rpl "#+END_SRC")
180 (setq rpl "#+BEGIN_SRC")
181 (when (setq lang (plist-get info :lang))
182 (setq rpl (concat rpl " " lang))
183 (when (setq switches (plist-get info :switches))
184 (setq rpl (concat rpl " " switches))))))
185 ((equal tag "include")
186 (setq file (plist-get info :file)
187 markup (downcase (plist-get info :markup))
188 lang (plist-get info :lang)
189 prefix (plist-get info :prefix)
190 prefix1 (plist-get info :prefix1))
191 (setq rpl "#+INCLUDE")
192 (when markup
193 (setq rpl (concat rpl " " markup))
194 (when (and (equal markup "src") lang)
195 (setq rpl (concat rpl " " lang))))
196 (when prefix
197 (setq rpl (concat rpl " :prefix " (prin1-to-string prefix))))
198 (when prefix1
199 (setq rpl (concat rpl " :prefix1 " (prin1-to-string prefix1))))))
200 (when rpl
201 (goto-char (plist-get info :match-beginning))
202 (delete-region (point-at-bol) (plist-get info :match-end))
203 (insert rpl))))))
205 (defun org-mtags-get-tag-and-attributes ()
206 "Parse a Muse-like tag at point ant rturn the information about it.
207 The return value is a property list which contains all the attributes
208 with string values. In addition, it reutnrs the following properties:
210 :tag The tag as a string.
211 :match-beginning The beginning of the match, just before \"<\".
212 :match-end The end of the match, just after \">\".
213 :closing t when the tag starts with \"</\"."
214 (when (looking-at "<\\(/\\)?\\([a-zA-Z]+\\>\\)\\([^>]*\\)>")
215 (let ((start 0)
216 tag rest prop attributes endp val)
217 (setq tag (org-match-string-no-properties 2)
218 endp (match-end 1)
219 rest (and (match-end 3)
220 (org-match-string-no-properties 3))
221 attributes (list :tag tag
222 :match-beginning (match-beginning 0)
223 :match-end (match-end 0)
224 :closing endp))
225 (when rest
226 (while (string-match "\\([a-zA-Z]+\\)=\\([^ \t\n>]+\\|\"[^>]+\"\\)"
227 rest start)
228 (setq start (match-end 0)
229 prop (org-match-string-no-properties 1 rest)
230 val (org-remove-double-quotes
231 (org-match-string-no-properties 2 rest)))
232 (setq attributes (plist-put attributes
233 (intern (concat ":" prop)) val))))
234 attributes)))
236 (defun org-mtags-fontify-tags (limit)
237 "Fontify the muse-like tags."
238 (while (re-search-forward org-mtags-fontification-re limit t)
239 (add-text-properties (match-beginning 0) (match-end 0)
240 '(face org-mtags font-lock-multiline t
241 font-lock-fontified t))))
243 (add-hook 'org-export-preprocess-hook 'org-mtags-replace)
244 (add-hook 'org-font-lock-hook 'org-mtags-fontify-tags)
246 (provide 'org-mtags)
248 ;;; org-mtags.el ends here