faml 0.3.3 → 0.3.4

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
2
  SHA1:
3
- metadata.gz: 9f188aeb028e6438b455033f6f2efe701297ad13
4
- data.tar.gz: cac035f6c7671aef877c83ff47d7e772941b2d1a
3
+ metadata.gz: c643b558a5d6ef910d8545a6be0501d258c730ea
4
+ data.tar.gz: 35de29c371d213c3291c3a3c0f5816b3d9638285
5
5
  SHA512:
6
- metadata.gz: 0e9c2a21ca2ad84c4cb9c219bfbf971c11e85bc07fa02910a177a9f081a82a18ea37a9e4b0ecf900f84150eb41f369f65ed14c1b6b5c3ea8dc5791500c9da58e
7
- data.tar.gz: 2f0873cb28c9d275e2c11ca00d2ff3b0ca3d37d794ab2c76c747eaf82cd8f780a7dc376f615dccbaf736f8a6e32c510516c790002e544fed70d0696bb260d961
6
+ metadata.gz: 5cebe334bdd49fb358a07f2004df19eb9542d4d215be3197b1bd52c45a035e646b5375084e009031669a7e40908d653bb29eb186f263cabee3211a18b419671d
7
+ data.tar.gz: 028cadedad4e8cbbafcb7e62896b2389e40f3c2f18c42bedbc48f1818b5cadfa90d6db8a04af01d8ca9ccdecfeb3d6e873d959008470d0f5d86dad7d91a4c8fb
data/.rubocop.yml CHANGED
@@ -11,31 +11,43 @@ Lint/HandleExceptions:
11
11
  - 'lib/faml/tilt.rb'
12
12
  Lint/Eval:
13
13
  Exclude:
14
- - 'lib/faml/static_hash_parser.rb'
15
14
  - 'spec/spec_helper.rb'
16
15
 
17
16
  Style/BarePercentLiterals:
18
17
  EnforcedStyle: percent_q
18
+
19
19
  Style/CaseEquality:
20
20
  Enabled: false
21
+
22
+ Style/FormatString:
23
+ EnforcedStyle: sprintf
24
+
21
25
  Style/GlobalVars:
22
26
  Exclude:
23
27
  - '**/extconf.rb'
28
+
24
29
  Style/GuardClause:
25
30
  Enabled: false
31
+
26
32
  Style/HashSyntax:
27
33
  Exclude:
28
34
  - 'Rakefile'
35
+
29
36
  Style/IfUnlessModifier:
30
37
  Enabled: false
38
+
31
39
  Style/PercentLiteralDelimiters:
32
40
  Enabled: false
41
+
33
42
  Style/RaiseArgs:
34
43
  EnforcedStyle: compact
44
+
35
45
  Style/SignalException:
36
46
  Enabled: false
47
+
37
48
  Style/TrailingComma:
38
49
  Enabled: false
50
+
39
51
  Style/TrailingWhitespace:
40
52
  Exclude:
41
53
  - 'spec/render/multiline_spec.rb'
data/.rubocop_todo.yml CHANGED
@@ -1,43 +1,23 @@
1
- # This configuration was generated by
2
- # `rubocop --auto-gen-config`
3
- # on 2015-10-06 23:31:05 +0900 using RuboCop version 0.34.2.
4
- # The point is for the user to remove these configuration records
5
- # one by one as the offenses are removed from the code base.
6
- # Note that changes in the inspected code, or installation of new
7
- # versions of RuboCop, may require this file to be generated again.
8
-
9
- # Offense count: 17
10
1
  Metrics/AbcSize:
11
- Max: 32
2
+ Enabled: false
12
3
 
13
- # Offense count: 1
14
4
  Metrics/BlockNesting:
15
- Max: 4
5
+ Enabled: false
16
6
 
17
- # Offense count: 4
18
- # Configuration parameters: CountComments.
19
7
  Metrics/ClassLength:
20
- Max: 341
8
+ Enabled: false
21
9
 
22
- # Offense count: 7
23
10
  Metrics/CyclomaticComplexity:
24
- Max: 12
11
+ Enabled: false
25
12
 
26
- # Offense count: 214
27
- # Configuration parameters: AllowURI, URISchemes.
28
13
  Metrics/LineLength:
29
- Max: 199
14
+ Enabled: false
30
15
 
31
- # Offense count: 20
32
- # Configuration parameters: CountComments.
33
16
  Metrics/MethodLength:
34
- Max: 29
17
+ Enabled: false
35
18
 
36
- # Offense count: 5
37
19
  Metrics/PerceivedComplexity:
38
- Max: 13
20
+ Enabled: false
39
21
 
40
- # Offense count: 45
41
- # Configuration parameters: Exclude.
42
22
  Style/Documentation:
43
23
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.3.4 (2015-10-19)
2
+ - Support array, rational and complex literal optimization
3
+ - Now `%div{class: %w[foo bar], data: { foo: 1i, bar: 2r }}` is compiled into string literal.
4
+ - Remove `Kernel#eval` from compiler
5
+ - Improve `faml stats` subcommand
6
+ - Show more detailed attribute information
7
+ - Fix several bugs
8
+
1
9
  ## 0.3.3 (2015-10-07)
2
10
  - Improve `Faml::AttributeBuilder.build` performance
3
11
  - Optimize string conversions
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'bundler/gem_tasks'
2
2
 
3
- task :default => [:compile, :spec]
3
+ task :default => [:compile, :spec, :rubocop]
4
4
 
5
5
  require 'rake/extensiontask'
6
6
  Rake::ExtensionTask.new('attribute_builder') do |ext|
@@ -10,6 +10,9 @@ end
10
10
  require 'rspec/core/rake_task'
11
11
  RSpec::Core::RakeTask.new(:spec)
12
12
 
13
+ require 'rubocop/rake_task'
14
+ RuboCop::RakeTask.new(:rubocop)
15
+
13
16
  task :benchmark => ['benchmark:rendering', 'benchmark:compiling']
14
17
 
15
18
  namespace :benchmark do
@@ -10,6 +10,8 @@
10
10
  # define rb_ary_new_capa rb_ary_new2
11
11
  #endif
12
12
 
13
+ #define FOREACH_FUNC(func) ((int (*)(ANYARGS))(func))
14
+
13
15
  VALUE rb_mAttributeBuilder;
14
16
  static ID id_keys, id_sort_bang, id_uniq_bang, id_merge_bang;
15
17
  static ID id_id, id_class, id_underscore, id_hyphen, id_space, id_equal;
@@ -43,7 +45,7 @@ static VALUE
43
45
  stringify_keys(VALUE hash)
44
46
  {
45
47
  VALUE h = rb_hash_new();
46
- rb_hash_foreach(hash, stringify_keys_i, h);
48
+ rb_hash_foreach(hash, FOREACH_FUNC(stringify_keys_i), h);
47
49
  return h;
48
50
  }
49
51
 
@@ -101,7 +103,7 @@ normalize_data_i(VALUE key, VALUE value, VALUE normalized)
101
103
  struct normalize_data_i2_arg arg;
102
104
  arg.key = key;
103
105
  arg.normalized = normalized;
104
- rb_hash_foreach(normalize_data(value), normalize_data_i2, (VALUE)(&arg));
106
+ rb_hash_foreach(normalize_data(value), FOREACH_FUNC(normalize_data_i2), (VALUE)(&arg));
105
107
  } else if (RB_TYPE_P(value, T_TRUE)) {
106
108
  /* Keep Qtrue value */
107
109
  rb_hash_aset(normalized, key, value);
@@ -120,7 +122,7 @@ normalize_data(VALUE data)
120
122
 
121
123
  Check_Type(data, T_HASH);
122
124
  normalized = rb_hash_new();
123
- rb_hash_foreach(data, normalize_data_i, normalized);
125
+ rb_hash_foreach(data, FOREACH_FUNC(normalize_data_i), normalized);
124
126
  return normalized;
125
127
  }
126
128
 
@@ -151,7 +153,7 @@ normalize(VALUE hash)
151
153
 
152
154
  rb_hash_delete(hash, key);
153
155
  data = normalize_data(value);
154
- rb_hash_foreach(data, put_data_attribute, hash);
156
+ rb_hash_foreach(data, FOREACH_FUNC(put_data_attribute), hash);
155
157
  } else if (RB_TYPE_P(value, T_TRUE)) {
156
158
  /* Keep Qtrue value */
157
159
  } else if (RB_TYPE_P(value, T_FALSE) || NIL_P(value)) {
@@ -1,7 +1,7 @@
1
1
  # Incompatibilities
2
2
  ## Versions
3
3
  - Haml 4.0.7
4
- - Faml 0.3.2
4
+ - Faml 0.3.3
5
5
  - Hamlit 1.7.2
6
6
 
7
7
  ## Table of contents
@@ -15,6 +15,7 @@
15
15
  - [spec/render/filters/escaped_spec.md](spec/render/filters/escaped_spec.md) (Hamlit's incompatibility)
16
16
  - [spec/render/filters/javascript_spec.md](spec/render/filters/javascript_spec.md)
17
17
  - [spec/render/filters/markdown_spec.md](spec/render/filters/markdown_spec.md)
18
+ - [spec/render/filters/plain_spec.md](spec/render/filters/plain_spec.md)
18
19
  - [spec/render/filters/preserve_spec.md](spec/render/filters/preserve_spec.md) (Hamlit's incompatibility)
19
20
  - [spec/render/helpers_spec.md](spec/render/helpers_spec.md) (Hamlit's incompatibility)
20
21
  - [spec/render/multiline_spec.md](spec/render/multiline_spec.md) (Hamlit's incompatibility)
@@ -0,0 +1,78 @@
1
+ # [./spec/render/filters/plain_spec.rb:4](../../../../spec/render/filters/plain_spec.rb#L4)
2
+ ## Input
3
+ ```haml
4
+ %span
5
+ :plain
6
+ he#{'llo'}
7
+ %span world
8
+
9
+ ```
10
+
11
+ ## Faml
12
+ ```html
13
+ <span>
14
+ hello
15
+ <span>world</span>
16
+ </span>
17
+
18
+ ```
19
+
20
+ ## Haml, Hamlit
21
+ ```html
22
+ <span>
23
+ hello
24
+
25
+ <span>world</span>
26
+ </span>
27
+
28
+ ```
29
+
30
+ # [./spec/render/filters/plain_spec.rb:13](../../../../spec/render/filters/plain_spec.rb#L13)
31
+ ## Input
32
+ ```haml
33
+ %span
34
+ :plain
35
+ he#{'llo'}
36
+
37
+ abc
38
+
39
+ %span world
40
+
41
+ ```
42
+
43
+ ## Faml
44
+ ```html
45
+ <span>
46
+ hello
47
+
48
+ abc
49
+ <span>world</span>
50
+ </span>
51
+
52
+ ```
53
+
54
+ ## Haml
55
+ ```html
56
+ <span>
57
+ hello
58
+
59
+ abc
60
+
61
+
62
+ <span>world</span>
63
+ </span>
64
+
65
+ ```
66
+
67
+ ## Hamlit
68
+ ```html
69
+ <span>
70
+ hello
71
+
72
+ abc
73
+
74
+ <span>world</span>
75
+ </span>
76
+
77
+ ```
78
+
data/lib/faml/compiler.rb CHANGED
@@ -318,13 +318,23 @@ module Faml
318
318
  parser.static_attributes.each do |k, v|
319
319
  static_attributes[k.to_s] = v
320
320
  end
321
+
322
+ class_list = Array(static_attributes['class']).flat_map { |c| c.to_s.split(/ +/) }
321
323
  unless static_class.empty?
322
- class_list = static_attributes.fetch('class', '').to_s.split(/ +/)
323
- static_attributes['class'] = static_class.split(/ +/).concat(class_list).uniq.sort.join(' ')
324
+ class_list.concat(static_class.split(/ +/))
325
+ end
326
+ unless class_list.empty?
327
+ static_attributes['class'] = class_list.uniq.sort.join(' ')
324
328
  end
329
+
330
+ id_list = Array(static_attributes['id'])
325
331
  unless static_id.empty?
326
- static_attributes['id'] = [static_id, static_attributes['id']].compact.join('_')
332
+ id_list = [static_id].concat(id_list)
327
333
  end
334
+ unless id_list.empty?
335
+ static_attributes['id'] = id_list.join('_')
336
+ end
337
+
328
338
  static_attributes
329
339
  end
330
340
 
@@ -58,35 +58,23 @@ module Faml
58
58
  end
59
59
  end
60
60
 
61
- SYMBOL_FIRST_CHARS = [
62
- ':', # { :'foo' => 'bar' } or { :"foo" => 'bar' }
63
- "'", # { 'foo': 'bar' }
64
- '"', # { "foo": 'bar' }
65
- ].freeze
66
-
67
- def eval_symbol(code)
68
- if SYMBOL_FIRST_CHARS.include?(code[0])
69
- eval(code).to_sym
70
- else
71
- code.to_sym
72
- end
73
- end
74
-
75
61
  def try_static_key(node)
76
62
  case node.type
77
- when :sym
78
- eval_symbol(node.location.expression.source)
79
- when :int, :float, :str
80
- eval(node.location.expression.source)
63
+ when :sym, :int, :float, :str, :rational, :complex
64
+ node.children[0]
81
65
  end
82
66
  end
83
67
 
84
68
  def try_static_value(key_static, node)
85
69
  case node.type
86
- when :sym
87
- @static_attributes[key_static] = eval_symbol(node.location.expression.source)
88
- when :true, :false, :nil, :int, :float, :str
89
- @static_attributes[key_static] = eval(node.location.expression.source)
70
+ when :sym, :int, :float, :str, :rational, :complex
71
+ @static_attributes[key_static] = node.children[0]
72
+ when :true
73
+ @static_attributes[key_static] = true
74
+ when :false
75
+ @static_attributes[key_static] = false
76
+ when :nil
77
+ @static_attributes[key_static] = nil
90
78
  when :dstr
91
79
  @dynamic_attributes[key_static] = node.location.expression.source
92
80
  when :send
@@ -97,7 +85,8 @@ module Faml
97
85
  end
98
86
  when :hash
99
87
  try_static_hash_value(key_static, node)
100
- # TODO: Add array case
88
+ when :array
89
+ try_static_array_value(key_static, node)
101
90
  else
102
91
  throw FAILURE_TAG
103
92
  end
@@ -125,5 +114,12 @@ module Faml
125
114
  @dynamic_attributes[key_static] = "{#{expr}}"
126
115
  end
127
116
  end
117
+
118
+ def try_static_array_value(key_static, node)
119
+ arr = node.children.map do |child|
120
+ try_static_value(key_static, child)
121
+ end
122
+ @static_attributes[key_static] = arr
123
+ end
128
124
  end
129
125
  end
data/lib/faml/stats.rb CHANGED
@@ -8,10 +8,12 @@ module Faml
8
8
  Info = Struct.new(
9
9
  :empty_attribute_count,
10
10
  :static_attribute_count,
11
+ :static_id_or_class_attribute_count,
11
12
  :dynamic_attribute_count,
12
13
  :dynamic_attribute_with_data_count,
13
14
  :dynamic_attribute_with_newline_count,
14
15
  :ruby_attribute_count,
16
+ :multi_attribute_count,
15
17
  :ast_types
16
18
  ) do
17
19
  def initialize(*)
@@ -101,7 +103,7 @@ module Faml
101
103
  if ast.static_class.empty? && ast.static_id.empty?
102
104
  info.empty_attribute_count += 1
103
105
  else
104
- info.static_attribute_count += 1
106
+ info.static_id_or_class_attribute_count += 1
105
107
  end
106
108
  else
107
109
  static_hash_parser = StaticHashParser.new
@@ -109,7 +111,7 @@ module Faml
109
111
  if static_hash_parser.dynamic_attributes.empty?
110
112
  info.static_attribute_count += 1
111
113
  else
112
- if static_hash_parser.dynamic_attributes.key?('data')
114
+ if static_hash_parser.dynamic_attributes.key?('data') || static_hash_parser.dynamic_attributes.key?(:data)
113
115
  info.dynamic_attribute_with_data_count += 1
114
116
  elsif ast.attributes.include?("\n")
115
117
  info.dynamic_attribute_with_newline_count += 1
@@ -118,7 +120,12 @@ module Faml
118
120
  end
119
121
  end
120
122
  else
121
- info.ruby_attribute_count += 1
123
+ call_ast = Parser::CurrentRuby.parse("call(#{ast.attributes})")
124
+ if call_ast.type == :send && call_ast.children[0].nil? && call_ast.children[1] == :call && !call_ast.children[3].nil?
125
+ info.multi_attribute_count += 1
126
+ else
127
+ info.ruby_attribute_count += 1
128
+ end
122
129
  end
123
130
  end
124
131
  end
@@ -126,14 +133,17 @@ module Faml
126
133
  def report_attribute_stats(info)
127
134
  static = info.static_attribute_count
128
135
  dynamic = info.dynamic_attribute_count + info.dynamic_attribute_with_data_count + info.dynamic_attribute_with_newline_count
129
- ruby = info.ruby_attribute_count
136
+ ruby = info.ruby_attribute_count + info.multi_attribute_count
130
137
  total = static + dynamic + ruby
131
138
  puts 'Attribute stats'
139
+ printf(" Empty attributes: %d\n", info.empty_attribute_count)
140
+ printf(" Attributes with id or class only: %d\n", info.static_id_or_class_attribute_count)
132
141
  printf(" Static attributes: %d (%.2f%%)\n", static, static * 100.0 / total)
133
142
  printf(" Dynamic attributes: %d (%.2f%%)\n", dynamic, dynamic * 100.0 / total)
134
143
  printf(" with data: %d\n", info.dynamic_attribute_with_data_count)
135
144
  printf(" with newline: %d\n", info.dynamic_attribute_with_newline_count)
136
145
  printf(" Ruby attributes: %d (%.2f%%)\n", ruby, ruby * 100.0 / total)
146
+ printf(" with multiple arguments: %d\n", info.multi_attribute_count)
137
147
  end
138
148
 
139
149
  def report_ast_stats(info)
data/lib/faml/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Faml
2
- VERSION = '0.3.3'
2
+ VERSION = '0.3.4'
3
3
  end
@@ -30,7 +30,7 @@ RSpec.describe 'Attributes rendering', type: :render do
30
30
 
31
31
  it 'renders array class' do
32
32
  expect(render_string('%span.c2{class: "c1"}')).to eq("<span class='c1 c2'></span>\n")
33
- expect(render_string('%span.c2{class: ["c1", "c3"]}')).to eq("<span class='c1 c2 c3'></span>\n")
33
+ expect(render_string('%span.c2{class: ["c1", "c3", :c2]}')).to eq("<span class='c1 c2 c3'></span>\n")
34
34
  end
35
35
 
36
36
  it 'renders boolean attributes' do
@@ -119,6 +119,7 @@ HAML
119
119
 
120
120
  it 'merges static id' do
121
121
  expect(render_string('#foo{id: "bar"} baz')).to eq("<div id='foo_bar'>baz</div>\n")
122
+ expect(render_string('#foo{id: %w[bar baz]} hoge')).to eq("<div id='foo_bar_baz'>hoge</div>\n")
122
123
  end
123
124
 
124
125
  it 'merges static class' do
@@ -72,7 +72,7 @@ class IncompatibilitiesGenerator
72
72
  obj = Object.new
73
73
  Haml::Engine.new(template, { ugly: true, escape_html: true }.merge(options)).def_method(obj, :haml)
74
74
  obj.haml
75
- rescue => e
75
+ rescue StandardError, SyntaxError => e
76
76
  e
77
77
  end
78
78
 
@@ -80,7 +80,7 @@ class IncompatibilitiesGenerator
80
80
  obj = Object.new
81
81
  obj.instance_eval "def hamlit; #{Hamlit::Engine.new(options).call(template)}; end"
82
82
  obj.hamlit
83
- rescue => e
83
+ rescue StandardError, SyntaxError => e
84
84
  e
85
85
  end
86
86
 
@@ -110,7 +110,7 @@ EOS
110
110
  file.write <<"EOS"
111
111
  ## #{render_section(title, result)}
112
112
  ```html
113
- #{result}
113
+ #{render_body(result)}
114
114
  ```
115
115
 
116
116
  EOS
@@ -125,6 +125,22 @@ EOS
125
125
  end
126
126
  end
127
127
 
128
+ def render_body(result)
129
+ if result.is_a?(Exception)
130
+ result
131
+ else
132
+ result.gsub(/[[:cntrl:]]/) do |m|
133
+ n = m[0].ord
134
+ if n == 0x0a
135
+ # Print NL character as is
136
+ m[0]
137
+ else
138
+ "<0x#{sprintf('%02X', n)}>"
139
+ end
140
+ end
141
+ end
142
+ end
143
+
128
144
  def markdown_path(markdown_root, spec_path)
129
145
  markdown_root.join(spec_path).sub_ext('.md')
130
146
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kohei Suzuki
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-06 00:00:00.000000000 Z
11
+ date: 2015-10-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: escape_utils
@@ -339,6 +339,7 @@ files:
339
339
  - incompatibilities/spec/render/filters/escaped_spec.md
340
340
  - incompatibilities/spec/render/filters/javascript_spec.md
341
341
  - incompatibilities/spec/render/filters/markdown_spec.md
342
+ - incompatibilities/spec/render/filters/plain_spec.md
342
343
  - incompatibilities/spec/render/filters/preserve_spec.md
343
344
  - incompatibilities/spec/render/helpers_spec.md
344
345
  - incompatibilities/spec/render/indent_spec.md
@@ -526,6 +527,7 @@ test_files:
526
527
  - incompatibilities/spec/render/filters/escaped_spec.md
527
528
  - incompatibilities/spec/render/filters/javascript_spec.md
528
529
  - incompatibilities/spec/render/filters/markdown_spec.md
530
+ - incompatibilities/spec/render/filters/plain_spec.md
529
531
  - incompatibilities/spec/render/filters/preserve_spec.md
530
532
  - incompatibilities/spec/render/helpers_spec.md
531
533
  - incompatibilities/spec/render/indent_spec.md