faml 0.2.16 → 0.3.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.
@@ -35,11 +35,4 @@ HAML
35
35
  expect(render_string('%span!~ "<p>hello\n<pre>pre\nworld</pre></p>"')).to eq("<span><p>hello\n<pre>pre&#x000A;world</pre></p></span>\n")
36
36
  end
37
37
  end
38
-
39
- context 'without Ruby code' do
40
- it 'raises error' do
41
- expect { render_string('%span!=') }.to raise_error(Faml::SyntaxError)
42
- expect { render_string('!=') }.to raise_error(Faml::SyntaxError)
43
- end
44
- end
45
38
  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.2.16
4
+ version: 0.3.0
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-08-04 00:00:00.000000000 Z
11
+ date: 2015-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: escape_utils
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: haml_parser
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.1.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: parser
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -319,10 +333,8 @@ files:
319
333
  - incompatibilities/spec/render/silent_script_spec.md
320
334
  - incompatibilities/spec/render/unescape_spec.md
321
335
  - lib/faml.rb
322
- - lib/faml/ast.rb
323
336
  - lib/faml/cli.rb
324
337
  - lib/faml/compiler.rb
325
- - lib/faml/element_parser.rb
326
338
  - lib/faml/engine.rb
327
339
  - lib/faml/error.rb
328
340
  - lib/faml/filter_compilers.rb
@@ -339,21 +351,13 @@ files:
339
351
  - lib/faml/filter_compilers/sass.rb
340
352
  - lib/faml/filter_compilers/scss.rb
341
353
  - lib/faml/filter_compilers/tilt_base.rb
342
- - lib/faml/filter_parser.rb
343
354
  - lib/faml/helpers.rb
344
355
  - lib/faml/html.rb
345
- - lib/faml/indent_tracker.rb
346
- - lib/faml/line_parser.rb
347
356
  - lib/faml/newline.rb
348
- - lib/faml/parser.rb
349
- - lib/faml/parser_utils.rb
350
357
  - lib/faml/rails_handler.rb
351
358
  - lib/faml/rails_helpers.rb
352
359
  - lib/faml/railtie.rb
353
- - lib/faml/ruby_multiline.rb
354
- - lib/faml/script_parser.rb
355
360
  - lib/faml/static_hash_parser.rb
356
- - lib/faml/syntax_error.rb
357
361
  - lib/faml/text_compiler.rb
358
362
  - lib/faml/tilt.rb
359
363
  - lib/faml/version.rb
@@ -437,7 +441,6 @@ files:
437
441
  - spec/render/filters_spec.rb
438
442
  - spec/render/haml_comment_spec.rb
439
443
  - spec/render/helpers_spec.rb
440
- - spec/render/indent_spec.rb
441
444
  - spec/render/multiline_spec.rb
442
445
  - spec/render/newline_spec.rb
443
446
  - spec/render/plain_spec.rb
@@ -469,7 +472,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
469
472
  version: '0'
470
473
  requirements: []
471
474
  rubyforge_project:
472
- rubygems_version: 2.5.0
475
+ rubygems_version: 2.4.5.1
473
476
  signing_key:
474
477
  specification_version: 4
475
478
  summary: Faster implementation of Haml template language.
@@ -574,7 +577,6 @@ test_files:
574
577
  - spec/render/filters_spec.rb
575
578
  - spec/render/haml_comment_spec.rb
576
579
  - spec/render/helpers_spec.rb
577
- - spec/render/indent_spec.rb
578
580
  - spec/render/multiline_spec.rb
579
581
  - spec/render/newline_spec.rb
580
582
  - spec/render/plain_spec.rb
@@ -1,116 +0,0 @@
1
- module Faml
2
- module Ast
3
- module HasChildren
4
- def initialize(*)
5
- super
6
- self.children ||= []
7
- end
8
-
9
- def <<(ast)
10
- self.children << ast
11
- end
12
- end
13
-
14
- class Root < Struct.new(:children)
15
- include HasChildren
16
- end
17
-
18
- class Doctype < Struct.new(:doctype, :filename, :lineno)
19
- end
20
-
21
- class Element < Struct.new(
22
- :children,
23
- :tag_name,
24
- :static_class,
25
- :static_id,
26
- :attributes,
27
- :oneline_child,
28
- :self_closing,
29
- :nuke_inner_whitespace,
30
- :nuke_outer_whitespace,
31
- :filename,
32
- :lineno,
33
- )
34
- include HasChildren
35
-
36
- def initialize(*)
37
- super
38
- self.static_class ||= ''
39
- self.static_id ||= ''
40
- self.attributes ||= ''
41
- self.self_closing ||= false
42
- self.nuke_inner_whitespace ||= false
43
- self.nuke_outer_whitespace ||= false
44
- end
45
- end
46
-
47
- class Script < Struct.new(
48
- :children,
49
- :script,
50
- :escape_html,
51
- :preserve,
52
- :mid_block_keyword,
53
- :filename,
54
- :lineno,
55
- )
56
- include HasChildren
57
-
58
- def initialize(*)
59
- super
60
- if self.escape_html.nil?
61
- self.escape_html = true
62
- end
63
- if self.preserve.nil?
64
- self.preserve = false
65
- end
66
- if self.mid_block_keyword.nil?
67
- self.mid_block_keyword = false
68
- end
69
- end
70
- end
71
-
72
- class SilentScript < Struct.new(:children, :script, :mid_block_keyword, :filename, :lineno)
73
- include HasChildren
74
-
75
- def initialize(*)
76
- super
77
- if self.mid_block_keyword.nil?
78
- self.mid_block_keyword = false
79
- end
80
- end
81
- end
82
-
83
- class HtmlComment < Struct.new(:children, :comment, :conditional, :filename, :lineno)
84
- include HasChildren
85
-
86
- def initialize(*)
87
- super
88
- self.comment ||= ''
89
- self.conditional ||= ''
90
- end
91
- end
92
-
93
- class HamlComment < Struct.new(:children, :filename, :lineno)
94
- include HasChildren
95
- end
96
-
97
- class Text < Struct.new(:text, :escape_html, :filename, :lineno)
98
- def initialize(*)
99
- super
100
- if self.escape_html.nil?
101
- self.escape_html = true
102
- end
103
- end
104
- end
105
-
106
- class Filter < Struct.new(:name, :texts, :filename, :lineno)
107
- def initialize(*)
108
- super
109
- self.texts ||= []
110
- end
111
- end
112
-
113
- class Empty < Struct.new(:filename, :lineno)
114
- end
115
- end
116
- end
@@ -1,235 +0,0 @@
1
- require 'strscan'
2
- require 'faml/ast'
3
- require 'faml/parser_utils'
4
- require 'faml/ruby_multiline'
5
- require 'faml/script_parser'
6
- require 'faml/syntax_error'
7
-
8
- module Faml
9
- class ElementParser
10
- def initialize(line_parser)
11
- @line_parser = line_parser
12
- end
13
-
14
- ELEMENT_REGEXP = /\A%([-:\w]+)([-:\w.#]*)(.+)?\z/o
15
-
16
- def parse(text)
17
- m = text.match(ELEMENT_REGEXP)
18
- unless m
19
- syntax_error!('Invalid element declaration')
20
- end
21
-
22
- element = Ast::Element.new
23
- element.filename = @line_parser.filename
24
- element.lineno = @line_parser.lineno
25
- element.tag_name = m[1]
26
- element.static_class, element.static_id = parse_class_and_id(m[2])
27
- rest = m[3] || ''
28
-
29
- element.attributes, rest = parse_attributes(rest)
30
- element.nuke_inner_whitespace, element.nuke_outer_whitespace, rest = parse_nuke_whitespace(rest)
31
- element.self_closing, rest = parse_self_closing(rest)
32
- element.oneline_child = ScriptParser.new(@line_parser).parse(rest)
33
-
34
- element
35
- end
36
-
37
- private
38
-
39
- def parse_class_and_id(class_and_id)
40
- classes = []
41
- id = ''
42
- scanner = StringScanner.new(class_and_id)
43
- until scanner.eos?
44
- unless scanner.scan(/([#.])([-:_a-zA-Z0-9]+)/)
45
- syntax_error!('Illegal element: classes and ids must have values.')
46
- end
47
- case scanner[1]
48
- when '.'
49
- classes << scanner[2]
50
- when '#'
51
- id = scanner[2]
52
- end
53
- end
54
-
55
- [classes.join(' '), id]
56
- end
57
-
58
- OLD_ATTRIBUTE_BEGIN = '{'
59
- NEW_ATTRIBUTE_BEGIN = '('
60
-
61
- def parse_attributes(rest)
62
- old_attributes = ''
63
- new_attributes = ''
64
-
65
- loop do
66
- case rest[0]
67
- when OLD_ATTRIBUTE_BEGIN
68
- unless old_attributes.empty?
69
- break
70
- end
71
- old_attributes, rest = parse_old_attributes(rest)
72
- when NEW_ATTRIBUTE_BEGIN
73
- unless new_attributes.empty?
74
- break
75
- end
76
- new_attributes, rest = parse_new_attributes(rest)
77
- else
78
- break
79
- end
80
- end
81
-
82
- attributes = old_attributes
83
- unless new_attributes.empty?
84
- if attributes.empty?
85
- attributes = new_attributes
86
- else
87
- attributes << ", " << new_attributes
88
- end
89
- end
90
- [attributes, rest]
91
- end
92
-
93
- def parse_old_attributes(text)
94
- text = text.dup
95
- s = StringScanner.new(text)
96
- s.pos = 1
97
- depth = 1
98
- loop do
99
- depth = ParserUtils.balance(s, '{', '}', depth)
100
- if depth == 0
101
- attr = s.pre_match + s.matched
102
- return [attr[1, attr.size-2], s.rest]
103
- else
104
- if /,\s*\z/ === text && @line_parser.has_next?
105
- text << "\n" << @line_parser.next_line
106
- else
107
- syntax_error!('Unmatched brace')
108
- end
109
- end
110
- end
111
- end
112
-
113
- def parse_new_attributes(text)
114
- text = text.dup
115
- s = StringScanner.new(text)
116
- s.pos = 1
117
- depth = 1
118
- loop do
119
- pre_pos = s.pos
120
- depth = ParserUtils.balance(s, '(', ')', depth)
121
- if depth == 0
122
- t = s.string.byteslice(pre_pos ... s.pos-1)
123
- return [parse_new_attribute_list(t), s.rest]
124
- else
125
- if @line_parser.has_next?
126
- text << "\n" << @line_parser.next_line
127
- else
128
- syntax_error!('Unmatched paren')
129
- end
130
- end
131
- end
132
- end
133
-
134
- def parse_new_attribute_list(text)
135
- s = StringScanner.new(text)
136
- attributes = []
137
- until s.eos?
138
- name = scan_key(s)
139
- s.skip(/\s*/)
140
-
141
- if scan_operator(s)
142
- s.skip(/\s*/)
143
- value = scan_value(s)
144
- else
145
- value = 'true'
146
- end
147
- spaces = s.scan(/\s*/)
148
- line_count = spaces.count("\n")
149
-
150
- attributes << "#{name.inspect} => #{value},#{"\n" * line_count}"
151
- end
152
- attributes.join
153
- end
154
-
155
- def scan_key(scanner)
156
- scanner.scan(/[-:\w]+/).tap do |name|
157
- unless name
158
- syntax_error!('Invalid attribute list (missing attribute name)')
159
- end
160
- end
161
- end
162
-
163
- def scan_operator(scanner)
164
- scanner.skip(/=/)
165
- end
166
-
167
- def scan_value(scanner)
168
- if quote = scanner.scan(/["']/)
169
- scan_quoted_value(scanner, quote)
170
- else
171
- scan_variable_value(scanner)
172
- end
173
- end
174
-
175
- def scan_quoted_value(scanner, quote)
176
- re = /((?:\\.|\#(?!\{)|[^#{quote}\\#])*)(#{quote}|#\{)/
177
- pos = scanner.pos
178
- loop do
179
- unless scanner.scan(re)
180
- syntax_error!('Invalid attribute list (mismatched quotation)')
181
- end
182
- if scanner[2] == quote
183
- break
184
- end
185
- depth = ParserUtils.balance(scanner, '{', '}')
186
- if depth != 0
187
- syntax_error!('Invalid attribute list (mismatched interpolation)')
188
- end
189
- end
190
- str = scanner.string.byteslice(pos-1 .. scanner.pos-1)
191
-
192
- # Even if the quote is single, string interpolation is performed in Haml.
193
- str[0] = '"'
194
- str[-1] = '"'
195
- str
196
- end
197
-
198
- def scan_variable_value(scanner)
199
- scanner.scan(/(@@?|\$)?\w+/).tap do |var|
200
- unless var
201
- syntax_error!('Invalid attribute list (invalid variable name)')
202
- end
203
- end
204
- end
205
-
206
- def parse_nuke_whitespace(rest)
207
- m = rest.match(/\A(><|<>|[><])(.*)\z/)
208
- if m
209
- nuke_whitespace = m[1]
210
- [
211
- nuke_whitespace.include?('<'),
212
- nuke_whitespace.include?('>'),
213
- m[2],
214
- ]
215
- else
216
- [false, false, rest]
217
- end
218
- end
219
-
220
- def parse_self_closing(rest)
221
- if rest[0] == '/'
222
- if rest.size > 1
223
- syntax_error!("Self-closing tags can't have content")
224
- end
225
- [true, '']
226
- else
227
- [false, rest]
228
- end
229
- end
230
-
231
- def syntax_error!(message)
232
- raise SyntaxError.new(message, @line_parser.lineno)
233
- end
234
- end
235
- end