faml 0.2.16 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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