Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 405 lines (322 sloc) 12.294 kB
b95c632 @technomancy Doc updates, textile-mode, and a haml fix.
authored
1 ;;; textile-mode.el --- Textile markup editing major mode
2
3 ;; Copyright (C) 2006 Free Software Foundation, Inc.
4
5 ;; Author: Julien Barnier <julien@nozav.org>
6 ;; $Id: textile-mode.el 6 2006-03-30 22:37:08Z juba $
7
8 ;; This file is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12
13 ;; This file is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU Emacs; see the file COPYING. If not, write to
20 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
22
23 ;;; Commentary:
24
25 ;;
26
27
28 ;; Known bugs or limitations:
29
30 ;; - if several {style}, [lang] or (class) attributes are given for
31 ;; the same block, only the first one of each type will be
32 ;; highlighted.
33 ;;
34 ;; - some complex imbrications of inline markup and attributes are
35 ;; not well-rendered (for example, *strong *{something}notstrong*)
36 ;;
37
38
39
40 ;;; Code:
41
42
43
44 (defvar textile-mode-map
45 (let ((map (make-sparse-keymap)))
46 (define-key map [foo] 'textile-do-foo)
47 map)
48 "Keymap for `textile-mode'.")
49
818ad61 @technomancy Add hooks to textile-mode.
authored
50 (defvar textile-mode-hook nil
51 "A list of functions to run when entering textile-mode.")
b95c632 @technomancy Doc updates, textile-mode, and a haml fix.
authored
52
53 (defun textile-re-concat (l)
54 "Concatenate the elements of a list with a \\| separator and
55 non-matching parentheses"
56 (concat
57 "\\(?:"
58 (mapconcat 'identity l "\\|")
59 "\\)"))
60
61
62 (setq textile-attributes
63 '("{[^}]*}" "([^)]*)" "\\[[^]]*\\]"))
64
65 (setq textile-blocks
66 '("^h1" "^h2" "^h3" "^h4" "^h5" "^h6" "^p" "^bq" "^fn[0-9]+" "^#+ " "^\\*+ " "^table"))
67
68 (setq textile-inline-markup
69 '("\\*" "\\*\\*" "_" "__" "\\?\\?" "@" "-" "\\+" "^" "~" "%"))
70
71 (setq textile-alignments
72 '( "<>" "<" ">" "=" "(+" ")+"))
73
74 (setq textile-table-alignments
75 '( "<>" "<" ">" "=" "_" "\\^" "~" "\\\\[0-9]+" "/[0-9]+"))
76
77 ; from gnus-button-url-regexp
78 (setq textile-url-regexp "\\b\\(\\(www\\.\\|\\(s?https?\\|ftp\\|file\\|gopher\\|nntp\\|news\\|telnet\\|wais\\|mailto\\|info\\):\\)\\(//[-a-z0-9_.]+:[0-9]*\\)?[-a-z0-9_=!?#$@~%&*+\\/:;.,[:word:]]+[-a-z0-9_=#$@~%&*+\\/[:word:]]\\)")
79
80
81 (defun textile-block-matcher (bloc)
82 "Return the matcher regexp for a block element"
83 (concat
84 "^"
85 bloc
86 (textile-re-concat textile-alignments) "?"
87 (textile-re-concat textile-attributes) "*"
88 "\\. "
89 "\\(\\(?:.\\|\n\\)*?\\)\n\n"))
90
91 (defun textile-attribute-matcher (attr-start attr-end)
92 "Return the matcher regexp for an attribute"
93 (concat
94 (textile-re-concat (append textile-blocks textile-inline-markup))
95 (textile-re-concat textile-alignments) "*"
96 (textile-re-concat textile-attributes) "*"
97 "\\(" attr-start "[^"
98 (if (string-equal attr-end "\\]") "]" attr-end)
99 "]*" attr-end "\\)"))
100
101 (defun textile-inline-markup-matcher (markup)
102 "Return the matcher regexp for an inline markup"
103 (concat
104 "\\W\\("
105 markup
106 "\\(?:\\w\\|\\w.*?\\w\\|[[{(].*?\\w\\)"
107 markup
108 "\\)\\W"))
109
110 (defun textile-list-bullet-matcher (bullet)
111 "Return the matcher regexp for a list bullet"
112 (concat
113 "^\\(" bullet "\\)"
114 (textile-re-concat textile-alignments) "*"
115 (textile-re-concat textile-attributes) "*"))
116
117 (defun textile-alignments-matcher ()
118 "Return the matcher regexp for an alignments or indentation"
119 (concat
120 "\\(?:" (textile-re-concat textile-blocks) "\\|" "!" "\\)"
121 "\\(" (textile-re-concat textile-alignments) "+" "\\)"))
122
123 (defun textile-table-matcher ()
124 "Return the matcher regexp for a table row or header"
125 (concat
126 "\\(?:"
127 "^table" (textile-re-concat textile-table-alignments) "*" (textile-re-concat textile-attributes) "*" "\\. *$"
128 "\\|"
129 "^" (textile-re-concat textile-table-alignments) "*" (textile-re-concat textile-attributes) "*" "\\(?:\\. *|\\)"
130 "\\|"
131 "|" (textile-re-concat textile-table-alignments) "*" (textile-re-concat textile-attributes) "*" "\\(?:\\. \\)?"
132 "\\|"
133 "| *$"
134 "\\)"))
135
136 (defun textile-link-matcher ()
137 "Return the matcher regexp for a link"
138 (concat
139 "\\(?:"
140 "\\(?:" "\".*?\"" "\\|" "\\[.*?\\]" "\\)?"
141 textile-url-regexp
142 "\\|"
143 "\".*?\":[^ \n\t]+"
144 "\\)"))
145
146 (defun textile-image-matcher ()
147 "Return the matcher regexp for an image link"
148 (concat
149 "!"
150 (textile-re-concat textile-alignments) "*"
151 "/?\\w[^ \n\t]*?\\(?: *(.*?)\\|\\w\\)"
152 "!:?"))
153
154 (defun textile-acronym-matcher ()
155 "Return the matcher regexp for an acronym"
156 (concat
157 "\\w+" "(.*?)"))
158
159 (defvar textile-font-lock-keywords
160 (list
161 ;; headers
162 `(,(textile-block-matcher "h1") 1 'textile-h1-face t t)
163 `(,(textile-block-matcher "h2") 1 'textile-h2-face t t)
164 `(,(textile-block-matcher "h3") 1 'textile-h3-face t t)
165 `(,(textile-block-matcher "h4") 1 'textile-h4-face t t)
166 `(,(textile-block-matcher "h5") 1 'textile-h5-face t t)
167 `(,(textile-block-matcher "h6") 1 'textile-h6-face t t)
168 ;; blockquotes
169 `(,(textile-block-matcher "bq") 1 'textile-blockquote-face t t)
170 ;; footnotes
171 `(,(textile-block-matcher "fn[0-9]+") 1 'textile-footnote-face t t)
172 ;; footnote marks
173 '("\\w\\([[0-9]+]\\)" 1 'textile-footnotemark-face prepend t)
174 ;; acronyms
175 `(,(textile-acronym-matcher) 0 'textile-acronym-face t t)
176
177 ;; emphasis
178 `(,(textile-inline-markup-matcher "__") 1 'textile-emph-face prepend t)
179 `(,(textile-inline-markup-matcher "_") 1 'textile-emph-face prepend t)
180 '("<em>\\(.\\|\n\\)*?</em>" 0 'textile-emph-face prepend t)
181 ;; strength
182 `(,(textile-inline-markup-matcher "\\*\\*") 1 'textile-strong-face prepend t)
183 `(,(textile-inline-markup-matcher "\\*") 1 'textile-strong-face prepend t)
184 '("<strong>\\(.\\|\n\\)*?</strong>" 0 'textile-strong-face prepend t)
185 ;; citation
186 `(,(textile-inline-markup-matcher "\\?\\?") 1 'textile-citation-face prepend t)
187 ;; code
188 `(,(textile-inline-markup-matcher "@") 1 'textile-code-face prepend t)
189 ;; deletion
190 `(,(textile-inline-markup-matcher "-") 1 'textile-deleted-face prepend t)
191 ;; insertion
192 `(,(textile-inline-markup-matcher "\\+") 1 'textile-inserted-face prepend t)
193 ;; superscript
194 `(,(textile-inline-markup-matcher "\\^") 1 'textile-superscript-face prepend t)
195 ;; subscript
196 `(,(textile-inline-markup-matcher "~") 1 'textile-subscript-face prepend t)
197 ;; span
198 `(,(textile-inline-markup-matcher "%") 1 'textile-span-face prepend t)
199
200 ;; image link
201 `(,(textile-image-matcher) 0 'textile-image-face t t)
202
203 ;; ordered list bullet
204 `(,(textile-list-bullet-matcher "#+") 1 'textile-ol-bullet-face)
205 ;; unordered list bullet
206 `(,(textile-list-bullet-matcher "\\*+") 1 'textile-ul-bullet-face)
207
208 ;; style
209 `(,(textile-attribute-matcher "{" "}") 1 'textile-style-face t t)
210 ;; class
211 `(,(textile-attribute-matcher "(" ")") 1 'textile-class-face t t)
212 ;; lang
213 `(,(textile-attribute-matcher "\\[" "\\]") 1 'textile-lang-face t t)
214
215 ;; alignments and indentation
216 `(,(textile-alignments-matcher) 1 'textile-alignments-face t t)
217
218 ;; tables
219 `(,(textile-table-matcher) 0 'textile-table-face t t)
220
221 ;; links
222 `(,(textile-link-matcher) 0 'textile-link-face t t)
223
224 ;; <pre> blocks
225 '("<pre>\\(.\\|\n\\)*?</pre>" 0 'textile-pre-face t t)
226 ;; <code> blocks
227 '("<code>\\(.\\|\n\\)*?</code>" 0 'textile-code-face t t))
228 "Keywords/Regexp for fontlocking of textile-mode")
229
230
231 ;; (defvar textile-imenu-generic-expression
232 ;; ...)
233
234 ;; (defvar textile-outline-regexp
235 ;; ...)
236
237
238 ;;;###autoload
239 (define-derived-mode textile-mode text-mode "Textile"
240 "A major mode for editing textile files."
241 (set (make-local-variable 'font-lock-defaults) '(textile-font-lock-keywords t))
818ad61 @technomancy Add hooks to textile-mode.
authored
242 (set (make-local-variable 'font-lock-multiline) 'undecided)
243 (run-mode-hooks 'textile-mode-hook))
b95c632 @technomancy Doc updates, textile-mode, and a haml fix.
authored
244
245 ;; FACES
246
247 (defgroup textile-faces nil
248 "Faces used by textile-mode for syntax highlighting"
249 :group 'faces)
250
251 (defface textile-h1-face
252 '((t (:height 2.0 :weight bold)))
253 "Face used to highlight h1 headers."
254 :group 'textile-faces)
255
256 (defface textile-h2-face
257 '((t (:height 1.75 :weight bold)))
258 "Face used to highlight h2 headers."
259 :group 'textile-faces)
260
261 (defface textile-h3-face
262 '((t (:height 1.5 :weight bold)))
263 "Face used to highlight h3 headers."
264 :group 'textile-faces)
265
266 (defface textile-h4-face
267 '((t (:height 1.35 :weight bold)))
268 "Face used to highlight h4 headers."
269 :group 'textile-faces)
270
271 (defface textile-h5-face
272 '((t (:height 1.2 :weight bold)))
273 "Face used to highlight h5 headers."
274 :group 'textile-faces)
275
276 (defface textile-h6-face
277 '((t (:height 1.0 :weight bold)))
278 "Face used to highlight h6 headers."
279 :group 'textile-faces)
280
281 (defface textile-blockquote-face
282 '((t (:foreground "ivory4")))
283 "Face used to highlight bq blocks."
284 :group 'textile-faces)
285
286 (defface textile-footnote-face
287 '((t (:foreground "orange red")))
288 "Face used to highlight footnote blocks."
289 :group 'textile-faces)
290
291 (defface textile-footnotemark-face
292 '((t (:foreground "orange red")))
293 "Face used to highlight footnote marks."
294 :group 'textile-faces)
295
296 (defface textile-style-face
297 '((t (:foreground "sandy brown")))
298 "Face used to highlight style parameters."
299 :group 'textile-faces)
300
301 (defface textile-class-face
302 '((t (:foreground "yellow green")))
303 "Face used to highlight class and id parameters."
304 :group 'textile-faces)
305
306 (defface textile-lang-face
307 '((t (:foreground "sky blue")))
308 "Face used to highlight lang parameters."
309 :group 'textile-faces)
310
311 (defface textile-emph-face
312 '((t (:slant italic)))
313 "Face used to highlight emphasized words."
314 :group 'textile-faces)
315
316 (defface textile-strong-face
317 '((t (:weight bold)))
318 "Face used to highlight strong words."
319 :group 'textile-faces)
320
321 (defface textile-code-face
322 '((t (:foreground "ivory3")))
323 "Face used to highlight inline code."
324 :group 'textile-faces)
325
326 (defface textile-citation-face
327 '((t (:slant italic)))
328 "Face used to highlight citations."
329 :group 'textile-faces)
330
331 (defface textile-deleted-face
332 '((t (:strike-through t)))
333 "Face used to highlight deleted words."
334 :group 'textile-faces)
335
336 (defface textile-inserted-face
337 '((t (:underline t)))
338 "Face used to highlight inserted words."
339 :group 'textile-faces)
340
341 (defface textile-superscript-face
342 '((t (:height 1.1)))
343 "Face used to highlight superscript words."
344 :group 'textile-faces)
345
346 (defface textile-subscript-face
347 '((t (:height 0.8)))
348 "Face used to highlight subscript words."
349 :group 'textile-faces)
350
351 (defface textile-span-face
352 '((t (:foreground "pink")))
353 "Face used to highlight span words."
354 :group 'textile-faces)
355
356 (defface textile-alignments-face
357 '((t (:foreground "cyan")))
358 "Face used to highlight alignments."
359 :group 'textile-faces)
360
361 (defface textile-ol-bullet-face
362 '((t (:foreground "red")))
363 "Face used to highlight ordered lists bullets."
364 :group 'textile-faces)
365
366 (defface textile-ul-bullet-face
367 '((t (:foreground "blue")))
368 "Face used to highlight unordered list bullets."
369 :group 'textile-faces)
370
371 (defface textile-pre-face
372 '((t (:foreground "green")))
373 "Face used to highlight <pre> blocks."
374 :group 'textile-faces)
375
376 (defface textile-code-face
377 '((t (:foreground "yellow")))
378 "Face used to highlight <code> blocks."
379 :group 'textile-faces)
380
381 (defface textile-table-face
382 '((t (:foreground "red")))
383 "Face used to highlight tables."
384 :group 'textile-faces)
385
386 (defface textile-link-face
387 '((t (:foreground "blue")))
388 "Face used to highlight links."
389 :group 'textile-faces)
390
391 (defface textile-image-face
392 '((t (:foreground "pink")))
393 "Face used to highlight image links."
394 :group 'textile-faces)
395
396 (defface textile-acronym-face
397 '((t (:foreground "cyan")))
398 "Face used to highlight acronyms links."
399 :group 'textile-faces)
400
401 ;;;###autoload
402 (add-to-list 'auto-mode-alist '("\\.textile\\'" . textile-mode))
403
404 (provide 'textile-mode)
405 ;;; textile-mode.el ends here
Something went wrong with that request. Please try again.