autoescape no longer is a plain boolean value but can also be a function
[jinja2.git] / ext / jinja.el
1 ;;; jinja.el --- Jinja mode highlighting
2 ;;
3 ;; Author: Georg Brandl
4 ;; Copyright: (c) 2009 by the Jinja Team
5 ;; Last modified: 2008-05-22 23:04 by gbr
6 ;;
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 ;;
9 ;;; Commentary:
10 ;;
11 ;; Mostly ripped off django-mode by Lennart Borgman.
12 ;;
13 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14 ;;
15 ;; This program is free software; you can redistribute it and/or
16 ;; modify it under the terms of the GNU General Public License as
17 ;; published by the Free Software Foundation; either version 2, or
18 ;; (at your option) any later version.
19 ;;
20 ;; This program is distributed in the hope that it will be useful,
21 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23 ;; General Public License for more details.
24 ;;
25 ;; You should have received a copy of the GNU General Public License
26 ;; along with this program; see the file COPYING.  If not, write to
27 ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
28 ;; Floor, Boston, MA 02110-1301, USA.
29 ;;
30 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
31 ;;
32 ;;; Code:
33
34 (defconst jinja-font-lock-keywords
35   (list
36 ;   (cons (rx "{% comment %}" (submatch (0+ anything))
37 ;             "{% endcomment %}") (list 1 font-lock-comment-face))
38    '("{# ?\\(.*?\\) ?#}" . (1 font-lock-comment-face))
39    '("{%-?\\|-?%}\\|{{\\|}}" . font-lock-preprocessor-face)
40    '("{#\\|#}" . font-lock-comment-delimiter-face)
41    ;; first word in a block is a command
42    '("{%-?[ \t\n]*\\([a-zA-Z_]+\\)" . (1 font-lock-keyword-face))
43    ;; variables
44    '("\\({{ ?\\)\\([^|]*?\\)\\(|.*?\\)? ?}}" . (1 font-lock-variable-name-face))
45    ;; keywords and builtins
46    (cons (rx word-start
47              (or "in" "as" "recursive" "not" "and" "or" "if" "else"
48                  "import" "with" "without" "context")
49              word-end)
50          font-lock-keyword-face)
51    (cons (rx word-start
52              (or "true" "false" "none" "loop" "self" "super")
53              word-end)
54          font-lock-builtin-face)
55    ;; tests
56    '("\\(is\\)[ \t]*\\(not\\)[ \t]*\\([a-zA-Z_]+\\)"
57      (1 font-lock-keyword-face) (2 font-lock-keyword-face)
58      (3 font-lock-function-name-face))
59    ;; builtin filters
60    (cons (rx
61           "|" (* space)
62           (submatch
63            (or "abs" "batch" "capitalize" "capture" "center" "count" "default"
64                "dformat" "dictsort" "e" "escape" "filesizeformat" "first"
65                "float" "format" "getattribute" "getitem" "groupby" "indent"
66                "int" "join" "jsonencode" "last" "length" "lower" "markdown"
67                "pprint" "random" "replace" "reverse" "round" "rst" "slice"
68                "sort" "string" "striptags" "sum" "textile" "title" "trim"
69                "truncate" "upper" "urlencode" "urlize" "wordcount" "wordwrap"
70                "xmlattr")))
71          (list 1 font-lock-builtin-face))
72    )
73    "Minimal highlighting expressions for Jinja mode")
74
75 (define-derived-mode jinja-mode nil "Jinja"
76   "Simple Jinja mode for use with `mumamo-mode'.
77 This mode only provides syntax highlighting."
78   ;;(set (make-local-variable 'comment-start) "{#")
79   ;;(set (make-local-variable 'comment-end)   "#}")
80   (setq font-lock-defaults '(jinja-font-lock-keywords)))
81
82 ;; mumamo stuff
83
84 (when (require 'mumamo nil t)
85
86   (defun mumamo-chunk-jinja3(pos min max)
87     "Find {# ... #}.  Return range and `jinja-mode'.
88 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
89     (mumamo-find-possible-chunk pos min max
90                                 'mumamo-search-bw-exc-start-jinja3
91                                 'mumamo-search-bw-exc-end-jinja3
92                                 'mumamo-search-fw-exc-start-jinja3
93                                 'mumamo-search-fw-exc-end-jinja3))
94
95   (defun mumamo-chunk-jinja2(pos min max)
96     "Find {{ ... }}.  Return range and `jinja-mode'.
97 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
98     (mumamo-find-possible-chunk pos min max
99                                 'mumamo-search-bw-exc-start-jinja2
100                                 'mumamo-search-bw-exc-end-jinja2
101                                 'mumamo-search-fw-exc-start-jinja2
102                                 'mumamo-search-fw-exc-end-jinja2))
103
104   (defun mumamo-chunk-jinja (pos min max)
105     "Find {% ... %}.  Return range and `jinja-mode'.
106 See `mumamo-find-possible-chunk' for POS, MIN and MAX."
107     (mumamo-find-possible-chunk pos min max
108                                 'mumamo-search-bw-exc-start-jinja
109                                 'mumamo-search-bw-exc-end-jinja
110                                 'mumamo-search-fw-exc-start-jinja
111                                 'mumamo-search-fw-exc-end-jinja))
112
113   (defun mumamo-search-bw-exc-start-jinja (pos min)
114     "Helper for `mumamo-chunk-jinja'.
115 POS is where to start search and MIN is where to stop."
116     (let ((exc-start (mumamo-chunk-start-bw-str-inc pos min "{%")))
117       (and exc-start
118            (<= exc-start pos)
119            (cons exc-start 'jinja-mode))))
120
121   (defun mumamo-search-bw-exc-start-jinja2(pos min)
122     "Helper for `mumamo-chunk-jinja2'.
123 POS is where to start search and MIN is where to stop."
124     (let ((exc-start (mumamo-chunk-start-bw-str-inc pos min "{{")))
125       (and exc-start
126            (<= exc-start pos)
127            (cons exc-start 'jinja-mode))))
128
129   (defun mumamo-search-bw-exc-start-jinja3(pos min)
130     "Helper for `mumamo-chunk-jinja3'.
131 POS is where to start search and MIN is where to stop."
132     (let ((exc-start (mumamo-chunk-start-bw-str-inc pos min "{#")))
133       (and exc-start
134            (<= exc-start pos)
135            (cons exc-start 'jinja-mode))))
136
137   (defun mumamo-search-bw-exc-end-jinja (pos min)
138     "Helper for `mumamo-chunk-jinja'.
139 POS is where to start search and MIN is where to stop."
140     (mumamo-chunk-end-bw-str-inc pos min "%}"))
141
142   (defun mumamo-search-bw-exc-end-jinja2(pos min)
143     "Helper for `mumamo-chunk-jinja2'.
144 POS is where to start search and MIN is where to stop."
145     (mumamo-chunk-end-bw-str-inc pos min "}}"))
146
147   (defun mumamo-search-bw-exc-end-jinja3(pos min)
148     "Helper for `mumamo-chunk-jinja3'.
149 POS is where to start search and MIN is where to stop."
150     (mumamo-chunk-end-bw-str-inc pos min "#}"))
151
152   (defun mumamo-search-fw-exc-start-jinja (pos max)
153     "Helper for `mumamo-chunk-jinja'.
154 POS is where to start search and MAX is where to stop."
155     (mumamo-chunk-start-fw-str-inc pos max "{%"))
156
157   (defun mumamo-search-fw-exc-start-jinja2(pos max)
158     "Helper for `mumamo-chunk-jinja2'.
159 POS is where to start search and MAX is where to stop."
160     (mumamo-chunk-start-fw-str-inc pos max "{{"))
161
162   (defun mumamo-search-fw-exc-start-jinja3(pos max)
163     "Helper for `mumamo-chunk-jinja3'.
164 POS is where to start search and MAX is where to stop."
165     (mumamo-chunk-start-fw-str-inc pos max "{#"))
166
167   (defun mumamo-search-fw-exc-end-jinja (pos max)
168     "Helper for `mumamo-chunk-jinja'.
169 POS is where to start search and MAX is where to stop."
170     (mumamo-chunk-end-fw-str-inc pos max "%}"))
171
172   (defun mumamo-search-fw-exc-end-jinja2(pos max)
173     "Helper for `mumamo-chunk-jinja2'.
174 POS is where to start search and MAX is where to stop."
175     (mumamo-chunk-end-fw-str-inc pos max "}}"))
176
177   (defun mumamo-search-fw-exc-end-jinja3(pos max)
178     "Helper for `mumamo-chunk-jinja3'.
179 POS is where to start search and MAX is where to stop."
180     (mumamo-chunk-end-fw-str-inc pos max "#}"))
181
182 ;;;###autoload
183   (define-mumamo-multi-major-mode jinja-html-mumamo
184     "Turn on multiple major modes for Jinja with main mode `html-mode'.
185 This also covers inlined style and javascript."
186     ("Jinja HTML Family" html-mode
187      (mumamo-chunk-jinja
188       mumamo-chunk-jinja2
189       mumamo-chunk-jinja3
190       mumamo-chunk-inlined-style
191       mumamo-chunk-inlined-script
192       mumamo-chunk-style=
193       mumamo-chunk-onjs=
194       )))
195
196 ;;;###autoload
197   (define-mumamo-multi-major-mode jinja-nxhtml-mumamo
198     "Turn on multiple major modes for Jinja with main mode `nxhtml-mode'.
199 This also covers inlined style and javascript."
200     ("Jinja nXhtml Family" nxhtml-mode
201      (mumamo-chunk-jinja
202       mumamo-chunk-jinja2
203       mumamo-chunk-jinja3
204       mumamo-chunk-inlined-style
205       mumamo-chunk-inlined-script
206       mumamo-chunk-style=
207       mumamo-chunk-onjs=
208       )))
209   )
210
211 (provide 'jinja)
212 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
213 ;;; jinja.el ends here