hamlit 2.13.0 → 2.14.2

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
2
  SHA256:
3
- metadata.gz: 1b080bac2aef1f473d967c016e0610d319cd43b89fbaea3a113949ed6dacfd04
4
- data.tar.gz: be1115f4778772e95102c2ab995abd7ff7f3f6c9e86ab8eefac26a38b1a20bd2
3
+ metadata.gz: c71aa1b03fd903408eef1cff941de4b5d6c9d56ee1a2a9d773f4b9c779ef28c1
4
+ data.tar.gz: 58113e96249289afc34d814ebda1c256bd7476fb4a2c94d842e6b2d2dc90b75e
5
5
  SHA512:
6
- metadata.gz: 2b5a640a456b34d551d4e65df868d59c027f4566ff357643f2b42458417356599f6d2cb3a9413ff17e431c69d782f2b9e5a603de147e1a6947f646910d8c3bf4
7
- data.tar.gz: d13cb779bc02e9914f754054a7b8ab6b2ff6721259b15c87638fbbb2b6a528323b407e22ce4fcdd0a1e91ab1c7f05c5cd7d26e19b96016efaf91b1a188ac6579
6
+ metadata.gz: 5b2641814756042ca0a03ddf2b8c8b6c1965c732871a6c9b6dc3249fdaf28afa478980bc4b88b1cac04082c75216d14009f1cd669e63dc1a4a7657780bd8cdb1
7
+ data.tar.gz: e1255baf55d678ed1300adfe905bf7a53ebec2f520bbfdd8eb0004cc607ae7967cf63f2308bdb015197679cb640820a0803e8c6713de6660876e09a0e5f6c8d4
@@ -0,0 +1,36 @@
1
+ name: test
2
+ on:
3
+ push:
4
+ branches:
5
+ - master
6
+ pull_request:
7
+ types:
8
+ - opened
9
+ - synchronize
10
+ - reopened
11
+ schedule:
12
+ - cron: "00 15 * * *" # 7:00 PST (-8), 8:00 PDT (-7)
13
+ jobs:
14
+ test:
15
+ runs-on: ubuntu-latest
16
+ container: ${{ matrix.ruby }}
17
+ strategy:
18
+ fail-fast: false
19
+ matrix:
20
+ ruby:
21
+ - ruby:2.5
22
+ - ruby:2.6
23
+ - ruby:2.7
24
+ - ruby:3.0
25
+ # TODO: add jruby and truffleruby
26
+ steps:
27
+ - uses: actions/checkout@v2
28
+ - uses: actions/cache@v2
29
+ with:
30
+ path: vendor/bundle
31
+ key: ${{ runner.os }}-${{ matrix.ruby }}-gems-${{ hashFiles('**/Gemfile.lock') }}
32
+ restore-keys: ${{ runner.os }}-gems-
33
+ - run: apt-get update && apt-get install -y nodejs # For execjs
34
+ - name: bundle install
35
+ run: bundle config path vendor/bundle && bundle install -j$(nproc) --retry 3
36
+ - run: bundle exec rake test
data/.gitignore CHANGED
@@ -13,6 +13,6 @@
13
13
  *.bundle
14
14
  *.so
15
15
  *.su
16
- *.o
17
16
  *.a
17
+ *.o
18
18
  *.swp
@@ -4,7 +4,45 @@ All notable changes to this project will be documented in this file. This
4
4
  project adheres to [Semantic Versioning](http://semver.org/). This change log is based upon
5
5
  [keep-a-changelog](https://github.com/olivierlacan/keep-a-changelog).
6
6
 
7
- ## [2.13.0](https://github.com/k0kubun/hamlit/compare/v2.12.0...v2.13.0) - 2020-10-2
7
+ ## [2.14.2](https://github.com/k0kubun/hamlit/compare/v2.14.1...v2.14.2) - 2021-01-21
8
+
9
+ ### Fixed
10
+
11
+ - Prevent SEGV in a C extension after `GC.compact` [#171](https://github.com/k0kubun/hamlit/issues/171)
12
+ *Thanks to @stanhu*
13
+
14
+ ## [2.14.1](https://github.com/k0kubun/hamlit/compare/v2.14.0...v2.14.1) - 2021-01-07
15
+
16
+ ### Added
17
+
18
+ - Add `-c` option to `hamlit compile` that works like `haml -c` [#166](https://github.com/k0kubun/hamlit/issues/166)
19
+ *Thanks to @knightq*
20
+
21
+ ## [2.14.0](https://github.com/k0kubun/hamlit/compare/v2.13.2...v2.14.0) - 2021-01-07
22
+
23
+ ### Changed
24
+
25
+ - CLI changes
26
+ - Remove `-c` shorthand of `--color`.
27
+ - Make `--color` default. Please use `--no-color` to disable it.
28
+ - `--color` uses IRB instead of Pry for syntax highlight.
29
+ - Syntax highlight of `hamlit compile` is enabled only with IRB of Ruby 2.7+.
30
+ - Syntax highlight of `hamlit parse` / `hamlit temple` is enabled only with IRB of Ruby 3.1+.
31
+
32
+ ## [2.13.2](https://github.com/k0kubun/hamlit/compare/v2.13.1...v2.13.2) - 2020-12-27
33
+
34
+ ### Added
35
+
36
+ - Speed up `hamlit` commands [#166](https://github.com/k0kubun/hamlit/issues/166)
37
+ *Thanks to @knightq*
38
+
39
+ ## [2.13.1](https://github.com/k0kubun/hamlit/compare/v2.13.0...v2.13.1) - 2020-12-27
40
+
41
+ ### Added
42
+
43
+ - Support [multiline attributes](https://github.com/haml/haml/pull/1043) of Haml 5.2.1.
44
+
45
+ ## [2.13.0](https://github.com/k0kubun/hamlit/compare/v2.12.0...v2.13.0) - 2020-10-02
8
46
 
9
47
  ### Added
10
48
 
@@ -16,6 +54,7 @@ project adheres to [Semantic Versioning](http://semver.org/). This change log is
16
54
  - Upgrade the Haml parser from Haml 4.0 to 5.2 [#163](https://github.com/k0kubun/hamlit/issues/163).
17
55
  - Allow `@` as tag's class name.
18
56
  - Fix NameError on an `InvalidAttributeNameError` reference introduced at Hamlit v2.12.0.
57
+ - You can no longer specify `ugly` option, which has had no effect.
19
58
 
20
59
  ## [2.12.0](https://github.com/k0kubun/hamlit/compare/v2.11.1...v2.12.0) - 2020-09-30
21
60
 
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/hamlit.svg)](http://badge.fury.io/rb/hamlit)
4
4
  [![Build Status](https://travis-ci.org/k0kubun/hamlit.svg?branch=master)](https://travis-ci.org/k0kubun/hamlit)
5
+ [![test](https://github.com/k0kubun/hamlit/workflows/test/badge.svg)](https://github.com/k0kubun/hamlit/actions?query=workflow%3Atest)
5
6
 
6
7
  Hamlit is a high performance [Haml](https://github.com/haml/haml) implementation.
7
8
 
@@ -10,17 +11,17 @@ Hamlit is a high performance [Haml](https://github.com/haml/haml) implementation
10
11
  ### What is Hamlit?
11
12
  Hamlit is another implementation of [Haml](https://github.com/haml/haml).
12
13
  With some [limitations](REFERENCE.md#limitations) by design for performance,
13
- Hamlit is **2.39x times faster** than original haml gem in [this benchmark](benchmark/slim/run-benchmarks.rb),
14
- which is an HTML-escaped version of [slim-template/slim's one](https://github.com/slim-template/slim/blob/v3.0.8/benchmarks/run-benchmarks.rb) for fairness. ([Result on Travis](https://travis-ci.org/k0kubun/hamlit/jobs/236567391))
14
+ Hamlit is **1.94x times faster** than original haml gem in [this benchmark](benchmark/slim/run-benchmarks.rb),
15
+ which is an HTML-escaped version of [slim-template/slim's one](https://github.com/slim-template/slim/blob/4.1.0/benchmarks/run-benchmarks.rb) for fairness. ([Result on Travis](https://travis-ci.org/github/k0kubun/hamlit/jobs/732178446))
15
16
 
16
- <img src="https://i.gyazo.com/0f0c0362b6bd69f82715bec1d8caa191.png" width="600px" alt="Hamlit Benchmark"/>
17
+ <img src="https://raw.githubusercontent.com/k0kubun/hamlit/afcc2b36c4861c2f764baa09afd9530ca25eeafa/benchmark/graph/graph.png" width="600x" alt="Hamlit Benchmark" />
17
18
 
18
19
  ```
19
- hamlit v2.8.1: 131048.9 i/s
20
- erubi v1.6.0: 125445.4 i/s - 1.04x slower
21
- slim v3.0.8: 121390.4 i/s - 1.08x slower
22
- faml v0.8.1: 100750.5 i/s - 1.30x slower
23
- haml v5.0.1: 54882.6 i/s - 2.39x slower
20
+ hamlit v2.13.0: 247404.4 i/s
21
+ erubi v1.9.0: 244356.4 i/s - 1.01x slower
22
+ slim v4.1.0: 238254.3 i/s - 1.04x slower
23
+ faml v0.8.1: 197293.2 i/s - 1.25x slower
24
+ haml v5.2.0: 127834.4 i/s - 1.94x slower
24
25
  ```
25
26
 
26
27
  ### Why is Hamlit faster?
Binary file
Binary file
@@ -3,7 +3,7 @@ require 'fileutils'
3
3
  require 'tmpdir'
4
4
 
5
5
  HAML_REPO = 'haml/haml'
6
- HAML_VERSION = 'v5.2.0'
6
+ HAML_VERSION = '5.2.1'
7
7
 
8
8
  module GitHubFetcher
9
9
  def self.fetch(repo, tag:, path:)
@@ -76,7 +76,7 @@ class HamlitParserBuilder
76
76
 
77
77
  DUMMY_CLASSES.each do |file, klass|
78
78
  dest_path = File.join(@hamlit_parser, "haml_#{file}")
79
- src = "class Hamlit::Haml#{klass}; end"
79
+ src = "class Hamlit::Haml#{klass}; end\n"
80
80
  File.write(dest_path, src)
81
81
  end
82
82
  end
@@ -6,15 +6,9 @@
6
6
 
7
7
  VALUE mAttributeBuilder, mObjectRef;
8
8
  static ID id_flatten, id_keys, id_parse, id_prepend, id_tr, id_uniq_bang;
9
- static ID id_aria, id_data, id_equal, id_hyphen, id_space, id_underscore;
10
9
  static ID id_boolean_attributes, id_xhtml;
11
10
 
12
- static VALUE str_aria() { return rb_const_get(mAttributeBuilder, id_aria); }
13
- static VALUE str_data() { return rb_const_get(mAttributeBuilder, id_data); }
14
- static VALUE str_equal() { return rb_const_get(mAttributeBuilder, id_equal); }
15
- static VALUE str_hyphen() { return rb_const_get(mAttributeBuilder, id_hyphen); }
16
- static VALUE str_space() { return rb_const_get(mAttributeBuilder, id_space); }
17
- static VALUE str_underscore() { return rb_const_get(mAttributeBuilder, id_underscore); }
11
+ static VALUE str_aria, str_data, str_equal, str_hyphen, str_space, str_underscore;
18
12
 
19
13
  static void
20
14
  delete_falsey_values(VALUE values)
@@ -51,7 +45,7 @@ hyphenate(VALUE str)
51
45
 
52
46
  for (i = 0; i < RSTRING_LEN(str); i++) {
53
47
  if (RSTRING_PTR(str)[i] == '_') {
54
- rb_str_update(str, i, 1, str_hyphen());
48
+ rb_str_update(str, i, 1, str_hyphen);
55
49
  }
56
50
  }
57
51
  return str;
@@ -97,7 +91,7 @@ hamlit_build_id(VALUE escape_attrs, VALUE values)
97
91
  values = rb_funcall(values, id_flatten, 0);
98
92
  delete_falsey_values(values);
99
93
 
100
- attr_value = rb_ary_join(values, str_underscore());
94
+ attr_value = rb_ary_join(values, str_underscore);
101
95
  return escape_attribute(escape_attrs, attr_value);
102
96
  }
103
97
 
@@ -110,7 +104,7 @@ hamlit_build_single_class(VALUE escape_attrs, VALUE value)
110
104
  case T_ARRAY:
111
105
  value = rb_funcall(value, id_flatten, 0);
112
106
  delete_falsey_values(value);
113
- value = rb_ary_join(value, str_space());
107
+ value = rb_ary_join(value, str_space);
114
108
  break;
115
109
  default:
116
110
  if (RTEST(value)) {
@@ -154,7 +148,7 @@ hamlit_build_multi_class(VALUE escape_attrs, VALUE values)
154
148
 
155
149
  rb_funcall(buf, id_uniq_bang, 0);
156
150
 
157
- return escape_attribute(escape_attrs, rb_ary_join(buf, str_space()));
151
+ return escape_attribute(escape_attrs, rb_ary_join(buf, str_space));
158
152
  }
159
153
 
160
154
  static VALUE
@@ -285,7 +279,7 @@ hamlit_build_data(VALUE escape_attrs, VALUE quote, VALUE values, VALUE key_str)
285
279
 
286
280
  switch (value) {
287
281
  case Qtrue:
288
- rb_str_concat(buf, str_space());
282
+ rb_str_concat(buf, str_space);
289
283
  rb_str_concat(buf, key);
290
284
  break;
291
285
  case Qnil:
@@ -293,9 +287,9 @@ hamlit_build_data(VALUE escape_attrs, VALUE quote, VALUE values, VALUE key_str)
293
287
  case Qfalse:
294
288
  break; // noop
295
289
  default:
296
- rb_str_concat(buf, str_space());
290
+ rb_str_concat(buf, str_space);
297
291
  rb_str_concat(buf, key);
298
- rb_str_concat(buf, str_equal());
292
+ rb_str_concat(buf, str_equal);
299
293
  rb_str_concat(buf, quote);
300
294
  rb_str_concat(buf, escape_attribute(escape_attrs, to_s(value)));
301
295
  rb_str_concat(buf, quote);
@@ -379,13 +373,13 @@ hamlit_build_for_class(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE values)
379
373
  void
380
374
  hamlit_build_for_data(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE values)
381
375
  {
382
- rb_str_concat(buf, hamlit_build_data(escape_attrs, quote, values, str_data()));
376
+ rb_str_concat(buf, hamlit_build_data(escape_attrs, quote, values, str_data));
383
377
  }
384
378
 
385
379
  void
386
380
  hamlit_build_for_aria(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE values)
387
381
  {
388
- rb_str_concat(buf, hamlit_build_data(escape_attrs, quote, values, str_aria()));
382
+ rb_str_concat(buf, hamlit_build_data(escape_attrs, quote, values, str_aria));
389
383
  }
390
384
 
391
385
  void
@@ -485,7 +479,7 @@ rb_hamlit_build_aria(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
485
479
  rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
486
480
  rb_scan_args(argc - 2, argv + 2, "*", &array);
487
481
 
488
- return hamlit_build_data(argv[0], argv[1], array, str_aria());
482
+ return hamlit_build_data(argv[0], argv[1], array, str_aria);
489
483
  }
490
484
 
491
485
  static VALUE
@@ -496,7 +490,7 @@ rb_hamlit_build_data(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
496
490
  rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
497
491
  rb_scan_args(argc - 2, argv + 2, "*", &array);
498
492
 
499
- return hamlit_build_data(argv[0], argv[1], array, str_data());
493
+ return hamlit_build_data(argv[0], argv[1], array, str_data);
500
494
  }
501
495
 
502
496
  static VALUE
@@ -534,21 +528,15 @@ Init_hamlit(void)
534
528
  id_tr = rb_intern("tr");
535
529
  id_uniq_bang = rb_intern("uniq!");
536
530
 
537
- id_aria = rb_intern("ARIA");
538
- id_data = rb_intern("DATA");
539
- id_equal = rb_intern("EQUAL");
540
- id_hyphen = rb_intern("HYPHEN");
541
- id_space = rb_intern("SPACE");
542
- id_underscore = rb_intern("UNDERSCORE");
543
-
544
531
  id_boolean_attributes = rb_intern("BOOLEAN_ATTRIBUTES");
545
532
  id_xhtml = rb_intern("xhtml");
546
533
 
547
- rb_const_set(mAttributeBuilder, id_aria, rb_obj_freeze(rb_str_new_cstr("aria")));
548
- rb_const_set(mAttributeBuilder, id_data, rb_obj_freeze(rb_str_new_cstr("data")));
549
- rb_const_set(mAttributeBuilder, id_equal, rb_obj_freeze(rb_str_new_cstr("=")));
550
- rb_const_set(mAttributeBuilder, id_hyphen, rb_obj_freeze(rb_str_new_cstr("-")));
551
- rb_const_set(mAttributeBuilder, id_space, rb_obj_freeze(rb_str_new_cstr(" ")));
552
- rb_const_set(mAttributeBuilder, id_underscore, rb_obj_freeze(rb_str_new_cstr("_")));
534
+ // Consider using rb_interned_str() once we stop supporting Ruby 2.7.
535
+ rb_gc_register_mark_object(str_aria = rb_obj_freeze(rb_str_new_cstr("aria")));
536
+ rb_gc_register_mark_object(str_data = rb_obj_freeze(rb_str_new_cstr("data")));
537
+ rb_gc_register_mark_object(str_equal = rb_obj_freeze(rb_str_new_cstr("=")));
538
+ rb_gc_register_mark_object(str_hyphen = rb_obj_freeze(rb_str_new_cstr("-")));
539
+ rb_gc_register_mark_object(str_space = rb_obj_freeze(rb_str_new_cstr(" ")));
540
+ rb_gc_register_mark_object(str_underscore = rb_obj_freeze(rb_str_new_cstr("_")));
553
541
  }
554
542
  #endif
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.add_development_dependency 'haml', '>= 5'
38
38
  spec.add_development_dependency 'less'
39
39
  spec.add_development_dependency 'minitest-reporters', '~> 1.1'
40
- spec.add_development_dependency 'rails', '>= 4.0.0'
40
+ spec.add_development_dependency 'rails', '>= 4.0'
41
41
  spec.add_development_dependency 'rake'
42
42
  spec.add_development_dependency 'rake-compiler'
43
43
  spec.add_development_dependency 'sass'
@@ -4,8 +4,10 @@ require 'hamlit/error'
4
4
  require 'hamlit/version'
5
5
  require 'hamlit/template'
6
6
 
7
- begin
8
- require 'rails'
9
- require 'hamlit/railtie'
10
- rescue LoadError
7
+ if File.basename($0) != 'hamlit'
8
+ begin
9
+ require 'rails'
10
+ require 'hamlit/railtie'
11
+ rescue LoadError
12
+ end
11
13
  end
@@ -13,25 +13,33 @@ module Hamlit
13
13
  def render(file)
14
14
  process_load_options
15
15
  code = generate_code(file)
16
- puts eval(code)
16
+ puts eval(code, binding, file)
17
17
  end
18
18
 
19
19
  desc 'compile HAML', 'Show compile result'
20
20
  option :actionview, type: :boolean, default: false, aliases: %w[-a]
21
- option :color, type: :boolean, default: false, aliases: %w[-c]
21
+ option :color, type: :boolean, default: true
22
+ option :check, type: :boolean, default: false, aliases: %w[-c]
22
23
  def compile(file)
23
24
  code = generate_code(file)
25
+ if options[:check]
26
+ if error = validate_ruby(code, file)
27
+ abort error.message.split("\n").first
28
+ end
29
+ puts "Syntax OK"
30
+ return
31
+ end
24
32
  puts_code(code, color: options[:color])
25
33
  end
26
34
 
27
35
  desc 'temple HAML', 'Show temple intermediate expression'
28
- option :color, type: :boolean, default: false, aliases: %w[-c]
36
+ option :color, type: :boolean, default: true
29
37
  def temple(file)
30
38
  pp_object(generate_temple(file), color: options[:color])
31
39
  end
32
40
 
33
41
  desc 'parse HAML', 'Show parse result'
34
- option :color, type: :boolean, default: false, aliases: %w[-c]
42
+ option :color, type: :boolean, default: true
35
43
  def parse(file)
36
44
  pp_object(generate_ast(file), color: options[:color])
37
45
  end
@@ -107,24 +115,40 @@ module Hamlit
107
115
  render(args.first.to_s)
108
116
  end
109
117
 
110
- def puts_code(code, color: false)
118
+ def puts_code(code, color: true)
119
+ begin
120
+ require 'irb/color'
121
+ rescue LoadError
122
+ color = false
123
+ end
111
124
  if color
112
- require 'pry'
113
- puts Pry.Code(code).highlighted
125
+ puts IRB::Color.colorize_code(code)
114
126
  else
115
127
  puts code
116
128
  end
117
129
  end
118
130
 
119
131
  # Enable colored pretty printing only for development environment.
120
- def pp_object(arg, color: false)
132
+ def pp_object(arg, color: true)
133
+ begin
134
+ require 'irb/color_printer'
135
+ rescue LoadError
136
+ color = false
137
+ end
121
138
  if color
122
- require 'pry'
123
- Pry::ColorPrinter.pp(arg)
139
+ IRB::ColorPrinter.pp(arg)
124
140
  else
125
141
  require 'pp'
126
142
  pp(arg)
127
143
  end
128
144
  end
145
+
146
+ def validate_ruby(code, file)
147
+ begin
148
+ eval("BEGIN {return nil}; #{code}", binding, file)
149
+ rescue ::SyntaxError # Not to be confused with Hamlit::SyntaxError
150
+ $!
151
+ end
152
+ end
129
153
  end
130
154
  end
@@ -1 +1 @@
1
- class Hamlit::HamlCompiler; end
1
+ class Hamlit::HamlCompiler; end
@@ -1 +1 @@
1
- class Hamlit::HamlEscapable; end
1
+ class Hamlit::HamlEscapable; end
@@ -1 +1 @@
1
- class Hamlit::HamlGenerator; end
1
+ class Hamlit::HamlGenerator; end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'ripper'
3
4
  require 'strscan'
4
5
 
5
6
  module Hamlit
@@ -90,6 +91,9 @@ module Hamlit
90
91
  ID_KEY = 'id'.freeze
91
92
  CLASS_KEY = 'class'.freeze
92
93
 
94
+ # Used for scanning old attributes, substituting the first '{'
95
+ METHOD_CALL_PREFIX = 'a('
96
+
93
97
  def initialize(options)
94
98
  @options = HamlOptions.wrap(options)
95
99
  # Record the indent levels of "if" statements to validate the subsequent
@@ -655,13 +659,18 @@ module Hamlit
655
659
  # @return [String] rest
656
660
  # @return [Integer] last_line
657
661
  def parse_old_attributes(text)
658
- text = text.dup
659
662
  last_line = @line.index + 1
660
663
 
661
664
  begin
662
- attributes_hash, rest = balance(text, ?{, ?})
665
+ # Old attributes often look like a valid Hash literal, but it sometimes allow code like
666
+ # `{ hash, foo: bar }`, which is compiled to `_hamlout.attributes({}, nil, hash, foo: bar)`.
667
+ #
668
+ # To scan such code correctly, this scans `a( hash, foo: bar }` instead, stops when there is
669
+ # 1 more :on_embexpr_end (the last '}') than :on_embexpr_beg, and resurrects '{' afterwards.
670
+ balanced, rest = balance_tokens(text.sub(?{, METHOD_CALL_PREFIX), :on_embexpr_beg, :on_embexpr_end, count: 1)
671
+ attributes_hash = balanced.sub(METHOD_CALL_PREFIX, ?{)
663
672
  rescue HamlSyntaxError => e
664
- if text.strip[-1] == ?, && e.message == HamlError.message(:unbalanced_brackets)
673
+ if e.message == HamlError.message(:unbalanced_brackets) && !@template.empty?
665
674
  text << "\n#{@next_line.text}"
666
675
  last_line += 1
667
676
  next_line
@@ -815,6 +824,25 @@ module Hamlit
815
824
  Hamlit::HamlUtil.balance(*args) or raise(HamlSyntaxError.new(HamlError.message(:unbalanced_brackets)))
816
825
  end
817
826
 
827
+ # Unlike #balance, this balances Ripper tokens to balance something like `{ a: "}" }` correctly.
828
+ def balance_tokens(buf, start, finish, count: 0)
829
+ text = ''.dup
830
+ Ripper.lex(buf).each do |_, token, str|
831
+ text << str
832
+ case token
833
+ when start
834
+ count += 1
835
+ when finish
836
+ count -= 1
837
+ end
838
+
839
+ if count == 0
840
+ return text, buf.sub(text, '')
841
+ end
842
+ end
843
+ raise HamlSyntaxError.new(HamlError.message(:unbalanced_brackets))
844
+ end
845
+
818
846
  def block_opened?
819
847
  @next_line.tabs > @line.tabs
820
848
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Hamlit
3
- VERSION = '2.13.0'
3
+ VERSION = '2.14.2'
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hamlit
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.13.0
4
+ version: 2.14.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Takashi Kokubun
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-02 00:00:00.000000000 Z
11
+ date: 2021-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: temple
@@ -156,14 +156,14 @@ dependencies:
156
156
  requirements:
157
157
  - - ">="
158
158
  - !ruby/object:Gem::Version
159
- version: 4.0.0
159
+ version: '4.0'
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
- version: 4.0.0
166
+ version: '4.0'
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: rake
169
169
  requirement: !ruby/object:Gem::Requirement
@@ -257,8 +257,8 @@ extensions:
257
257
  - ext/hamlit/extconf.rb
258
258
  extra_rdoc_files: []
259
259
  files:
260
+ - ".github/workflows/test.yml"
260
261
  - ".gitignore"
261
- - ".travis.yml"
262
262
  - CHANGELOG.md
263
263
  - Gemfile
264
264
  - LICENSE.txt
@@ -287,6 +287,8 @@ files:
287
287
  - benchmark/etc/tags_loop.haml
288
288
  - benchmark/ext/build_data.rb
289
289
  - benchmark/ext/build_id.rb
290
+ - benchmark/graph/graph.key
291
+ - benchmark/graph/graph.png
290
292
  - benchmark/id_attribute.haml
291
293
  - benchmark/plain.haml
292
294
  - benchmark/script.haml
@@ -389,7 +391,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
389
391
  - !ruby/object:Gem::Version
390
392
  version: '0'
391
393
  requirements: []
392
- rubygems_version: 3.1.2
394
+ rubygems_version: 3.1.4
393
395
  signing_key:
394
396
  specification_version: 4
395
397
  summary: High Performance Haml Implementation
@@ -1,53 +0,0 @@
1
- language: ruby
2
- cache: bundler
3
- branches:
4
- only:
5
- - master
6
- script:
7
- - bundle exec rake $TASK
8
- env:
9
- - RUBYOPT='-w'
10
- matrix:
11
- include:
12
- - rvm: 2.3.8
13
- env: TASK=test
14
- - rvm: 2.4.9
15
- env: TASK=test
16
- - rvm: 2.5.7
17
- env: TASK=test
18
- - rvm: 2.6.5
19
- env: TASK=test
20
- - rvm: 2.7.0
21
- env: TASK=test
22
- - rvm: 2.7.0
23
- env: TASK=test RUBYOPT='-w --enable-frozen-string-literal'
24
- - rvm: ruby-head
25
- env: TASK=test
26
- - rvm: jruby-9.2.8.0
27
- env: TASK=test
28
- - rvm: truffleruby
29
- env: TASK=test
30
- - rvm: 2.7.0
31
- env: TASK=bench TEMPLATE=benchmark/boolean_attribute.haml,benchmark/class_attribute.haml,benchmark/id_attribute.haml,benchmark/data_attribute.haml,benchmark/common_attribute.haml
32
- - rvm: 2.7.0
33
- env: TASK=bench TEMPLATE=benchmark/dynamic_attributes/boolean_attribute.haml,benchmark/dynamic_attributes/class_attribute.haml,benchmark/dynamic_attributes/id_attribute.haml,benchmark/dynamic_attributes/data_attribute.haml,benchmark/dynamic_attributes/common_attribute.haml
34
- - rvm: 2.7.0
35
- env: TASK=bench SLIM_BENCH=1
36
- - rvm: 2.7.0
37
- env: TASK=bench TEMPLATE=benchmark/etc/attribute_builder.haml
38
- - rvm: 2.7.0
39
- env: TASK=bench TEMPLATE=benchmark/etc/static_analyzer.haml
40
- - rvm: 2.7.0
41
- env: TASK=bench TEMPLATE=benchmark/etc/string_interpolation.haml
42
- - rvm: 2.7.0
43
- env: TASK=bench TEMPLATE=test/haml/templates/standard.haml COMPILE=1
44
- allow_failures:
45
- - rvm: ruby-head
46
- env: TASK=test
47
- - env: TASK=bench TEMPLATE=benchmark/boolean_attribute.haml,benchmark/class_attribute.haml,benchmark/id_attribute.haml,benchmark/data_attribute.haml,benchmark/common_attribute.haml
48
- - env: TASK=bench TEMPLATE=benchmark/dynamic_attributes/boolean_attribute.haml,benchmark/dynamic_attributes/class_attribute.haml,benchmark/dynamic_attributes/id_attribute.haml,benchmark/dynamic_attributes/data_attribute.haml,benchmark/dynamic_attributes/common_attribute.haml
49
- - env: TASK=bench SLIM_BENCH=1
50
- - env: TASK=bench TEMPLATE=benchmark/etc/attribute_builder.haml
51
- - env: TASK=bench TEMPLATE=benchmark/etc/static_analyzer.haml
52
- - env: TASK=bench TEMPLATE=benchmark/etc/string_interpolation.haml
53
- - env: TASK=bench TEMPLATE=test/haml/templates/standard.haml COMPILE=1