flavour_saver 0.3.7 → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c3efa30121a2e226ebb1274cf5597d35ab7f9c47
4
- data.tar.gz: c89bc7f065e3dfbb07882c44465711981643d454
2
+ SHA256:
3
+ metadata.gz: 2874ca7f6ce28bbd9ed5f1ba887a0bc7244bdd448be995c2447078439e32bb82
4
+ data.tar.gz: cdae84ceb24202a2f03db262a973f254dc750a3de30efae7138e01a3ef6187cb
5
5
  SHA512:
6
- metadata.gz: 1292541b248293451704808a7458b2132ab7109f9664845c77d01c375581396192af2ee2a19c6cfae4fa567294757cb5b563803e23ccfd8110961f204adbdd03
7
- data.tar.gz: a74f63a36b4864fbc248fde7ff9e03c19ffc49412f37b472521cf2ed13bf7403e24243e423211c1599c924a92a8e9f9b1472ba15c07b12a12955de70f131da7c
6
+ metadata.gz: 404531d6a27b3c6e8739d98dc7ab9b5af81e8b29cc9260869784882704b58b4cd7ab2e2f3e741768cbe5386c326c66e1fc1be66d3ab1f6702a2902b9ee811017
7
+ data.tar.gz: b5ae4b6c36462dfc80a29e6eb25cca006330462aa44b1d38dd234e353a072ee906ac41943201ab5cce233b3812f14da697be6b29a189b4bf7b8820a98afecc7e
@@ -0,0 +1,26 @@
1
+ name: Continuous integration
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ test:
11
+
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ matrix:
15
+ ruby-version: ['2.6', '2.7', '3.0', '3.1']
16
+
17
+ steps:
18
+ - uses: actions/checkout@v2
19
+ - name: Set up Ruby
20
+ uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{ matrix.ruby-version }}
23
+ bundler-cache: true
24
+ - name: Run tests
25
+ run: bundle exec rspec
26
+
data/CHANGELOG.md ADDED
@@ -0,0 +1,23 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [1.0.0] - 2022-01-19
11
+
12
+ ### Added
13
+
14
+ * Ruby 3.0 and 3.1 support
15
+
16
+ ### Changed
17
+
18
+ * The gem is now maintained by the FlavourSaver organization
19
+
20
+ ### Removed
21
+
22
+ * Dropped support for Ruby 1.9, 2.0, 2.1, 2.2, 2.3, and 2.4
23
+
data/Gemfile.lock CHANGED
@@ -1,82 +1,54 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- flavour_saver (0.3.7)
4
+ flavour_saver (1.0.0)
5
5
  rltk (~> 2.2.0)
6
6
  tilt
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activesupport (4.0.13)
12
- i18n (~> 0.6, >= 0.6.9)
13
- minitest (~> 4.2)
14
- multi_json (~> 1.3)
15
- thread_safe (~> 0.1)
16
- tzinfo (~> 0.3.37)
17
- coderay (1.0.9)
18
- diff-lcs (1.2.4)
19
- ffi (1.9.0)
20
- formatador (0.2.4)
21
- guard (1.8.3)
22
- formatador (>= 0.2.4)
23
- listen (~> 1.3)
24
- lumberjack (>= 1.0.2)
25
- pry (>= 0.9.10)
26
- thor (>= 0.14.6)
27
- guard-bundler (1.0.0)
28
- bundler (~> 1.0)
29
- guard (~> 1.1)
30
- guard-rspec (3.1.0)
31
- guard (>= 1.8)
32
- rspec (~> 2.13)
33
- i18n (0.7.0)
34
- listen (1.3.1)
35
- rb-fsevent (>= 0.9.3)
36
- rb-inotify (>= 0.9)
37
- rb-kqueue (>= 0.2)
38
- lumberjack (1.0.4)
39
- method_source (0.8.2)
40
- minitest (4.7.5)
41
- multi_json (1.10.1)
42
- pry (0.9.12.2)
43
- coderay (~> 1.0.5)
44
- method_source (~> 0.8)
45
- slop (~> 3.4)
46
- rake (10.1.0)
47
- rb-fsevent (0.9.3)
48
- rb-inotify (0.9.2)
49
- ffi (>= 0.5.0)
50
- rb-kqueue (0.2.0)
51
- ffi (>= 0.5.0)
11
+ activesupport (6.1.4.4)
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ i18n (>= 1.6, < 2)
14
+ minitest (>= 5.1)
15
+ tzinfo (~> 2.0)
16
+ zeitwerk (~> 2.3)
17
+ concurrent-ruby (1.1.9)
18
+ diff-lcs (1.5.0)
19
+ ffi (1.15.5)
20
+ i18n (1.8.11)
21
+ concurrent-ruby (~> 1.0)
22
+ minitest (5.15.0)
23
+ rake (13.0.6)
52
24
  rltk (2.2.1)
53
25
  ffi (>= 1.0.0)
54
- rspec (2.14.1)
55
- rspec-core (~> 2.14.0)
56
- rspec-expectations (~> 2.14.0)
57
- rspec-mocks (~> 2.14.0)
58
- rspec-core (2.14.5)
59
- rspec-expectations (2.14.3)
60
- diff-lcs (>= 1.1.3, < 2.0)
61
- rspec-mocks (2.14.3)
62
- slop (3.4.6)
63
- thor (0.18.1)
64
- thread_safe (0.3.4)
65
- tilt (2.0.1)
66
- tzinfo (0.3.42)
26
+ rspec (3.10.0)
27
+ rspec-core (~> 3.10.0)
28
+ rspec-expectations (~> 3.10.0)
29
+ rspec-mocks (~> 3.10.0)
30
+ rspec-core (3.10.1)
31
+ rspec-support (~> 3.10.0)
32
+ rspec-expectations (3.10.2)
33
+ diff-lcs (>= 1.2.0, < 2.0)
34
+ rspec-support (~> 3.10.0)
35
+ rspec-mocks (3.10.2)
36
+ diff-lcs (>= 1.2.0, < 2.0)
37
+ rspec-support (~> 3.10.0)
38
+ rspec-support (3.10.3)
39
+ tilt (2.0.10)
40
+ tzinfo (2.0.4)
41
+ concurrent-ruby (~> 1.0)
42
+ zeitwerk (2.5.3)
67
43
 
68
44
  PLATFORMS
69
45
  ruby
70
46
 
71
47
  DEPENDENCIES
72
- activesupport (~> 4.0.2)
48
+ activesupport (< 7.0)
73
49
  flavour_saver!
74
- guard-bundler
75
- guard-rspec
76
50
  rake
77
- rspec-core
78
- rspec-expectations
79
- rspec-mocks
51
+ rspec
80
52
 
81
53
  BUNDLED WITH
82
- 1.10.6
54
+ 2.2.17
data/README.md CHANGED
@@ -2,25 +2,18 @@
2
2
 
3
3
  [Handlebars.js](http://handlebarsjs.com) without the `.js`
4
4
 
5
- [![Build Status](https://travis-ci.org/jamesotron/FlavourSaver.png)](https://travis-ci.org/jamesotron/FlavourSaver)
6
- [![Dependency Status](https://gemnasium.com/jamesotron/FlavourSaver.png)](https://gemnasium.com/jamesotron/FlavourSaver)
7
- [![Code Climate](https://codeclimate.com/github/jamesotron/FlavourSaver.png)](https://codeclimate.com/github/jamesotron/FlavourSaver)
5
+ [![Gem Version](https://badge.fury.io/rb/flavour_saver.svg)](https://badge.fury.io/rb/flavour_saver)
6
+ ![Build Status](https://github.com/FlavourSaver/FlavourSaver/actions/workflows/ci.yml/badge.svg)
7
+ [![Maintainability](https://api.codeclimate.com/v1/badges/89a99bec5bbf49359081/maintainability)](https://codeclimate.com/github/FlavourSaver/FlavourSaver/maintainability)
8
8
 
9
9
  ## WAT?
10
10
 
11
- FlavourSaver is a ruby-based implementation of the [Handlebars.js](http://handlebars.js)
11
+ FlavourSaver is a ruby-based implementation of the [Handlebars.js](http://handlebarsjs.com)
12
12
  templating language. FlavourSaver supports Handlebars template rendering natively on
13
13
  Rails and on other frameworks (such as Sinatra) via Tilt.
14
14
 
15
15
  Please use it, break it, and send issues/PR's for improvement.
16
16
 
17
- ## Caveat
18
-
19
- FlavourSaver is used in production by a lot of folks, none of whom are me. As
20
- I don't use FlavourSaver in my daily life I will not be responding to issues
21
- unless they have a corresponding PR. If you'd like to take over maintaining
22
- this project then get in contact.
23
-
24
17
  ## License
25
18
 
26
19
  FlavourSaver is Copyright (c) 2013 Resistor Limited and licensed under the terms
@@ -74,6 +67,7 @@ Currently supported:
74
67
  - Inverse blocks
75
68
  - Partials
76
69
  - Raw content (`{{{{raw}}}} not parsed or validated {{{{/raw}}}}`)
70
+ - Subexpressions (`{{sum 1 (sum 1 1)}}` returns `3`)
77
71
 
78
72
  ## Helpers
79
73
 
@@ -248,6 +242,35 @@ Which could be used like so:
248
242
  {{/isFemale}}
249
243
  ```
250
244
 
245
+ ### Subexpressions
246
+
247
+ You can use a subexpression as any value for a helper, and it will be executed before it is ran. You can also nest them, and use them in assignment of variables.
248
+
249
+ Below are some examples, utilizing a "sum" helper than adds together two numbers.
250
+
251
+ ```
252
+ {{sum (sum 5 10) (sum 2 (sum 1 4))}}
253
+ #=> 22
254
+
255
+ {{#if (sum 1 2) > 2}}its more{{/if}}
256
+ #=> its more
257
+
258
+ {{#student_heights size=(sum boys girls)}}
259
+ ```
260
+
261
+ ### Raw Content
262
+
263
+ Sometimes you don't want a section of content to be evaluted as handlebars, such as when you want to display it in a page that renders with handlebars. FlavourSaver offers a `raw` helper, that will allow you to pass anything through wrapped in those elements, and it will not be evaluated.
264
+
265
+ ```
266
+ {{{{raw}}}}
267
+ {{if} this tries to parse, it will break on syntax
268
+ {{{{/raw}}}}
269
+ => {{if} this tries to parse, it will break on syntax
270
+ ```
271
+
272
+ Its important to note that while this looks like a block helper, it is not in practice. This is why you must omit the use of a `#` when writing it.
273
+
251
274
  ### Using Partials
252
275
 
253
276
  Handlebars allows you to register a partial either as a function or a string template with
@@ -2,11 +2,18 @@
2
2
  require File.expand_path('../lib/flavour_saver/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
- gem.authors = ["James Harton"]
6
- gem.email = ["james@resistor.io"]
5
+ gem.authors = ["Clayton Passmore", "James Harton"]
6
+ gem.email = ["ctpassmore+flavoursaver@gmail.com"]
7
7
  gem.description = %q{FlavourSaver is a pure-ruby implimentation of the Handlebars templating language}
8
8
  gem.summary = %q{Handlebars.js without the .js}
9
- gem.homepage = "http://jamesotron.github.com/FlavourSaver/"
9
+ gem.homepage = "http://github.com/FlavourSaver/FlavourSaver"
10
+ gem.license = "MIT"
11
+ gem.metadata = {
12
+ "bug_tracker_uri" => "http://github.com/FlavourSaver/FlavourSaver/issues",
13
+ "changelog_uri" => "http://github.com/FlavourSaver/FlavourSaver/blob/master/CHANGELOG.md",
14
+ "homepage_uri" => "http://github.com/FlavourSaver/FlavourSaver",
15
+ "source_code_uri" => "http://github.com/FlavourSaver/FlavourSaver",
16
+ }
10
17
 
11
18
  gem.files = `git ls-files`.split($\)
12
19
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -15,13 +22,11 @@ Gem::Specification.new do |gem|
15
22
  gem.require_paths = ["lib"]
16
23
  gem.version = FlavourSaver::VERSION
17
24
 
25
+ gem.required_ruby_version = ">= 2.6.0"
26
+
18
27
  gem.add_development_dependency 'rake'
19
- gem.add_development_dependency 'guard-rspec'
20
- gem.add_development_dependency 'rspec-core'
21
- gem.add_development_dependency 'rspec-mocks'
22
- gem.add_development_dependency 'rspec-expectations'
23
- gem.add_development_dependency 'guard-bundler'
24
- gem.add_development_dependency 'activesupport', '~> 4.0.2'
28
+ gem.add_development_dependency 'rspec'
29
+ gem.add_development_dependency 'activesupport', '< 7.0'
25
30
 
26
31
  gem.add_dependency 'rltk', '~> 2.2.0'
27
32
  gem.add_dependency 'tilt'
@@ -11,7 +11,10 @@ module FlavourSaver
11
11
  r = []
12
12
  count = 0
13
13
  collection.each do |element|
14
- r << yield.contents(element, 'index' => count)
14
+ r << yield.contents(element,
15
+ 'index' => count,
16
+ 'last' => count == collection.size - 1,
17
+ 'first' => count == 0)
15
18
  count += 1
16
19
  end
17
20
  yield.rendered!
@@ -59,7 +62,7 @@ module FlavourSaver
59
62
 
60
63
  def [](accessor)
61
64
  if array?
62
- if accessor.match /[0-9]+/
65
+ if accessor.match?(/[0-9]+/)
63
66
  return @source.at(accessor.to_i)
64
67
  end
65
68
  end
@@ -85,7 +88,7 @@ module FlavourSaver
85
88
  end
86
89
 
87
90
  def register_helper(method,&b)
88
- if method.respond_to? :name
91
+ if !method.is_a?(Symbol) && method.respond_to?(:name)
89
92
  registered_helpers[method.name.to_sym] = method
90
93
  elsif b
91
94
  registered_helpers[method.to_sym] = b
@@ -112,7 +115,5 @@ module FlavourSaver
112
115
  helpers = helpers.merge(locals)
113
116
  Decorator.new(helpers, context)
114
117
  end
115
-
116
118
  end
117
119
  end
118
-
@@ -78,7 +78,7 @@ module FlavourSaver
78
78
  :ELSE
79
79
  end
80
80
 
81
- rule /([A-Za-z]\w*)/, :expression do |name|
81
+ rule /([A-Za-z_]\w*)/, :expression do |name|
82
82
  [ :IDENT, name ]
83
83
  end
84
84
 
@@ -86,6 +86,14 @@ module FlavourSaver
86
86
  :DOT
87
87
  end
88
88
 
89
+ rule /\(/, :expression do
90
+ :OPAR
91
+ end
92
+
93
+ rule /\)/, :expression do
94
+ :CPAR
95
+ end
96
+
89
97
  rule /\=/, :expression do
90
98
  :EQ
91
99
  end
@@ -114,10 +122,15 @@ module FlavourSaver
114
122
  pop_state
115
123
  end
116
124
 
117
- # Handlebars allows methods with hyphens in them. Ruby doesn't, so
118
- # we'll assume you're trying to index the context with the identifier
119
- # and call the result.
120
- rule /([A-Za-z][a-z0-9_-]*[a-z0-9])/, :expression do |str|
125
+ # Handlebars allows identifiers with characters in them which Ruby does not.
126
+ # These are mapped to the literal notation and accessed in this way.
127
+ #
128
+ # As per the http://handlebarsjs.com/expressions.html:
129
+ #
130
+ # Identifiers may be any unicode character except for the following:
131
+ # Whitespace ! " # % & ' ( ) * + , . / ; < = > @ [ \ ] ^ ` { | } ~
132
+ #
133
+ rule /([^\s!-#%-,.\/;->@\[-^`{-~]+)/, :expression do |str|
121
134
  [ :LITERAL, str ]
122
135
  end
123
136
 
@@ -95,7 +95,7 @@ module FlavourSaver
95
95
  end
96
96
 
97
97
  class ParentCallNode < CallNode
98
- value :depth, Fixnum
98
+ value :depth, Integer
99
99
 
100
100
  def to_callnode
101
101
  CallNode.new(name,arguments)
@@ -86,6 +86,10 @@ module FlavourSaver
86
86
  clause('EXPRST expression_contents EXPRE') { |_,e,_| e }
87
87
  end
88
88
 
89
+ production(:subexpr) do
90
+ clause('OPAR expression_contents CPAR') { |_,e,_| e }
91
+ end
92
+
89
93
  production(:expr_comment) do
90
94
  clause('EXPRST BANG COMMENT EXPRE') { |_,_,e,_| e }
91
95
  end
@@ -129,8 +133,8 @@ module FlavourSaver
129
133
  clause('argument_list WHITE hash') { |e0,_,e1| e0 + [e1] }
130
134
  clause('hash') { |e| [e] }
131
135
  end
132
-
133
- nonempty_list(:argument_list, [:object_path,:lit], :WHITE)
136
+
137
+ nonempty_list(:argument_list, [:object_path,:lit, :local, :subexpr], :WHITE)
134
138
 
135
139
  production(:lit) do
136
140
  clause('string') { |e| e }
@@ -157,6 +161,7 @@ module FlavourSaver
157
161
  end
158
162
 
159
163
  production(:hash_item) do
164
+ clause('IDENT EQ subexpr') { |e0,_,e1| { e0.to_sym => e1 } }
160
165
  clause('IDENT EQ string') { |e0,_,e1| { e0.to_sym => e1 } }
161
166
  clause('IDENT EQ number') { |e0,_,e1| { e0.to_sym => e1 } }
162
167
  clause('IDENT EQ object_path') { |e0,_,e1| { e0.to_sym => e1 } }
@@ -34,7 +34,7 @@ module FlavourSaver
34
34
  @privates = old_privates
35
35
  @context = old_context
36
36
  else
37
- result = evaluate_node(@ast)
37
+ result = evaluate_node(@ast).to_s.force_encoding(Encoding::default_external)
38
38
  end
39
39
  result
40
40
  end
@@ -46,13 +46,13 @@ module FlavourSaver
46
46
  def private_variable_get(name)
47
47
  begin
48
48
  @privates.fetch(name)
49
- rescue KeyError => e
49
+ rescue KeyError
50
50
  raise UndefinedPrivateVariableException, "private variable not found @#{name}"
51
51
  end
52
52
  end
53
53
 
54
54
  def strip(tmp_context = nil)
55
- self.to_s(tmp_context).gsub(/[\s\r\n]+/,' ').strip
55
+ self.to_s(tmp_context).gsub(/[\s]+/,' ').strip
56
56
  end
57
57
 
58
58
  def evaluate_node(node)
@@ -256,9 +256,9 @@ module FlavourSaver
256
256
  "&#x27;"
257
257
  when '"'
258
258
  "&quot;"
259
- when '`'
260
- "&#x60;"
261
- end
259
+ when '`'
260
+ "&#x60;"
261
+ end
262
262
  end
263
263
 
264
264
  # Mark it as already escaped if we're in Rails
@@ -1,3 +1,3 @@
1
1
  module FlavourSaver
2
- VERSION = "0.3.7"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -9,6 +9,6 @@ describe 'Fixture: backtrack.hbs' do
9
9
  it 'renders correctly' do
10
10
  context.person = Struct.new(:name).new('Alan')
11
11
  context.company = Struct.new(:name).new('Rad, Inc.')
12
- subject.should == "Alan - Rad, Inc."
12
+ expect(subject).to eq "Alan - Rad, Inc."
13
13
  end
14
14
  end
@@ -7,6 +7,6 @@ describe 'Fixture: comment.hbs' do
7
7
  let(:context) { double(:context) }
8
8
 
9
9
  it 'renders correctly' do
10
- subject.should == "I am a very nice person!"
10
+ expect(subject).to eq "I am a very nice person!"
11
11
  end
12
12
  end
@@ -18,7 +18,7 @@ describe 'Fixture: custom_block_helper.hbs' do
18
18
  end.join ''
19
19
  end
20
20
  FlavourSaver.register_helper(method(:three_times))
21
- subject.should == "1 time. 2 time. 3 time."
21
+ expect(subject).to eq "1 time. 2 time. 3 time."
22
22
  end
23
23
  end
24
24
 
@@ -29,7 +29,7 @@ describe 'Fixture: custom_block_helper.hbs' do
29
29
  b.call.contents i
30
30
  end.join ''
31
31
  }
32
- subject.should == "1 time. 2 time. 3 time."
32
+ expect(subject).to eq "1 time. 2 time. 3 time."
33
33
  end
34
34
  end
35
35
  end
@@ -10,6 +10,6 @@ describe 'Fixture: custom_helper.hbs' do
10
10
  FlavourSaver.register_helper(:say_what_again) do
11
11
  'What?'
12
12
  end
13
- subject.should == "What?"
13
+ expect(subject).to eq "What?"
14
14
  end
15
15
  end
@@ -8,7 +8,7 @@ describe "Can't call methods that the context doesn't respond to" do
8
8
 
9
9
  it 'renders correctly' do
10
10
  expect(Kernel).not_to receive(:system)
11
- expect { subject }.to raise_error
11
+ expect { subject }.to raise_error(RuntimeError)
12
12
  end
13
13
  end
14
14
 
@@ -19,7 +19,7 @@ describe "Can't eval arbitrary Ruby code" do
19
19
 
20
20
  it 'renders correctly' do
21
21
  expect(Kernel).not_to receive(:eval)
22
- expect { subject }.to raise_error
22
+ expect { subject }.to raise_error(RuntimeError)
23
23
  end
24
24
  end
25
25