hamlit 1.5.9 → 1.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/doc/README.md +15 -2
  4. data/doc/engine/indent.md +24 -0
  5. data/doc/engine/new_attribute.md +77 -0
  6. data/doc/engine/old_attributes.md +127 -0
  7. data/doc/engine/silent_script.md +97 -0
  8. data/doc/engine/tag.md +48 -0
  9. data/doc/engine/text.md +7 -1
  10. data/doc/faml/README.md +19 -0
  11. data/doc/faml/engine/indent.md +24 -0
  12. data/doc/faml/engine/old_attributes.md +108 -0
  13. data/doc/faml/engine/silent_script.md +97 -0
  14. data/doc/faml/engine/text.md +35 -0
  15. data/doc/faml/filters/coffee.md +125 -0
  16. data/doc/faml/filters/erb.md +24 -0
  17. data/doc/faml/filters/javascript.md +27 -0
  18. data/doc/faml/filters/less.md +57 -0
  19. data/doc/faml/filters/plain.md +25 -0
  20. data/doc/faml/filters/sass.md +62 -0
  21. data/doc/faml/filters/scss.md +68 -0
  22. data/doc/haml/README.md +15 -0
  23. data/doc/haml/engine/new_attribute.md +77 -0
  24. data/doc/haml/engine/old_attributes.md +142 -0
  25. data/doc/haml/engine/tag.md +48 -0
  26. data/doc/haml/engine/text.md +59 -0
  27. data/doc/haml/filters/erb.md +26 -0
  28. data/doc/haml/filters/javascript.md +76 -0
  29. data/doc/haml/filters/markdown.md +31 -0
  30. data/lib/hamlit/compilers/attributes.rb +1 -1
  31. data/lib/hamlit/compilers/new_attribute.rb +6 -6
  32. data/lib/hamlit/compilers/old_attribute.rb +2 -2
  33. data/lib/hamlit/compilers/text.rb +7 -10
  34. data/lib/hamlit/concerns/lexable.rb +32 -0
  35. data/lib/hamlit/parser.rb +9 -8
  36. data/lib/hamlit/parsers/attribute.rb +6 -3
  37. data/lib/hamlit/version.rb +1 -1
  38. data/spec/hamlit/engine/indent_spec.rb +1 -1
  39. data/spec/hamlit/engine/new_attribute_spec.rb +13 -2
  40. data/spec/hamlit/engine/old_attributes_spec.rb +5 -5
  41. data/spec/hamlit/engine/silent_script_spec.rb +4 -4
  42. data/spec/hamlit/engine/tag_spec.rb +23 -0
  43. data/spec/hamlit/engine/text_spec.rb +7 -3
  44. data/spec/spec_helper.rb +7 -231
  45. data/spec/spec_helper/document_generator.rb +93 -0
  46. data/spec/spec_helper/render_helper.rb +112 -0
  47. data/spec/spec_helper/test_case.rb +55 -0
  48. metadata +33 -3
  49. data/lib/hamlit/concerns/ripperable.rb +0 -20
@@ -0,0 +1,48 @@
1
+ # [tag\_spec.rb:271](/spec/hamlit/engine/tag_spec.rb#L271)
2
+ ## Input
3
+ ```haml
4
+ %div<
5
+ #{'hello'}
6
+ world
7
+
8
+ ```
9
+
10
+ ## Output
11
+ ### Haml
12
+ ```html
13
+ <div>helloworld</div>
14
+
15
+ ```
16
+
17
+ ### Hamlit
18
+ ```html
19
+ <div>hello
20
+ world</div>
21
+
22
+ ```
23
+
24
+
25
+ # [tag\_spec.rb:282](/spec/hamlit/engine/tag_spec.rb#L282)
26
+ ## Input
27
+ ```haml
28
+ .bar<
29
+ - 1.times do
30
+ = '1'
31
+ = '2'
32
+
33
+ ```
34
+
35
+ ## Output
36
+ ### Haml
37
+ ```html
38
+ <div class='bar'>12</div>
39
+
40
+ ```
41
+
42
+ ### Hamlit
43
+ ```html
44
+ <div class='bar'>1
45
+ 2</div>
46
+
47
+ ```
48
+
@@ -0,0 +1,59 @@
1
+ # [text\_spec.rb:15](/spec/hamlit/engine/text_spec.rb#L15)
2
+ ## Input
3
+ ```haml
4
+ .
5
+ .*
6
+ ..
7
+ #
8
+ #+
9
+ ##
10
+
11
+ ```
12
+
13
+ ## Output
14
+ ### Haml
15
+ ```html
16
+ Haml::SyntaxError: Illegal element: classes and ids must have values.
17
+ ```
18
+
19
+ ### Hamlit
20
+ ```html
21
+ .
22
+ .*
23
+ ..
24
+ #
25
+ #+
26
+ ##
27
+
28
+ ```
29
+
30
+
31
+ # [text\_spec.rb:118](/spec/hamlit/engine/text_spec.rb#L118)
32
+ ## Input
33
+ ```haml
34
+ &nbsp;
35
+ \&nbsp;
36
+ !hello
37
+ \!hello
38
+
39
+ ```
40
+
41
+ ## Output
42
+ ### Haml
43
+ ```html
44
+ &nbsp;
45
+ &nbsp;
46
+ !hello
47
+ !hello
48
+
49
+ ```
50
+
51
+ ### Hamlit
52
+ ```html
53
+ nbsp;
54
+ &nbsp;
55
+ hello
56
+ !hello
57
+
58
+ ```
59
+
@@ -0,0 +1,26 @@
1
+ # [erb\_spec.rb:3](/spec/hamlit/filters/erb_spec.rb#L3)
2
+ ## Input
3
+ ```haml
4
+ :erb
5
+ <% if true %>
6
+ ok
7
+ <% else %>
8
+ ng
9
+ <% end %>
10
+
11
+ ```
12
+
13
+ ## Output
14
+ ### Haml
15
+ ```html
16
+ ok
17
+
18
+
19
+ ```
20
+
21
+ ### Hamlit
22
+ ```html
23
+ ok
24
+
25
+ ```
26
+
@@ -0,0 +1,76 @@
1
+ # [javascript\_spec.rb:3](/spec/hamlit/filters/javascript_spec.rb#L3)
2
+ ## Input
3
+ ```haml
4
+ before
5
+ :javascript
6
+ after
7
+
8
+ ```
9
+
10
+ ## Output
11
+ ### Haml
12
+ ```html
13
+ before
14
+ <script>
15
+
16
+ </script>
17
+ after
18
+
19
+ ```
20
+
21
+ ### Hamlit
22
+ ```html
23
+ before
24
+ <script>
25
+
26
+ </script>
27
+ after
28
+
29
+ ```
30
+
31
+
32
+ # [javascript\_spec.rb:32](/spec/hamlit/filters/javascript_spec.rb#L32)
33
+ ## Input
34
+ ```haml
35
+ :javascript
36
+ if {
37
+ alert('hello');
38
+ }
39
+ :javascript
40
+ if {
41
+ alert('hello');
42
+ }
43
+
44
+ ```
45
+
46
+ ## Output
47
+ ### Haml
48
+ ```html
49
+ <script>
50
+ if {
51
+ alert('hello');
52
+ }
53
+ </script>
54
+ <script>
55
+ if {
56
+ alert('hello');
57
+ }
58
+ </script>
59
+
60
+ ```
61
+
62
+ ### Hamlit
63
+ ```html
64
+ <script>
65
+ if {
66
+ alert('hello');
67
+ }
68
+ </script>
69
+ <script>
70
+ if {
71
+ alert('hello');
72
+ }
73
+ </script>
74
+
75
+ ```
76
+
@@ -0,0 +1,31 @@
1
+ # [markdown\_spec.rb:15](/spec/hamlit/filters/markdown_spec.rb#L15)
2
+ ## Input
3
+ ```haml
4
+ - project = '<Hamlit>'
5
+ :markdown
6
+ # #{project}
7
+ #{'<&>'}
8
+ Yet another haml implementation
9
+
10
+ ```
11
+
12
+ ## Output
13
+ ### Haml
14
+ ```html
15
+ <h1><Hamlit></h1>
16
+
17
+ <p>&lt;&amp;&gt;
18
+ Yet another haml implementation</p>
19
+
20
+
21
+ ```
22
+
23
+ ### Hamlit
24
+ ```html
25
+ <h1><Hamlit></h1>
26
+
27
+ <p>&lt;&amp;&gt;
28
+ Yet another haml implementation</p>
29
+
30
+ ```
31
+
@@ -49,7 +49,7 @@ module Hamlit
49
49
  attrs = []
50
50
  exps.each do |exp|
51
51
  case exp
52
- when /\A\(.+\)\Z/
52
+ when /\A\(.+\)\Z/m
53
53
  attrs += compile_new_attribute(exp)
54
54
  when /\A{.+}\Z/
55
55
  attrs += compile_old_attribute(exp)
@@ -1,15 +1,15 @@
1
- require 'hamlit/concerns/ripperable'
1
+ require 'hamlit/concerns/lexable'
2
2
 
3
3
  # This module compiles new-style attributes, which is
4
4
  # surrounded by parentheses.
5
5
  module Hamlit
6
6
  module Compilers
7
7
  module NewAttribute
8
- include Concerns::Ripperable
8
+ include Concerns::Lexable
9
9
 
10
10
  def compile_new_attribute(str)
11
- str = str.gsub(/\A\(|\)\Z/, '')
12
- attrs = parse_new_attributes(str)
11
+ str = str.gsub(/\A\(|\)\Z/, '')
12
+ attrs = parse_new_attributes(str)
13
13
  attrs.map do |key, value|
14
14
  next true_attribute(key) if value == 'true'
15
15
  [:html, :attr, key, [:dynamic, value]]
@@ -34,7 +34,7 @@ module Hamlit
34
34
  token = tokens.first
35
35
  break unless token
36
36
 
37
- pos = token.first.last
37
+ pos = convert_position(str, *token.first)
38
38
  str = str[pos..-1]
39
39
  end
40
40
 
@@ -42,7 +42,7 @@ module Hamlit
42
42
  end
43
43
 
44
44
  def read_key!(tokens)
45
- skip_tokens!(tokens, :on_sp)
45
+ skip_tokens!(tokens, :on_sp, :on_nl, :on_ignored_nl)
46
46
  (row, col), type, key = tokens.shift
47
47
  key
48
48
  end
@@ -1,6 +1,6 @@
1
1
  require 'hamlit/concerns/attribute_builder'
2
2
  require 'hamlit/concerns/balanceable'
3
- require 'hamlit/concerns/ripperable'
3
+ require 'hamlit/concerns/lexable'
4
4
 
5
5
  # This module compiles only old-style attribute, which is
6
6
  # surrounded by brackets.
@@ -13,7 +13,7 @@ module Hamlit
13
13
  module OldAttribute
14
14
  include Concerns::AttributeBuilder
15
15
  include Concerns::Balanceable
16
- include Concerns::Ripperable
16
+ include Concerns::Lexable
17
17
 
18
18
  # Only data can be nested for performance.
19
19
  NESTABLE_ATTRIBUTES = %w[data].freeze
@@ -1,6 +1,7 @@
1
1
  require 'hamlit/concerns/error'
2
2
  require 'hamlit/concerns/escapable'
3
3
  require 'hamlit/concerns/included'
4
+ require 'hamlit/concerns/lexable'
4
5
  require 'hamlit/concerns/string_interpolation'
5
6
 
6
7
  module Hamlit
@@ -8,6 +9,7 @@ module Hamlit
8
9
  module Text
9
10
  extend Concerns::Included
10
11
  include Concerns::Error
12
+ include Concerns::Lexable
11
13
  include Concerns::StringInterpolation
12
14
 
13
15
  included do
@@ -51,11 +53,11 @@ module Hamlit
51
53
  Ripper.lex(literal).each do |(row, col), type, str|
52
54
  case type
53
55
  when :on_embexpr_beg
54
- open_pos = calc_position(exp, row, col, offset) if open_count == 0
56
+ open_pos = shifted_position(exp, row, col, offset) if open_count == 0
55
57
  open_count += 1
56
58
  when :on_embexpr_end
57
59
  open_count -= 1
58
- return [open_pos, calc_position(exp, row, col, offset)] if open_count == 0
60
+ return [open_pos, shifted_position(exp, row, col, offset)] if open_count == 0
59
61
  end
60
62
  open_count
61
63
  end
@@ -100,15 +102,10 @@ module Hamlit
100
102
  "%#{marker}#{exp}#{marker}"
101
103
  end
102
104
 
103
- def calc_position(exp, row, col, offset)
105
+ # In this compiler, only first line is shifted 2 chars.
106
+ def shifted_position(exp, row, col, offset)
104
107
  return col - offset if row <= 1
105
-
106
- pos = col
107
- lines = exp.split("\n")
108
- (0..(row - 2)).each do |row_index|
109
- pos += lines[row_index].bytesize + 1
110
- end
111
- pos
108
+ convert_position(exp, row, col)
112
109
  end
113
110
  end
114
111
  end
@@ -0,0 +1,32 @@
1
+ require 'ripper'
2
+
3
+ module Hamlit
4
+ module Concerns
5
+ module Lexable
6
+ TYPE_POSITION = 1
7
+
8
+ def skip_tokens!(tokens, *types)
9
+ while types.include?(type_of(tokens.first))
10
+ tokens.shift
11
+ end
12
+ end
13
+
14
+ def type_of(token)
15
+ return nil unless token
16
+ token[TYPE_POSITION]
17
+ end
18
+
19
+ # Convert ripper's position to StringScanner's one.
20
+ def convert_position(text, row, col)
21
+ return col if row <= 1
22
+
23
+ pos = col
24
+ lines = text.split("\n")
25
+ (0..(row - 2)).each do |row_index|
26
+ pos += lines[row_index].bytesize + 1
27
+ end
28
+ pos
29
+ end
30
+ end
31
+ end
32
+ end
@@ -76,7 +76,7 @@ module Hamlit
76
76
  return ast if ast
77
77
  end
78
78
 
79
- parse_inner_line(scanner)
79
+ parse_inner_line(scanner, inline: inline)
80
80
  end
81
81
 
82
82
  # Parse a line and return ast if it is acceptable outside an inline tag
@@ -100,20 +100,21 @@ module Hamlit
100
100
  end
101
101
 
102
102
  # Parse a line and return ast which is acceptable inside an inline tag
103
- def parse_inner_line(scanner)
103
+ def parse_inner_line(scanner, inline: false)
104
104
  return parse_text(scanner, lstrip: true) if scanner.scan(/==/)
105
- return parse_text(scanner, lstrip: true, escape: false) if scanner.scan(/!==/)
106
- return parse_text(scanner, lstrip: true, escape: true) if scanner.scan(/&==/)
105
+ return parse_text(scanner, lstrip: true, escape: false) if scanner.scan(/! |!==/)
106
+ return parse_text(scanner, lstrip: true, escape: true) if scanner.scan(/& |&==/)
107
107
  return parse_script(scanner, disable_escape: true) if scanner.match?(/!=/)
108
108
  return parse_script(scanner, force_escape: true) if scanner.match?(/&=/)
109
109
 
110
+ if inline
111
+ return parse_text(scanner, lstrip: true, escape: false) if scanner.scan(/!/)
112
+ return parse_text(scanner, lstrip: true, escape: true) if scanner.scan(/&/)
113
+ end
114
+
110
115
  case scanner.peek(1)
111
116
  when '=', '~'
112
117
  parse_script(scanner)
113
- when '!'
114
- parse_text(scanner, lstrip: true, escape: false, scan: /!/)
115
- when '&'
116
- parse_text(scanner, lstrip: true, escape: true, scan: /&/)
117
118
  else
118
119
  parse_text(scanner)
119
120
  end
@@ -1,10 +1,12 @@
1
1
  require 'ripper'
2
2
  require 'hamlit/concerns/balanceable'
3
+ require 'hamlit/concerns/lexable'
3
4
 
4
5
  module Hamlit
5
6
  module Parsers
6
7
  module Attribute
7
8
  include Concerns::Balanceable
9
+ include Concerns::Lexable
8
10
 
9
11
  EMBEXPR_PREFIX = '"#'.freeze
10
12
 
@@ -45,13 +47,14 @@ module Hamlit
45
47
  until balanced_parens_exist?(tokens)
46
48
  @current_lineno += 1
47
49
  break unless @lines[@current_lineno]
48
- scanner.concat(current_line)
50
+ scanner.concat("\n#{current_line}")
49
51
  tokens = Ripper.lex(scanner.rest)
50
52
  end
51
53
 
52
54
  tokens = fetch_balanced_parentheses(tokens)
53
- scanner.pos += tokens.last.first.last + 1
54
- [tokens.map(&:last).join]
55
+ text = tokens.map(&:last).join
56
+ scanner.pos += convert_position(text, *tokens.last.first) + 1
57
+ [text]
55
58
  end
56
59
 
57
60
  # Ripper.lex and reject tokens whose row is 0 (invalid).