]> git.rkrishnan.org Git - .emacs.d.git/blob - emacs/nxhtml/util/mumamo-fun.el
submodulized .emacs.d setup
[.emacs.d.git] / emacs / nxhtml / util / mumamo-fun.el
1 ;;; mumamo-fun.el --- Multi major mode functions
2 ;;
3 ;; Author: Lennart Borgman (lennart O borgman A gmail O com)
4 ;; Created: 2008-03-09T01:35:21+0100 Sun
5 ;; Version: 0.51
6 ;; Last-Updated: 2008-08-04T17:54:29+0200 Mon
7 ;; URL:
8 ;; Keywords:
9 ;; Compatibility:
10 ;;
11 ;; Features that might be required by this library:
12 ;;
13 ;;   `backquote', `bytecomp', `cl', `flyspell', `ispell', `mumamo',
14 ;;   `sgml-mode'.
15 ;;
16 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17 ;;
18 ;; This program is free software; you can redistribute it and/or modify
19 ;; it under the terms of the GNU General Public License as published by
20 ;; the Free Software Foundation; either version 3, or (at your option)
21 ;; any later version.
22 ;;
23 ;; This program is distributed in the hope that it will be useful,
24 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
25 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26 ;; GNU General Public License for more details.
27 ;;
28 ;; You should have received a copy of the GNU General Public License
29 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
30 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
31 ;; Boston, MA 02110-1301, USA.
32 ;;
33 ;;
34 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
35 ;;
36 ;;; Commentary:
37 ;;
38 ;; Defines some "multi major modes" functions.  See mumamo.el for more
39 ;; information.
40 ;;
41 ;;;; Usage:
42 ;;
43 ;;  See mumamo.el for how to use the multi major mode functions
44 ;;  defined here.
45 ;;
46 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
47 ;;
48 ;;; Change log:
49 ;;
50 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
51 ;;
52 ;;; Code:
53
54 (eval-when-compile (require 'cl))
55 (eval-when-compile (add-to-list 'load-path default-directory))
56 (eval-when-compile (require 'mumamo))
57 (eval-when-compile (require 'sgml-mode))
58 ;;(mumamo-require)
59
60 ;;;#autoload
61 ;;(defun mumamo-fun-require ())
62
63 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
64 ;;;; File wide key bindings
65
66 (defun mumamo-multi-mode-map ()
67   "Return mumamo multi mode keymap."
68   (symbol-value
69    (intern-soft (concat (symbol-name mumamo-multi-major-mode) "-map"))))
70
71 ;; (defun mumamo-multi-mode-hook-symbol ()
72 ;;   "Return mumamo multi mode hook symbol."
73 ;;   (intern-soft (concat (symbol-name mumamo-multi-major-mode) "-hook")))
74
75 ;;;###autoload
76 (defun mumamo-define-html-file-wide-keys ()
77   "Define keys in multi major mode keymap for html files."
78   (let ((map (mumamo-multi-mode-map)))
79     (define-key map [(control ?c) (control ?h) ?b] 'nxhtml-browse-file)
80     ))
81 ;; (defun mumamo-add-html-file-wide-keys (hook)
82 ;;   (add-hook hook 'mumamo-define-html-file-wide-keys)
83 ;;   )
84
85 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
86 ;;;; Chunk search routines for XHTML things
87
88 (defun mumamo-chunk-attr= (pos min max attr= attr=is-regex attr-regex submode)
89   "This should work similar to `mumamo-find-possible-chunk'.
90 See `mumamo-chunk-style=' for an example of use.
91 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
92   (mumamo-chunk-attr=-new pos max attr= attr=is-regex attr-regex submode))
93
94 (defun mumamo-chunk-attr=-new-fw-exc-fun (pos max)
95   ;;(msgtrc "(mumamo-chunk-attr=-new-fw-exc-fun %s %s)" pos max)
96   (save-match-data
97     (let ((here (point))
98           first-dq
99           next-dq
100           (this-chunk (mumamo-get-existing-new-chunk-at pos)))
101       (if this-chunk
102           (goto-char (overlay-end this-chunk))
103         (goto-char (overlay-end mumamo-last-chunk)))
104       (setq first-dq (search-forward "\"" max t))
105       (unless (bobp)
106         (backward-char)
107         (condition-case err
108             (with-syntax-table (standard-syntax-table)
109               (setq next-dq (scan-sexps (point) 1)))
110           (error nil)))
111       (prog1
112           next-dq
113         (goto-char here)))))
114
115 (defun mumamo-chunk-attr=-new-find-borders-fun (start-border end-border dummy)
116   ;;(setq borders (funcall find-borders-fun start-border end-border exc-mode))
117   (save-match-data
118     (let ((here (point))
119           (end2 (when end-border (1- end-border)))
120           start2)
121       (goto-char start-border)
122       (save-match-data
123         (setq start2 (search-forward "\"" (+ start-border 200) t)))
124       (goto-char here)
125       (list start2 end2))))
126
127 (defun mumamo-chunk-attr=-new (pos
128                                ;;min
129                                max
130                                attr=
131                                attr=is-regex
132                                attr-regex
133                                submode)
134   ;;(message "\n(mumamo-chunk-attr=-new %s %s %s %s %s %s)" pos max attr= attr=is-regex attr-regex submode)
135   ;;(mumamo-condition-case err
136   (condition-case err
137       (save-match-data
138         (let ((here (point))
139               (next-attr= (progn
140                             ;; fix-me:
141                             (if (not attr=is-regex)
142                                 (goto-char (+ pos (length attr=)))
143                               (goto-char pos)
144                               (skip-chars-forward "a-zA-Z="))
145                             (goto-char pos)
146                             (if attr=is-regex
147                                 (re-search-forward attr= max t)
148                               (search-forward attr= max t))))
149               next-attr-sure
150               ;;next-attr=
151               start start-border
152               end   end-border
153               exc-mode
154               borders
155               exc-start-next
156               exc-end-next
157               exc-start-next
158               exc-end-next
159               (tries 0)
160               (min (1- pos))
161               look-max
162               )
163           ;; make sure if we have find prev-attr= or not
164           (unless (eq (char-after) ?\")
165             (setq next-attr= nil))
166           (when next-attr=
167             (forward-char)
168             (skip-chars-forward "^\"")
169             (setq look-max (+ (point) 2)))
170           (while (and next-attr=
171                       (< min (point))
172                       (not next-attr-sure)
173                       (< tries 5))
174             ;;(msgtrc "attr=-new: min=%s, point=%s" min (point))
175             (setq tries (1+ tries))
176             ;;(if (not (re-search-backward "<[^?]" (- min 300) t))
177             (if (not (re-search-backward "<[^?]\\|\?>" (- min 300) t))
178                 (setq next-attr= nil)
179               ;;(if (looking-at attr-regex)
180               (if (let ((here (point)))
181                     (prog1
182                         (re-search-forward attr-regex look-max t)
183                       (goto-char here)))
184               ;;(if (mumamo-end-in-code (point) next-attr= 'php-mode)
185                   (setq next-attr-sure 'found)
186                 (unless (bobp)
187                   (backward-char)
188                   ;;(msgtrc "attr=-new 1: min=%s, point=%s" min (point))
189                   (setq next-attr= (if attr=is-regex
190                                        (re-search-backward attr= (- min 300) t)
191                                      (search-backward attr= (- min 300) t)))))))
192           (unless next-attr-sure (setq next-attr= nil))
193
194
195           ;; find prev change and if inside style= the next change
196           (when next-attr=
197               (setq exc-start-next (match-beginning 1))
198               (setq exc-end-next   (match-end 2))
199               (when (>= exc-start-next pos)
200                 (if (> pos exc-end-next)
201                     (progn
202                       (setq start (+ (match-end 2) 1))
203                       ;;(setq start-border (+ (match-end 2) 2))
204                       )
205                   (setq exc-mode submode)
206                   (setq start (match-beginning 1))
207                   (setq start-border (match-beginning 2))
208                   (setq end (1+ (match-end 2)))
209                   (setq end-border (1- end)))
210                 ))
211           ;; find next change
212           (unless end
213             (if start
214                 (goto-char start)
215               (goto-char pos)
216               (search-backward "<" min t))
217             ;;(msgtrc "attr=-new 2: min=%s, point=%s" min (point))
218             (setq next-attr= (if attr=is-regex
219                                  (re-search-forward attr= max t)
220                                (search-forward attr= max t)))
221             (when (and next-attr=
222                        (search-backward "<" min t))
223               (when (looking-at attr-regex)
224                 (setq end (match-beginning 1)))))
225           (when start (assert (>= start pos) t))
226           (when end   (assert (<= pos end) t))
227           ;;(message "start-border=%s end-border=%s" start-border end-border)
228           (when (or start-border end-border)
229             (setq borders (list start-border end-border nil)))
230           ;; (message "mumamo-chunk-attr=-new: %s"
231           ;;          (list start
232           ;;                end
233           ;;                exc-mode
234           ;;                borders
235           ;;                nil ;; parseable-by
236           ;;                'mumamo-chunk-attr=-new-fw-exc-fun ;; fw-exc-fun
237           ;;                'mumamo-chunk-attr=-new-find-borders-fun ;; find-borders-fun
238           ;;                ))
239           (goto-char here)
240           (setq end nil)
241           (when (or start end)
242             (list start
243                   end
244                   exc-mode
245                   borders
246                   nil ;; parseable-by
247                   'mumamo-chunk-attr=-new-fw-exc-fun ;; fw-exc-fun
248                   'mumamo-chunk-attr=-new-find-borders-fun ;; find-borders-fun
249                   ))))
250     (error (mumamo-display-error 'mumamo-chunk-attr=-new "%s" (error-message-string err)))
251     ))
252
253 ;;;; xml pi
254
255 (defvar mumamo-xml-pi-mode-alist
256   '(("php"    . php-mode)
257     ("python" . python-mode))
258   "Alist used by `mumamo-chunk-xml-pi' to get exception mode." )
259
260 ;; Fix-me: make it possible to make the borders part of the php chunk
261 ;; so that parsing of them by nxml may be skipped. Or, rather if the
262 ;; borders are not part of the chunk then assume nxml can not parse
263 ;; the chunk and the borders.
264 ;; (defun mumamo-search-bw-exc-start-xml-pi-1 (pos min lt-chars)
265 ;;   "Helper for `mumamo-chunk-xml-pi'.
266 ;; POS is where to start search and MIN is where to stop.
267 ;; LT-CHARS is just <?.
268
269 ;; Actual use is in `mumamo-search-bw-exc-start-xml-pi'."
270 ;;   (let ((exc-start (mumamo-chunk-start-bw-str (+ pos 2) min lt-chars))
271 ;;         spec
272 ;;         exc-mode
273 ;;         hit)
274 ;;     (when exc-start
275 ;;       (goto-char exc-start)
276 ;;       (when (and (not (looking-at "xml"))
277 ;;                  (looking-at (rx (0+ (any "a-z")))))
278 ;;         ;; (setq exc-start (match-end 0)) include it in sub chunk instead
279 ;;         (setq exc-start (- exc-start 2))
280 ;;         (setq spec (match-string-no-properties 0))
281 ;;         (setq exc-mode (assoc spec mumamo-xml-pi-mode-alist))
282 ;;         (when exc-mode (setq exc-mode (cdr exc-mode)))
283 ;;         (setq hit t)
284 ;;         )
285 ;;       (when hit
286 ;;         (unless exc-mode
287 ;;           ;;(setq exc-mode 'fundamental-mode)
288 ;;           ;; Fix-me: Better assume php-mode
289 ;;           (setq exc-mode 'php-mode))
290 ;;         (when (<= exc-start pos)
291 ;;           ;;(cons exc-start exc-mode)
292 ;;           (list exc-start exc-mode nil)
293 ;;           )))))
294
295 ;; (defun mumamo-search-bw-exc-start-xml-pi (pos min)
296 ;;   "Helper for `mumamo-chunk-xml-pi'.
297 ;; POS is where to start search and MIN is where to stop."
298 ;;   (mumamo-search-bw-exc-start-xml-pi-1 pos min "<?"))
299
300 (defun mumamo-search-fw-exc-start-xml-pi-new (pos max)
301   (let ((here (point))
302         start
303         spec
304         exc-mode
305         ret)
306     (setq start (search-forward "<?" max t))
307     (when (and start
308                (looking-at (rx (0+ (any "a-z")))))
309       (setq spec (match-string-no-properties 0))
310       (unless (string= spec "xml")
311         (when (= 0 (length spec))
312           (setq spec "php"))
313         (setq exc-mode (assoc spec mumamo-xml-pi-mode-alist))
314         (if exc-mode
315             (setq exc-mode (cdr exc-mode))
316           (setq exc-mode 'mumamo-bad-mode))
317         (setq ret (list (- start 2) exc-mode nil))))
318     (goto-char here)
319     ret))
320
321 (defun mumamo-xml-pi-end-is-xml-end (pos)
322   "Return t if the ?> at pos is end of <?xml."
323   (when (> 1000 pos)
324 ;;;     (assert (and (= (char-after pos) ??)
325 ;;;                  (= (char-after (1+ pos)) ?>)))
326     (save-excursion
327       (save-restriction
328         (widen)
329         (save-match-data
330           (when (search-backward "<" (- pos 150) t)
331             (when (looking-at (rx line-start "<\?xml" (1+ space)))
332               (mumamo-msgfntfy "mumamo-xml-pi-end-is-xml-end %s => t" pos)
333               t)))))))
334
335 ;; (defun mumamo-search-bw-exc-end-xml-pi (pos min)
336 ;;   "Helper for `mumamo-chunk-xml-pi'.
337 ;; POS is where to start search and MIN is where to stop."
338 ;;   ;; Fix me: merge xml header
339 ;;   (mumamo-msgfntfy "mumamo-search-bw-exc-end-xml-pi %s %s" pos min)
340 ;;   ;;(let ((end-pos (mumamo-chunk-end-bw-str pos min "?>")))
341 ;;   (let ((end-pos (mumamo-chunk-end-bw-str-inc pos min "?>")))
342 ;;     (mumamo-msgfntfy "  end-pos=%s" end-pos)
343 ;;     (when end-pos
344 ;;       (unless (or (mumamo-xml-pi-end-is-xml-end end-pos)
345 ;;                   (= (save-restriction
346 ;;                        (widen)
347 ;;                        (char-after (- end-pos 1)))
348 ;;                      ?<))
349 ;;         (mumamo-msgfntfy "  returning end-pos")
350 ;;         end-pos))))
351
352 (defun mumamo-search-fw-exc-end-xml-pi (pos max)
353   "Helper for `mumamo-chunk-xml-pi'.
354 POS is where to start search and MAX is where to stop."
355   ;; Fix me: merge xml header
356   ;;(let ((end-pos (mumamo-chunk-end-fw-str pos max "?>")))
357   (save-match-data
358     (let ((end-pos (mumamo-chunk-end-fw-str-inc pos max "?>")))
359       (when end-pos
360         (unless (mumamo-xml-pi-end-is-xml-end end-pos)
361           end-pos)))))
362
363 (defun mumamo-search-fw-exc-start-xml-pi-1 (pos max lt-chars)
364   "Helper for `mumamo-chunk-xml-pi'.
365 POS is where to start search and MAX is where to stop.
366
367 Used in `mumamo-search-fw-exc-start-xml-pi'.  For an explanation
368 of LT-CHARS see `mumamo-search-bw-exc-start-xml-pi-1'."
369   (goto-char pos)
370   (skip-chars-backward "a-zA-Z")
371   ;;(let ((end-out (mumamo-chunk-start-fw-str (point) max lt-chars)))
372   (let ((end-out (mumamo-chunk-start-fw-str-inc (point) max lt-chars))
373         spec
374         exc-mode
375         hit)
376     (when (looking-at "xml")
377       (if t ;(= 1 pos)
378           (setq end-out (mumamo-chunk-start-fw-str-inc (1+ (point)) max lt-chars))
379         (setq end-out nil)))
380     (when end-out
381       ;; Get end-out:
382       (if (looking-at (rx (0+ (any "a-z"))))
383           (progn
384             ;;(setq end-out (match-end 0))
385             (setq end-out (- (match-beginning 0) 2))
386             (setq spec (match-string-no-properties 0))
387             (setq exc-mode (assoc spec mumamo-xml-pi-mode-alist))
388             (if exc-mode
389                 (setq exc-mode (cdr exc-mode))
390               (setq exc-mode 'php-mode))
391             (setq end-out (list end-out exc-mode nil))
392             )
393         (setq end-out nil))
394       end-out)))
395
396 (defun mumamo-search-fw-exc-start-xml-pi-old (pos max)
397   "Helper for `mumamo-chunk-xml-pi'.
398 POS is where to start search and MAX is where to stop."
399   (mumamo-search-fw-exc-start-xml-pi-1 pos max "<?"))
400
401 ;; Add a find-borders-fun here so that for example src="<?php some
402 ;; code ?>" can be handled.
403 ;;
404 ;; Fix-me: Maybe generalize for other values than <?php
405 (defun mumamo-find-borders-xml-pi (start end exc-mode)
406   (let (start-border
407         end-border
408         (inc t)
409         ;;(begin-mark "<?php")
410         (begin-mark "<?")
411         (end-mark "?>")
412         (here (point)))
413     (if (and inc) ;; exc-mode)
414         (progn
415           (when start
416             ;;(setq start-border (+ start (length begin-mark)))
417             (goto-char (+ start (length begin-mark)))
418             (skip-chars-forward "=a-zA-Z")
419             (setq start-border (point))
420             )
421           (when end
422             (setq end-border
423                   (- end (length end-mark)))))
424       (if (and (not inc) (not exc-mode))
425           (progn
426             (when start
427               (setq start-border
428                     (+ start (length end-mark))))
429             (when end
430               (setq end-border (- end (length begin-mark)))
431               ;;(goto-char end)
432               ;;(skip-chars-forward "=a-zA-Z")
433               ;;(setq end-border (point))
434               ))))
435     (goto-char here)
436     (when (or start-border end-border)
437       (list start-border end-border))))
438
439 (defun mumamo-chunk-xml-pi (pos min max)
440   "Find process instruction, <? ... ?>.  Return range and wanted mode.
441 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
442   ;; (mumamo-find-possible-chunk pos min max
443   ;;                             'mumamo-search-bw-exc-start-xml-pi
444   ;;                             'mumamo-search-bw-exc-end-xml-pi
445   ;;                             'mumamo-search-fw-exc-start-xml-pi-old
446   ;;                             'mumamo-search-fw-exc-end-xml-pi
447   ;;                             'mumamo-find-borders-xml-pi)
448   (mumamo-possible-chunk-forward pos max
449                                  'mumamo-search-fw-exc-start-xml-pi-new
450                                  'mumamo-search-fw-exc-end-xml-pi
451                                  'mumamo-find-borders-xml-pi))
452
453
454 ;;;; <style ...>
455
456 (defconst mumamo-style-tag-start-regex
457   (rx "<style"
458       space
459       (0+ (not (any ">")))
460       "type"
461       (0+ space)
462       "="
463       (0+ space)
464       ?\"
465       "text/css"
466       ?\"
467       (0+ (not (any ">")))
468       ">"
469       ;; FIX-ME: Commented out because of bug in Emacs
470       ;;
471       ;;(optional (0+ space) "<![CDATA[")
472       ))
473
474 ;; (defun mumamo-search-bw-exc-start-inlined-style (pos min)
475 ;;   "Helper for `mumamo-chunk-inlined-style'.
476 ;; POS is where to start search and MIN is where to stop."
477 ;;   (goto-char (+ pos 6))
478 ;;   (let ((marker-start (search-backward "<style" min t))
479 ;;         exc-mode
480 ;;         exc-start)
481 ;;     (when marker-start
482 ;;       (when (looking-at mumamo-style-tag-start-regex)
483 ;;         (setq exc-start (match-end 0))
484 ;;         (goto-char exc-start)
485 ;;         (when (<= exc-start pos)
486 ;;           ;;(cons (point) 'css-mode)
487 ;;           ;;(list (point) 'css-mode '(nxml-mode))
488 ;;           ;; Fix-me: Kubica looping problem
489 ;;           (list (point) 'css-mode)
490 ;;           )
491 ;;         ))))
492
493 ;; (defun mumamo-search-bw-exc-end-inlined-style (pos min)
494 ;;   "Helper for `mumamo-chunk-inlined-style'.
495 ;; POS is where to start search and MIN is where to stop."
496 ;;   (mumamo-chunk-end-bw-str pos min "</style>"))
497
498 ;; (defun mumamo-search-fw-exc-start-inlined-style-old (pos max)
499 ;;   "Helper for `mumamo-chunk-inlined-style'.
500 ;; POS is where to start search and MAX is where to stop."
501 ;;   (goto-char (1+ pos))
502 ;;   (skip-chars-backward "^<")
503 ;;   ;; Handle <![CDATA[
504 ;;   (when (and
505 ;;          (eq ?< (char-before))
506 ;;          (eq ?! (char-after))
507 ;;          (not (bobp)))
508 ;;     (backward-char)
509 ;;     (skip-chars-backward "^<"))
510 ;;   (unless (bobp)
511 ;;     (backward-char 1))
512 ;;   (let ((exc-start (search-forward "<style" max t))
513 ;;         exc-mode)
514 ;;     (when exc-start
515 ;;       (goto-char (- exc-start 6))
516 ;;       (when (looking-at mumamo-style-tag-start-regex)
517 ;;         (goto-char (match-end 0))
518 ;;         (point)
519 ;;         ))))
520
521 (defun mumamo-search-fw-exc-end-inlined-style (pos max)
522   "Helper for `mumamo-chunk-inlined-style'.
523 POS is where to start search and MAX is where to stop."
524   (save-match-data
525     (mumamo-chunk-end-fw-str pos max "</style>")))
526
527 ;; (defun mumamo-chunk-inlined-style-old (pos min max)
528 ;;   "Find <style>...</style>.  Return range and 'css-mode.
529 ;; See `mumamo-find-possible-chunk' for POS, MIN and MAX."
530 ;;   (mumamo-find-possible-chunk pos min max
531 ;;                               'mumamo-search-bw-exc-start-inlined-style
532 ;;                               'mumamo-search-bw-exc-end-inlined-style
533 ;;                               'mumamo-search-fw-exc-start-inlined-style-old
534 ;;                               'mumamo-search-fw-exc-end-inlined-style))
535
536 (defun mumamo-search-fw-exc-start-inlined-style (pos max)
537   "Helper for `mumamo-chunk-inlined-style'.
538 POS is where to start search and MAX is where to stop."
539   (goto-char (1+ pos))
540   (skip-chars-backward "^<")
541   ;; Handle <![CDATA[
542   (when (and
543          (eq ?< (char-before))
544          (eq ?! (char-after))
545          (not (bobp)))
546     (backward-char)
547     (skip-chars-backward "^<"))
548   (unless (bobp)
549     (backward-char 1))
550   (let ((exc-start (search-forward "<style" max t))
551         exc-mode)
552     (when exc-start
553       (goto-char (- exc-start 6))
554       (when (looking-at mumamo-style-tag-start-regex)
555         (goto-char (match-end 0))
556         (list (point) 'css-mode nil)
557         ))))
558
559 (defun mumamo-chunk-inlined-style (pos min max)
560   "Find <style>...</style>.  Return range and 'css-mode.
561 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
562   (mumamo-possible-chunk-forward pos max
563                                  'mumamo-search-fw-exc-start-inlined-style
564                                  'mumamo-search-fw-exc-end-inlined-style))
565
566 ;;;; <script ...>
567
568 (defconst mumamo-script-tag-start-regex
569   (rx "<script"
570       space
571       (0+ (not (any ">")))
572       "type"
573       (0+ space)
574       "="
575       (0+ space)
576       ?\"
577       ;;(or "text" "application")
578       ;;"/"
579       ;;(or "javascript" "ecmascript")
580       "text/javascript"
581       ?\"
582       (0+ (not (any ">")))
583       ">"
584       ;; FIX-ME: Commented out because of bug in Emacs
585       ;;
586       ;;(optional (0+ space) "<![CDATA[" )
587       ))
588
589 ;; (defun mumamo-search-bw-exc-start-inlined-script (pos min)
590 ;;   "Helper for `mumamo-chunk-inlined-script'.
591 ;; POS is where to start search and MIN is where to stop."
592 ;;   (goto-char (+ pos 7))
593 ;;   (let ((marker-start (when (< min (point)) (search-backward "<script" min t)))
594 ;;         exc-mode
595 ;;         exc-start)
596 ;;     (when marker-start
597 ;;       (when (looking-at mumamo-script-tag-start-regex)
598 ;;         (setq exc-start (match-end 0))
599 ;;         (goto-char exc-start)
600 ;;         (when (<= exc-start pos)
601 ;;           ;;(cons (point) 'javascript-mode)
602 ;;           (list (point) 'javascript-mode '(nxml-mode))
603 ;;           )
604 ;;         ))))
605
606 ;; (defun mumamo-search-bw-exc-end-inlined-script (pos min)
607 ;;   "Helper for `mumamo-chunk-inlined-script'.
608 ;; POS is where to start search and MIN is where to stop."
609 ;;   (mumamo-chunk-end-bw-str pos min "</script>"))
610
611 ;; (defun mumamo-search-fw-exc-start-inlined-script-old (pos max)
612 ;;   "Helper for `mumamo-chunk-inlined-script'.
613 ;; POS is where to start search and MAX is where to stop."
614 ;;   (goto-char (1+ pos))
615 ;;   (skip-chars-backward "^<")
616 ;;   ;; Handle <![CDATA[
617 ;;   (when (and
618 ;;          (eq ?< (char-before))
619 ;;          (eq ?! (char-after))
620 ;;          (not (bobp)))
621 ;;     (backward-char)
622 ;;     (skip-chars-backward "^<"))
623 ;;   (unless (bobp)
624 ;;     (backward-char 1))
625 ;;   (let ((exc-start (search-forward "<script" max t))
626 ;;         exc-mode)
627 ;;     (when exc-start
628 ;;       (goto-char (- exc-start 7))
629 ;;       (when (looking-at mumamo-script-tag-start-regex)
630 ;;         (goto-char (match-end 0))
631 ;;         (point)
632 ;;         ))))
633
634 (defun mumamo-search-fw-exc-end-inlined-script (pos max)
635   "Helper for `mumamo-chunk-inlined-script'.
636 POS is where to start search and MAX is where to stop."
637   (save-match-data
638     (mumamo-chunk-end-fw-str pos max "</script>")))
639
640 ;; (defun mumamo-chunk-inlined-script-old (pos min max)
641 ;;   "Find <script>...</script>.  Return range and 'javascript-mode.
642 ;; See `mumamo-find-possible-chunk' for POS, MIN and MAX."
643 ;;   (mumamo-find-possible-chunk pos min max
644 ;;                               'mumamo-search-bw-exc-start-inlined-script
645 ;;                               'mumamo-search-bw-exc-end-inlined-script
646 ;;                               'mumamo-search-fw-exc-start-inlined-script-old
647 ;;                               'mumamo-search-fw-exc-end-inlined-script))
648
649 (defun mumamo-search-fw-exc-start-inlined-script (pos max)
650   "Helper for `mumamo-chunk-inlined-script'.
651 POS is where to start search and MAX is where to stop."
652   (goto-char (1+ pos))
653   (skip-chars-backward "^<")
654   ;; Handle <![CDATA[
655   (when (and
656          (eq ?< (char-before))
657          (eq ?! (char-after))
658          (not (bobp)))
659     (backward-char)
660     (skip-chars-backward "^<"))
661   (unless (bobp)
662     (backward-char 1))
663   (let ((exc-start (search-forward "<script" max t))
664         exc-mode)
665     (when exc-start
666       (goto-char (- exc-start 7))
667       (when (looking-at mumamo-script-tag-start-regex)
668         (goto-char (match-end 0))
669         (list (point) 'javascript-mode '(nxml-mode))
670         ))))
671
672 (defun mumamo-chunk-inlined-script (pos min max)
673   "Find <script>...</script>.  Return range and 'javascript-mode.
674 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
675   (mumamo-possible-chunk-forward pos max
676                                  'mumamo-search-fw-exc-start-inlined-script
677                                  'mumamo-search-fw-exc-end-inlined-script))
678
679 ;;;; on[a-z]+=\"javascript:"
680
681 (defconst mumamo-onjs=-attr=
682   (rx
683    ;;"on[a-z]+="
684    (or "onclick" "ondblclick" "onmousedown" "onmousemove" "onmouseout" "onmouseover" "onmouseup" "onkeydown" "onkeypress" "onkeyup")
685    "="))
686
687 (defconst mumamo-onjs=-attr-regex
688   (rx point
689       (or "<" "?>")
690       (* (not (any ">")))
691       space
692       (submatch
693        ;;"on" (1+ (any "a-za-z"))
694        (or "onclick" "ondblclick" "onmousedown" "onmousemove" "onmouseout" "onmouseover" "onmouseup" "onkeydown" "onkeypress" "onkeyup")
695        "=")
696       (0+ space)
697       ?\"
698       (submatch
699        (opt "javascript:")
700        (0+
701         (not (any "\""))))
702       ))
703
704 (defun mumamo-chunk-onjs=(pos min max)
705   "Find javascript on...=\"...\".  Return range and 'javascript-mode."
706   (mumamo-chunk-attr= pos min max mumamo-onjs=-attr= t mumamo-onjs=-attr-regex
707                       'javascript-mode))
708
709 ;;;; py:somthing=\"python\"
710
711 (defconst mumamo-py:=-attr= "py:[a-z]+=")
712
713 (defconst mumamo-py:=-attr-regex
714   (rx point
715       (or "<" "?>")
716       (* (not (any ">")))
717       space
718       (submatch
719        "py:" (1+ (any "a-za-z"))
720        "=")
721       (0+ space)
722       ?\"
723       (submatch
724        (0+
725         (not (any "\""))))
726       ))
727
728 (defun mumamo-chunk-py:=(pos min max)
729   "Find python py:...=\"...\".  Return range and 'python-mode."
730   (mumamo-chunk-attr= pos min max mumamo-py:=-attr= t mumamo-py:=-attr-regex
731                       'python-mode))
732
733 (defun mumamo-chunk-py:match (pos min max)
734   (save-match-data
735     (let ((here (point))
736           (py:match (progn
737                       (goto-char pos)
738                       (re-search-forward (rx "py:match"
739                                              (1+ space)
740                                              (0+ (not (any ">")))
741                                              word-start
742                                              (submatch "path=")
743                                              (0+ space)
744                                              ?\"
745                                              (submatch
746                                               (0+
747                                                (not (any "\"")))))
748                                          max t)))
749           start end borders
750           )
751       (when py:match
752         (setq start (match-beginning 1))
753         (setq end   (match-end 2))
754         (setq borders (list (match-end 1) (1- end)))
755         )
756       (goto-char here)
757       (when start
758         (list start
759               end
760               'python-mode
761               borders
762               nil ;; parseable-by
763               'mumamo-chunk-attr=-new-fw-exc-fun ;; fw-exc-fun
764               'mumamo-chunk-attr=-new-find-borders-fun ;; find-borders-fun
765             )))))
766
767 ;;;; style=
768
769 (defconst mumamo-style=start-regex
770   (rx "<"
771       (0+ (not (any ">")))
772       space
773       (submatch "style=")
774       (0+ space)
775       ?\"
776       (submatch
777        (0+
778         (not (any "\""))))
779       ))
780
781 (defun mumamo-chunk-style=(pos min max)
782   "Find style=\"...\".  Return range and 'css-mode."
783   (mumamo-chunk-attr= pos min max "style=" nil mumamo-style=start-regex
784                       'css-mode))
785
786
787 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
788 ;;;; HTML w html-mode
789
790 (put 'mumamo-alt-php-tags-mode 'permanent-local t)
791 (define-minor-mode mumamo-alt-php-tags-mode
792   "Minor mode for using '(?php' instead of '<?php' in buffer.
793 When turning on this mode <?php is replace with (?php in the buffer.
794 If you write the buffer to file (?php is however written as <?php.
795
796 When turning off this mode (?php is replace with <?php in the buffer.
797
798 The purpose of this minor mode is to work around problems with
799 using the `nxml-mode' parser in php files.  `nxml-mode' knows
800 damned well that you can not have the character < in strings and
801 I can't make it forget that.  For PHP programmers it is however
802 very convient to use <?php ... ?> in strings.
803
804 There is no reason to use this minor mode unless you want XML
805 validation and/or completion in your php file.  If you do not
806 want that then you can simply use a multi major mode based on
807 `html-mode' instead of `nxml-mode'/`nxhtml-mode'.  Or, of course,
808 just `php-mode' if there is no html code in the file."
809   :lighter "<?php "
810   (if mumamo-alt-php-tags-mode
811       (progn
812         ;;(unless mumamo-multi-major-mode (error "Only for mumamo multi major modes"))
813         (unless (let ((major-mode (mumamo-main-major-mode)))
814                   (derived-mode-p 'nxml-mode))
815           ;;(error "Mumamo multi major mode must be based on nxml-mode")
816           )
817         (unless (memq 'mumamo-chunk-alt-php (caddr mumamo-current-chunk-family))
818           (error "Mumamo multi major must have chunk function mumamo-chunk-alt-php"))
819
820         ;; Be paranoid about the file/content write hooks
821         (when (<= emacs-major-version 22)
822           (with-no-warnings
823             (when local-write-file-hooks ;; obsolete, but check!
824               (error "Will not do this because local-write-file-hooks is non-nil"))))
825         (remove-hook 'write-contents-functions 'mumamo-alt-php-write-contents t)
826         (when write-contents-functions
827           (error "Will not do this because write-contents-functions is non-nil"))
828         (when (delq 'recentf-track-opened-file (copy-sequence write-file-functions))
829           (error "Will not do this because write-file-functions is non-nil"))
830
831         (add-hook 'write-contents-functions 'mumamo-alt-php-write-contents t t)
832         (put 'write-contents-functions 'permanent-local t)
833         (save-restriction
834           (let ((here (point)))
835             (widen)
836             (goto-char (point-min))
837             (while (search-forward "<?php" nil t)
838               (replace-match "(?php"))
839             (goto-char (point-min))
840             (while (search-forward "<?=" nil t)
841               (replace-match "(?="))
842             (goto-char (point-min))
843             (while (search-forward "?>" nil t)
844                 (replace-match "?)"))
845             (goto-char here))))
846     (save-restriction
847       (let ((here (point)))
848         (widen)
849         (goto-char (point-min))
850         (while (search-forward "(?php" nil t)
851           (replace-match "<?php"))
852         (goto-char (point-min))
853         (while (search-forward "(?=" nil t)
854           (replace-match "<?="))
855         (goto-char (point-min))
856         (while (search-forward "?)" nil t)
857           (replace-match "?>"))
858         (goto-char here)))
859     (remove-hook 'write-contents-functions 'mumamo-alt-php-write-contents t)))
860
861 (defun mumamo-chunk-alt-php (pos min max)
862   "Find (?php ... ?), return range and `php-mode'.
863 Workaround for the problem that I can not tame `nxml-mode' to recognize <?php.
864
865 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
866   (when mumamo-alt-php-tags-mode
867     (mumamo-quick-static-chunk pos min max "(?php" "?)" t 'php-mode t)))
868
869 (defun mumamo-chunk-alt-php= (pos min max)
870   "Find (?= ... ?), return range and `php-mode'.
871 Workaround for the problem that I can not tame `nxml-mode' to recognize <?php.
872
873 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
874   (when mumamo-alt-php-tags-mode
875     (mumamo-quick-static-chunk pos min max "(?=" "?)" t 'php-mode t)))
876
877 ;;;###autoload
878 (define-mumamo-multi-major-mode html-mumamo-mode
879   "Turn on multiple major modes for (X)HTML with main mode `html-mode'.
880 This covers inlined style and javascript and PHP."
881   ("HTML Family" html-mode
882    (mumamo-chunk-xml-pi
883     mumamo-chunk-alt-php
884     mumamo-chunk-alt-php=
885     mumamo-chunk-inlined-style
886     mumamo-chunk-inlined-script
887     mumamo-chunk-style=
888     mumamo-chunk-onjs=
889     )))
890 (add-hook 'html-mumamo-mode-hook 'mumamo-define-html-file-wide-keys)
891 (mumamo-inherit-sub-chunk-family 'html-mumamo-mode)
892
893 ;; (define-mumamo-multi-major-mode xml-pi-only-mumamo-mode
894 ;;   "Test"
895 ;;   ("HTML Family" html-mode
896 ;;    (mumamo-chunk-xml-pi
897 ;;     )))
898
899
900 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
901 ;;;; XHTML w nxml-mode
902
903 (defun mumamo-alt-php-write-contents ()
904   "For `write-contents-functions' when `mumamo-chunk-alt-php' is used."
905   (let ((here (point)))
906     (save-match-data
907       (save-restriction
908         (widen)
909         (condition-case nil
910             (atomic-change-group
911               (progn
912                 (goto-char (point-min))
913                 (while (search-forward "(?php" nil t)
914                   (replace-match "<?php"))
915                 (goto-char (point-min))
916                 (while (search-forward "(?=" nil t)
917                   (replace-match "<?="))
918                 (goto-char (point-min))
919                 (while (search-forward "?)" nil t)
920                   (replace-match "?>"))
921                 (basic-save-buffer-1)
922                 (signal 'mumamo-error-ind-0 nil)))
923           (mumamo-error-ind-0)))
924       (set-buffer-modified-p nil))
925     (goto-char here))
926   ;; saved, return t
927   t)
928
929 ;;;###autoload
930 (define-mumamo-multi-major-mode nxml-mumamo-mode
931   "Turn on multiple major modes for (X)HTML with main mode `nxml-mode'.
932 This covers inlined style and javascript and PHP.
933
934 See also `mumamo-alt-php-tags-mode'."
935   ("nXml Family" nxml-mode
936    (mumamo-chunk-xml-pi
937     mumamo-chunk-alt-php
938     mumamo-chunk-inlined-style
939     mumamo-chunk-inlined-script
940     mumamo-chunk-style=
941     mumamo-chunk-onjs=
942     )))
943 (add-hook 'nxml-mumamo-mode-hook 'mumamo-define-html-file-wide-keys)
944
945
946 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
947 ;;;; Mason (not ready)
948 ;; http://www.masonhq.com/docs/manual/Devel.html#examples_and_recommended_usage
949
950 (defun mumamo-chunk-mason-perl-line (pos min max)
951   (mumamo-whole-line-chunk pos min max "%" 'perl-mode))
952
953 (defun mumamo-chunk-mason-perl-single (pos min max)
954   (mumamo-quick-static-chunk pos min max "<% " " %>" t 'perl-mode t))
955
956 (defun mumamo-chunk-mason-perl-block (pos min max)
957   (mumamo-quick-static-chunk pos min max "<%perl>" "</%perl>" t 'perl-mode t))
958
959 (defun mumamo-chunk-mason-perl-init (pos min max)
960   (mumamo-quick-static-chunk pos min max "<%init>" "</%init>" t 'perl-mode t))
961
962 (defun mumamo-chunk-mason-perl-once (pos min max)
963   (mumamo-quick-static-chunk pos min max "<%once>" "</%once>" t 'perl-mode t))
964
965 (defun mumamo-chunk-mason-perl-cleanup (pos min max)
966   (mumamo-quick-static-chunk pos min max "<%cleanup>" "</%cleanup>" t 'perl-mode t))
967
968 (defun mumamo-chunk-mason-perl-shared (pos min max)
969   (mumamo-quick-static-chunk pos min max "<%shared>" "</%shared>" t 'perl-mode t))
970
971 (defun mumamo-chunk-mason-simple-comp (pos min max)
972   (mumamo-quick-static-chunk pos min max "<& " " &>" t 'text-mode t))
973
974 (defun mumamo-chunk-mason-args (pos min max)
975   ;; Fix-me: perl-mode is maybe not the best here?
976   (mumamo-quick-static-chunk pos min max "<%args>" "</%args>" t 'perl-mode t))
977
978 (defun mumamo-chunk-mason-doc (pos min max)
979   (mumamo-quick-static-chunk pos min max "<%doc>" "</%doc>" t 'mumamo-comment-mode t))
980
981 (defun mumamo-chunk-mason-text (pos min max)
982   (mumamo-quick-static-chunk pos min max "<%text>" "</%text>" t 'text-mode t))
983
984 ;; component calls with content
985
986 ;; (defun mumamo-chunk-mason-compcont-bw-exc-start-fun (pos min)
987 ;;   (let ((exc-start (mumamo-chunk-start-bw-str-inc pos min "<&| ")))
988 ;;     (and exc-start
989 ;;          (<= exc-start pos)
990 ;;          (cons exc-start 'html-mode))))
991
992 ;; (defun mumamo-chunk-mason-compcont-fw-exc-start-fun-old (pos max)
993 ;;   (mumamo-chunk-start-fw-str-inc pos max "<&| "))
994
995 (defun mumamo-chunk-mason-compcont-fw-exc-end-fun (pos max)
996   (mumamo-chunk-end-fw-str-inc pos max "</&>"))
997
998 (defun mumamo-chunk-mason-compcont-find-borders-fun (start end dummy)
999   (when dummy
1000     (list
1001      (when start
1002        (save-match-data
1003          (let ((here (point))
1004                ret)
1005            (goto-char start)
1006            (when (re-search-forward "[^>]* &>" end t)
1007              (setq ret (point))
1008              (goto-char here)
1009              ret))
1010          ))
1011      (when end (- end 4))
1012      dummy)))
1013
1014 ;; (defun mumamo-chunk-mason-compcont-old (pos min max)
1015 ;;   (mumamo-find-possible-chunk-new pos
1016 ;;                                   max
1017 ;;                                   'mumamo-chunk-mason-compcont-bw-exc-start-fun
1018 ;;                                   'mumamo-chunk-mason-compcont-fw-exc-start-fun-old
1019 ;;                                   'mumamo-chunk-mason-compcont-fw-exc-end-fun
1020 ;;                                   'mumamo-chunk-mason-compcont-find-borders-fun))
1021
1022 (defun mumamo-chunk-mason-compcont-fw-exc-start-fun (pos max)
1023   (let ((where (mumamo-chunk-start-fw-str-inc pos max "<&| ")))
1024     (when where
1025       (list where 'html-mode nil))))
1026
1027 (defun mumamo-chunk-mason-compcont (pos min max)
1028   (mumamo-possible-chunk-forward pos max
1029                                  'mumamo-chunk-mason-compcont-fw-exc-start-fun
1030                                  'mumamo-chunk-mason-compcont-fw-exc-end-fun
1031                                  'mumamo-chunk-mason-compcont-find-borders-fun))
1032
1033 ;;;###autoload
1034 (define-mumamo-multi-major-mode mason-html-mumamo-mode
1035   "Turn on multiple major modes for Mason using main mode `html-mode'.
1036 This covers inlined style and javascript."
1037   ("Mason html Family" html-mode
1038    (
1039     mumamo-chunk-mason-perl-line
1040     mumamo-chunk-mason-perl-single
1041     mumamo-chunk-mason-perl-block
1042     mumamo-chunk-mason-perl-init
1043     mumamo-chunk-mason-perl-once
1044     mumamo-chunk-mason-perl-cleanup
1045     mumamo-chunk-mason-perl-shared
1046     mumamo-chunk-mason-simple-comp
1047     mumamo-chunk-mason-compcont
1048     mumamo-chunk-mason-args
1049     mumamo-chunk-mason-doc
1050     mumamo-chunk-mason-text
1051     mumamo-chunk-inlined-style
1052     mumamo-chunk-inlined-script
1053     mumamo-chunk-style=
1054     mumamo-chunk-onjs=
1055     )))
1056 (add-hook 'mason-html-mumamo-mode-hook 'mumamo-define-html-file-wide-keys)
1057 (mumamo-inherit-sub-chunk-family-locally 'mason-html-mumamo-mode 'mason-html-mumamo-mode)
1058
1059 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1060 ;;;; Embperl
1061
1062 (defun mumamo-chunk-embperl-<- (pos min max)
1063   "Find [- ... -], return range and `perl-mode'.
1064 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1065   (mumamo-quick-static-chunk pos min max "[-" "-]" t 'perl-mode t))
1066
1067 (defun mumamo-chunk-embperl-<+ (pos min max)
1068   "Find [+ ... +], return range and `perl-mode'.
1069 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1070   (mumamo-quick-static-chunk pos min max "[+" "+]" t 'perl-mode nil))
1071
1072 (defun mumamo-chunk-embperl-<! (pos min max)
1073   "Find [! ... !], return range and `perl-mode'.
1074 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1075   (mumamo-quick-static-chunk pos min max "[!" "!]" t 'perl-mode t))
1076
1077 (defun mumamo-chunk-embperl-<$ (pos min max)
1078   "Find [$ ... $], return range and `perl-mode'.
1079 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1080   ;; This is a bit tricky since [$var] etc must be avoided.
1081   (let* ((begin-mark "[$")
1082          (end-mark "$]")
1083          (good-chars '(32 ;space
1084                        10 ;line feed
1085                        9  ;tab
1086                        ))
1087          ;; (search-bw-exc-start (lambda (pos min)
1088          ;;                        (let ((not-found t)
1089          ;;                              (next-char nil)
1090          ;;                              (exc-start (mumamo-chunk-start-bw-str
1091          ;;                                          pos min begin-mark))
1092          ;;                              (here (point)))
1093          ;;                          (while (and not-found
1094          ;;                                      exc-start)
1095          ;;                            (setq next-char (char-after (+ (point) 2)))
1096          ;;                            (if (memq next-char good-chars)
1097          ;;                                (setq not-found nil)
1098          ;;                              (setq exc-start
1099          ;;                                    (search-backward begin-mark
1100          ;;                                                     min t))))
1101          ;;                          (when (and exc-start
1102          ;;                                     (<= exc-start pos))
1103          ;;                            (cons exc-start 'perl-mode)))))
1104          ;; (search-bw-exc-end (lambda (pos min)
1105          ;;                      (mumamo-chunk-end-bw-str pos min end-mark)))
1106          ;; (search-fw-exc-start-old (lambda (pos max)
1107          ;;                            (let ((not-found t)
1108          ;;                                  (next-char nil)
1109          ;;                                  (exc-start (mumamo-chunk-start-fw-str
1110          ;;                                              pos max begin-mark))
1111          ;;                                  (here (point)))
1112          ;;                              (while (and not-found
1113          ;;                                          exc-start)
1114          ;;                                (setq next-char (char-after))
1115          ;;                                (if (memq next-char good-chars)
1116          ;;                                    (setq not-found nil)
1117          ;;                                  (setq exc-start
1118          ;;                                    (search-forward begin-mark
1119          ;;                                                    max t))))
1120          ;;                              exc-start)))
1121          (search-fw-exc-start (lambda (pos max)
1122                                 (let ((not-found t)
1123                                       (next-char nil)
1124                                       (exc-start (mumamo-chunk-start-fw-str
1125                                                   pos max begin-mark))
1126                                       (here (point)))
1127                                   (while (and not-found
1128                                               exc-start)
1129                                     (setq next-char (char-after))
1130                                     (if (memq next-char good-chars)
1131                                         (setq not-found nil)
1132                                       (setq exc-start
1133                                             (search-forward begin-mark
1134                                                             max t))))
1135                                   (list exc-start 'perl-mode))))
1136          (search-fw-exc-end (lambda (pos max)
1137                               (save-match-data
1138                                 (mumamo-chunk-end-fw-str pos max end-mark))))
1139          )
1140     ;; (mumamo-find-possible-chunk pos min max
1141     ;;                             search-bw-exc-start
1142     ;;                             search-bw-exc-end
1143     ;;                             search-fw-exc-start-old
1144     ;;                             search-fw-exc-end)
1145     (mumamo-possible-chunk-forward pos max
1146                                 search-fw-exc-start
1147                                 search-fw-exc-end)
1148     ))
1149
1150 ;;;###autoload
1151 (define-mumamo-multi-major-mode embperl-html-mumamo-mode
1152   "Turn on multiple major modes for Embperl files with main mode `html-mode'.
1153 This also covers inlined style and javascript."
1154     ("Embperl HTML Family" html-mode
1155      (mumamo-chunk-embperl-<-
1156       mumamo-chunk-embperl-<+
1157       mumamo-chunk-embperl-<!
1158       mumamo-chunk-embperl-<$
1159       mumamo-chunk-inlined-style
1160       mumamo-chunk-inlined-script
1161       mumamo-chunk-style=
1162       mumamo-chunk-onjs=
1163      )))
1164
1165
1166 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1167 ;;;; django
1168
1169 (defun mumamo-chunk-django4(pos min max)
1170   "Find {% comment %}.  Return range and `django-mode'.
1171 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1172   (mumamo-quick-static-chunk pos min max "{% comment %}" "{% endcomment %}" t 'mumamo-comment-mode t))
1173
1174 (defun mumamo-chunk-django3(pos min max)
1175   "Find {# ... #}.  Return range and `django-mode'.
1176 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1177   (mumamo-quick-static-chunk pos min max "{#" "#}" t 'mumamo-comment-mode t))
1178
1179 (defun mumamo-chunk-django2(pos min max)
1180   "Find {{ ... }}.  Return range and `django-mode'.
1181 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1182   (mumamo-quick-static-chunk pos min max "{{" "}}" t 'django-variable-mode t))
1183
1184 (defun mumamo-chunk-django (pos min max)
1185   "Find {% ... %}.  Return range and `django-mode'.
1186 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1187   (let ((chunk (mumamo-quick-static-chunk pos min max "{%" "%}" t 'django-mode t)))
1188     (when chunk
1189       (setcdr (last chunk) '(mumamo-template-indentor))
1190       chunk)))
1191
1192 ;; (defun mumamo-search-bw-exc-start-django (pos min)
1193 ;;   "Helper for `mumamo-chunk-django'.
1194 ;; POS is where to start search and MIN is where to stop."
1195 ;;   (let ((exc-start (mumamo-chunk-start-bw-str-inc pos min "{%")))
1196 ;;     (and exc-start
1197 ;;          (<= exc-start pos)
1198 ;;          (cons exc-start 'django-mode))))
1199
1200 ;; (defun mumamo-search-bw-exc-start-django2(pos min)
1201 ;;   "Helper for `mumamo-chunk-django2'.
1202 ;; POS is where to start search and MIN is where to stop."
1203 ;;   (let ((exc-start (mumamo-chunk-start-bw-str-inc pos min "{{")))
1204 ;;     (and exc-start
1205 ;;          (<= exc-start pos)
1206 ;;          (cons exc-start 'django-mode))))
1207
1208 ;; (defun mumamo-search-bw-exc-start-django3(pos min)
1209 ;;   "Helper for `mumamo-chunk-django3'.
1210 ;; POS is where to start search and MIN is where to stop."
1211 ;;   (let ((exc-start (mumamo-chunk-start-bw-str-inc pos min "{#")))
1212 ;;     (and exc-start
1213 ;;          (<= exc-start pos)
1214 ;;          (cons exc-start 'mumamo-comment-mode))))
1215
1216 ;; (defun mumamo-search-bw-exc-start-django4(pos min)
1217 ;;   "Helper for `mumamo-chunk-django4'.
1218 ;; POS is where to start search and MIN is where to stop."
1219 ;;   (let ((exc-start (mumamo-chunk-start-bw-str-inc pos min
1220 ;;                                                        "{% comment %}")))
1221 ;;     (and exc-start
1222 ;;          (<= exc-start pos)
1223 ;;          (cons exc-start 'mumamo-comment-mode))))
1224
1225 ;; (defun mumamo-search-bw-exc-end-django (pos min)
1226 ;;   "Helper for `mumamo-chunk-django'.
1227 ;; POS is where to start search and MIN is where to stop."
1228 ;;   (mumamo-chunk-end-bw-str-inc pos min "%}"))
1229
1230 ;; (defun mumamo-search-bw-exc-end-django2(pos min)
1231 ;;   "Helper for `mumamo-chunk-django2'.
1232 ;; POS is where to start search and MIN is where to stop."
1233 ;;   (mumamo-chunk-end-bw-str-inc pos min "}}"))
1234
1235 ;; (defun mumamo-search-bw-exc-end-django3(pos min)
1236 ;;   "Helper for `mumamo-chunk-django3'.
1237 ;; POS is where to start search and MIN is where to stop."
1238 ;;   (mumamo-chunk-end-bw-str-inc pos min "#}"))
1239
1240 ;; (defun mumamo-search-bw-exc-end-django4(pos min)
1241 ;;   "Helper for `mumamo-chunk-django4'.
1242 ;; POS is where to start search and MIN is where to stop."
1243 ;;   (mumamo-chunk-end-bw-str-inc pos min "{% endcomment %}"))
1244
1245 (defun mumamo-search-fw-exc-start-django (pos max)
1246   "Helper for `mumamo-chunk-django'.
1247 POS is where to start search and MAX is where to stop."
1248   (mumamo-chunk-start-fw-str-inc pos max "{%"))
1249
1250 (defun mumamo-search-fw-exc-start-django2(pos max)
1251   "Helper for `mumamo-chunk-django2'.
1252 POS is where to start search and MAX is where to stop."
1253   (mumamo-chunk-start-fw-str-inc pos max "{{"))
1254
1255 (defun mumamo-search-fw-exc-start-django3(pos max)
1256   "Helper for `mumamo-chunk-django3'.
1257 POS is where to start search and MAX is where to stop."
1258   (mumamo-chunk-start-fw-str-inc pos max "{#"))
1259
1260 (defun mumamo-search-fw-exc-start-django4(pos max)
1261   "Helper for `mumamo-chunk-django4'.
1262 POS is where to start search and MAX is where to stop."
1263   (mumamo-chunk-start-fw-str-inc pos max "{% comment %}"))
1264
1265 (defun mumamo-search-fw-exc-end-django (pos max)
1266   "Helper for `mumamo-chunk-django'.
1267 POS is where to start search and MAX is where to stop."
1268   (mumamo-chunk-end-fw-str-inc pos max "%}"))
1269
1270 (defun mumamo-search-fw-exc-end-django2(pos max)
1271   "Helper for `mumamo-chunk-django2'.
1272 POS is where to start search and MAX is where to stop."
1273   (mumamo-chunk-end-fw-str-inc pos max "}}"))
1274
1275 (defun mumamo-search-fw-exc-end-django3(pos max)
1276   "Helper for `mumamo-chunk-django3'.
1277 POS is where to start search and MAX is where to stop."
1278   (mumamo-chunk-end-fw-str-inc pos max "#}"))
1279
1280 (defun mumamo-search-fw-exc-end-django4(pos max)
1281   "Helper for `mumamo-chunk-django4'.
1282 POS is where to start search and MAX is where to stop."
1283   (mumamo-chunk-end-fw-str-inc pos max "{% endcomment %}"))
1284
1285 ;;;###autoload
1286 (define-mumamo-multi-major-mode django-html-mumamo-mode
1287   "Turn on multiple major modes for Django with main mode `html-mode'.
1288 This also covers inlined style and javascript."
1289   ("Django HTML Family" html-mode
1290    (mumamo-chunk-django4
1291     mumamo-chunk-django
1292     mumamo-chunk-django2
1293     mumamo-chunk-django3
1294     mumamo-chunk-inlined-style
1295     mumamo-chunk-inlined-script
1296     mumamo-chunk-style=
1297     mumamo-chunk-onjs=
1298     )))
1299
1300
1301 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1302 ;;;; Genshi / kid
1303
1304 ;; {% python ... %}
1305 (defun mumamo-chunk-genshi%(pos min max)
1306   "Find {% python ... %}.  Return range and `genshi-mode'.
1307 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1308   (mumamo-quick-static-chunk pos min max "{% python" "%}" t 'python-mode t))
1309
1310 ;; ${expr}
1311 (defun mumamo-chunk-genshi$(pos min max)
1312   "Find ${ ... }, return range and `python-mode'.
1313 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1314   (let ((chunk
1315          (mumamo-quick-static-chunk pos min max "${" "}" t 'python-mode t)))
1316     (when chunk
1317       ;; Test for clash with %}
1318       (let ((sub-mode (nth 2 chunk))
1319             (start (nth 0 chunk)))
1320         (if sub-mode
1321             chunk
1322           ;;(message "point.1=%s" (point))
1323           (when (and start
1324                      (eq ?% (char-before start)))
1325             ;;(message "point.2=%s" (point))
1326             ;;(message "clash with %%}, chunk=%s" chunk)
1327             ;;(setq chunk nil)
1328             (setcar chunk (1- start))
1329             )
1330           ;;(message "chunk.return=%s" chunk)
1331           chunk)))))
1332
1333 ;; Fix-me: Because of the way chunks currently are searched for there
1334 ;; is an error when a python chunk is used. This is because mumamo
1335 ;; gets confused by the %} ending and the } ending.  This can be
1336 ;; solved by running a separate phase to get the chunks first and
1337 ;; during that phase match start and end of the chunk.
1338
1339
1340 ;; Note: You will currently get fontification errors if you use
1341 ;; python chunks
1342
1343 ;;   {% python ... %}
1344
1345 ;; The reason is that the chunk routines currently do not know when
1346 ;; to just look for the } or %} endings.  However this should not
1347 ;; affect your editing normally.
1348
1349 ;;;###autoload
1350 (define-mumamo-multi-major-mode genshi-html-mumamo-mode
1351   "Turn on multiple major modes for Genshi with main mode `html-mode'.
1352 This also covers inlined style and javascript."
1353   ("Genshi HTML Family" html-mode
1354    (
1355     ;;mumamo-chunk-genshi%
1356     mumamo-chunk-genshi$
1357     mumamo-chunk-py:=
1358     mumamo-chunk-py:match
1359     mumamo-chunk-xml-pi
1360     mumamo-chunk-inlined-style
1361     mumamo-chunk-inlined-script
1362     mumamo-chunk-style=
1363     mumamo-chunk-onjs=
1364     )))
1365
1366 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1367 ;;;; MJT
1368
1369 ;; ${expr}
1370 (defun mumamo-chunk-mjt$(pos min max)
1371   "Find ${ ... }, return range and `javascript-mode'.
1372 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1373   (mumamo-quick-static-chunk pos min max "${" "}" t 'javascript-mode t))
1374
1375 ;;;###autoload
1376 (define-mumamo-multi-major-mode mjt-html-mumamo-mode
1377   "Turn on multiple major modes for MJT with main mode `html-mode'.
1378 This also covers inlined style and javascript."
1379   ("MJT HTML Family" html-mode
1380    (
1381     mumamo-chunk-mjt$
1382     mumamo-chunk-xml-pi
1383     mumamo-chunk-inlined-style
1384     mumamo-chunk-inlined-script
1385     mumamo-chunk-style=
1386     mumamo-chunk-onjs=
1387     )))
1388
1389
1390 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1391 ;;;; smarty
1392
1393 (defun mumamo-chunk-smarty-literal (pos min max)
1394   "Find {literal} ... {/literal}.  Return range and 'html-mode.
1395 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1396   (mumamo-quick-static-chunk pos min max "{literal}" "{/literal}" t 'html-mode t))
1397
1398 (defun mumamo-chunk-smarty-t (pos min max)
1399   "Find {t} ... {/t}.  Return range and 'html-mode.
1400 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1401   (mumamo-quick-static-chunk pos min max "{t}" "{/t}" t 'text-mode t))
1402
1403 (defun mumamo-chunk-smarty-comment (pos min max)
1404   "Find {* ... *}.  Return range and 'mumamo-comment-mode.
1405 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1406   (mumamo-quick-static-chunk pos min max "{*" "*}" t 'mumamo-comment-mode nil))
1407
1408 (defun mumamo-chunk-smarty (pos min max)
1409   "Find { ... }.  Return range and 'smarty-mode.
1410 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1411   (mumamo-quick-static-chunk pos min max "{" "}" t 'smarty-mode nil))
1412
1413 ;;;###autoload
1414 (define-mumamo-multi-major-mode smarty-html-mumamo-mode
1415   "Turn on multiple major modes for Smarty with main mode `html-mode'.
1416 This also covers inlined style and javascript."
1417   ("Smarty HTML Family" html-mode
1418    (mumamo-chunk-xml-pi
1419     mumamo-chunk-style=
1420     mumamo-chunk-onjs=
1421     ;;mumamo-chunk-inlined-style
1422     ;;mumamo-chunk-inlined-script
1423     mumamo-chunk-smarty-literal
1424     mumamo-chunk-smarty-t
1425     mumamo-chunk-smarty-comment
1426     mumamo-chunk-smarty
1427     )))
1428
1429
1430 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1431 ;;;; ssjs - server side javascript
1432
1433 ;; http://www.sitepoint.com/blogs/2009/03/10/server-side-javascript-will-be-as-common-as-php/
1434 ;;
1435 ;; It looks like there are different syntaxes, both
1436 ;;
1437 ;;  <script runat="server">...</script> and <% ... %>.
1438
1439 (defun mumamo-chunk-ssjs-% (pos min max)
1440   "Find <% ... %>.  Return range and 'javascript-mode.
1441 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1442   (mumamo-quick-static-chunk pos min max "<%" "%>" t 'javascript-mode t))
1443
1444 (defconst mumamo-ssjs-tag-start-regex
1445   (rx "<script"
1446       space
1447       (0+ (not (any ">")))
1448       "runat"
1449       (0+ space)
1450       "="
1451       (0+ space)
1452       ?\"
1453       ;;(or "text" "application")
1454       ;;"/"
1455       ;;(or "javascript" "ecmascript")
1456       (or "server" "both" "server-proxy")
1457       ?\"
1458       (0+ (not (any ">")))
1459       ">"
1460       ;; FIX-ME: Commented out because of bug in Emacs
1461       ;;
1462       ;;(optional (0+ space) "<![CDATA[" )
1463       ))
1464
1465 ;; (defun mumamo-search-bw-exc-start-inlined-ssjs (pos min)
1466 ;;   "Helper for `mumamo-chunk-inlined-ssjs'.
1467 ;; POS is where to start search and MIN is where to stop."
1468 ;;   (goto-char (+ pos 7))
1469 ;;   (let ((marker-start (when (< min (point)) (search-backward "<script" min t)))
1470 ;;         exc-mode
1471 ;;         exc-start)
1472 ;;     (when marker-start
1473 ;;       (when (looking-at mumamo-ssjs-tag-start-regex)
1474 ;;         (setq exc-start (match-end 0))
1475 ;;         (goto-char exc-start)
1476 ;;         (when (<= exc-start pos)
1477 ;;           ;;(cons (point) 'javascript-mode)
1478 ;;           (list (point) 'javascript-mode '(nxml-mode))
1479 ;;           )
1480 ;;         ))))
1481
1482 ;; (defun mumamo-search-fw-exc-start-inlined-ssjs-old (pos max)
1483 ;;   "Helper for `mumamo-chunk-inlined-ssjs'.
1484 ;; POS is where to start search and MAX is where to stop."
1485 ;;   (goto-char (1+ pos))
1486 ;;   (skip-chars-backward "^<")
1487 ;;   ;; Handle <![CDATA[
1488 ;;   (when (and
1489 ;;          (eq ?< (char-before))
1490 ;;          (eq ?! (char-after))
1491 ;;          (not (bobp)))
1492 ;;     (backward-char)
1493 ;;     (skip-chars-backward "^<"))
1494 ;;   (unless (bobp)
1495 ;;     (backward-char 1))
1496 ;;   (let ((exc-start (search-forward "<script" max t))
1497 ;;         exc-mode)
1498 ;;     (when exc-start
1499 ;;       (goto-char (- exc-start 7))
1500 ;;       (when (looking-at mumamo-ssjs-tag-start-regex)
1501 ;;         (goto-char (match-end 0))
1502 ;;         (point)
1503 ;;         ))))
1504
1505 (defun mumamo-search-fw-exc-start-inlined-ssjs (pos max)
1506   "Helper for `mumamo-chunk-inlined-ssjs'.
1507 POS is where to start search and MAX is where to stop."
1508   (goto-char (1+ pos))
1509   (skip-chars-backward "^<")
1510   ;; Handle <![CDATA[
1511   (when (and
1512          (eq ?< (char-before))
1513          (eq ?! (char-after))
1514          (not (bobp)))
1515     (backward-char)
1516     (skip-chars-backward "^<"))
1517   (unless (bobp)
1518     (backward-char 1))
1519   (let ((exc-start (search-forward "<script" max t))
1520         exc-mode)
1521     (when exc-start
1522       (goto-char (- exc-start 7))
1523       (when (looking-at mumamo-ssjs-tag-start-regex)
1524         (goto-char (match-end 0))
1525         (list (point) 'javascript-mode)
1526         ))))
1527
1528 (defun mumamo-chunk-inlined-ssjs (pos min max)
1529   "Find <script runat=...>...</script>.  Return range and 'javascript-mode.
1530 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1531   ;; (mumamo-find-possible-chunk pos min max
1532   ;;                             'mumamo-search-bw-exc-start-inlined-ssjs
1533   ;;                             'mumamo-search-bw-exc-end-inlined-script
1534   ;;                             'mumamo-search-fw-exc-start-inlined-ssjs-old
1535   ;;                             'mumamo-search-fw-exc-end-inlined-script)
1536   (mumamo-possible-chunk-forward pos max
1537                                  'mumamo-search-fw-exc-start-inlined-ssjs
1538                                  'mumamo-search-fw-exc-end-inlined-script))
1539
1540 ;;;###autoload
1541 (define-mumamo-multi-major-mode ssjs-html-mumamo-mode
1542   "Turn on multiple major modes for SSJS with main mode `html-mode'.
1543 This covers inlined style and javascript."
1544   ("HTML Family" html-mode
1545    (mumamo-chunk-inlined-style
1546     mumamo-chunk-inlined-script
1547     mumamo-chunk-inlined-ssjs
1548     mumamo-chunk-ssjs-%
1549     mumamo-chunk-style=
1550     mumamo-chunk-onjs=
1551     )))
1552 (add-hook 'html-mumamo-mode-hook 'mumamo-define-html-file-wide-keys)
1553 (mumamo-inherit-sub-chunk-family 'ssjs-html-mumamo-mode)
1554
1555 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1556 ;;;; gsp
1557
1558 (defun mumamo-chunk-gsp (pos min max)
1559   "Find <% ... %>.  Return range and 'groovy-mode.
1560 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1561   (mumamo-quick-static-chunk pos min max "<%" "%>" t 'groovy-mode t))
1562
1563 ;;;###autoload
1564 (define-mumamo-multi-major-mode gsp-html-mumamo-mode
1565   "Turn on multiple major modes for GSP with main mode `html-mode'.
1566 This also covers inlined style and javascript."
1567     ("GSP HTML Family" html-mode
1568      (mumamo-chunk-gsp
1569       mumamo-chunk-inlined-style
1570       mumamo-chunk-inlined-script
1571       mumamo-chunk-style=
1572       mumamo-chunk-onjs=
1573       )))
1574
1575 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1576 ;;;; jsp - Java Server Pages
1577
1578 (defun mumamo-chunk-jsp (pos min max)
1579   "Find <% ... %>.  Return range and 'java-mode.
1580 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1581   (mumamo-quick-static-chunk pos min max "<%" "%>" t 'java-mode t))
1582
1583 ;;;###autoload
1584 (define-mumamo-multi-major-mode jsp-html-mumamo-mode
1585   "Turn on multiple major modes for JSP with main mode `html-mode'.
1586 This also covers inlined style and javascript."
1587     ("JSP HTML Family" html-mode
1588      (mumamo-chunk-jsp
1589       mumamo-chunk-inlined-style
1590       mumamo-chunk-inlined-script
1591       mumamo-chunk-style=
1592       mumamo-chunk-onjs=
1593       )))
1594
1595
1596 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1597 ;;;; eruby
1598
1599 ;; Fix-me: Maybe take care of <%= and <%- and -%>, but first ask the
1600 ;; ruby people if this is worth doing.
1601 ;;
1602 ;; See also http://wiki.rubyonrails.org/rails/pages/UnderstandingViews
1603 (defun mumamo-chunk-eruby (pos min max)
1604   "Find <% ... %>.  Return range and 'ruby-mode.
1605 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
1606   (let ((chunk (mumamo-quick-static-chunk pos min max "<%" "%>" t 'ruby-mode t)))
1607     (when chunk
1608       ;; Put indentation type on 'mumamo-next-indent on the chunk:
1609       ;; Fix-me: use this!
1610       (setcdr (last chunk) '(mumamo-template-indentor))
1611       chunk)))
1612
1613 (defun mumamo-chunk-eruby-quoted (pos min max)
1614   "Find \"<%= ... %>\".  Return range and 'ruby-mode.
1615 See `mumamo-find-possible-chunk' for POS, MIN and MAX.
1616
1617 This is a workaround for problems with strings."
1618   (let ((chunk (mumamo-quick-static-chunk pos min max "\"<%=" "%>\"" t 'ruby-mode t)))
1619     (when chunk
1620       ;; Put indentation type on 'mumamo-next-indent on the chunk:
1621       ;; Fix-me: use this!
1622       (setcdr (last chunk) '(mumamo-template-indentor))
1623       chunk)))
1624
1625 (defun mumamo-chunk-eruby-comment (pos min max)
1626   "Find <%# ... %>.  Return range and 'ruby-mode.
1627 See `mumamo-find-possible-chunk' for POS, MIN and MAX.
1628
1629 This is needed since otherwise the end marker is thought to be
1630 part of a comment."
1631   (mumamo-quick-static-chunk pos min max "<%#" "%>" t 'mumamo-comment-mode t))
1632
1633 ;; (defun mumamo-search-bw-exc-start-ruby (pos min)
1634 ;;   "Helper for `mumamo-chunk-ruby'.
1635 ;; POS is where to start search and MIN is where to stop."
1636 ;;   (let ((exc-start (mumamo-chunk-start-bw-str pos min "<%")))
1637 ;;     (when (and exc-start
1638 ;;                (<= exc-start pos))
1639 ;;       (cons exc-start 'ruby-mode))))
1640
1641 ;;;###autoload
1642 (define-mumamo-multi-major-mode eruby-mumamo-mode
1643   "Turn on multiple major mode for eRuby with unspecified main mode.
1644 Current major-mode will be used as the main major mode."
1645   ("eRuby Family" nil
1646    (mumamo-chunk-eruby-comment
1647     mumamo-chunk-eruby
1648     )))
1649
1650 ;;;###autoload
1651 (define-mumamo-multi-major-mode eruby-html-mumamo-mode
1652   "Turn on multiple major modes for eRuby with main mode `html-mode'.
1653 This also covers inlined style and javascript."
1654   ("eRuby Html Family" html-mode
1655    (
1656     mumamo-chunk-eruby-comment
1657     mumamo-chunk-eruby
1658     mumamo-chunk-inlined-style
1659     mumamo-chunk-inlined-script
1660     mumamo-chunk-style=
1661     mumamo-chunk-onjs=
1662     )))
1663
1664 ;;;###autoload
1665 (define-mumamo-multi-major-mode eruby-javascript-mumamo-mode
1666   "Turn on multiple major modes for eRuby with main mode `javascript-mode'."
1667   ("eRuby Html Family" javascript-mode
1668    (
1669     mumamo-chunk-eruby-comment
1670     mumamo-chunk-eruby-quoted
1671     mumamo-chunk-eruby
1672     ;;mumamo-chunk-inlined-style
1673     ;;mumamo-chunk-inlined-script
1674     ;;mumamo-chunk-style=
1675     ;;mumamo-chunk-onjs=
1676     )))
1677
1678
1679 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1680 ;;;; heredoc
1681
1682 (defcustom mumamo-heredoc-modes
1683   '(
1684     ("HTML" html-mode)
1685     ("CSS" css-mode)
1686     ("JAVASCRIPT" javascript-mode)
1687     ("JAVA" java-mode)
1688     ("GROOVY" groovy-mode)
1689     ("SQL" sql-mode)
1690     )
1691   "Matches for heredoc modes.
1692 The entries in this list have the form
1693
1694   (REGEXP MAJOR-MODE-SPEC)
1695
1696 where REGEXP is a regular expression that should match the
1697 heredoc marker line and MAJOR-MODE-SPEC is the major mode spec to
1698 use in the heredoc part.
1699
1700 The major mode spec is translated to a major mode using
1701 `mumamo-major-mode-from-modespec'."
1702   :type '(repeat
1703           (list
1704            regexp
1705            (function :tag "Major mode")))
1706   :group 'mumamo-modes)
1707
1708 (defun mumamo-mode-for-heredoc (marker)
1709   "Return major mode associated with MARKER.
1710 Use first match in `mumamo-heredoc-modes'.
1711 If no match use `text-mode'."
1712   (let ((mode (catch 'mode
1713                 (save-match-data
1714                   (dolist (rec mumamo-heredoc-modes)
1715                     (let ((regexp (nth 0 rec))
1716                           (mode   (nth 1 rec)))
1717                       (when (string-match regexp marker)
1718                         (throw 'mode mode))))))))
1719     (if mode
1720         (mumamo-major-mode-from-modespec mode)
1721       'text-mode)))
1722
1723 (defun mumamo-chunk-heredoc (pos min max lang)
1724   "This should work similar to `mumamo-find-possible-chunk'.
1725 POS, MIN and MAX have the same meaning as there.
1726
1727 LANG is the programming language.
1728 Supported values are 'perl."
1729   ;; Fix-me: LANG
1730   ;; Fix-me: use mumamo-end-in-code
1731   (mumamo-condition-case err
1732       (let ((old-point (point)))
1733         (goto-char pos)
1734         (beginning-of-line)
1735         (let (next-<<
1736               (want-<< t)
1737               heredoc-mark
1738               end-mark-len
1739               heredoc-line
1740               delimiter
1741               skipped
1742               (skip-b "")
1743               start-inner
1744               end
1745               exc-mode
1746               fw-exc-fun
1747               border-fun
1748               allow-code-after
1749               start-outer
1750               ps
1751               )
1752           (goto-char pos)
1753           (beginning-of-line)
1754           (case lang
1755             ('sh
1756              (setq allow-code-after t)
1757              (while want-<<
1758                (setq next-<< (search-forward "<<" max t))
1759                (if (not next-<<)
1760                    (setq want-<< nil) ;; give up
1761                  ;; Check inside string or comment.
1762                  (setq ps (parse-partial-sexp (line-beginning-position) (point)))
1763                  (unless (or (nth 3 ps) (nth 4 ps))
1764                    (setq want-<< nil))))
1765              (when next-<<
1766                (setq start-outer (- (point) 2))
1767                (when (= (char-after) ?-)
1768                  (setq skip-b "\t*")
1769                  (unless (eolp) (forward-char)))
1770                ;; fix-me: space
1771                (setq skipped (skip-chars-forward " \t"))
1772                (when (memq (char-after) '(?\" ?\'))
1773                  (setq delimiter (list (char-after))))
1774                (if (and (> skipped 0) (not delimiter))
1775                    (setq heredoc-mark "")
1776                  (when (looking-at (rx-to-string
1777                                     `(and (regexp ,(if delimiter
1778                                                        (concat delimiter "\\([^\n<>;]+\\)" delimiter)
1779                                                      "\\([^ \t\n<>;]+\\)"))
1780                                           (or blank line-end))))
1781                    (setq heredoc-mark  (buffer-substring-no-properties
1782                                         (match-beginning 1)
1783                                         (match-end 1)))))
1784                (when heredoc-mark
1785                  (setq heredoc-line (buffer-substring-no-properties (point-at-bol) (point-at-eol)))
1786                  (setq start-inner (1+ (point-at-eol)))
1787                  (setq end-mark-len (length heredoc-mark))
1788                  )))
1789             ('w32-ps (error "No support for windows power shell yet"))
1790             ('php
1791              (while want-<<
1792                (setq next-<< (search-forward "<<<" max t))
1793                ;; Check inside string or comment.
1794                (if (not next-<<)
1795                    (setq want-<< nil) ;; give up
1796                  (setq ps (parse-partial-sexp (line-beginning-position) (- (point) 0)))
1797                  (unless (or (nth 3 ps) (nth 4 ps))
1798                    (setq want-<< nil))))
1799              (when next-<<
1800                (setq start-outer (- (point) 3))
1801                (skip-chars-forward " \t")
1802                (when (looking-at (concat "\\([^\n;]*\\)[[:blank:]]*\n"))
1803                  (setq heredoc-mark  (buffer-substring-no-properties
1804                                       (match-beginning 1)
1805                                       (match-end 1)))
1806                  (setq heredoc-line (buffer-substring-no-properties (point-at-bol) (point-at-eol)))
1807                  ;; fix-me: nowdoc
1808                  (when (and (= ?\' (string-to-char heredoc-mark))
1809                             (= ?\' (string-to-char (substring heredoc-mark (1- (length heredoc-mark))))))
1810                    (setq heredoc-mark (substring heredoc-mark 1 (- (length heredoc-mark) 1))))
1811                  (setq end-mark-len (1+ (length heredoc-mark)))
1812                  (setq start-inner (match-end 0)))))
1813             ('perl
1814              (setq allow-code-after t)
1815              (while want-<<
1816                (setq next-<< (search-forward "<<" max t))
1817                (if (not next-<<)
1818                    (setq want-<< nil) ;; give up
1819                  ;; Check inside string or comment.
1820                  (setq ps (parse-partial-sexp (line-beginning-position) (point)))
1821                  (unless (or (nth 3 ps) (nth 4 ps))
1822                    (setq want-<< nil))))
1823              (when next-<<
1824                (setq start-outer (- (point) 2))
1825                ;; fix-me: space
1826                (setq skipped (skip-chars-forward " \t"))
1827                (when (memq (char-after) '(?\" ?\'))
1828                  (setq delimiter (list (char-after))))
1829                (if (and (> skipped 0) (not delimiter))
1830                    (setq heredoc-mark "") ;; blank line
1831                  (when (looking-at (rx-to-string
1832                                     `(and (regexp ,(if delimiter
1833                                                        (concat delimiter "\\([^\n;]*\\)" delimiter)
1834                                                      "\\([^ \t\n<>;]+\\)"))
1835                                           (or blank ";"))))
1836                    (setq heredoc-mark  (buffer-substring-no-properties
1837                                         (match-beginning 1)
1838                                         (match-end 1)))))
1839                (when heredoc-mark
1840                  (setq heredoc-line (buffer-substring-no-properties (point-at-bol) (point-at-eol)))
1841                  ;;(setq start-inner (1+ (match-end 0)))
1842                  (setq start-inner (1+ (point-at-eol)))
1843                  (setq end-mark-len (length heredoc-mark))
1844                  )))
1845             ('python
1846              (unless (eobp) (forward-char))
1847              (while want-<<
1848                (setq next-<< (re-search-forward "\"\"\"\\|'''" max t))
1849                (setq start-outer (- (point) 3))
1850                (if (not next-<<)
1851                    (setq want-<< nil) ;; give up
1852                  ;; Check inside string or comment.
1853                  (setq ps (parse-partial-sexp (line-beginning-position) (- (point) 3)))
1854                  (unless (or (nth 3 ps) (nth 4 ps))
1855                    (setq want-<< nil)))))
1856             ('ruby
1857              (while want-<<
1858                (setq next-<< (search-forward "<<" max t))
1859                (if (not next-<<)
1860                    (setq want-<< nil) ;; give up
1861                  ;; Check inside string or comment.
1862                  (setq ps (parse-partial-sexp (line-beginning-position) (point)))
1863                  (unless (or (nth 3 ps) (nth 4 ps))
1864                    (setq want-<< nil))))
1865              (when next-<<
1866                (setq start-outer (- (point) 2))
1867                (when (= (char-after) ?-)
1868                  (setq skip-b "[ \t]*")
1869                  (forward-char))
1870                (when (looking-at (concat "[^\n[:blank:]]*"))
1871                  (setq heredoc-mark  (buffer-substring-no-properties
1872                                       (match-beginning 0)
1873                                       (match-end 0)))
1874                  (setq end-mark-len (length heredoc-mark))
1875                  (setq heredoc-line (buffer-substring-no-properties (point-at-bol) (point-at-eol)))
1876                  (setq start-inner (match-end 0)))))
1877             (t (error "next-<< not implemented for lang %s" lang)))
1878           (when start-inner (assert (<= pos start-inner) t))
1879           (goto-char old-point)
1880           (when (or start-inner end)
1881             (let ((endmark-regexp
1882                    (case lang
1883                      ('sh (concat "^" skip-b heredoc-mark "$"))
1884                      ('php (concat "^" heredoc-mark ";?$"))
1885                      ('perl (concat "^" heredoc-mark "$"))
1886                      ('python (concat "^" heredoc-mark "[[:space:]]*"))
1887                      ('ruby (concat "^" skip-b heredoc-mark "$"))
1888                      (t (error "mark-regexp not implemented for %s" lang)))))
1889               ;; Fix-me: rename start-inner <=> start-outer...
1890               (setq border-fun `(lambda (start end exc-mode)
1891                                   ;; Fix-me: use lengths...
1892                                   (list
1893                                    (if ,allow-code-after nil (+ start (- ,start-inner ,start-outer 1)))
1894                                    (when end (- end ,end-mark-len)))))
1895               (setq fw-exc-fun `(lambda (pos max)
1896                                   (save-match-data
1897                                     (let ((here (point)))
1898                                       (goto-char pos)
1899                                       (prog1
1900                                           (when (re-search-forward ,endmark-regexp max t)
1901                                             (- (point) 1 ,(length heredoc-mark))
1902                                             (- (point) 0)
1903                                             )
1904                                         (goto-char here)))))))
1905             (setq exc-mode (mumamo-mode-for-heredoc heredoc-line))
1906             (list start-inner end exc-mode nil nil fw-exc-fun nil)
1907             ;; Fix me: Add overriding for inner chunks (see
1908             ;; http://www.emacswiki.org/emacs/NxhtmlMode#toc13). Maybe
1909             ;; make fw-exc-fun a list (or a cons, since overriding is
1910             ;; probably all that I want to add)? And make the
1911             ;; corresponding chunk property a list too?
1912             ;;(list start-outer end exc-mode (list start-inner end) nil fw-exc-fun border-fun 'heredoc)
1913             (list (if allow-code-after start-inner start-outer)
1914                   end exc-mode (list start-inner end) nil fw-exc-fun border-fun 'heredoc)
1915             )))
1916     (error (mumamo-display-error 'mumamo-chunk-heredoc
1917                                  "%s" (error-message-string err)))))
1918
1919
1920 ;;;; Unix style sh heredoc
1921
1922 (defun mumamo-chunk-sh-heredoc (pos min max)
1923   "Find sh here docs.
1924 See `mumamo-find-possible-chunk' for POS, MIN
1925 and MAX."
1926   (let ((r (mumamo-chunk-heredoc pos min max 'sh)))
1927     r))
1928
1929 ;;;###autoload
1930 (define-mumamo-multi-major-mode sh-heredoc-mumamo-mode
1931   "Turn on multiple major modes for sh heredoc document.
1932 See `mumamo-heredoc-modes' for how to specify heredoc major modes."
1933   ("SH HereDoc" sh-mode
1934    (mumamo-chunk-sh-heredoc
1935     )))
1936 (mumamo-inherit-sub-chunk-family 'sh-heredoc-mumamo-mode)
1937
1938
1939 ;;;; PHP heredoc
1940
1941 (defun mumamo-chunk-php-heredoc (pos min max)
1942   "Find PHP here docs.
1943 See `mumamo-find-possible-chunk' for POS, MIN
1944 and MAX."
1945   (let ((r (mumamo-chunk-heredoc pos min max 'php)))
1946     r))
1947
1948 ;;;###autoload
1949 (define-mumamo-multi-major-mode php-heredoc-mumamo-mode
1950   "Turn on multiple major modes for PHP heredoc document.
1951 See `mumamo-heredoc-modes' for how to specify heredoc major modes."
1952   ("PHP HereDoc" php-mode
1953    (mumamo-chunk-php-heredoc
1954     )))
1955 (mumamo-inherit-sub-chunk-family 'php-heredoc-mumamo-mode)
1956 (mumamo-inherit-sub-chunk-family-locally 'php-heredoc-mumamo-mode 'html-mumamo-mode)
1957
1958
1959 ;;;; Perl heredoc
1960
1961 (defun mumamo-chunk-perl-heredoc (pos min max)
1962   "Find perl here docs.
1963 See `mumamo-find-possible-chunk' for POS, MIN
1964 and MAX."
1965   (let ((r (mumamo-chunk-heredoc pos min max 'perl)))
1966     r))
1967
1968 ;;;###autoload
1969 (define-mumamo-multi-major-mode perl-heredoc-mumamo-mode
1970   "Turn on multiple major modes for Perl heredoc document.
1971 See `mumamo-heredoc-modes' for how to specify heredoc major modes."
1972   ("Perl HereDoc" perl-mode
1973    (mumamo-chunk-perl-heredoc
1974     )))
1975 (mumamo-inherit-sub-chunk-family 'perl-heredoc-mumamo-mode)
1976
1977 ;;;###autoload
1978 (define-mumamo-multi-major-mode cperl-heredoc-mumamo-mode
1979   "Turn on multiple major modes for Perl heredoc document.
1980 See `mumamo-heredoc-modes' for how to specify heredoc major modes."
1981   ("Perl HereDoc" cperl-mode
1982    (mumamo-chunk-perl-heredoc
1983     )))
1984 (mumamo-inherit-sub-chunk-family 'cperl-heredoc-mumamo-mode)
1985
1986
1987 ;;;; Python heredoc
1988
1989 (defun mumamo-chunk-python-heredoc (pos min max)
1990   "Find python here docs.
1991 See `mumamo-find-possible-chunk' for POS, MIN
1992 and MAX."
1993   (let ((r (mumamo-chunk-heredoc pos min max 'python)))
1994     r))
1995
1996 ;;;###autoload
1997 (define-mumamo-multi-major-mode python-heredoc-mumamo-mode
1998   "Turn on multiple major modes for Perl heredoc document.
1999 See `mumamo-heredoc-modes' for how to specify heredoc major modes."
2000   ("Python HereDoc" python-mode
2001    (mumamo-chunk-python-heredoc
2002     )))
2003 (mumamo-inherit-sub-chunk-family 'python-heredoc-mumamo-mode)
2004
2005
2006 ;;;; Ruby heredoc
2007
2008 (defun mumamo-chunk-ruby-heredoc (pos min max)
2009   "Find Ruby here docs.
2010 See `mumamo-find-possible-chunk' for POS, MIN
2011 and MAX."
2012   (let ((r (mumamo-chunk-heredoc pos min max 'ruby)))
2013     r))
2014
2015 ;;;###autoload
2016 (define-mumamo-multi-major-mode ruby-heredoc-mumamo-mode
2017   "Turn on multiple major modes for Ruby heredoc document.
2018 See `mumamo-heredoc-modes' for how to specify heredoc major modes."
2019   ("Ruby HereDoc" ruby-mode
2020    (mumamo-chunk-ruby-heredoc
2021     )))
2022 (mumamo-inherit-sub-chunk-family 'ruby-heredoc-mumamo-mode)
2023
2024
2025 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2026 ;;;; Tex meta
2027
2028 ;; (defun mumamo-search-bw-textext-start (pos min)
2029 ;;   "Helper for `mumamo-chunk-textext'.
2030 ;; POS is where to start search and MIN is where to stop."
2031 ;;   (let ((exc-start (mumamo-chunk-start-bw-str pos min "textext(\""))
2032 ;;         (exc-mode 'plain-tex-mode))
2033 ;;     (when exc-start
2034 ;;       (when (<= exc-start pos)
2035 ;;         (cons exc-start exc-mode)))))
2036
2037 (defconst mumamo-textext-end-regex
2038   (rx "textext("
2039       (0+
2040        (0+ (not (any "\"()")))
2041        ?\"
2042        (0+ (not (any "\"")))
2043        ?\"
2044        )
2045       (0+ (not (any "\"()")))
2046       ")"))
2047
2048 (defun mumamo-textext-test-is-end (pos)
2049   "Helper for `mumamo-chunk-textext'.
2050 Return POS if POS is at the end of textext chunk."
2051   (when pos
2052     (let ((here (point))
2053           hit)
2054       (goto-char (+ 2 pos))
2055       (when (looking-back mumamo-textext-end-regex)
2056         (setq hit t))
2057       (goto-char here)
2058       (when hit pos))))
2059
2060 ;; (defun mumamo-search-bw-textext-end (pos min)
2061 ;;   "Helper for `mumamo-chunk-textext'.
2062 ;; POS is where to start search and MIN is where to stop."
2063 ;;   (let ((end (mumamo-chunk-end-bw-str pos min "\")"))
2064 ;;         res)
2065 ;;     (while (and end
2066 ;;                 (not (setq res (mumamo-textext-test-is-end end))))
2067 ;;       (setq end (mumamo-chunk-end-bw-str (1- end) min "\")")))
2068 ;;     res))
2069
2070 ;; (defun mumamo-search-fw-textext-start-old (pos max)
2071 ;;   "Helper for `mumamo-chunk-textext'.
2072 ;; POS is where to start search and MAX is where to stop."
2073 ;;   (mumamo-chunk-start-fw-str pos max "textext(\""))
2074
2075 (defun mumamo-search-fw-textext-start (pos max)
2076   "Helper for `mumamo-chunk-textext'.
2077 POS is where to start search and MAX is where to stop."
2078   (let ((where (mumamo-chunk-start-fw-str pos max "textext(\"")))
2079     (when where
2080       (list where 'plain-tex-mode))))
2081
2082 (defun mumamo-search-fw-textext-end (pos max)
2083   "Helper for `mumamo-chunk-textext'.
2084 POS is where to start search and MAX is where to stop."
2085   (save-match-data
2086     (let ((end (mumamo-chunk-end-fw-str pos max "\")")))
2087       (mumamo-textext-test-is-end end))))
2088
2089 (defun mumamo-chunk-textext (pos min max)
2090   "Find textext or TEX chunks.  Return range and 'plain-tex-mode.
2091 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
2092   ;; (mumamo-find-possible-chunk pos min max
2093   ;;                             'mumamo-search-bw-textext-start
2094   ;;                             'mumamo-search-bw-textext-end
2095   ;;                             'mumamo-search-fw-textext-start-old
2096   ;;                             'mumamo-search-fw-textext-end)
2097   (mumamo-possible-chunk-forward pos max
2098                                  'mumamo-search-fw-textext-start
2099                                  'mumamo-search-fw-textext-end))
2100
2101 ;; (defun mumamo-search-bw-verbatimtex-start (pos min)
2102 ;;   "Helper for `mumamo-chunk-verbatimtextext'.
2103 ;; POS is where to start search and MIN is where to stop."
2104 ;;   (let ((exc-start (mumamo-chunk-start-bw-str pos min "\nverbatimtex"))
2105 ;;         (exc-mode 'plain-tex-mode))
2106 ;;     (when exc-start
2107 ;;       (when (<= exc-start pos)
2108 ;;         (cons exc-start exc-mode)))))
2109
2110 ;; (defun mumamo-search-bw-verbatimtex-end (pos min)
2111 ;;   "Helper for `mumamo-chunk-verbatimtextext'.
2112 ;; POS is where to start search and MIN is where to stop."
2113 ;;   (mumamo-chunk-end-bw-str pos min "\netex"))
2114
2115 ;; (defun mumamo-search-fw-verbatimtex-start-old (pos max)
2116 ;;   "Helper for `mumamo-chunk-verbatimtextext'.
2117 ;; POS is where to start search and MAX is where to stop."
2118 ;;   (mumamo-chunk-start-fw-str pos max "\nverbatimtex"))
2119
2120 (defun mumamo-search-fw-verbatimtex-start (pos max)
2121   "Helper for `mumamo-chunk-verbatimtextext'.
2122 POS is where to start search and MAX is where to stop."
2123   (let ((where (mumamo-chunk-start-fw-str pos max "\nverbatimtex")))
2124     (when where
2125       (list where 'plain-tex-mode))))
2126
2127 (defun mumamo-search-fw-verbatimtex-end (pos max)
2128   "Helper for `mumamo-chunk-verbatimtextext'.
2129 POS is where to start search and MAX is where to stop."
2130   (save-match-data
2131     (mumamo-chunk-end-fw-str pos max "\netex")))
2132
2133 (defun mumamo-chunk-verbatimtex (pos min max)
2134   "Find verbatimtex - etex chunks.  Return range and 'plain-tex-mode.
2135 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
2136   ;; (mumamo-find-possible-chunk pos min max
2137   ;;                             'mumamo-search-bw-verbatimtex-start
2138   ;;                             'mumamo-search-bw-verbatimtex-end
2139   ;;                             'mumamo-search-fw-verbatimtex-start-old
2140   ;;                             'mumamo-search-fw-verbatimtex-end)
2141   (mumamo-possible-chunk-forward pos max
2142                                  'mumamo-search-fw-verbatimtex-start
2143                                  'mumamo-search-fw-verbatimtex-end))
2144
2145 ;; (defun mumamo-search-bw-btex-start (pos min)
2146 ;;   "Helper for `mumamo-chunk-btex'.
2147 ;; POS is where to start search and MIN is where to stop."
2148 ;;   (let ((exc-start (mumamo-chunk-start-bw-str pos min "\nverbatimtex"))
2149 ;;         (exc-mode 'plain-tex-mode))
2150 ;;     (when exc-start
2151 ;;       (when (<= exc-start pos)
2152 ;;         (cons exc-start exc-mode)))))
2153
2154 ;; (defun mumamo-search-bw-btex-end (pos min)
2155 ;;   "Helper for `mumamo-chunk-btex'.
2156 ;; POS is where to start search and MIN is where to stop."
2157 ;;   (mumamo-chunk-end-bw-str pos min "\netex"))
2158
2159 ;; (defun mumamo-search-fw-btex-start-old (pos max)
2160 ;;   "Helper for `mumamo-chunk-btex'.
2161 ;; POS is where to start search and MAX is where to stop."
2162 ;;   (mumamo-chunk-start-fw-str pos max "\nverbatimtex"))
2163
2164 (defun mumamo-search-fw-btex-start (pos max)
2165   "Helper for `mumamo-chunk-btex'.
2166 POS is where to start search and MAX is where to stop."
2167   (let ((where (mumamo-chunk-start-fw-str pos max "\nverbatimtex")))
2168     (when where
2169       (list where 'plain-tex-mode))))
2170
2171 (defun mumamo-search-fw-btex-end (pos max)
2172   "Helper for `mumamo-chunk-btex'.
2173 POS is where to start search and MAX is where to stop."
2174   (save-match-data
2175     (mumamo-chunk-end-fw-str pos max "\netex")))
2176
2177 (defun mumamo-chunk-btex (pos min max)
2178   "Find btex - etex chunks.
2179 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
2180   ;; (mumamo-find-possible-chunk pos min max
2181   ;;                             'mumamo-search-bw-btex-start
2182   ;;                             'mumamo-search-bw-btex-end
2183   ;;                             'mumamo-search-fw-btex-start-old
2184   ;;                             'mumamo-search-fw-btex-end)
2185   (mumamo-possible-chunk-forward pos max
2186                                  'mumamo-search-fw-btex-start
2187                                  'mumamo-search-fw-btex-end))
2188
2189 ;;;###autoload
2190 (define-mumamo-multi-major-mode metapost-mumamo-mode
2191   "Turn on multiple major modes for MetaPost."
2192   ("MetaPost TeX Family" metapost-mode
2193    (mumamo-chunk-textext
2194     mumamo-chunk-verbatimtex
2195     )))
2196
2197
2198 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2199 ;;;; OpenLaszlo
2200
2201 (defconst mumamo-lzx-method-tag-start-regex
2202   (rx "<method"
2203       (optional
2204        space
2205        (0+ (not (any ">"))))
2206       ">"
2207       ;; FIX-ME: Commented out because of bug in Emacs
2208       ;;
2209       ;;(optional (0+ space) "<![CDATA[" )
2210       ))
2211
2212 (defun mumamo-search-bw-exc-start-inlined-lzx-method (pos min)
2213   "Helper for `mumamo-chunk-inlined-lzx-method'.
2214 POS is where to start search and MIN is where to stop."
2215   (goto-char (+ pos 7))
2216   (let ((marker-start (search-backward "<method" min t))
2217         exc-mode
2218         exc-start)
2219     (when marker-start
2220       (when (looking-at mumamo-lzx-method-tag-start-regex)
2221         (setq exc-start (match-end 0))
2222         (goto-char exc-start)
2223         (when (<= exc-start pos)
2224           (cons (point) 'javascript-mode))
2225         ))))
2226
2227 ;; (defun mumamo-search-bw-exc-end-inlined-lzx-method (pos min)
2228 ;;   "Helper for `mumamo-chunk-inlined-lzx-method'.
2229 ;; POS is where to start search and MIN is where to stop."
2230 ;;   (mumamo-chunk-end-bw-str pos min "</method>"))
2231
2232 ;; (defun mumamo-search-fw-exc-start-inlined-lzx-method-old (pos max)
2233 ;;   "Helper for `mumamo-chunk-inlined-lzx-method'.
2234 ;; POS is where to start search and MAX is where to stop."
2235 ;;   (goto-char (1+ pos))
2236 ;;   (skip-chars-backward "^<")
2237 ;;   ;; Handle <![CDATA[
2238 ;;   (when (and
2239 ;;          (eq ?< (char-before))
2240 ;;          (eq ?! (char-after))
2241 ;;          (not (bobp)))
2242 ;;     (backward-char)
2243 ;;     (skip-chars-backward "^<"))
2244 ;;   (unless (bobp)
2245 ;;     (backward-char 1))
2246 ;;   (let ((exc-start (search-forward "<method" max t))
2247 ;;         exc-mode)
2248 ;;     (when exc-start
2249 ;;       (goto-char (- exc-start 7))
2250 ;;       (when (looking-at mumamo-lzx-method-tag-start-regex)
2251 ;;         (goto-char (match-end 0))
2252 ;;         (point)
2253 ;;         ))))
2254
2255 (defun mumamo-search-fw-exc-start-inlined-lzx-method (pos max)
2256   "Helper for `mumamo-chunk-inlined-lzx-method'.
2257 POS is where to start search and MAX is where to stop."
2258   (goto-char (1+ pos))
2259   (skip-chars-backward "^<")
2260   ;; Handle <![CDATA[
2261   (when (and
2262          (eq ?< (char-before))
2263          (eq ?! (char-after))
2264          (not (bobp)))
2265     (backward-char)
2266     (skip-chars-backward "^<"))
2267   (unless (bobp)
2268     (backward-char 1))
2269   (let ((exc-start (search-forward "<method" max t))
2270         exc-mode)
2271     (when exc-start
2272       (goto-char (- exc-start 7))
2273       (when (looking-at mumamo-lzx-method-tag-start-regex)
2274         (goto-char (match-end 0))
2275         (list (point) 'javascript-mode)
2276         ))))
2277
2278 (defun mumamo-search-fw-exc-end-inlined-lzx-method (pos max)
2279   "Helper for `mumamo-chunk-inlined-lzx-method'.
2280 POS is where to start search and MAX is where to stop."
2281   (save-match-data
2282     (mumamo-chunk-end-fw-str pos max "</method>")))
2283
2284 (defun mumamo-chunk-inlined-lzx-method (pos min max)
2285   "Find <method>...</method>.  Return range and 'javascript-mode.
2286 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
2287   ;; (mumamo-find-possible-chunk pos min max
2288   ;;                             'mumamo-search-bw-exc-start-inlined-lzx-method
2289   ;;                             'mumamo-search-bw-exc-end-inlined-lzx-method
2290   ;;                             'mumamo-search-fw-exc-start-inlined-lzx-method-old
2291   ;;                             'mumamo-search-fw-exc-end-inlined-lzx-method)
2292   (mumamo-possible-chunk-forward pos max
2293                                  'mumamo-search-fw-exc-start-inlined-lzx-method
2294                                  'mumamo-search-fw-exc-end-inlined-lzx-method))
2295
2296 (defconst mumamo-lzx-handler-tag-start-regex
2297   (rx "<handler"
2298       (optional
2299        space
2300        (0+ (not (any ">"))))
2301       ">"
2302       ;; FIX-ME: Commented out because of bug in Emacs
2303       ;;
2304       ;;(optional (0+ space) "<![CDATA[" )
2305       ))
2306
2307 ;; (defun mumamo-search-bw-exc-start-inlined-lzx-handler (pos min)
2308 ;;   "Helper for `mumamo-chunk-inlined-lzx-handler'.
2309 ;; POS is where to start search and MIN is where to stop."
2310 ;;   (goto-char (+ pos 8))
2311 ;;   (let ((marker-start (search-backward "<handler" min t))
2312 ;;         exc-mode
2313 ;;         exc-start)
2314 ;;     (when marker-start
2315 ;;       (when (looking-at mumamo-lzx-handler-tag-start-regex)
2316 ;;         (setq exc-start (match-end 0))
2317 ;;         (goto-char exc-start)
2318 ;;         (when (<= exc-start pos)
2319 ;;           (cons (point) 'javascript-mode))
2320 ;;         ))))
2321
2322 ;; (defun mumamo-search-bw-exc-end-inlined-lzx-handler (pos min)
2323 ;;   "Helper for `mumamo-chunk-inlined-lzx-handler'.
2324 ;; POS is where to start search and MIN is where to stop."
2325 ;;   (mumamo-chunk-end-bw-str pos min "</handler>"))
2326
2327 ;; (defun mumamo-search-fw-exc-start-inlined-lzx-handler-old (pos max)
2328 ;;   "Helper for `mumamo-chunk-inlined-lzx-handler'.
2329 ;; POS is where to start search and MAX is where to stop."
2330 ;;   (goto-char (1+ pos))
2331 ;;   (skip-chars-backward "^<")
2332 ;;   ;; Handle <![CDATA[
2333 ;;   (when (and
2334 ;;          (eq ?< (char-before))
2335 ;;          (eq ?! (char-after))
2336 ;;          (not (bobp)))
2337 ;;     (backward-char)
2338 ;;     (skip-chars-backward "^<"))
2339 ;;   (unless (bobp)
2340 ;;     (backward-char 1))
2341 ;;   (let ((exc-start (search-forward "<handler" max t))
2342 ;;         exc-mode)
2343 ;;     (when exc-start
2344 ;;       (goto-char (- exc-start 8))
2345 ;;       (when (looking-at mumamo-lzx-handler-tag-start-regex)
2346 ;;         (goto-char (match-end 0))
2347 ;;         (point)
2348 ;;         ))))
2349
2350 (defun mumamo-search-fw-exc-start-inlined-lzx-handler (pos max)
2351   "Helper for `mumamo-chunk-inlined-lzx-handler'.
2352 POS is where to start search and MAX is where to stop."
2353   (goto-char (1+ pos))
2354   (skip-chars-backward "^<")
2355   ;; Handle <![CDATA[
2356   (when (and
2357          (eq ?< (char-before))
2358          (eq ?! (char-after))
2359          (not (bobp)))
2360     (backward-char)
2361     (skip-chars-backward "^<"))
2362   (unless (bobp)
2363     (backward-char 1))
2364   (let ((exc-start (search-forward "<handler" max t))
2365         exc-mode)
2366     (when exc-start
2367       (goto-char (- exc-start 8))
2368       (when (looking-at mumamo-lzx-handler-tag-start-regex)
2369         (goto-char (match-end 0))
2370         (list (point) 'javascript-mode)
2371         ))))
2372
2373 (defun mumamo-search-fw-exc-end-inlined-lzx-handler (pos max)
2374   "Helper for `mumamo-chunk-inlined-lzx-handler'.
2375 POS is where to start search and MAX is where to stop."
2376   (save-match-data
2377     (mumamo-chunk-end-fw-str pos max "</handler>")))
2378
2379 (defun mumamo-chunk-inlined-lzx-handler (pos min max)
2380   "Find <handler>...</handler>.  Return range and 'javascript-mode.
2381 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
2382   ;; (mumamo-find-possible-chunk pos min max
2383   ;;                             'mumamo-search-bw-exc-start-inlined-lzx-handler
2384   ;;                             'mumamo-search-bw-exc-end-inlined-lzx-handler
2385   ;;                             'mumamo-search-fw-exc-start-inlined-lzx-handler-old
2386   ;;                             'mumamo-search-fw-exc-end-inlined-lzx-handler)
2387   (mumamo-possible-chunk-forward pos max
2388                                  'mumamo-search-fw-exc-start-inlined-lzx-handler
2389                                  'mumamo-search-fw-exc-end-inlined-lzx-handler))
2390
2391
2392 ;;;###autoload
2393 (define-mumamo-multi-major-mode laszlo-nxml-mumamo-mode
2394   "Turn on multiple major modes for OpenLaszlo."
2395   ("OpenLaszlo Family" nxml-mode
2396    (mumamo-chunk-inlined-script
2397     mumamo-chunk-inlined-lzx-method
2398     mumamo-chunk-inlined-lzx-handler
2399     )))
2400
2401
2402 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2403 ;;;; csound
2404
2405 ;; (defun mumamo-search-bw-exc-start-csound-orc (pos min)
2406 ;;   "Helper for `mumamo-chunk-csound-orc'.
2407 ;; POS is where to start search and MIN is where to stop."
2408 ;;   (let ((exc-start (mumamo-chunk-start-bw-str pos min "<csinstruments>")))
2409 ;;     (and exc-start
2410 ;;          (<= exc-start pos)
2411 ;;          (cons exc-start 'csound-orc-mode))))
2412
2413 ;; (defun mumamo-search-bw-exc-end-csound-orc (pos min)
2414 ;;   "Helper for `mumamo-chunk-csound-orc'.
2415 ;; POS is where to start search and MIN is where to stop."
2416 ;;   (mumamo-chunk-end-bw-str pos min "</csinstruments>"))
2417
2418 ;; (defun mumamo-search-fw-exc-start-csound-orc-old (pos max)
2419 ;;   "Helper for `mumamo-chunk-csound-orc'.
2420 ;; POS is where to start search and MAX is where to stop."
2421 ;;   (mumamo-chunk-start-fw-str pos max "<csinstruments>"))
2422
2423 (defun mumamo-search-fw-exc-start-csound-orc (pos max)
2424   "Helper for `mumamo-chunk-csound-orc'.
2425 POS is where to start search and MAX is where to stop."
2426   (let ((where (mumamo-chunk-start-fw-str pos max "<csinstruments>")))
2427     (when where
2428       (list where 'csound-orc-mode))))
2429
2430 (defun mumamo-search-fw-exc-end-csound-orc (pos max)
2431   "Helper for `mumamo-chunk-csound-orc'.
2432 POS is where to start search and MAX is where to stop."
2433   (save-match-data
2434     (mumamo-chunk-end-fw-str pos max "</csinstruments>")))
2435
2436 (defun mumamo-chunk-csound-orc (pos min max)
2437   "Find <csinstruments>...</...>.  Return range and 'csound-orc-mode.
2438 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
2439   ;; (mumamo-find-possible-chunk pos min max
2440   ;;                             'mumamo-search-bw-exc-start-csound-orc
2441   ;;                             'mumamo-search-bw-exc-end-csound-orc
2442   ;;                             'mumamo-search-fw-exc-start-csound-orc-old
2443   ;;                             'mumamo-search-fw-exc-end-csound-orc)
2444   (mumamo-possible-chunk-forward pos max
2445                                  'mumamo-search-fw-exc-start-csound-orc
2446                                  'mumamo-search-fw-exc-end-csound-orc))
2447
2448 ;; (defun mumamo-search-bw-exc-start-csound-sco (pos min)
2449 ;;   "Helper for `mumamo-chunk-csound-sco'.
2450 ;; POS is where to start search and MIN is where to stop."
2451 ;;   (let ((exc-start (mumamo-chunk-start-bw-str pos min "<csscore>")))
2452 ;;     (and exc-start
2453 ;;          (<= exc-start pos)
2454 ;;          (cons exc-start 'csound-sco-mode))))
2455
2456 ;; (defun mumamo-search-bw-exc-end-csound-sco (pos min)
2457 ;;   "Helper for `mumamo-chunk-csound-sco'.
2458 ;; POS is where to start search and MIN is where to stop."
2459 ;;   (mumamo-chunk-end-bw-str pos min "</csscore>"))
2460
2461 ;; (defun mumamo-search-fw-exc-start-csound-sco-old (pos max)
2462 ;;   "Helper for `mumamo-chunk-csound-sco'.
2463 ;; POS is where to start search and MAX is where to stop."
2464 ;;   (mumamo-chunk-start-fw-str pos max "<csscore>"))
2465
2466 (defun mumamo-search-fw-exc-start-csound-sco (pos max)
2467   "Helper for `mumamo-chunk-csound-sco'.
2468 POS is where to start search and MAX is where to stop."
2469   (let ((where (mumamo-chunk-start-fw-str pos max "<csscore>")))
2470     (when where
2471       (list where 'csound-sco-mode))))
2472
2473 (defun mumamo-search-fw-exc-end-csound-sco (pos max)
2474   "Helper for `mumamo-chunk-csound-sco'.
2475 POS is where to start search and MAX is where to stop."
2476   (save-match-data
2477     (mumamo-chunk-end-fw-str pos max "</csscore>")))
2478
2479 (defun mumamo-chunk-csound-sco (pos min max)
2480   "Found <csscore>...</csscore>.  Return range and 'csound-sco-mode.
2481 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
2482   ;; (mumamo-find-possible-chunk pos min max
2483   ;;                             'mumamo-search-bw-exc-start-csound-sco
2484   ;;                             'mumamo-search-bw-exc-end-csound-sco
2485   ;;                             'mumamo-search-fw-exc-start-csound-sco-old
2486   ;;                             'mumamo-search-fw-exc-end-csound-sco)
2487   (mumamo-possible-chunk-forward pos max
2488                                  'mumamo-search-fw-exc-start-csound-sco
2489                                  'mumamo-search-fw-exc-end-csound-sco))
2490
2491 ;;;###autoload
2492 (define-mumamo-multi-major-mode csound-sgml-mumamo-mode
2493   "Turn on mutiple major modes for CSound orc/sco Modes."
2494   ("CSound orc/sco Modes" sgml-mode
2495    (mumamo-chunk-csound-sco
2496     mumamo-chunk-csound-orc
2497     )))
2498
2499
2500 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2501 ;;;; noweb
2502
2503 ;;;###autoload
2504 (defgroup mumamo-noweb2 nil
2505   "Customization group for `noweb2-mumamo-mode'."
2506   :group 'mumamo-modes)
2507
2508 (defcustom mumamo-noweb2-mode-from-ext
2509   '(
2510     ("php" . php-mode)
2511     ("c" . c-mode)
2512     )
2513   "File extension regexp to major mode mapping.
2514 Used by `noweb2-mumamo-mode'."
2515   :type '(repeat
2516           (cons regexp major-mode-function))
2517   :group 'mumamo-noweb2)
2518
2519 (defvar mumamo-noweb2-found-mode-from-ext nil
2520   "Major modes determined from file names.  Internal use.")
2521
2522 (defun mumamo-noweb2-chunk-start-fw (pos max)
2523   "Helper for `mumamo-noweb2-chunk'.
2524 POS is where to start search and MAX is where to stop."
2525   (let ((where (mumamo-chunk-start-fw-re pos max "^<<\\(.*?\\)>>="))
2526         (exc-mode 'text-mode))
2527     (when where
2528       (let* ((file-name (match-string-no-properties 1))
2529              (file-ext (when file-name (file-name-extension file-name))))
2530         (when file-ext
2531           (setq exc-mode (catch 'major
2532                            (dolist (rec mumamo-noweb2-mode-from-ext)
2533                              (when (string-match (car rec) file-ext)
2534                                (throw 'major (cdr rec))))
2535                            nil))))
2536       (list where exc-mode))))
2537
2538 ;; (defun mumamo-noweb2-chunk-start-bw (pos min)
2539 ;;   "Helper for `mumamo-noweb2-chunk'.
2540 ;; POS is where to start search and MIN is where to stop."
2541 ;;   (let ((exc-start (mumamo-chunk-start-bw-re pos min "^<<\\(.*?\\)>>="))
2542 ;;         (exc-mode 'text-mode))
2543 ;;     (when exc-start
2544 ;;       (let* ((file-name (match-string 1))
2545 ;;              (file-ext  (when file-name (file-name-extension file-name))))
2546 ;;         (when file-ext
2547 ;;           (setq exc-mode (catch 'major
2548 ;;                            (dolist (rec mumamo-noweb2-mode-from-ext)
2549 ;;                              (when (string-match (car rec) file-ext)
2550 ;;                                (throw 'major (cdr rec))))
2551 ;;                            nil))
2552 ;;           (unless exc-mode
2553 ;;             (setq exc-mode
2554 ;;                   (cdr (assoc file-ext mumamo-noweb2-found-mode-from-ext)))
2555 ;;             (unless exc-mode
2556 ;;               ;; Get the major mode from file name
2557 ;;               (with-temp-buffer
2558 ;;                 (setq buffer-file-name file-name)
2559 ;;                 (condition-case err
2560 ;;                     (normal-mode)
2561 ;;                   (error (message "error (normal-mode): %s"
2562 ;;                                   (error-message-string err))))
2563 ;;                 (setq exc-mode (or major-mode
2564 ;;                                    'text-mode))
2565 ;;                 (add-to-list 'mumamo-noweb2-found-mode-from-ext
2566 ;;                              (cons file-ext exc-mode)))
2567 ;;               ))))
2568 ;;       (cons exc-start exc-mode))))
2569
2570 (defun mumamo-noweb2-chunk-end-fw (pos max)
2571   "Helper for `mumamo-noweb2-chunk'.
2572 POS is where to start search and MAX is where to stop."
2573   (save-match-data
2574     (mumamo-chunk-end-fw-re pos max "^@")))
2575
2576 ;; (defun mumamo-noweb2-chunk-end-bw (pos min)
2577 ;;   "Helper for `mumamo-noweb2-chunk'.
2578 ;; POS is where to start search and MIN is where to stop."
2579 ;;   (mumamo-chunk-end-bw-re pos min "^@"))
2580
2581 (defun mumamo-noweb2-code-chunk (pos min max)
2582   "Find noweb chunks.  Return range and found mode.
2583 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
2584   (save-match-data
2585     ;; (mumamo-find-possible-chunk pos min max
2586     ;;                             'mumamo-noweb2-chunk-start-bw
2587     ;;                             'mumamo-noweb2-chunk-end-bw
2588     ;;                             'mumamo-noweb2-chunk-start-fw-old
2589     ;;                             'mumamo-noweb2-chunk-end-fw)
2590     (mumamo-possible-chunk-forward pos max
2591                                    'mumamo-noweb2-chunk-start-fw
2592                                    'mumamo-noweb2-chunk-end-fw)))
2593
2594
2595 ;;;###autoload
2596 (define-mumamo-multi-major-mode noweb2-mumamo-mode
2597   "Multi major mode for noweb files."
2598   ("noweb Family" latex-mode
2599    (mumamo-noweb2-code-chunk)))
2600
2601
2602 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2603 ;;;; Template-Toolkit
2604
2605
2606
2607 ;; (setq auto-mode-alist
2608 ;;       (append '(("\\.tt2?$" . tt-mode))  auto-mode-alist ))
2609
2610 ;;(require 'tt-mode)
2611 (defun mumamo-chunk-tt (pos min max)
2612   "Find [% ... %], return range and `tt-mode'.
2613 See `mumamo-find-possible-chunk' for POS, MIN and MAX.
2614
2615 This is for Template Toolkit.
2616 See URL `http://dave.org.uk/emacs/' for `tt-mode'."
2617   (mumamo-quick-static-chunk pos min max "[%" "%]" t 'tt-mode nil))
2618
2619 (define-mumamo-multi-major-mode tt-html-mumamo-mode
2620   "Turn on multiple major modes for TT files with main mode `nxhtml-mode'.
2621 TT = Template-Toolkit.
2622
2623 This also covers inlined style and javascript."
2624     ("TT HTML Family" html-mode
2625      (mumamo-chunk-tt
2626       mumamo-chunk-inlined-style
2627       mumamo-chunk-inlined-script
2628       mumamo-chunk-style=
2629       mumamo-chunk-onjs=
2630      )))
2631
2632
2633 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2634 ;;;; Asp
2635
2636 ;;;; asp <%@language="javscript"%>
2637
2638 (defvar mumamo-asp-default-major 'asp-js-mode)
2639 (make-variable-buffer-local 'mumamo-asp-default-major)
2640 (put 'mumamo-asp-default-major 'permanent-local t)
2641
2642 (defconst mumamo-asp-lang-marker
2643   (rx "<%@"
2644       (0+ space)
2645       "language"
2646       (0+ space)
2647       "="
2648       (0+ space)
2649       "\""
2650       (submatch (1+ (not (any "\""))))
2651       "\""
2652       (0+ space)))
2653
2654 (defun mumamo-search-fw-exc-start-jsp (pos min max)
2655   ;; fix-me
2656   )
2657 (defun mumamo-chunk-asp (pos min max)
2658   "Find <% ... %>.  Return range and 'asp-js-mode.
2659 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
2660   ;; Fix-me: this is broken!
2661   ;; (mumamo-find-possible-chunk pos min max
2662   ;;                             'mumamo-search-bw-exc-start-asp
2663   ;;                             'mumamo-search-bw-exc-end-jsp
2664   ;;                             'mumamo-search-fw-exc-start-jsp-old
2665   ;;                             'mumamo-search-fw-exc-end-jsp)
2666   (mumamo-possible-chunk-forward pos max
2667                                  'mumamo-search-fw-exc-start-asp
2668                                  'mumamo-search-fw-exc-end-jsp))
2669
2670
2671 ;;;; asp <% ...>
2672
2673 (defun mumamo-chunk-asp% (pos min max)
2674   "Find <% ... %>.  Return range and 'asp-js-mode or 'asp-vb-mode.
2675 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
2676   (let* ((chunk (mumamo-quick-static-chunk pos min max "<%" "%>" t 'java-mode t))
2677          (beg (nth 0 chunk))
2678          (here (point))
2679          glang)
2680     (when chunk
2681       (goto-char beg)
2682       (if (looking-at mumamo-asp-lang-marker)
2683           (progn
2684             (setq glang (downcase (match-string 1)))
2685             (cond
2686              ((string= glang "javascript")
2687               (setq mumamo-asp-default-major 'asp-js-mode))
2688              ((string= glang "vbscript")
2689               (setq mumamo-asp-default-major 'asp-vb-mode))
2690              )
2691             (setcar (nthcdr 2 chunk) 'mumamo-comment-mode))
2692         (setcar (nthcdr 2 chunk) mumamo-asp-default-major))
2693       chunk)))
2694
2695 ;;;; asp <script ...>
2696
2697 (defconst mumamo-asp-script-tag-start-regex
2698   (rx "<script"
2699       space
2700       (0+ (not (any ">")))
2701       "language"
2702       (0+ space)
2703       "="
2704       (0+ space)
2705       ?\"
2706       ;;(or "text" "application")
2707       ;;"/"
2708       ;;(or "javascript" "ecmascript")
2709       ;; "text/javascript"
2710       (submatch
2711        (or "javascript" "vbscript"))
2712       ?\"
2713       (0+ (not (any ">")))
2714       ">"
2715       ;; FIX-ME: Commented out because of bug in Emacs
2716       ;;
2717       ;;(optional (0+ space) "<![CDATA[" )
2718       ))
2719
2720 ;; (defun mumamo-asp-search-bw-exc-start-inlined-script (pos min)
2721 ;;   "Helper function for `mumamo-asp-chunk-inlined-script'.
2722 ;; POS is where to start search and MIN is where to stop."
2723 ;;   (goto-char (+ pos 7))
2724 ;;   (let ((marker-start (search-backward "<script" min t))
2725 ;;         (exc-mode 'asp-vb-mode)
2726 ;;         exc-start
2727 ;;         lang)
2728 ;;     (when marker-start
2729 ;;       (when (looking-at mumamo-asp-script-tag-start-regex)
2730 ;;         (setq lang (downcase (match-string-no-properties 1)))
2731 ;;         (cond
2732 ;;          ((string= lang "javascript")
2733 ;;           (setq exc-mode 'asp-js-mode))
2734 ;;          ((string= lang "vbscript")
2735 ;;           (setq exc-mode 'asp-vb-mode))))
2736 ;;       (setq exc-start (match-end 0))
2737 ;;       (goto-char exc-start)
2738 ;;       (when (<= exc-start pos)
2739 ;;         (cons (point) exc-mode))
2740 ;;       )))
2741
2742 ;; (defun mumamo-asp-search-fw-exc-start-inlined-script-old (pos max)
2743 ;;   "Helper for `mumamo-chunk-inlined-script'.
2744 ;; POS is where to start search and MAX is where to stop."
2745 ;;   (goto-char (1+ pos))
2746 ;;   (skip-chars-backward "^<")
2747 ;;   ;; Handle <![CDATA[
2748 ;;   (when (and
2749 ;;          (eq ?< (char-before))
2750 ;;          (eq ?! (char-after))
2751 ;;          (not (bobp)))
2752 ;;     (backward-char)
2753 ;;     (skip-chars-backward "^<"))
2754 ;;   (unless (bobp)
2755 ;;     (backward-char 1))
2756 ;;   (let ((exc-start (search-forward "<script" max t))
2757 ;;         exc-mode)
2758 ;;     (when exc-start
2759 ;;       (goto-char (- exc-start 7))
2760 ;;       (when (looking-at mumamo-asp-script-tag-start-regex)
2761 ;;         (goto-char (match-end 0))
2762 ;;         (point)
2763 ;;         ))))
2764
2765 (defun mumamo-asp-search-fw-exc-start-inlined-script (pos max)
2766   "Helper for `mumamo-chunk-inlined-script'.
2767 POS is where to start search and MAX is where to stop."
2768   (goto-char (1+ pos))
2769   (skip-chars-backward "^<")
2770   ;; Handle <![CDATA[
2771   (when (and
2772          (eq ?< (char-before))
2773          (eq ?! (char-after))
2774          (not (bobp)))
2775     (backward-char)
2776     (skip-chars-backward "^<"))
2777   (unless (bobp)
2778     (backward-char 1))
2779   (let ((exc-start (search-forward "<script" max t))
2780         (exc-mode 'asp-vb-mode)
2781         (lang "vbscript"))
2782     (when exc-start
2783       (goto-char (- exc-start 7))
2784       (when (looking-at mumamo-asp-script-tag-start-regex)
2785         (goto-char (match-end 0))
2786         (setq lang (downcase (match-string-no-properties 1)))
2787         (cond
2788          ((string= lang "javascript")
2789           (setq exc-mode 'asp-js-mode))
2790          ((string= lang "vbscript")
2791           (setq exc-mode 'asp-vb-mode)))
2792         (list (point) exc-mode)
2793         ))))
2794
2795 (defun mumamo-asp-chunk-inlined-script (pos min max)
2796   "Find <script language=...  runat=...>...</script>.  Return 'asp-js-mode.
2797 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
2798   ;; (mumamo-find-possible-chunk pos min max
2799   ;;                             'mumamo-asp-search-bw-exc-start-inlined-script
2800   ;;                             'mumamo-search-bw-exc-end-inlined-script
2801   ;;                             'mumamo-asp-search-fw-exc-start-inlined-script-old
2802   ;;                             'mumamo-search-fw-exc-end-inlined-script)
2803   (mumamo-possible-chunk-forward pos max
2804                                  'mumamo-asp-search-fw-exc-start-inlined-script
2805                                  'mumamo-search-fw-exc-end-inlined-script))
2806
2807 ;;;###autoload
2808 (define-mumamo-multi-major-mode asp-html-mumamo-mode
2809   "Turn on multiple major modes for ASP with main mode `html-mode'.
2810 This also covers inlined style and javascript."
2811   ("ASP Html Family" html-mode
2812    (mumamo-chunk-asp%
2813     mumamo-asp-chunk-inlined-script
2814     mumamo-chunk-inlined-script
2815     mumamo-chunk-style=
2816     mumamo-chunk-onjs=
2817     )))
2818
2819
2820 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2821 ;;;; Org-mode
2822
2823 (defcustom mumamo-org-submodes
2824   '(
2825     (emacs-lisp emacs-lisp-mode)
2826     (ruby ruby-mode)
2827     (python python-mode)
2828     (sh sh-mode)
2829     (R R-mode)
2830     (ditaa picture-mode)
2831     )
2832   "Alist for conversion of org #+BEGIN_SRC specifier to major mode.
2833 Works kind of like `mumamo-major-modes'.
2834
2835 This may be used for example for org-babel \(see URL
2836 `http://orgmode.org/worg/org-contrib/babel/')."
2837   :type '(alist
2838           :key-type (symbol :tag "Symbol in #BEGIN_SRC specifier")
2839           :value-type (repeat (choice
2840                                (command :tag "Major mode")
2841                                (symbol :tag "Major mode (not yet loaded)")))
2842           )
2843   :group 'mumamo-modes)
2844
2845 (defun mumamo-org-mode-from-spec (major-spec)
2846   "Translate MAJOR-SPEC to a major mode.
2847 Translate MAJOR-SPEC used in #BEGIN_SRC to a major mode.
2848
2849 See `mumamo-org-submodes' for an explanation."
2850   (mumamo-major-mode-from-spec major-spec mumamo-org-submodes))
2851
2852 (defun mumamo-chunk-org-html (pos min max)
2853   "Find #+BEGIN_HTML ... #+END_HTML, return range and `html-mode'.
2854 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
2855   (mumamo-quick-static-chunk pos min max "#+BEGIN_HTML" "#+END_HTML" nil 'html-mode nil))
2856
2857 ;; (defun mumamo-search-bw-org-src-start (pos min)
2858 ;;   "Helper for `mumamo-chunk-org-src'.
2859 ;; POS is where to start search and MIN is where to stop."
2860 ;;   (let* ((exc-start (mumamo-chunk-start-bw-str pos min "#+BEGIN_SRC"))
2861 ;;          (exc-mode (when exc-start
2862 ;;                      (let ((here (point)))
2863 ;;                        (goto-char exc-start)
2864 ;;                        (prog1
2865 ;;                            (read (current-buffer))
2866 ;;                          (goto-char here))))))
2867 ;;     (setq exc-mode (mumamo-org-mode-from-spec exc-mode))
2868 ;;     ;;(setq exc-mode (eval exc-mode))
2869 ;;     ;;(setq exc-mode 'text-mode)
2870 ;;     ;;(when exc-mode (setq exc-mode (quote exc-mode)))
2871 ;;     ;;(assert (eq exc-mode 'emacs-lisp-mode) t)
2872 ;;     (when exc-start
2873 ;;       (when (<= exc-start pos)
2874 ;;         (cons exc-start exc-mode)))))
2875
2876 ;; (defun mumamo-search-bw-org-src-end (pos min)
2877 ;;   "Helper for `mumamo-chunk-org-src'.
2878 ;; POS is where to start search and MIN is where to stop."
2879 ;;   (mumamo-chunk-end-bw-str pos min "#+END_SRC"))
2880
2881 ;; (defun mumamo-search-fw-org-src-start-old (pos max)
2882 ;;   "Helper for `mumamo-chunk-org-src'.
2883 ;; POS is where to start search and MAX is where to stop."
2884 ;;   (mumamo-chunk-start-fw-str pos max "#+BEGIN_SRC"))
2885
2886 (defun mumamo-search-fw-org-src-start (pos max)
2887   "Helper for `mumamo-chunk-org-src'.
2888 POS is where to start search and MAX is where to stop."
2889   (let ((where (mumamo-chunk-start-fw-str pos max "#+BEGIN_SRC")))
2890     (when where
2891       (let ((exc-mode (let ((here (point)))
2892                         (goto-char where)
2893                         (prog1
2894                             (read (current-buffer))
2895                           (goto-char here)))))
2896         (setq exc-mode (mumamo-org-mode-from-spec exc-mode))
2897         (list where exc-mode)))))
2898
2899 (defun mumamo-search-fw-org-src-end (pos max)
2900   "Helper for `mumamo-chunk-org-src'.
2901 POS is where to start search and MAX is where to stop."
2902   (save-match-data
2903     (mumamo-chunk-end-fw-str pos max "#+END_SRC")))
2904
2905 (defun mumamo-chunk-org-src (pos min max)
2906   "Find #+BEGIN_SRC ... #+END_SRC, return range and choosen major mode.
2907 See `mumamo-find-possible-chunk' for POS, MIN and MAX.
2908
2909 See Info node `(org) Literal Examples' for how to specify major
2910 mode."
2911   ;; (mumamo-find-possible-chunk pos min max
2912   ;;                             'mumamo-search-bw-org-src-start
2913   ;;                             'mumamo-search-bw-org-src-end
2914   ;;                             'mumamo-search-fw-org-src-start-old
2915   ;;                             'mumamo-search-fw-org-src-end)
2916   (mumamo-possible-chunk-forward pos max
2917                                  'mumamo-search-fw-org-src-start
2918                                  'mumamo-search-fw-org-src-end))
2919
2920 ;;;###autoload
2921 (define-mumamo-multi-major-mode org-mumamo-mode
2922   "Turn on multiple major modes for `org-mode' files with main mode `org-mode'.
2923 ** Note about HTML subchunks:
2924 Unfortunately this only allows `html-mode' (not `nxhtml-mode') in
2925 sub chunks."
2926     ("Org Mode + Html" org-mode
2927      (mumamo-chunk-org-html
2928       mumamo-chunk-org-src
2929       )))
2930
2931
2932 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2933 ;;;; Mako
2934
2935 ;; See http://www.makotemplates.org/docs/syntax.html
2936
2937 ;;; Comments mode
2938 ;; Fix-me: move to mumamo.el
2939 (defconst mumamo-comment-font-lock-keywords
2940   (list
2941    (cons "\\(.*\\)" (list 1 font-lock-comment-face))
2942    ))
2943 (defvar mumamo-comment-font-lock-defaults
2944   '(mumamo-comment-font-lock-keywords t t))
2945
2946 (define-derived-mode mumamo-comment-mode nil "Comment chunk"
2947   "For comment blocks."
2948   (set (make-local-variable 'font-lock-defaults) mumamo-comment-font-lock-defaults))
2949
2950
2951
2952 (defun mumamo-chunk-mako-<% (pos min max)
2953   "Find <% ... %> and <%! ... %>. Return range and `python-mode'.
2954 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
2955   ;; (mumamo-find-possible-chunk pos min max
2956   ;;                             'mumamo-mako-<%-bw-start
2957   ;;                             'mumamo-mako-<%-bw-end
2958   ;;                             'mumamo-mako-<%-fw-start-old
2959   ;;                             'mumamo-mako-<%-fw-end
2960   ;;                             'mumamo-mako-<%-find-borders)
2961   (let ((chunk (mumamo-possible-chunk-forward pos max
2962                                               'mumamo-mako-<%-fw-start
2963                                               'mumamo-mako-<%-fw-end
2964                                               'mumamo-mako-<%-find-borders
2965                                               )))
2966     (when chunk
2967       (setcdr (last chunk) '(mumamo-template-indentor))
2968       chunk)))
2969
2970 (defun mumamo-mako-<%-find-borders (start end exc-mode)
2971   (when exc-mode
2972     (list
2973      (when start
2974        (+ start
2975           (if (eq ?! (char-after (+ start 2)))
2976               3
2977             2)))
2978      (when end (- end 2))
2979      exc-mode)))
2980
2981 ;; (defun mumamo-mako-<%-bw-start (pos min)
2982 ;;   (let ((here (point))
2983 ;;         start
2984 ;;         ret
2985 ;;         )
2986 ;;     (goto-char (+ pos 3))
2987 ;;     (setq start (re-search-backward "<%!?\\(?:[ \t]\\|$\\)" min t))
2988 ;;     (when (and start (<= start pos))
2989 ;;       (setq ret (list start 'python-mode)))
2990 ;;     (goto-char here)
2991 ;;     ret))
2992
2993 ;; (defun mumamo-mako-<%-bw-end (pos min)
2994 ;;   (mumamo-chunk-end-bw-str-inc pos min "%>")) ;; ok
2995
2996 ;; (defun mumamo-mako-<%-fw-start-old (pos max)
2997 ;;   (let ((here (point))
2998 ;;         start
2999 ;;         ret)
3000 ;;     (goto-char pos)
3001 ;;     (setq start
3002 ;;           (re-search-forward "<%!?\\(?:[ \t]\\|$\\)" max t))
3003 ;;     (when start
3004 ;;       (setq ret (match-beginning 0)))
3005 ;;     (goto-char here)
3006 ;;     ret))
3007
3008 (defun mumamo-mako-<%-fw-start (pos max)
3009   (let ((here (point))
3010         start
3011         ret)
3012     (goto-char pos)
3013     (setq start
3014           (re-search-forward "<%!?\\(?:[ \t]\\|$\\)" max t))
3015     (when start
3016       (setq ret (match-beginning 0)))
3017     (goto-char here)
3018     (when ret
3019       (list ret 'python-mode))))
3020
3021 (defun mumamo-mako-<%-fw-end (pos max)
3022   (save-match-data
3023     (mumamo-chunk-end-fw-str-inc pos max "%>"))) ;; ok
3024
3025
3026
3027 (defun mumamo-chunk-mako-% (pos min max)
3028   "Find % python EOL.  Return range and `python-mode'.
3029 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
3030   (let ((chunk (mumamo-whole-line-chunk pos min max "%" 'python-mode)))
3031     (when chunk
3032       (setcdr (last chunk) '(mumamo-template-indentor))
3033       chunk)))
3034
3035 (defun mumamo-chunk-mako-one-line-comment (pos min max)
3036   "Find ## comment EOL.  Return range and `python-mode'.
3037 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
3038   (mumamo-whole-line-chunk pos min max "##" 'mumamo-comment-mode))
3039
3040 ;; Fix-me: Move this to mumamo.el
3041 ;; Fix-me: does not work with new chunk div
3042 (defun mumamo-whole-line-chunk-fw-exc-end-fun (pos max)
3043   (let ((here (point)))
3044     (goto-char pos)
3045     (prog1
3046         (line-end-position)
3047       (goto-char here))))
3048
3049 (defun mumamo-whole-line-chunk (pos min max marker mode)
3050   (let* ((here (point))
3051          (len-marker (length marker))
3052          (pattern (rx-to-string `(and bol (0+ blank) ,marker blank) t))
3053          (whole-line-chunk-borders-fun
3054           `(lambda (start end dummy)
3055              (let ((start-border (+ start ,len-marker)))
3056                (list start-border nil))))
3057          beg
3058          end
3059          ret)
3060     (goto-char pos)
3061     (setq beg (re-search-forward pattern max t))
3062     (when beg
3063       (setq beg (- beg len-marker 1))
3064       (setq end (line-end-position))
3065       (setq ret (list beg
3066                       end
3067                       mode
3068                       (let ((start-border (+ beg len-marker)))
3069                         (list start-border nil))
3070                       nil
3071                       'mumamo-whole-line-chunk-fw-exc-end-fun
3072                       whole-line-chunk-borders-fun
3073                       )))
3074     (goto-char here)
3075     ret))
3076
3077 ;; (defun mumamo-single-regexp-chunk (pos min max begin-mark end-mark mode)
3078 ;;   "Not ready yet. `mumamo-quick-static-chunk'"
3079 ;;   (let ((here (point))
3080 ;;         (len-marker (length marker))
3081 ;;         beg
3082 ;;         end
3083 ;;         ret)
3084 ;;     (goto-char pos)
3085 ;;     (setq beg (line-beginning-position))
3086 ;;     (setq end (line-end-position))
3087 ;;     (unless (or (when min (< beg min))
3088 ;;                 (when max (> end max))
3089 ;;                 (= pos end))
3090 ;;       (goto-char beg)
3091 ;;       (skip-chars-forward " \t")
3092 ;;       (when (and
3093 ;;              (string= marker (buffer-substring-no-properties (point) (+ (point) len-marker)))
3094 ;;              (memq (char-after (+ (point) len-marker))
3095 ;;                    '(?\  ?\t ?\n))
3096 ;;              (>= pos (point)))
3097 ;;         (setq ret
3098 ;;               (list (point)
3099 ;;                     end
3100 ;;                     mode
3101 ;;                     (let ((start-border (+ (point) len-marker)))
3102 ;;                       (list start-border nil))))))
3103 ;;     (unless ret
3104 ;;       (let ((range-regexp
3105 ;;              (concat "^[ \t]*"
3106 ;;                      "\\("
3107 ;;                      (regexp-quote marker)
3108 ;;                      "[ \t\n].*\\)$")))
3109 ;;         ;; Backward
3110 ;;         (goto-char pos)
3111 ;;         (unless (= pos (line-end-position))
3112 ;;           (goto-char (line-beginning-position)))
3113 ;;         (setq beg (re-search-backward range-regexp min t))
3114 ;;         (when beg (setq beg (match-end 1)))
3115 ;;         ;; Forward, take care of indentation part
3116 ;;         (goto-char pos)
3117 ;;         (unless (= pos (line-end-position))
3118 ;;           (goto-char (line-beginning-position)))
3119 ;;         (setq end (re-search-forward range-regexp max t))
3120 ;;         (when end (setq end (match-beginning 1))))
3121 ;;       (setq ret (list beg end)))
3122 ;;     (goto-char here)
3123 ;;     ;;(setq ret nil)
3124 ;;     ret))
3125
3126
3127 (defun mumamo-chunk-mako-<%doc (pos min max)
3128   (mumamo-quick-static-chunk pos min max "<%doc>" "</%doc>" t 'mumamo-comment-mode t))
3129
3130 (defun mumamo-chunk-mako-<%include (pos min max)
3131   (mumamo-quick-static-chunk pos min max "<%include" "/>" t 'html-mode t))
3132
3133 (defun mumamo-chunk-mako-<%inherit (pos min max)
3134   (mumamo-quick-static-chunk pos min max "<%inherit" "/>" t 'html-mode t))
3135
3136 (defun mumamo-chunk-mako-<%namespace (pos min max)
3137   (mumamo-quick-static-chunk pos min max "<%namespace" "/>" t 'html-mode t))
3138
3139 (defun mumamo-chunk-mako-<%page (pos min max)
3140   (mumamo-quick-static-chunk pos min max "<%page" "/>" t 'html-mode t))
3141
3142 ;; Fix-me: this is not correct
3143 (defun mumamo-chunk-mako-<%def (pos min max)
3144   (mumamo-quick-static-chunk pos min max "<%def" "</%def>" t 'html-mode t))
3145
3146 (defun mumamo-chunk-mako$(pos min max)
3147   "Find ${ ... }, return range and `python-mode'.
3148 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
3149   (mumamo-quick-static-chunk pos min max "${" "}" t 'python-mode t))
3150
3151 ;;;###autoload
3152 (define-mumamo-multi-major-mode mako-html-mumamo-mode
3153   "Turn on multiple major modes for Mako with main mode `html-mode'.
3154 This also covers inlined style and javascript."
3155 ;; Fix-me: test case
3156 ;;
3157 ;; Fix-me: Add chunks for the tags, but make sure these are made
3158 ;; invisible to nxml-mode parser.
3159 ;;
3160 ;; Fix-me: Maybe finally add that indentation support for one-line chunks?
3161   ("Mako HTML Family" html-mode
3162    (
3163     mumamo-chunk-mako-one-line-comment
3164     mumamo-chunk-mako-<%doc
3165     mumamo-chunk-mako-<%include
3166     mumamo-chunk-mako-<%inherit
3167     mumamo-chunk-mako-<%namespace
3168     mumamo-chunk-mako-<%page
3169
3170     mumamo-chunk-mako-<%def
3171     ;;mumamo-chunk-mako-<%namesp:name
3172     ;;mumamo-chunk-mako-<%call
3173     ;;mumamo-chunk-mako-<%text
3174
3175     mumamo-chunk-mako-<%
3176     mumamo-chunk-mako-%
3177     mumamo-chunk-mako$
3178
3179     mumamo-chunk-xml-pi
3180     mumamo-chunk-inlined-style
3181     mumamo-chunk-inlined-script
3182     mumamo-chunk-style=
3183     mumamo-chunk-onjs=
3184     )))
3185 (mumamo-inherit-sub-chunk-family-locally 'mako-html-mumamo-mode 'mako-html-mumamo-mode)
3186
3187
3188 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3189 ;;;; XSL
3190
3191 ;;;###autoload
3192 (define-mumamo-multi-major-mode xsl-nxml-mumamo-mode
3193   "Turn on multi major mode for XSL with main mode `nxml-mode'.
3194 This covers inlined style and javascript."
3195   ("XSL nXtml Family" nxml-mode
3196    (
3197     mumamo-chunk-inlined-style
3198     mumamo-chunk-inlined-script
3199     )))
3200
3201 ;;;###autoload
3202 (define-mumamo-multi-major-mode xsl-sgml-mumamo-mode
3203   "Turn on multi major mode for XSL with main mode `sgml-mode'.
3204 This covers inlined style and javascript."
3205   ("XSL SGML Family" sgml-mode
3206    (
3207     mumamo-chunk-inlined-style
3208     mumamo-chunk-inlined-script
3209     )))
3210
3211 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3212 ;;;; Markdown
3213
3214 (defun mumamo-chunk-markdown-html-1 (pos min max)
3215   (save-restriction
3216     (goto-char pos)
3217     (narrow-to-region (or min (point)) (or max (point-max)))
3218     (save-match-data
3219       (let ((here (point)))
3220         (when (re-search-forward (rx (* space)
3221                                      (submatch "<")
3222                                      (* (any "a-z"))
3223                                      (or ">" (any " \t\n")))
3224                                  nil t)
3225           (let ((beg (match-beginning 1))
3226                 (end))
3227             (goto-char beg)
3228             (condition-case err
3229                 (progn
3230                   (while (not (sgml-skip-tag-forward 1)))
3231                   (setq end (point)))
3232               (error (message "mumamo-chunk-markdown-html-1: %s" err)))
3233             (goto-char here)
3234             (when (and beg end)
3235               (cons beg end))))))))
3236
3237 (defun mumamo-chunk-markdown-html-fw-exc-fun (pos max)
3238   (let ((beg-end (mumamo-chunk-markdown-html-1 pos nil max)))
3239     (cdr beg-end)))
3240
3241 (defun mumamo-chunk-markdown-html (pos min max)
3242   "Find a chunk of html code in `markdown-mode'.
3243 Return range and `html-mode'.
3244 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
3245   (let ((beg-end (mumamo-chunk-markdown-html-1 pos nil max)))
3246     (when beg-end
3247       (let ((beg (car beg-end))
3248             (end (cdr beg-end)))
3249         (list beg end 'html-mode
3250               nil ;; borders
3251               nil ;; parseable y
3252               'mumamo-chunk-markdown-html-fw-exc-fun
3253               nil ;; find-borders fun
3254               )))))
3255
3256 ;;;###autoload
3257 (define-mumamo-multi-major-mode markdown-html-mumamo-mode
3258   "Turn on multi major markdown mode in buffer.
3259 Main major mode will be `markdown-mode'.
3260 Inlined html will be in `html-mode'.
3261
3262 You need `markdown-mode' which you can download from URL
3263 `http://jblevins.org/projects/markdown-mode/'."
3264   ("Markdown HTML Family" markdown-mode
3265    (
3266     mumamo-chunk-markdown-html
3267     )))
3268
3269
3270
3271 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3272 ;;;; Latex related
3273
3274 (defun mumamo-latex-closure-chunk (pos min max)
3275   (mumamo-quick-static-chunk pos min max "\\begin{clojure}" "\\end{clojure}" t 'clojure-mode t))
3276
3277 ;;;###autoload
3278 (define-mumamo-multi-major-mode latex-clojure-mumamo-mode
3279   "Turn on multi major mode latex+clojure.
3280 Main major mode will be `latex-mode'.
3281 Subchunks will be in `clojure-mode'.
3282
3283 You will need `clojure-mode' which you can download from URL
3284 `http://github.com/jochu/clojure-mode/tree'."
3285   ("Latex+clojur Family" latex-mode
3286    (
3287     mumamo-latex-closure-chunk
3288     )))
3289
3290 (add-to-list 'auto-mode-alist '("\\.lclj\\'" . latex-clojure-mumamo-mode))
3291
3292
3293 (defun mumamo-latex-haskell-chunk (pos min max)
3294   (mumamo-quick-static-chunk pos min max "\\begin{code}" "\\end{code}" t 'haskell-mode t))
3295
3296 ;;;###autoload
3297 (define-mumamo-multi-major-mode latex-haskell-mumamo-mode
3298   "Turn on multi major mode latex+haskell.
3299 Main major mode will be `latex-mode'.
3300 Subchunks will be in `haskell-mode'.
3301
3302 You will need `haskell-mode' which you can download from URL
3303 `http://projects.haskell.org/haskellmode-emacs/'."
3304   ("Latex+haskell Family" latex-mode
3305    (
3306     mumamo-latex-haskell-chunk
3307     )))
3308
3309
3310
3311 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3312 ;;;; Python + ReST
3313
3314 ;; From Martin Soto
3315
3316 (defun python-rst-long-string-chunk (pos min max)
3317  "Find Python long strings.  Return range and 'mumamo-comment-mode.
3318 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
3319  ;;(mumamo-quick-static-chunk pos min max "\"\"\"((" "))\"\"\"" nil 'rst-mode nil))
3320  (mumamo-quick-static-chunk pos min max "\"\"\"" "\"\"\"" t 'rst-mode t))
3321
3322 ;;;###autoload
3323 (define-mumamo-multi-major-mode python-rst-mumamo-mode
3324  "Turn on multiple major modes for Python with RestructuredText docstrings."
3325  ("Python ReST Family" python-mode
3326   (
3327    python-rst-long-string-chunk
3328    )))
3329
3330
3331 (provide 'mumamo-fun)
3332 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3333 ;;; mumamo-fun.el ends here