mustache 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +30 -197
- data/Rakefile +87 -46
- data/bin/mustache +5 -29
- data/lib/mustache/context.rb +54 -11
- data/lib/mustache/template.rb +2 -14
- data/lib/mustache/version.rb +1 -1
- data/man/mustache.1 +138 -0
- data/man/mustache.1.html +168 -0
- data/man/mustache.1.ron +94 -0
- data/man/mustache.5 +364 -0
- data/man/mustache.5.html +300 -0
- data/man/mustache.5.ron +220 -0
- data/test/helper.rb +1 -0
- data/test/mustache_test.rb +19 -16
- metadata +32 -65
- data/.gitignore +0 -1
- data/.kick +0 -26
- data/CONTRIBUTORS +0 -7
- data/HISTORY.md +0 -76
- data/benchmarks/complex.erb +0 -15
- data/benchmarks/complex.haml +0 -10
- data/benchmarks/helper.rb +0 -20
- data/benchmarks/simple.erb +0 -5
- data/benchmarks/speed.rb +0 -76
- data/contrib/mustache.vim +0 -69
- data/contrib/tpl-mode.el +0 -274
- data/examples/comments.mustache +0 -1
- data/examples/comments.rb +0 -14
- data/examples/complex_view.mustache +0 -16
- data/examples/complex_view.rb +0 -34
- data/examples/delimiters.mustache +0 -6
- data/examples/delimiters.rb +0 -22
- data/examples/double_section.mustache +0 -7
- data/examples/double_section.rb +0 -14
- data/examples/escaped.mustache +0 -1
- data/examples/escaped.rb +0 -14
- data/examples/inner_partial.mustache +0 -1
- data/examples/inner_partial.txt +0 -1
- data/examples/namespaced.mustache +0 -1
- data/examples/namespaced.rb +0 -25
- data/examples/partial_with_module.mustache +0 -3
- data/examples/partial_with_module.rb +0 -37
- data/examples/passenger.conf +0 -5
- data/examples/passenger.rb +0 -27
- data/examples/simple.mustache +0 -5
- data/examples/simple.rb +0 -26
- data/examples/template_partial.mustache +0 -2
- data/examples/template_partial.rb +0 -18
- data/examples/template_partial.txt +0 -4
- data/examples/unescaped.mustache +0 -1
- data/examples/unescaped.rb +0 -14
data/HISTORY.md
DELETED
@@ -1,76 +0,0 @@
|
|
1
|
-
## 0.5.1 (2009-12-15)
|
2
|
-
|
3
|
-
* Added "mail merge" functionality to `mustache` script.
|
4
|
-
* Support for multi-line tags (useful for comments)
|
5
|
-
* Sinatra Bugfix: Use Sinatra app's view path, not Sinatra base class'.
|
6
|
-
|
7
|
-
## 0.5.0 (2009-11-23)
|
8
|
-
|
9
|
-
* Partial classes are no longer supported. Use modules!
|
10
|
-
* Added `mustache` script for rendering templates on the command line.
|
11
|
-
* ctemplate compat: Partials are indicated by >, not <
|
12
|
-
* Bugfix: Context miss should return nil, not empty string. Fixes 1.9.x
|
13
|
-
|
14
|
-
## 0.4.2 (2009-10-28)
|
15
|
-
|
16
|
-
* Bugfix: Ignore bad constant names when autoloading
|
17
|
-
|
18
|
-
## 0.4.1 (2009-10-27)
|
19
|
-
|
20
|
-
* Partials now respect the `view_namespace` setting.
|
21
|
-
* Added tpl-mode.el to contrib/ for us Emacs users.
|
22
|
-
* Rack::Bug bugfix: ensure benchmark is required before using it
|
23
|
-
* Rack::Bug: truncate too-large variables (click expands them)
|
24
|
-
|
25
|
-
## 0.4.0 (2009-10-27)
|
26
|
-
|
27
|
-
* Stopped raising context miss exceptions by default
|
28
|
-
* Added `Mustache.raise_on_context_miss` setting (defaults to false)
|
29
|
-
* Throw Mustache::ContextMiss when raise_on_context_miss is true and
|
30
|
-
we encounter a miss.
|
31
|
-
* The default template extension is now "mustache" (instead of "html").
|
32
|
-
* Added the `view_namespace` and `view_path` settings to `Mustache`
|
33
|
-
* Added `Mustache.view_class` method which autoloads a class using the
|
34
|
-
new `view_namespace` and `view_path` settings. Should be used by
|
35
|
-
plugin developers.
|
36
|
-
* Updated the Sinatra extension to use the new `view_class` method
|
37
|
-
* Unclosed sections now throw a helpful error message
|
38
|
-
* Report line numbers on unclosed section errors
|
39
|
-
* Added Rack::Bug panel
|
40
|
-
|
41
|
-
## 0.3.2 (2009-10-19)
|
42
|
-
|
43
|
-
* Bugfix: Partials in Sinatra were using the wrong path.
|
44
|
-
|
45
|
-
## 0.3.1 (2009-10-19)
|
46
|
-
|
47
|
-
* Added mustache.vim to contrib/ (Thanks Juvenn Woo!)
|
48
|
-
* Support string keys in contexts (not just symbol keys).
|
49
|
-
* Bugfix: # and / were not permitted in tag names. Now they are.
|
50
|
-
* Bugfix: Partials in Sinatra needed to know their extension and path
|
51
|
-
* Bugfix: Using the same boolean section twice was failing
|
52
|
-
|
53
|
-
## 0.3.0 (2009-10-14)
|
54
|
-
|
55
|
-
* Set Delimiter tags are now supported. See the README
|
56
|
-
* Improved error message when an enumerable section did not return all
|
57
|
-
hashes.
|
58
|
-
* Added a shortcut: if a section's value is a single hash, treat is as
|
59
|
-
a one element array whose value is the hash.
|
60
|
-
* Bugfix: String templates set at the class level were not compiled
|
61
|
-
* Added a class-level `compiled?` method for checking if a template
|
62
|
-
has been compiled.
|
63
|
-
* Added an instance-level `compiled?` method.
|
64
|
-
* Cache template compilation in Sinatra
|
65
|
-
|
66
|
-
## 0.2.2 (2009-10-11)
|
67
|
-
|
68
|
-
* Improved documentation
|
69
|
-
* Fixed single line sections
|
70
|
-
* Broke preserved indentation (issue #2)
|
71
|
-
|
72
|
-
## 0.2.1 (2009-10-11)
|
73
|
-
|
74
|
-
* Mustache.underscore can now be called without an argument
|
75
|
-
* Settings now mostly live at the class level, excepting `template`
|
76
|
-
* Any setting changes causes the template to be recompiled
|
data/benchmarks/complex.erb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
<h1><%= header %></h1>
|
2
|
-
<% if not item.empty? %>
|
3
|
-
<ul>
|
4
|
-
<% for i in item %>
|
5
|
-
<% if i[:current] %>
|
6
|
-
<li><strong><%= i[:name] %></strong></li>
|
7
|
-
<% else %>
|
8
|
-
<li><a href="<%= i[:url] %>"><%= i[:name] %></a></li>
|
9
|
-
<% end %>
|
10
|
-
<% end %>
|
11
|
-
</ul>
|
12
|
-
<% end %>
|
13
|
-
<% if item.empty? %>
|
14
|
-
<p>The list is empty.</p>
|
15
|
-
<% end %>
|
data/benchmarks/complex.haml
DELETED
data/benchmarks/helper.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'benchmark'
|
2
|
-
|
3
|
-
count = (ENV['COUNT'] || 5000).to_i
|
4
|
-
|
5
|
-
$benches = []
|
6
|
-
def bench(name, &block)
|
7
|
-
$benches.push([name, block])
|
8
|
-
end
|
9
|
-
|
10
|
-
at_exit do
|
11
|
-
Benchmark.bmbm do |x|
|
12
|
-
$benches.each do |name, block|
|
13
|
-
x.report name.to_s do
|
14
|
-
count.times do
|
15
|
-
block.call
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
data/benchmarks/simple.erb
DELETED
data/benchmarks/speed.rb
DELETED
@@ -1,76 +0,0 @@
|
|
1
|
-
require 'erb'
|
2
|
-
|
3
|
-
$LOAD_PATH.unshift File.dirname(__FILE__)
|
4
|
-
require 'helper'
|
5
|
-
|
6
|
-
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../examples'
|
7
|
-
require 'complex_view'
|
8
|
-
|
9
|
-
## erb
|
10
|
-
template = File.read(File.dirname(__FILE__) + '/complex.erb')
|
11
|
-
|
12
|
-
unless ENV['NOERB']
|
13
|
-
erb = ERB.new(template)
|
14
|
-
scope = ComplexView.new.send(:binding)
|
15
|
-
bench 'ERB w/ caching' do
|
16
|
-
erb.result(scope)
|
17
|
-
end
|
18
|
-
|
19
|
-
unless ENV['CACHED']
|
20
|
-
scope = ComplexView.new.send(:binding)
|
21
|
-
bench 'ERB w/o caching' do
|
22
|
-
ERB.new(template).result(scope)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
|
28
|
-
## haml
|
29
|
-
require 'haml'
|
30
|
-
template = File.read(File.dirname(__FILE__) + '/complex.haml')
|
31
|
-
|
32
|
-
unless ENV['NOHAML']
|
33
|
-
haml = Haml::Engine.new(template)
|
34
|
-
scope = ComplexView.new.send(:binding)
|
35
|
-
bench 'HAML w/ caching' do
|
36
|
-
haml.render(scope)
|
37
|
-
end
|
38
|
-
|
39
|
-
unless ENV['CACHED']
|
40
|
-
scope = ComplexView.new.send(:binding)
|
41
|
-
bench 'HAML w/o caching' do
|
42
|
-
Haml::Engine.new(template).render(scope)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
|
48
|
-
## mustache
|
49
|
-
tpl = ComplexView.new
|
50
|
-
tpl.template
|
51
|
-
|
52
|
-
tpl[:header] = 'Chris'
|
53
|
-
tpl[:empty] = false
|
54
|
-
tpl[:list] = true
|
55
|
-
|
56
|
-
items = []
|
57
|
-
items << { :name => 'red', :current => true, :url => '#Red' }
|
58
|
-
items << { :name => 'green', :current => false, :url => '#Green' }
|
59
|
-
items << { :name => 'blue', :current => false, :url => '#Blue' }
|
60
|
-
|
61
|
-
tpl[:item] = items
|
62
|
-
|
63
|
-
bench '{{ w/ caching' do
|
64
|
-
tpl.to_html
|
65
|
-
end
|
66
|
-
|
67
|
-
content = File.read(ComplexView.template_file)
|
68
|
-
|
69
|
-
unless ENV['CACHED']
|
70
|
-
bench '{{ w/o caching' do
|
71
|
-
ctpl = ComplexView.new
|
72
|
-
ctpl.template = content
|
73
|
-
ctpl[:item] = items
|
74
|
-
ctpl.to_html
|
75
|
-
end
|
76
|
-
end
|
data/contrib/mustache.vim
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
" Vim syntax file
|
2
|
-
" Language: Mustache
|
3
|
-
" Maintainer: Juvenn Woo <machese@gmail.com>
|
4
|
-
" Screenshot: http://imgur.com/6F408
|
5
|
-
" Version: 1
|
6
|
-
" Last Change: 2009 Oct 15
|
7
|
-
" Remark:
|
8
|
-
" It lexically hilights embedded mustaches (exclusively) in html file.
|
9
|
-
" While it was written for Ruby-based Mustache template system, it should work for Google's C-based *ctemplate* as well as Erlang-based *et*. All of them are, AFAIK, based on the idea of ctemplate.
|
10
|
-
" References:
|
11
|
-
" [Mustache](http://github.com/defunkt/mustache)
|
12
|
-
" [ctemplate](http://code.google.com/p/google-ctemplate/)
|
13
|
-
" [ctemplate doc](http://google-ctemplate.googlecode.com/svn/trunk/doc/howto.html)
|
14
|
-
" [et](http://www.ivan.fomichev.name/2008/05/erlang-template-engine-prototype.html)
|
15
|
-
" TODO: Feedback is welcomed.
|
16
|
-
|
17
|
-
|
18
|
-
" Read the HTML syntax to start with
|
19
|
-
if version < 600
|
20
|
-
so <sfile>:p:h/html.vim
|
21
|
-
else
|
22
|
-
runtime! syntax/html.vim
|
23
|
-
unlet b:current_syntax
|
24
|
-
endif
|
25
|
-
|
26
|
-
if version < 600
|
27
|
-
syntax clear
|
28
|
-
elseif exists("b:current_syntax")
|
29
|
-
finish
|
30
|
-
endif
|
31
|
-
|
32
|
-
" Standard HiLink will not work with included syntax files
|
33
|
-
if version < 508
|
34
|
-
command! -nargs=+ HtmlHiLink hi link <args>
|
35
|
-
else
|
36
|
-
command! -nargs=+ HtmlHiLink hi def link <args>
|
37
|
-
endif
|
38
|
-
|
39
|
-
syntax match mustacheError '}}}\?'
|
40
|
-
syntax match mustacheInsideError '{{[{#<>=!\/]\?' containedin=@mustacheInside
|
41
|
-
syntax region mustacheVariable matchgroup=mustacheMarker start=/{{/ end=/}}/ containedin=@htmlMustacheContainer
|
42
|
-
syntax region mustacheVariableUnescape matchgroup=mustacheMarker start=/{{{/ end=/}}}/ containedin=@htmlMustacheContainer
|
43
|
-
syntax region mustacheSection matchgroup=mustacheMarker start='{{[#/]' end=/}}/ containedin=@htmlMustacheContainer
|
44
|
-
syntax region mustachePartial matchgroup=mustacheMarker start=/{{[<>]/ end=/}}/
|
45
|
-
syntax region mustacheMarkerSet matchgroup=mustacheMarker start=/{{=/ end=/=}}/
|
46
|
-
syntax region mustacheComment start=/{{!/ end=/}}/ contains=Todo containedin=htmlHead
|
47
|
-
|
48
|
-
|
49
|
-
" Clustering
|
50
|
-
syntax cluster mustacheInside add=mustacheVariable,mustacheVariableUnescape,mustacheSection,mustachePartial,mustacheMarkerSet
|
51
|
-
syntax cluster htmlMustacheContainer add=htmlHead,htmlTitle,htmlString,htmlH1,htmlH2,htmlH3,htmlH4,htmlH5,htmlH6
|
52
|
-
|
53
|
-
|
54
|
-
" Hilighting
|
55
|
-
" mustacheInside hilighted as Number, which is rarely used in html
|
56
|
-
" you might like change it to Function or Identifier
|
57
|
-
HtmlHiLink mustacheVariable Number
|
58
|
-
HtmlHiLink mustacheVariableUnescape Number
|
59
|
-
HtmlHiLink mustachePartial Number
|
60
|
-
HtmlHiLink mustacheSection Number
|
61
|
-
HtmlHiLink mustacheMarkerSet Number
|
62
|
-
|
63
|
-
HtmlHiLink mustacheComment Comment
|
64
|
-
HtmlHiLink mustacheMarker Identifier
|
65
|
-
HtmlHiLink mustacheError Error
|
66
|
-
HtmlHiLink mustacheInsideError Error
|
67
|
-
|
68
|
-
let b:current_syntax = "mustache"
|
69
|
-
delcommand HtmlHiLink
|
data/contrib/tpl-mode.el
DELETED
@@ -1,274 +0,0 @@
|
|
1
|
-
;;; tpl-mode.el -- a major mode for editing Google CTemplate files.
|
2
|
-
;;; By Tony Gentilcore, July 2006
|
3
|
-
;;;
|
4
|
-
;;; Very minor, backwards compatible changes added for Mustache compatibility
|
5
|
-
;;; by Chris Wanstrath, October 2009
|
6
|
-
;;;
|
7
|
-
;;; TO USE:
|
8
|
-
;;; 1) Copy this file somewhere you in emacs load-path. To see what
|
9
|
-
;;; your load-path is, run inside emacs: C-h v load-path<RET>
|
10
|
-
;;; 2) Add the following two lines to your .emacs file:
|
11
|
-
;;; (setq auto-mode-alist (cons '("\\.tpl$" . tpl-mode) auto-mode-alist))
|
12
|
-
;;; (autoload 'tpl-mode "tpl-mode" "Major mode for editing CTemplate files." t)
|
13
|
-
;;; 3) Optionally (but recommended), add this third line as well:
|
14
|
-
;;; (add-hook 'tpl-mode-hook '(lambda () (font-lock-mode 1)))
|
15
|
-
;;; ---
|
16
|
-
;;;
|
17
|
-
;;; While the CTemplate language can be used for any types of text,
|
18
|
-
;;; this mode is intended for using CTemplate to write HTML.
|
19
|
-
;;;
|
20
|
-
;;; The indentation still has minor bugs due to the fact that
|
21
|
-
;;; templates do not require valid HTML.
|
22
|
-
;;;
|
23
|
-
;;; It would be nice to be able to highlight attributes of HTML tags,
|
24
|
-
;;; however this is difficult due to the presence of CTemplate symbols
|
25
|
-
;;; embedded within attributes.
|
26
|
-
|
27
|
-
(eval-when-compile
|
28
|
-
(require 'font-lock))
|
29
|
-
|
30
|
-
(defgroup tpl-mode nil
|
31
|
-
"Major mode for editing Google CTemplate and Mustache files"
|
32
|
-
:group 'languages)
|
33
|
-
|
34
|
-
(defvar tpl-mode-version "1.1"
|
35
|
-
"Version of `tpl-mode.el'.")
|
36
|
-
|
37
|
-
(defvar tpl-mode-abbrev-table nil
|
38
|
-
"Abbrev table for use in tpl-mode buffers.")
|
39
|
-
|
40
|
-
(define-abbrev-table 'tpl-mode-abbrev-table ())
|
41
|
-
|
42
|
-
(defcustom tpl-mode-hook nil
|
43
|
-
"*Hook that runs upon entering tpl-mode."
|
44
|
-
:type 'hook)
|
45
|
-
|
46
|
-
(defvar tpl-mode-map nil
|
47
|
-
"Keymap for tpl-mode major mode")
|
48
|
-
|
49
|
-
(if tpl-mode-map
|
50
|
-
nil
|
51
|
-
(setq tpl-mode-map (make-sparse-keymap)))
|
52
|
-
|
53
|
-
(define-key tpl-mode-map "\t" 'tpl-indent-command)
|
54
|
-
(define-key tpl-mode-map "\C-m" 'reindent-then-newline-and-indent)
|
55
|
-
(define-key tpl-mode-map "\C-ct" 'tpl-insert-tag)
|
56
|
-
(define-key tpl-mode-map "\C-cv" 'tpl-insert-variable)
|
57
|
-
(define-key tpl-mode-map "\C-cs" 'tpl-insert-section)
|
58
|
-
|
59
|
-
|
60
|
-
(defvar tpl-mode-syntax-table nil
|
61
|
-
"Syntax table in use in tpl-mode buffers.")
|
62
|
-
|
63
|
-
;; Syntax table.
|
64
|
-
(if tpl-mode-syntax-table
|
65
|
-
nil
|
66
|
-
(setq tpl-mode-syntax-table (make-syntax-table text-mode-syntax-table))
|
67
|
-
(modify-syntax-entry ?< "(> " tpl-mode-syntax-table)
|
68
|
-
(modify-syntax-entry ?> ")< " tpl-mode-syntax-table)
|
69
|
-
(modify-syntax-entry ?\" ". " tpl-mode-syntax-table)
|
70
|
-
(modify-syntax-entry ?\\ ". " tpl-mode-syntax-table)
|
71
|
-
(modify-syntax-entry ?' "w " tpl-mode-syntax-table))
|
72
|
-
|
73
|
-
(defvar tpl-basic-offset 2
|
74
|
-
"The basic indentation offset.")
|
75
|
-
|
76
|
-
;; Constant regular expressions to identify template elements.
|
77
|
-
(defconst tpl-mode-tpl-token "[a-zA-Z_][a-zA-Z0-9_:=\?!-]*?")
|
78
|
-
(defconst tpl-mode-section (concat "\\({{[#/]\s*"
|
79
|
-
tpl-mode-tpl-token
|
80
|
-
"\s*}}\\)"))
|
81
|
-
(defconst tpl-mode-open-section (concat "\\({{#\s*"
|
82
|
-
tpl-mode-tpl-token
|
83
|
-
"\s*}}\\)"))
|
84
|
-
(defconst tpl-mode-close-section (concat "{{/\\(\s*"
|
85
|
-
tpl-mode-tpl-token
|
86
|
-
"\s*\\)}}"))
|
87
|
-
;; TODO(tonyg) Figure out a way to support multiline comments.
|
88
|
-
(defconst tpl-mode-comment "\\({{!.*?}}\\)")
|
89
|
-
(defconst tpl-mode-include (concat "\\({{[><]\s*"
|
90
|
-
tpl-mode-tpl-token
|
91
|
-
"\s*}}\\)"))
|
92
|
-
(defconst tpl-mode-variable (concat "\\({{\s*"
|
93
|
-
tpl-mode-tpl-token
|
94
|
-
"\s*}}\\)"))
|
95
|
-
(defconst tpl-mode-builtins
|
96
|
-
(concat
|
97
|
-
"\\({{\\<\s*"
|
98
|
-
(regexp-opt
|
99
|
-
'("BI_NEWLINE" "BI_SPACE")
|
100
|
-
t)
|
101
|
-
"\s*\\>}}\\)"))
|
102
|
-
(defconst tpl-mode-close-section-at-start (concat "^[ \t]*?"
|
103
|
-
tpl-mode-close-section))
|
104
|
-
|
105
|
-
;; Constant regular expressions to identify html tags.
|
106
|
-
;; Taken from HTML 4.01 / XHTML 1.0 Reference found at:
|
107
|
-
;; http://www.w3schools.com/tags/default.asp.
|
108
|
-
(defconst tpl-mode-html-constant "\\(&#?[a-z0-9]\\{2,5\\};\\)")
|
109
|
-
(defconst tpl-mode-pair-tag
|
110
|
-
(concat
|
111
|
-
"\\<"
|
112
|
-
(regexp-opt
|
113
|
-
'("a" "abbr" "acronym" "address" "applet" "area" "b" "bdo"
|
114
|
-
"big" "blockquote" "body" "button" "caption" "center" "cite"
|
115
|
-
"code" "col" "colgroup" "dd" "del" "dfn" "dif" "div" "dl"
|
116
|
-
"dt" "em" "fieldset" "font" "form" "frame" "frameset" "h1"
|
117
|
-
"h2" "h3" "h4" "h5" "h6" "head" "html" "i" "iframe" "ins"
|
118
|
-
"kbd" "label" "legend" "li" "link" "map" "menu" "noframes"
|
119
|
-
"noscript" "object" "ol" "optgroup" "option" "p" "pre" "q"
|
120
|
-
"s" "samp" "script" "select" "small" "span" "strike"
|
121
|
-
"strong" "style" "sub" "sup" "table" "tbody" "td" "textarea"
|
122
|
-
"tfoot" "th" "thead" "title" "tr" "tt" "u" "ul" "var")
|
123
|
-
t)
|
124
|
-
"\\>"))
|
125
|
-
(defconst tpl-mode-standalone-tag
|
126
|
-
(concat
|
127
|
-
"\\<"
|
128
|
-
(regexp-opt
|
129
|
-
'("base" "br" "hr" "img" "input" "meta" "param")
|
130
|
-
t)
|
131
|
-
"\\>"))
|
132
|
-
(defconst tpl-mode-open-tag (concat "<\\("
|
133
|
-
tpl-mode-pair-tag
|
134
|
-
"\\)"))
|
135
|
-
(defconst tpl-mode-close-tag (concat "</\\("
|
136
|
-
tpl-mode-pair-tag
|
137
|
-
"\\)>"))
|
138
|
-
(defconst tpl-mode-close-tag-at-start (concat "^[ \t]*?"
|
139
|
-
tpl-mode-close-tag))
|
140
|
-
|
141
|
-
(defconst tpl-mode-blank-line "^[ \t]*?$")
|
142
|
-
(defconst tpl-mode-dangling-open (concat "\\("
|
143
|
-
tpl-mode-open-section
|
144
|
-
"\\)\\|\\("
|
145
|
-
tpl-mode-open-tag
|
146
|
-
"\\)[^/]*$"))
|
147
|
-
|
148
|
-
(defun tpl-indent-command ()
|
149
|
-
"Command for indenting text. Just calls tpl-indent."
|
150
|
-
(interactive)
|
151
|
-
(tpl-indent))
|
152
|
-
|
153
|
-
(defun tpl-insert-tag (tag)
|
154
|
-
"Inserts an HTML tag."
|
155
|
-
(interactive "sTag: ")
|
156
|
-
(tpl-indent)
|
157
|
-
(insert (concat "<" tag ">"))
|
158
|
-
(insert "\n\n")
|
159
|
-
(insert (concat "</" tag ">"))
|
160
|
-
(tpl-indent)
|
161
|
-
(forward-line -1)
|
162
|
-
(tpl-indent))
|
163
|
-
|
164
|
-
(defun tpl-insert-variable (variable)
|
165
|
-
"Inserts a tpl variable."
|
166
|
-
(interactive "sVariable: ")
|
167
|
-
(insert (concat "{{" variable "}}")))
|
168
|
-
|
169
|
-
(defun tpl-insert-section (section)
|
170
|
-
"Inserts a tpl section."
|
171
|
-
(interactive "sSection: ")
|
172
|
-
(tpl-indent)
|
173
|
-
(insert (concat "{{#" section "}}\n"))
|
174
|
-
(insert "\n")
|
175
|
-
(insert (concat "{{/" section "}}"))
|
176
|
-
(tpl-indent)
|
177
|
-
(forward-line -1)
|
178
|
-
(tpl-indent))
|
179
|
-
|
180
|
-
;; Function to control indenting.
|
181
|
-
(defun tpl-indent ()
|
182
|
-
"Indent current line"
|
183
|
-
;; Set the point to beginning of line.
|
184
|
-
(beginning-of-line)
|
185
|
-
;; If we are at the beginning of the file, indent to 0.
|
186
|
-
(if (bobp)
|
187
|
-
(indent-line-to 0)
|
188
|
-
(let ((tag-stack 1) (close-tag "") (cur-indent 0) (old-pnt (point-marker))
|
189
|
-
(close-at-start) (open-token) (dangling-open))
|
190
|
-
(progn
|
191
|
-
;; Determine if this is a template line or an html line.
|
192
|
-
(if (looking-at "^[ \t]*?{{")
|
193
|
-
(setq close-at-start tpl-mode-close-section-at-start
|
194
|
-
open-token "{{#")
|
195
|
-
(setq close-at-start tpl-mode-close-tag-at-start
|
196
|
-
open-token "<"))
|
197
|
-
;; If there is a closing tag at the start of the line, search back
|
198
|
-
;; for its opener and indent to that level.
|
199
|
-
(if (looking-at close-at-start)
|
200
|
-
(progn
|
201
|
-
(save-excursion
|
202
|
-
(setq close-tag (match-string 1))
|
203
|
-
;; Keep searching for a match for the close tag until
|
204
|
-
;; the tag-stack is 0.
|
205
|
-
(while (and (not (bobp))
|
206
|
-
(> tag-stack 0)
|
207
|
-
(re-search-backward (concat open-token
|
208
|
-
"\\(/?\\)"
|
209
|
-
close-tag) nil t))
|
210
|
-
(if (string-equal (match-string 1) "/")
|
211
|
-
;; We found another close tag, so increment tag-stack.
|
212
|
-
(setq tag-stack (+ tag-stack 1))
|
213
|
-
;; We found an open tag, so decrement tag-stack.
|
214
|
-
(setq tag-stack (- tag-stack 1)))
|
215
|
-
(setq cur-indent (current-indentation))))
|
216
|
-
(if (> tag-stack 0)
|
217
|
-
(save-excursion
|
218
|
-
(forward-line -1)
|
219
|
-
(setq cur-indent (current-indentation)))))
|
220
|
-
;; This was not a closing tag, so we check if the previous line
|
221
|
-
;; was an opening tag.
|
222
|
-
(save-excursion
|
223
|
-
;; Keep moving back until we find a line that is not blank
|
224
|
-
(while (progn
|
225
|
-
(forward-line -1)
|
226
|
-
(and (not (bobp)) (looking-at tpl-mode-blank-line))))
|
227
|
-
(setq cur-indent (current-indentation))
|
228
|
-
(if (re-search-forward tpl-mode-dangling-open old-pnt t)
|
229
|
-
(setq cur-indent (+ cur-indent tpl-basic-offset)))))
|
230
|
-
;; Finally, we execute the actual indentation.
|
231
|
-
(if (> cur-indent 0)
|
232
|
-
(indent-line-to cur-indent)
|
233
|
-
(indent-line-to 0))))))
|
234
|
-
|
235
|
-
;; controls highlighting
|
236
|
-
(defconst tpl-mode-font-lock-keywords
|
237
|
-
(list
|
238
|
-
(list tpl-mode-section
|
239
|
-
'(1 font-lock-keyword-face))
|
240
|
-
(list tpl-mode-comment
|
241
|
-
'(1 font-lock-comment-face))
|
242
|
-
(list tpl-mode-include
|
243
|
-
'(1 font-lock-function-name-face))
|
244
|
-
(list tpl-mode-builtins
|
245
|
-
'(1 font-lock-variable-name-face))
|
246
|
-
(list tpl-mode-variable
|
247
|
-
'(1 font-lock-reference-face))
|
248
|
-
(list (concat "</?\\(" tpl-mode-pair-tag "\\)")
|
249
|
-
'(1 font-lock-function-name-face))
|
250
|
-
(list (concat "<\\(" tpl-mode-standalone-tag "\\)")
|
251
|
-
'(1 font-lock-function-name-face))
|
252
|
-
(list tpl-mode-html-constant
|
253
|
-
'(1 font-lock-variable-name-face))))
|
254
|
-
|
255
|
-
(put 'tpl-mode 'font-lock-defaults '(tpl-font-lock-keywords nil t))
|
256
|
-
|
257
|
-
(defun tpl-mode ()
|
258
|
-
"Major mode for editing Google CTemplate file."
|
259
|
-
(interactive)
|
260
|
-
(kill-all-local-variables)
|
261
|
-
(use-local-map tpl-mode-map)
|
262
|
-
(setq major-mode 'tpl-mode)
|
263
|
-
(setq mode-name "tpl-mode")
|
264
|
-
(setq local-abbrev-table tpl-mode-abbrev-table)
|
265
|
-
(setq indent-tabs-mode nil)
|
266
|
-
(set-syntax-table tpl-mode-syntax-table)
|
267
|
-
;; show trailing whitespace, but only when the user can fix it
|
268
|
-
(setq show-trailing-whitespace (not buffer-read-only))
|
269
|
-
(make-local-variable 'indent-line-function)
|
270
|
-
(setq indent-line-function 'tpl-indent)
|
271
|
-
(setq font-lock-defaults '(tpl-mode-font-lock-keywords))
|
272
|
-
(run-hooks 'tpl-mode-hook))
|
273
|
-
|
274
|
-
(provide 'tpl-mode)
|