emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
blob cbae72134abc5bbb47b17219224d31e120fe34f5 9528 bytes (raw)
name: contrib/lisp/org-mtags.el 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
 
;;; org-mtags.el --- Muse-like tags in Org-mode
;; Copyright (C) 2008-2012 Free Software Foundation, Inc.
;;
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: http://orgmode.org
;; Version: 0.01
;;
;; This file is not yet part of GNU Emacs.
;;
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Commentary:
;;
;; This modules implements some of the formatting tags available in
;; Emacs Muse.  This is not a way if adding new functionality, but just
;; a different way to write some formatting directives.  The advantage is
;; that files written in this way can be read by Muse reasonably well,
;; and that this provides an alternative way of writing formatting
;; directives in Org, a way that some might find more pleasant to type
;; and look at that the Org's #+BEGIN..#+END notation.

;; The goal of this development is to make it easier for people to
;; move between both worlds as they see fit for different tasks.

;; The following muse tags will be translated during export into their
;; native Org equivalents:
;;
;;   <br>
;;        Needs to be at the end of a line.  Will be translated to "\\".
;;
;;   <example switches="-n -r">
;;        Needs to be on a line by itself, similarly the </example> tag.
;;        Will be translated into Org's #+BEGIN_EXAMPLE construct.
;;
;;   <quote>
;;        Needs to be on a line by itself, similarly the </quote> tag.
;;        Will be translated into Org's #+BEGIN_QUOTE construct.
;;
;;   <comment>
;;        Needs to be on a line by itself, similarly the </comment> tag.
;;        Will be translated into Org's #+BEGIN_COMMENT construct.
;;
;;   <verse>
;;        Needs to be on a line by itself, similarly the </verse> tag.
;;        Will be translated into Org's #+BEGIN_VERSE construct.
;;
;;   <contents>
;;        This gets translated into "[TABLE-OF-CONTENTS]".  It will not
;;        trigger the production of a table of contents - that is done
;;        in Org with the "#+OPTIONS: toc:t" setting.  But it will define
;;        the location where the TOC will be placed.
;;
;;   <literal style="STYLE">    ;; only latex, html, and docbook supported
;;        in Org.
;;        Needs to be on a line by itself, similarly the </literal> tag.
;;
;;   <src lang="LANG" switches="-n -r">
;;        Needs to be on a line by itself, similarly the </src> tag.
;;        Will be translated into Org's BEGIN_SRC construct.
;;
;;   <include file="FILE" markup="MARKUP" lang="LANG"
;;            prefix="str" prefix1="str" switches="-n -r">
;;        Needs to be on a line by itself.
;;        Will be translated into Org's #+INCLUDE construct.
;;
;; The lisp/perl/ruby/python tags can be implemented using the
;; `org-eval.el' module, which see.

(require 'org)

;;; Customization

(defgroup org-mtags nil
  "Options concerning Muse tags in Org mode."
  :tag "Org Muse Tags"
  :group 'org)

(defface org-mtags    ; similar to shadow
  (org-compatible-face 'shadow
    '((((class color grayscale) (min-colors 88) (background light))
       (:foreground "grey50"))
      (((class color grayscale) (min-colors 88) (background dark))
       (:foreground "grey70"))
      (((class color) (min-colors 8) (background light))
       (:foreground "green"))
      (((class color) (min-colors 8) (background dark))
       (:foreground "yellow"))))
  "Face for Muse-like tags in Org."
  :group 'org-mtags
  :group 'org-faces)

(defcustom org-mtags-prefer-muse-templates t
  "Non-nil means prefere Muse tags for structure elements.
This is relevane when expanding the templates defined in the variable
`org-structure-templates'."
  :group 'org-mtags
  :type 'boolean)

(defconst org-mtags-supported-tags
  '("example" "quote" "comment" "verse" "contents" "literal" "src" "include")
  "The tags that are supported by org-mtags.el for conversion.
In addition to this list, the <br> tag is supported as well.")

(defconst org-mtags-fontification-re
  (concat
   "^[ \t]*</?\\("
   (mapconcat 'identity org-mtags-supported-tags "\\|")
   "\\)\\>[^>]*>\\|<br>[ \t]*$")
  "Regular expression used for fontifying muse tags.")

(defun org-mtags-replace ()
  "Replace Muse-like tags with the appropriate Org constructs.
The is done in the entire buffer."
  (interactive) ;; FIXME
  (let ((re (concat "^[ \t]*\\(</?\\("
		    (mapconcat 'identity org-mtags-supported-tags "\\|")
		    "\\)\\>\\)"))
	info tag rpl style markup lang file prefix prefix1 switches)
    ;; First, do the <br> tag
    (goto-char (point-min))
    (while (re-search-forward "<br>[ \t]*$" nil t)
      (replace-match "\\\\" t t))
    ;; Now, all the other tags
    (goto-char (point-min))
    (while (re-search-forward re nil t)
      (goto-char (match-beginning 1))
      (setq info (org-mtags-get-tag-and-attributes))
      (if (not info)
	  (end-of-line 1)
	(setq tag (plist-get info :tag))
	(cond
	 ((equal tag "contents")
	  (setq rpl "[TABLE-OF-CONTENTS]")
	  ;; FIXME: also trigger TOC in options-plist?????
	  )
	 ((member tag '("quote" "comment" "verse"))
	  (if (plist-get info :closing)
	      (setq rpl (format "#+END_%s" (upcase tag)))
	    (setq rpl (format "#+BEGIN_%s" (upcase tag)))))
	 ((equal tag "literal")
	  (setq style (plist-get info :style))
	  (and style (setq style (downcase style)))
	  (if (plist-get info :closing)
	      (setq rpl (cond
			 ((member style '("latex"))
			  "#+END_LaTeX")
			 ((member style '("html"))
			  "#+END_HTML")
			 ((member style '("docbook"))
			  "#+END_DOCBOOK")
			 ((member style '("ascii"))
			  "#+END_ASCII")))
	    (setq rpl (cond
		       ((member style '("latex"))
			"#+BEGIN_LaTeX")
		       ((member style '("html"))
			"#+BEGIN_HTML")
		       ((member style '("ascii"))
			"#+BEGIN_ASCII")))))
	 ((equal tag "example")
	  (if (plist-get info :closing)
	      (setq rpl "#+END_EXAMPLE")
	    (setq rpl "#+BEGIN_EXAMPLE")
	    (when (setq switches (plist-get info :switches))
	      (setq rpl (concat rpl " " switches)))))
	 ((equal tag "src")
	  (if (plist-get info :closing)
	      (setq rpl "#+END_SRC")
	    (setq rpl "#+BEGIN_SRC")
	    (when (setq lang (plist-get info :lang))
	      (setq rpl (concat rpl " " lang))
	      (when (setq switches (plist-get info :switches))
		(setq rpl (concat rpl " " switches))))))
	 ((equal tag "include")
	  (setq file (plist-get info :file)
		markup (downcase (plist-get info :markup))
		lang (plist-get info :lang)
		prefix (plist-get info :prefix)
		prefix1 (plist-get info :prefix1)
		switches (plist-get info :switches))
	  (setq rpl "#+INCLUDE")
	  (setq rpl (concat rpl " " (prin1-to-string file)))
	  (when markup
	    (setq rpl (concat rpl " " markup))
	    (when (and (equal markup "src") lang)
	      (setq rpl (concat rpl " " lang))))
	  (when prefix
	    (setq rpl (concat rpl " :prefix " (prin1-to-string prefix))))
	  (when prefix1
	    (setq rpl (concat rpl " :prefix1 " (prin1-to-string prefix1))))
	  (when switches
	    (setq rpl (concat rpl " " switches)))))
	(when rpl
	  (goto-char (plist-get info :match-beginning))
	  (delete-region (point-at-bol) (plist-get info :match-end))
	  (insert rpl))))))

(defun org-mtags-get-tag-and-attributes ()
  "Parse a Muse-like tag at point ant rturn the information about it.
The return value is a property list which contains all the attributes
with string values.  In addition, it reutnrs the following properties:

:tag              The tag as a string.
:match-beginning  The beginning of the match, just before \"<\".
:match-end        The end of the match, just after \">\".
:closing          t when the tag starts with \"</\"."
  (when (looking-at "<\\(/\\)?\\([a-zA-Z]+\\>\\)\\([^>]*\\)>")
    (let ((start 0)
	  tag rest prop attributes endp val)
      (setq tag (org-match-string-no-properties 2)
	    endp (match-end 1)
	    rest (and (match-end 3)
		      (org-match-string-no-properties 3))
	    attributes (list :tag tag
			     :match-beginning (match-beginning 0)
			     :match-end (match-end 0)
			     :closing endp))
      (when rest
	(while (string-match "\\([a-zA-Z]+\\)=\\([^ \t\n>]+\\|\"[^>]+\"\\)"
			     rest start)
	  (setq start (match-end 0)
		prop (org-match-string-no-properties 1 rest)
		val (org-remove-double-quotes
		     (org-match-string-no-properties 2 rest)))
	  (setq attributes (plist-put attributes
				      (intern (concat ":" prop)) val))))
      attributes)))

(defun org-mtags-fontify-tags (limit)
  "Fontify the muse-like tags."
  (while (re-search-forward org-mtags-fontification-re limit t)
    (add-text-properties (match-beginning 0) (match-end 0)
			 '(face org-mtags font-lock-multiline t
				font-lock-fontified t))))

(add-hook 'org-export-preprocess-hook 'org-mtags-replace)
(add-hook 'org-font-lock-hook 'org-mtags-fontify-tags)

(provide 'org-mtags)

;;; org-mtags.el ends here

debug log:

solving cbae721 ...
found cbae721 in https://git.savannah.gnu.org/cgit/emacs/org-mode.git

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).