mustache 1.0.5 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: bf94eeecd19f735037d7bbb26dec6b31fd744220
4
- data.tar.gz: 1950b718fced739f53562898d3577a10ca88cdbf
2
+ SHA256:
3
+ metadata.gz: bfcec948b9e5fbd73d9c72e3ade21724d3fd73a1d2ee2ea58ab26bf7e1a341ba
4
+ data.tar.gz: 1a5d4d062ad29d4a4057a6489f6779d3e61bb7132ecf56fc1ab97a48bfcb926d
5
5
  SHA512:
6
- metadata.gz: 2aa2853641590267b49b7264f8592fed44f3fa430ea10e60ae3ce8b58a5fadea3b532f256b70229a0fbd62835176ead87b8dff0d66ac73750af603c9739e6587
7
- data.tar.gz: 31a31d089046ab7d11b6541a02b588d92c26a6b5879185203ddc4ffedd64a41cc6b0651b818066333ee9af4000754a8f1d3885b5647895390ebe3e62d65532ae
6
+ metadata.gz: afd9888e324611b31fb9a6ac809393b2c42261befce363ab691d68719edb2687dda2129ba64a12367bd0f39d31b1fda861b209345f2abfc06debf67aa0e3ab99
7
+ data.tar.gz: c225773518109b0eeeecaf89d39faaec30b951361b10c16944f4e016aec6597fc41e75237920dc8c44e00956a00edfcf1b72f2e914ea4dc3f8b296f2436977dc
data/Rakefile CHANGED
@@ -35,7 +35,7 @@ if command? :ronn
35
35
 
36
36
  desc "Build the manual"
37
37
  task "man:build" do
38
- sh "ronn -br5 --organization=DEFUNKT --manual='Mustache Manual' man/*.ron"
38
+ sh "ronn -br5 --organization=DEFUNKT --manual='Mustache Manual' man/*.ronn"
39
39
  end
40
40
  end
41
41
 
@@ -51,12 +51,12 @@ class Mustache
51
51
 
52
52
  # Allows customization of how Mustache escapes things.
53
53
  #
54
- # @param [String] str String to escape.
54
+ # @param [Object] value Value to escape.
55
55
  #
56
- # @return [String] Escaped HTML string.
56
+ # @return [String] Escaped string.
57
57
  #
58
- def escapeHTML(str)
59
- mustache_in_stack.escapeHTML(str)
58
+ def escape(value)
59
+ mustache_in_stack.escape(value)
60
60
  end
61
61
 
62
62
  # Adds a new object to the context's internal stack.
@@ -133,7 +133,7 @@ class Mustache
133
133
  when Proc
134
134
  #{proc_handling}
135
135
  when Array, Enumerator, Mustache::Enumerable
136
- v.map { |h| ctx.push(h); r = #{code}; ctx.pop; r }.join
136
+ v.map { |_| ctx.push(_); r = #{code}; ctx.pop; r }.join
137
137
  else
138
138
  ctx.push(v); r = #{code}; ctx.pop; r
139
139
  end
@@ -182,7 +182,7 @@ class Mustache
182
182
  if v.is_a?(Proc)
183
183
  v = #{@option_static_lambdas ? 'v.call' : 'Mustache::Template.new(v.call.to_s).render(ctx.dup)'}
184
184
  end
185
- ctx.escapeHTML(v.to_s)
185
+ ctx.escape(v)
186
186
  compiled
187
187
  end
188
188
 
@@ -323,12 +323,14 @@ EOF
323
323
 
324
324
  def scan_tag_close content, fetch, padding, pre_match_position
325
325
  section, pos, result = @sections.pop
326
+ if section.nil?
327
+ error "Closing unopened #{content.inspect}"
328
+ end
329
+
326
330
  raw = @scanner.pre_match[pos[3]...pre_match_position] + padding
327
331
  (@result = result).last << raw << [self.otag, self.ctag]
328
332
 
329
- if section.nil?
330
- error "Closing unopened #{content.inspect}"
331
- elsif section != content
333
+ if section != content
332
334
  error "Unclosed section #{section.inspect}", pos
333
335
  end
334
336
  end
@@ -2,6 +2,30 @@
2
2
  # view class, or a single Mustache instance.
3
3
  class Mustache
4
4
 
5
+ def initialize_settings
6
+ @template = nil
7
+ @template_path = nil
8
+ @template_extension = nil
9
+ @template_name = nil
10
+ @template_file = nil
11
+ @raise_on_context_miss = nil
12
+ end
13
+
14
+ def self.initialize_settings
15
+ @template = nil
16
+ @template_path = nil
17
+ @template_extension = nil
18
+ @template_name = nil
19
+ @template_file = nil
20
+ @raise_on_context_miss = nil
21
+ end
22
+
23
+ initialize_settings
24
+
25
+ def self.inherited(subclass)
26
+ subclass.initialize_settings
27
+ end
28
+
5
29
  #
6
30
  # Template Path
7
31
  #
@@ -1,3 +1,3 @@
1
1
  class Mustache
2
- VERSION = '1.0.5'
2
+ VERSION = '1.1.1'
3
3
  end
data/lib/mustache.rb CHANGED
@@ -74,10 +74,19 @@ require 'mustache/utils'
74
74
  #
75
75
  class Mustache
76
76
 
77
- # Initialize a new mustache instance.
77
+ # Initialize a new Mustache instance.
78
+ #
78
79
  # @param [Hash] options An options hash
80
+ # @option options [String] template_path
81
+ # @option options [String] template_extension
82
+ # @option options [String] template_file
83
+ # @option options [String] template
84
+ # @option options [String] view_namespace
85
+ # @option options [String] view_path
79
86
  def initialize(options = {})
80
87
  @options = options
88
+
89
+ initialize_settings
81
90
  end
82
91
 
83
92
  # Instantiates an instance of this class and calls `render` with
@@ -91,19 +100,18 @@ class Mustache
91
100
  # Parses our fancy pants template file and returns normal file with
92
101
  # all special {{tags}} and {{#sections}}replaced{{/sections}}.
93
102
  #
94
- # Examples
95
- #
96
- # @view.render("Hi {{thing}}!", :thing => :world)
103
+ # @example Render view
104
+ # @view.render("Hi {{thing}}!", :thing => :world)
97
105
  #
98
- # View.template = "Hi {{thing}}!"
99
- # @view = View.new
100
- # @view.render(:thing => :world)
106
+ # @example Set view template and then render
107
+ # View.template = "Hi {{thing}}!"
108
+ # @view = View.new
109
+ # @view.render(:thing => :world)
101
110
  #
102
111
  # @param [String,Hash] data A String template or a Hash context.
103
112
  # If a Hash is given, we'll try to figure
104
113
  # out the template from the class.
105
114
  # @param [Hash] ctx A Hash context if `data` is a String template.
106
- #
107
115
  # @return [String] Returns a rendered version of a template.
108
116
  def render(data = template, ctx = {})
109
117
  case data
@@ -134,11 +142,11 @@ class Mustache
134
142
 
135
143
  # Context accessors.
136
144
  #
137
- # Example:
138
- # view = Mustache.new
139
- # view[:name] = "Jon"
140
- # view.template = "Hi, {{name}}!"
141
- # view.render # => "Hi, Jon!"
145
+ # @example Context accessors
146
+ # view = Mustache.new
147
+ # view[:name] = "Jon"
148
+ # view.template = "Hi, {{name}}!"
149
+ # view.render # => "Hi, Jon!"
142
150
  def [](key)
143
151
  context[key.to_sym]
144
152
  end
@@ -190,17 +198,36 @@ class Mustache
190
198
  end
191
199
 
192
200
  # Override this to provide custom escaping.
201
+ # By default it uses `CGI.escapeHTML`.
202
+ #
203
+ # @example Overriding #escape
204
+ # class PersonView < Mustache
205
+ # def escape(value)
206
+ # my_html_escape_method(value.to_s)
207
+ # end
208
+ # end
193
209
  #
194
- # Example:
210
+ # @param [Object] value Value to escape.
211
+ # @return [String] Escaped content.
212
+ def escape(value)
213
+ self.escapeHTML(value.to_s)
214
+ end
215
+
216
+ # Override this to provide custom escaping.
195
217
  #
218
+ # @example Overriding #escapeHTML
196
219
  # class PersonView < Mustache
197
220
  # def escapeHTML(str)
198
221
  # my_html_escape_method(str)
199
222
  # end
200
223
  # end
201
224
  #
202
- # @param [String] str String to escape.
225
+ # @deprecated Use {#escape} instead.
203
226
  #
227
+ # Note that {#escape} can receive any kind of object.
228
+ # If your override logic is expecting a string, you will
229
+ # have to call to_s on it yourself.
230
+ # @param [String] str String to escape.
204
231
  # @return [String] Escaped HTML.
205
232
  def escapeHTML(str)
206
233
  CGI.escapeHTML(str)
@@ -217,7 +244,8 @@ class Mustache
217
244
 
218
245
  # When given a symbol or string representing a class, will try to produce an
219
246
  # appropriate view class.
220
- # e.g.
247
+ #
248
+ # @example
221
249
  # Mustache.view_namespace = Hurl::Views
222
250
  # Mustache.view_class(:Partial) # => Hurl::Views::Partial
223
251
  def self.view_class(name)
@@ -244,7 +272,7 @@ class Mustache
244
272
  file_name = underscore(name)
245
273
  file_path = "#{view_path}/#{file_name}.rb"
246
274
 
247
- return Mustache unless File.exists?(file_path)
275
+ return Mustache unless File.exist?(file_path)
248
276
 
249
277
  require file_path.chomp('.rb')
250
278
  rescued_const_get(name)
@@ -263,7 +291,7 @@ class Mustache
263
291
  Mustache::Utils::String.new(underscored).classify
264
292
  end
265
293
 
266
- # TemplatePartial => template_partial
294
+ # TemplatePartial => template_partial
267
295
  # Template::Partial => template/partial
268
296
  # Takes a string but defaults to using the current class' name.
269
297
  def self.underscore(classified = name)
data/man/mustache.1.html CHANGED
@@ -102,7 +102,7 @@ names: [ {name: chris}, {name: mark}, {name: scott} ]
102
102
  should work fine.</p>
103
103
 
104
104
  <p>After the frontmatter should come any valid Mustache template. See
105
- <a class="man-ref" href="mustache.5.ron.html">mustache<span class="s">(5)</span></a> for an overview of Mustache templates.</p>
105
+ <a class="man-ref" href="mustache.5.ronn.html">mustache<span class="s">(5)</span></a> for an overview of Mustache templates.</p>
106
106
 
107
107
  <p>For example:</p>
108
108
 
@@ -198,7 +198,7 @@ data
198
198
 
199
199
  <h2 id="SEE-ALSO">SEE ALSO</h2>
200
200
 
201
- <p><a class="man-ref" href="mustache.5.ron.html">mustache<span class="s">(5)</span></a>, <span class="man-ref">gem<span class="s">(1)</span></span>,
201
+ <p><a class="man-ref" href="mustache.5.ronn.html">mustache<span class="s">(5)</span></a>, <span class="man-ref">gem<span class="s">(1)</span></span>,
202
202
  <a href="http://mustache.github.io/" data-bare-link="true">http://mustache.github.io/</a></p>
203
203
 
204
204
 
data/man/mustache.5.html CHANGED
@@ -409,7 +409,7 @@ markup."</p>
409
409
 
410
410
  <h2 id="SEE-ALSO">SEE ALSO</h2>
411
411
 
412
- <p><a class="man-ref" href="mustache.1.ron.html">mustache<span class="s">(1)</span></a>,
412
+ <p><a class="man-ref" href="mustache.1.ronn.html">mustache<span class="s">(1)</span></a>,
413
413
  <a href="http://mustache.github.io/" data-bare-link="true">http://mustache.github.io/</a></p>
414
414
 
415
415
 
data/man/mustache.5.ron CHANGED
@@ -310,7 +310,7 @@ markup."
310
310
 
311
311
  Custom delimiters may not contain whitespace or the equals sign.
312
312
 
313
- [ct]: http://google-ctemplate.googlecode.com/svn/trunk/doc/howto.html
313
+ [ct]: http://goog-ctemplate.sourceforge.net/doc/howto.html
314
314
 
315
315
 
316
316
  ## COPYRIGHT
@@ -1,5 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  require_relative 'helper'
3
+ require 'json'
3
4
 
4
5
  class MustacheTest < Minitest::Test
5
6
  def test_instance_render
@@ -659,7 +660,7 @@ template
659
660
  assert_equal('[ 0 1 2 3 4 5 6 7 8 9 10 ]', MethodMissing.render)
660
661
  end
661
662
 
662
- def test_custom_escaping
663
+ def test_custom_html_escaping
663
664
  view = Class.new(Mustache) do
664
665
  def escapeHTML(str)
665
666
  "pong"
@@ -670,6 +671,17 @@ template
670
671
  assert_equal 'nothing', Mustache.render("{{thing}}", :thing => "nothing")
671
672
  end
672
673
 
674
+ def test_custom_escaping
675
+ view = Class.new(Mustache) do
676
+ def escape(str)
677
+ JSON.dump(str)
678
+ end
679
+ end
680
+
681
+ assert_equal '{ "key": "a\"b" }', view.render('{ "key": {{thing}} }', :thing => 'a"b')
682
+ assert_equal 'nothing', Mustache.render("{{thing}}", :thing => "nothing")
683
+ end
684
+
673
685
  def test_implicit_iterator
674
686
  view = Mustache.new
675
687
  view.template = "{{#people}}* {{.}}\n{{/people}}"
@@ -820,6 +832,7 @@ template
820
832
  def test_instance_with_initialize_render
821
833
  klass = Class.new(Mustache) do
822
834
  def initialize(name)
835
+ super
823
836
  @name = name
824
837
  end
825
838
  attr_reader :name
data/test/parser_test.rb CHANGED
@@ -94,4 +94,68 @@ EOF
94
94
 
95
95
  assert_equal expected, tokens
96
96
  end
97
+
98
+ def test_unclosed_section
99
+ lexer = Mustache::Parser.new
100
+ exception = assert_raises Mustache::Parser::SyntaxError do
101
+ lexer.compile("{{#list}}")
102
+ end
103
+
104
+ expected = <<-EOF
105
+ Unclosed section "list"
106
+ Line 1
107
+ {{#list}}
108
+ ^
109
+ EOF
110
+
111
+ assert_equal expected, exception.message
112
+ end
113
+
114
+ def test_closing_unopened
115
+ lexer = Mustache::Parser.new
116
+ exception = assert_raises Mustache::Parser::SyntaxError do
117
+ lexer.compile("{{/list}}")
118
+ end
119
+
120
+ expected = <<-EOF
121
+ Closing unopened "list"
122
+ Line 1
123
+ {{/list}}
124
+ ^
125
+ EOF
126
+
127
+ assert_equal expected, exception.message
128
+ end
129
+
130
+ def test_unclosed_tag
131
+ lexer = Mustache::Parser.new
132
+ exception = assert_raises Mustache::Parser::SyntaxError do
133
+ lexer.compile("{{list")
134
+ end
135
+
136
+ expected = <<-EOF
137
+ Unclosed tag
138
+ Line 1
139
+ {{list
140
+ ^
141
+ EOF
142
+
143
+ assert_equal expected, exception.message
144
+ end
145
+
146
+ def test_illegal_content
147
+ lexer = Mustache::Parser.new
148
+ exception = assert_raises Mustache::Parser::SyntaxError do
149
+ lexer.compile("{{")
150
+ end
151
+
152
+ expected = <<-EOF
153
+ Illegal content in tag
154
+ Line 1
155
+ {{
156
+ ^
157
+ EOF
158
+
159
+ assert_equal expected, exception.message
160
+ end
97
161
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mustache
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Wanstrath
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2017-03-26 00:00:00.000000000 Z
14
+ date: 2019-12-03 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -219,8 +219,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
219
219
  - !ruby/object:Gem::Version
220
220
  version: '0'
221
221
  requirements: []
222
- rubyforge_project:
223
- rubygems_version: 2.6.8
222
+ rubygems_version: 3.0.3
224
223
  signing_key:
225
224
  specification_version: 4
226
225
  summary: Mustache is a framework-agnostic way to render logic-free views.