1 ;; django-html-mode.el --- django html mode
3 ;; Author: TSKim (http://tsgates.cafe24.com, tsgatesv@gmail.com)
4 ;; Keywords: django html languages
7 ;; This file is NOT part of GNU Emacs.
9 ;; This file is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; This file is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 ;; Boston, MA 02110-1301, USA.
32 (defvar django-html-mode-hook nil
)
34 (defvar django-html-mode-map
35 (let ((django-html-mode-map (make-keymap)))
36 (define-key django-html-mode-map
"\C-j" 'newline-and-indent
)
38 "Keymap for Django major mode")
40 ;; if : if, if not, if A or B, if not A or B, if not A and B
42 ;; for : for a in alist reversed
43 ;; forloop.counter The current iteration of the loop (1-indexed)
44 ;; forloop.counter0 The current iteration of the loop (0-indexed)
45 ;; forloop.revcounter The number of iterations from the end of the loop (1-indexed)
46 ;; forloop.revcounter0 The number of iterations from the end of the loop (0-indexed)
47 ;; forloop.first True if this is the first time through the loop
48 ;; forloop.last True if this is the last time through the loop
49 ;; forloop.parentloop For nested loops, this is the loop "above" the current one
51 ;; ifequal : ifequal A B
52 ;; comment : {% This is comment %}
53 ;; filter : {{ name | lower }}
55 ;; keyword-end : if, for, ifequal, block, ifnotequal, spaceless
56 ;; keyword-3 : regroup
57 ;; keyword-2 : for, ifequal
58 ;; keyword-1 : if, block, extends, include, ifchanged, load, now, ssi, withratio
59 ;; keyword-0 : else, spaceless
61 ;; start and end keyword for block/comment/variable
62 (defconst django-html-open-block
"{%")
63 (defconst django-html-close-block
"%}")
64 (defconst django-html-open-comment
"{#")
65 (defconst django-html-close-comment
"#}")
66 (defconst django-html-open-variable
"{{")
67 (defconst django-html-close-variable
"}}")
69 (defconst django-html-font-lock-keywords-1
72 sgml-font-lock-keywords-1
)
74 "First level keyword highlighting")
76 (defconst django-html-font-lock-keywords-2
78 django-html-font-lock-keywords-1
79 sgml-font-lock-keywords-2
))
81 (defconst django-html-font-lock-keywords-3
83 django-html-font-lock-keywords-1
84 django-html-font-lock-keywords-2
87 (,(rx (eval django-html-open-comment
)
91 (eval django-html-close-comment
))
92 . font-lock-comment-face
)
95 (,(rx (eval django-html-open-variable
)
97 (group (0+ (not (any "}"))))
99 (eval django-html-close-variable
))
100 (1 font-lock-variable-name-face
))
102 ;; start, end keyword font lock
103 (,(rx (group (or (eval django-html-open-block
)
104 (eval django-html-close-block
)
105 (eval django-html-open-comment
)
106 (eval django-html-close-comment
)
107 (eval django-html-open-variable
)
108 (eval django-html-close-variable
))))
109 (1 font-lock-builtin-face
))
111 ;; end prefix keyword font lock
112 (,(rx (eval django-html-open-block
)
115 ;; end prefix keywords
116 (or "if" "for" "ifequal" "block" "ifnotequal" "spaceless" "filter")))
118 (eval django-html-close-block
))
119 (1 font-lock-keyword-face
))
121 ;; more words after keyword
122 (,(rx (eval django-html-open-block
)
124 (group (or "extends" "for" "cycle" "filter" "if not" "else"
125 "firstof" "debug" "if" "ifchanged" "ifequal" "ifnotequal"
126 "include" "load" "now" "regroup" "spaceless" "ssi"
127 "templatetag" "widthratio" "block"))
129 ;; TODO: is there a more beautiful way?
133 (eval django-html-close-block
))
134 (1 font-lock-keyword-face
))
136 ;; TODO: if specific cases for supporting "or", "not", and "and"
138 ;; for sepcific cases for supporting in
139 (,(rx (eval django-html-open-block
)
144 (group (1+ (or word ?_ ?.
)))
150 (group (1+ (or word ?_ ?.
)))
152 (group (?
(1+ space
) "reverse"))
155 (eval django-html-close-block
))
156 (1 font-lock-variable-name-face
) (2 font-lock-keyword-face
)
157 (3 font-lock-variable-name-face
) (4 font-lock-keyword-face
)))))
159 (defvar django-html-font-lock-keywords
160 django-html-font-lock-keywords-1
)
162 (defvar django-html-mode-syntax-table
163 (let ((django-html-mode-syntax-table (make-syntax-table)))
164 django-html-mode-syntax-table
)
165 "Syntax table for django-html-mode")
168 (define-derived-mode django-html-mode html-mode
"django-html"
169 "Major mode for editing django html files(.djhtml)"
172 ;; it mainly from sgml-mode font lock setting
173 (set (make-local-variable 'font-lock-defaults
)
174 '((django-html-font-lock-keywords
175 django-html-font-lock-keywords-1
176 django-html-font-lock-keywords-2
177 django-html-font-lock-keywords-3
)
179 (font-lock-syntactic-keywords
180 . sgml-font-lock-syntactic-keywords
))))
182 ;; ".html" is common in django
183 ;; (add-to-list 'auto-mode-alist '("\\.djhtml$'" . django-html-mode))
185 (provide 'django-html-mode
)