bade 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Bade.gemspec +9 -7
- data/Gemfile +12 -3
- data/README.md +3 -3
- data/lib/bade/ast/document.rb +1 -1
- data/lib/bade/ast/node/mixin_node.rb +3 -3
- data/lib/bade/ast/node/static_text_node.rb +4 -2
- data/lib/bade/ast/node/value_node.rb +14 -3
- data/lib/bade/ast/node.rb +12 -3
- data/lib/bade/ast/node_registrator.rb +3 -2
- data/lib/bade/ast/string_serializer.rb +3 -5
- data/lib/bade/generator.rb +75 -25
- data/lib/bade/parser/parser_constants.rb +4 -4
- data/lib/bade/parser/parser_lines.rb +21 -19
- data/lib/bade/parser/parser_mixin.rb +17 -11
- data/lib/bade/parser/parser_ruby_code.rb +17 -7
- data/lib/bade/parser/parser_tag.rb +4 -4
- data/lib/bade/parser/parser_text.rb +3 -3
- data/lib/bade/parser.rb +7 -3
- data/lib/bade/precompiled.rb +6 -3
- data/lib/bade/renderer.rb +69 -20
- data/lib/bade/ruby2_keywords.rb +3 -0
- data/lib/bade/ruby_extensions/string.rb +4 -8
- data/lib/bade/runtime/block.rb +51 -11
- data/lib/bade/runtime/globals_tracker.rb +59 -0
- data/lib/bade/runtime/mixin.rb +47 -32
- data/lib/bade/runtime/render_binding.rb +56 -13
- data/lib/bade/runtime.rb +79 -1
- data/lib/bade/version.rb +1 -1
- data/lib/bade.rb +1 -0
- metadata +32 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 202b283306b0a05d870766ff8d7c17f8312727843632958adb2bb3f2300a673f
|
4
|
+
data.tar.gz: '0820f4f77eb7936b77748257faa1fd4ee51b206d4a7929c656f717127c7b2248'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ecd2dbf7aa570c8051a2e1b59a1a537583cd2cd5005bb06328795de099fab4213a9cfd616a788d66e333a862253d6aecedd928632e3edb923f021e86658f6780
|
7
|
+
data.tar.gz: 8633aba2120eaf8f60f96a357cde8eda8c32d862e92dca3c060f66c014bf1031e5bc2916077ee1d1a7de6494cc62c426ded062065c664949acaf849fce71de66
|
data/Bade.gemspec
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
lib = File.expand_path('
|
4
|
+
lib = File.expand_path('lib', __dir__)
|
4
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
6
|
|
6
7
|
require 'bade/version'
|
7
8
|
|
8
|
-
|
9
9
|
Gem::Specification.new do |spec|
|
10
10
|
spec.name = 'bade'
|
11
11
|
spec.version = Bade::VERSION
|
@@ -14,15 +14,17 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.summary = 'Minimalistic template engine for Ruby.'
|
15
15
|
spec.homepage = 'https://github.com/epuber-io/bade'
|
16
16
|
spec.license = 'MIT'
|
17
|
-
spec.
|
17
|
+
spec.metadata = { 'rubygems_mfa_required' => 'true' }
|
18
|
+
spec.required_ruby_version = '>= 2.5'
|
18
19
|
|
19
|
-
spec.files = Dir['bin/**/*'] + Dir['lib/**/*'] + %w
|
20
|
+
spec.files = Dir['bin/**/*'] + Dir['lib/**/*'] + %w[Bade.gemspec Gemfile README.md]
|
20
21
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
22
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
22
23
|
spec.require_paths = ['lib']
|
23
24
|
|
24
|
-
spec.
|
25
|
+
spec.add_dependency 'psych', '>= 2.2', '< 5.0'
|
26
|
+
|
27
|
+
spec.add_development_dependency 'fakefs', '~> 1.3'
|
25
28
|
spec.add_development_dependency 'rspec', '~> 3.2'
|
26
|
-
spec.add_development_dependency '
|
27
|
-
spec.add_development_dependency 'rubocop', '~> 0.35'
|
29
|
+
spec.add_development_dependency 'rubocop', '~> 1.14'
|
28
30
|
end
|
data/Gemfile
CHANGED
@@ -1,8 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source 'https://rubygems.org'
|
2
4
|
|
3
5
|
gemspec
|
4
6
|
|
5
|
-
gem 'coveralls', require: false
|
6
7
|
gem 'benchmark-ips', require: false
|
7
|
-
|
8
|
-
|
8
|
+
|
9
|
+
group :dev, optional: true do
|
10
|
+
gem 'debase', require: false
|
11
|
+
gem 'ruby-debug-ide', require: false
|
12
|
+
end
|
13
|
+
|
14
|
+
group :benchmarks, optional: true do
|
15
|
+
gem 'flamegraph'
|
16
|
+
gem 'ruby-prof'
|
17
|
+
end
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
# Bade
|
3
3
|
|
4
|
-
[![Gem Version](https://badge.fury.io/rb/bade.svg)](http://badge.fury.io/rb/bade) [![Build Status](https://
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/bade.svg)](http://badge.fury.io/rb/bade) [![Build Status](https://github.com/epuber-io/bade/actions/workflows/tests.yml/badge.svg)](https://github.com/epuber-io/bade/actions) [![Coverage Status](https://coveralls.io/repos/epuber-io/bade/badge.svg?branch=master&service=github)](https://coveralls.io/github/epuber-io/bade?branch=master) [![Inline docs](https://inch-ci.org/github/epuber-io/bade.svg?branch=master)](https://inch-ci.org/github/epuber-io/bade)
|
5
5
|
|
6
6
|
|
7
7
|
Minimalistic template engine written in Ruby for Ruby. Developed mainly to help with creating e-books. Highly influenced by [Jade](http://jade-lang.com) and [Slim](http://slim-lang.com).
|
@@ -30,7 +30,7 @@ Or install it yourself as:
|
|
30
30
|
|
31
31
|
## Development
|
32
32
|
|
33
|
-
After checking out the repo, run `bundle install` to install dependencies. Then, run `rake spec` to run the tests.
|
33
|
+
After checking out the repo, run `bundle install --with dev` to install dependencies. Then, run `rake spec` to run the tests.
|
34
34
|
|
35
35
|
To install this gem onto your local machine, run `bundle exec rake install`.
|
36
36
|
|
@@ -40,7 +40,7 @@ To install this gem onto your local machine, run `bundle exec rake install`.
|
|
40
40
|
Bug reports and pull requests are welcome on GitHub at https://github.com/epuber-io/bade. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
|
41
41
|
|
42
42
|
|
43
|
-
##
|
43
|
+
## TODO
|
44
44
|
|
45
45
|
- [ ] create documentation about syntax
|
46
46
|
- [ ] create several examples
|
data/lib/bade/ast/document.rb
CHANGED
@@ -22,19 +22,19 @@ module Bade
|
|
22
22
|
|
23
23
|
class MixinDeclarationNode < MixinCommonNode
|
24
24
|
def allowed_parameter_types
|
25
|
-
[
|
25
|
+
%i[mixin_param mixin_key_param mixin_block_param]
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
class MixinBlockNode < MixinCommonNode
|
30
30
|
def allowed_parameter_types
|
31
|
-
[
|
31
|
+
%i[mixin_param mixin_key_param]
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
35
|
class MixinCallNode < MixinCommonNode
|
36
36
|
def allowed_parameter_types
|
37
|
-
[
|
37
|
+
%i[mixin_param mixin_key_param]
|
38
38
|
end
|
39
39
|
|
40
40
|
def blocks
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../../ruby2_keywords'
|
4
|
+
|
3
5
|
module Bade
|
4
6
|
module AST
|
5
7
|
class StaticTextNode < Node
|
@@ -11,8 +13,8 @@ module Bade
|
|
11
13
|
#
|
12
14
|
attr_accessor :escaped
|
13
15
|
|
14
|
-
def initialize(*args)
|
15
|
-
super
|
16
|
+
ruby2_keywords def initialize(*args)
|
17
|
+
super(*args)
|
16
18
|
|
17
19
|
@escaped = false
|
18
20
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../../ruby2_keywords'
|
4
|
+
|
3
5
|
module Bade
|
4
6
|
module AST
|
5
7
|
class ValueNode < Node
|
@@ -15,17 +17,26 @@ module Bade
|
|
15
17
|
#
|
16
18
|
attr_accessor :conditional
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
+
# @return [String, nil]
|
21
|
+
#
|
22
|
+
attr_accessor :default_value
|
23
|
+
|
24
|
+
ruby2_keywords def initialize(*args)
|
25
|
+
super(*args)
|
20
26
|
|
21
27
|
@escaped = false
|
22
28
|
@conditional = false
|
29
|
+
@default_value = nil
|
23
30
|
end
|
24
31
|
|
25
32
|
# @param [ValueNode] other
|
26
33
|
#
|
27
34
|
def ==(other)
|
28
|
-
super &&
|
35
|
+
super &&
|
36
|
+
value == other.value &&
|
37
|
+
escaped == other.escaped &&
|
38
|
+
conditional == other.conditional &&
|
39
|
+
default_value == other.default_value
|
29
40
|
end
|
30
41
|
end
|
31
42
|
end
|
data/lib/bade/ast/node.rb
CHANGED
@@ -10,7 +10,11 @@ module Bade
|
|
10
10
|
#
|
11
11
|
attr_reader :type
|
12
12
|
|
13
|
-
# @return [
|
13
|
+
# @return [Bade::AST::Node, nil]
|
14
|
+
#
|
15
|
+
attr_accessor :parent
|
16
|
+
|
17
|
+
# @return [Array<Bade::AST::Node>]
|
14
18
|
#
|
15
19
|
attr_accessor :children
|
16
20
|
|
@@ -20,11 +24,16 @@ module Bade
|
|
20
24
|
#
|
21
25
|
attr_reader :lineno
|
22
26
|
|
23
|
-
|
27
|
+
# @return [String] filename
|
28
|
+
#
|
29
|
+
attr_reader :filename
|
30
|
+
|
31
|
+
def initialize(type, parent = nil, lineno: nil, filename: nil)
|
24
32
|
@type = type
|
33
|
+
@parent = parent
|
25
34
|
@children = []
|
26
|
-
|
27
35
|
@lineno = lineno
|
36
|
+
@filename = filename
|
28
37
|
end
|
29
38
|
|
30
39
|
def to_s
|
@@ -38,12 +38,12 @@ module Bade
|
|
38
38
|
#
|
39
39
|
# @return [Bade::AST::Node]
|
40
40
|
#
|
41
|
-
def create(type, lineno)
|
41
|
+
def create(type, parent, lineno: nil, filename: nil)
|
42
42
|
klass = registered_types[type]
|
43
43
|
|
44
44
|
raise ::KeyError, "Undefined node type #{type.inspect}" if klass.nil?
|
45
45
|
|
46
|
-
klass.new(type, lineno: lineno)
|
46
|
+
klass.new(type, parent, lineno: lineno, filename: filename)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -55,6 +55,7 @@ module Bade
|
|
55
55
|
register_type DoctypeNode, :doctype
|
56
56
|
|
57
57
|
register_type ValueNode, :import
|
58
|
+
register_type ValueNode, :yield
|
58
59
|
|
59
60
|
# --- Comments
|
60
61
|
|
@@ -37,13 +37,13 @@ module Bade
|
|
37
37
|
|
38
38
|
children_s = ''
|
39
39
|
if node.children.count > 0
|
40
|
-
children_s = "\n
|
40
|
+
children_s = "\n#{node.children.map { |n| node_to_s(n, level + 1) }.join("\n")}\n#{indent}"
|
41
41
|
end
|
42
42
|
|
43
43
|
other = ''
|
44
44
|
|
45
45
|
case node
|
46
|
-
when TagNode
|
46
|
+
when TagNode, MixinCommonNode
|
47
47
|
other = node.name
|
48
48
|
when KeyValueNode
|
49
49
|
other = "#{node.name}:#{node.value}"
|
@@ -56,15 +56,13 @@ module Bade
|
|
56
56
|
''
|
57
57
|
end
|
58
58
|
other = "#{escaped_sign}#{node.value}"
|
59
|
-
when MixinCommonNode
|
60
|
-
other = node.name
|
61
59
|
when Node
|
62
60
|
# nothing
|
63
61
|
else
|
64
62
|
raise "Unknown node class #{node.class} of type #{node.type} for serializing"
|
65
63
|
end
|
66
64
|
|
67
|
-
other =
|
65
|
+
other = " #{other}" if other && !other.empty?
|
68
66
|
|
69
67
|
"#{indent}(#{type_s}#{other}#{children_s})"
|
70
68
|
end
|
data/lib/bade/generator.rb
CHANGED
@@ -66,7 +66,7 @@ module Bade
|
|
66
66
|
# @param [String] text
|
67
67
|
#
|
68
68
|
def buff_print_static_text(text)
|
69
|
-
buff_print_value("'#{text.gsub("'", "
|
69
|
+
buff_print_value("'#{text.gsub("'", "\\\\'")}'") unless text.empty?
|
70
70
|
end
|
71
71
|
|
72
72
|
def buff_print_value(value)
|
@@ -75,10 +75,9 @@ module Bade
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def buff_code(text)
|
78
|
-
@buff << ' ' * @code_indent
|
78
|
+
@buff << "#{' ' * @code_indent}#{text}"
|
79
79
|
end
|
80
80
|
|
81
|
-
|
82
81
|
# @param document [Bade::Document]
|
83
82
|
#
|
84
83
|
def visit_document(document)
|
@@ -87,6 +86,7 @@ module Bade
|
|
87
86
|
end
|
88
87
|
|
89
88
|
buff_code("# ----- start file #{document.file_path}") unless document.file_path.nil?
|
89
|
+
buff_code "__buffs_push(#{location(filename: document.file_path, lineno: 0, label: '<top>')})"
|
90
90
|
|
91
91
|
new_root = if @optimize
|
92
92
|
Optimizer.new(document.root).optimize
|
@@ -116,6 +116,8 @@ module Bade
|
|
116
116
|
# @param current_node [Node]
|
117
117
|
#
|
118
118
|
def visit_node(current_node)
|
119
|
+
update_location_node(current_node)
|
120
|
+
|
119
121
|
case current_node.type
|
120
122
|
when :root
|
121
123
|
visit_node_children(current_node)
|
@@ -135,7 +137,7 @@ module Bade
|
|
135
137
|
buff_print_text ' -->'
|
136
138
|
|
137
139
|
when :comment
|
138
|
-
comment_text =
|
140
|
+
comment_text = "##{current_node.children.map(&:value).join("\n#")}"
|
139
141
|
buff_code(comment_text)
|
140
142
|
|
141
143
|
when :doctype
|
@@ -158,8 +160,7 @@ module Bade
|
|
158
160
|
buff_print_text output_code
|
159
161
|
|
160
162
|
when :newline
|
161
|
-
#
|
162
|
-
|
163
|
+
# no-op
|
163
164
|
when :import
|
164
165
|
base_path = File.expand_path(current_node.value, File.dirname(@document.file_path))
|
165
166
|
load_path = if base_path.end_with?('.rb') && File.exist?(base_path)
|
@@ -168,8 +169,11 @@ module Bade
|
|
168
169
|
"#{base_path}.rb"
|
169
170
|
end
|
170
171
|
|
171
|
-
buff_code "
|
172
|
-
|
172
|
+
buff_code "__load('#{load_path}')" unless load_path.nil?
|
173
|
+
when :yield
|
174
|
+
block_name = DEFAULT_BLOCK_NAME
|
175
|
+
method = current_node.conditional ? 'call' : 'call!'
|
176
|
+
buff_code "#{block_name}.#{method}"
|
173
177
|
else
|
174
178
|
raise "Unknown type #{current_node.type}"
|
175
179
|
end
|
@@ -269,19 +273,22 @@ module Bade
|
|
269
273
|
params = mixin_node.params
|
270
274
|
result = []
|
271
275
|
|
272
|
-
|
276
|
+
case mixin_node.type
|
277
|
+
when :mixin_call
|
273
278
|
blocks = mixin_node.blocks
|
274
279
|
|
275
280
|
other_children = (mixin_node.children - mixin_node.blocks - mixin_node.params)
|
276
281
|
if other_children.count { |n| n.type != :newline } > 0
|
277
|
-
def_block_node = AST::NodeRegistrator.create(:mixin_block, mixin_node.lineno)
|
282
|
+
def_block_node = AST::NodeRegistrator.create(:mixin_block, mixin_node, lineno: mixin_node.lineno)
|
278
283
|
def_block_node.name = DEFAULT_BLOCK_NAME
|
279
284
|
def_block_node.children = other_children
|
280
285
|
|
281
286
|
blocks << def_block_node
|
282
287
|
end
|
283
288
|
|
284
|
-
if
|
289
|
+
if blocks.empty?
|
290
|
+
result << '{}'
|
291
|
+
else
|
285
292
|
buff_code '__blocks = {}'
|
286
293
|
|
287
294
|
blocks.each do |block|
|
@@ -289,17 +296,18 @@ module Bade
|
|
289
296
|
end
|
290
297
|
|
291
298
|
result << '__blocks.dup'
|
292
|
-
else
|
293
|
-
result << '{}'
|
294
299
|
end
|
295
|
-
|
300
|
+
when :mixin_decl
|
296
301
|
result << '__blocks'
|
297
302
|
end
|
298
303
|
|
304
|
+
# positional params
|
305
|
+
result += params.select { |n| n.type == :mixin_param }
|
306
|
+
.map { |param| param.default_value ? "#{param.value} = #{param.default_value}" : param.value }
|
299
307
|
|
300
|
-
#
|
301
|
-
result += params.select { |n| n.type == :
|
302
|
-
|
308
|
+
# key-value params
|
309
|
+
result += params.select { |n| n.type == :mixin_key_param }
|
310
|
+
.map { |param| "#{param.name}: #{param.value}" }
|
303
311
|
|
304
312
|
result.join(', ')
|
305
313
|
end
|
@@ -311,14 +319,10 @@ module Bade
|
|
311
319
|
# @return [nil]
|
312
320
|
#
|
313
321
|
def block_definition(block_node)
|
314
|
-
buff_code "__blocks['#{block_node.name}'] = __create_block('#{block_node.name}') do"
|
322
|
+
buff_code "__blocks['#{block_node.name}'] = __create_block('#{block_node.name}', #{location_node(block_node)}) do"
|
315
323
|
|
316
324
|
code_indent do
|
317
|
-
buff_code '__buffs_push()'
|
318
|
-
|
319
325
|
visit_node_children(block_node)
|
320
|
-
|
321
|
-
buff_code '__buffs_pop()'
|
322
326
|
end
|
323
327
|
|
324
328
|
buff_code 'end'
|
@@ -352,7 +356,7 @@ module Bade
|
|
352
356
|
#
|
353
357
|
def visit_block_decl(current_node)
|
354
358
|
params = formatted_mixin_params(current_node)
|
355
|
-
buff_code "#{MIXINS_NAME}['#{current_node.name}'] = __create_mixin('#{current_node.name}', &lambda { |#{params}|"
|
359
|
+
buff_code "#{MIXINS_NAME}['#{current_node.name}'] = __create_mixin('#{current_node.name}', #{location_node(current_node)}, &lambda { |#{params}|"
|
356
360
|
|
357
361
|
code_indent do
|
358
362
|
blocks_name_declaration(current_node)
|
@@ -362,8 +366,6 @@ module Bade
|
|
362
366
|
buff_code '})'
|
363
367
|
end
|
364
368
|
|
365
|
-
|
366
|
-
|
367
369
|
# @param [String] str
|
368
370
|
#
|
369
371
|
# @return [Void]
|
@@ -371,6 +373,54 @@ module Bade
|
|
371
373
|
def escape_double_quotes!(str)
|
372
374
|
str.gsub!(/"/, '\"')
|
373
375
|
end
|
376
|
+
|
377
|
+
# @param [Bade::AST::Node]
|
378
|
+
# @return [Void]
|
379
|
+
def update_location_node(node)
|
380
|
+
should_skip = case node.type
|
381
|
+
when :code
|
382
|
+
value = node.value.strip
|
383
|
+
|
384
|
+
%w[end else }].include?(value) || value.match(/^when /)
|
385
|
+
when :newline
|
386
|
+
true
|
387
|
+
else
|
388
|
+
false
|
389
|
+
end
|
390
|
+
return if should_skip
|
391
|
+
return if node.lineno.nil?
|
392
|
+
|
393
|
+
buff_code "__update_lineno(#{node.lineno})"
|
394
|
+
end
|
395
|
+
|
396
|
+
# @param [String] filename
|
397
|
+
# @param [Fixnum] lineno
|
398
|
+
# @param [String] label
|
399
|
+
# @return [String]
|
400
|
+
def location(filename:, lineno:, label:)
|
401
|
+
args = [
|
402
|
+
filename ? "path: '#{filename}'" : nil,
|
403
|
+
"lineno: #{lineno}",
|
404
|
+
"label: '#{label}'",
|
405
|
+
].compact
|
406
|
+
|
407
|
+
"Location.new(#{args.join(',')})"
|
408
|
+
end
|
409
|
+
|
410
|
+
# @param [Node] node
|
411
|
+
# @return [String]
|
412
|
+
def location_node(node)
|
413
|
+
label = case node.type
|
414
|
+
when :mixin_decl
|
415
|
+
"+#{node.name}"
|
416
|
+
when :mixin_block
|
417
|
+
"#{node.name} in +#{node.parent.name}"
|
418
|
+
else
|
419
|
+
node.name
|
420
|
+
end
|
421
|
+
|
422
|
+
location(filename: node.filename, lineno: node.lineno, label: label)
|
423
|
+
end
|
374
424
|
end
|
375
425
|
|
376
426
|
# backward compatibility
|
@@ -9,10 +9,10 @@ module Bade
|
|
9
9
|
NAME_RE_STRING = "(#{WORD_RE}(?:#{WORD_RE}|:|-|_)*)".freeze
|
10
10
|
|
11
11
|
ATTR_NAME_RE_STRING = "\\A\\s*#{NAME_RE_STRING}".freeze
|
12
|
-
CODE_ATTR_RE = /#{ATTR_NAME_RE_STRING}\s*&?:\s
|
12
|
+
CODE_ATTR_RE = /#{ATTR_NAME_RE_STRING}\s*&?:\s*/.freeze
|
13
13
|
|
14
|
-
TAG_RE = /\A#{NAME_RE_STRING}
|
15
|
-
CLASS_TAG_RE = /\A\.#{NAME_RE_STRING}
|
16
|
-
ID_TAG_RE = /\A##{NAME_RE_STRING}
|
14
|
+
TAG_RE = /\A#{NAME_RE_STRING}/.freeze
|
15
|
+
CLASS_TAG_RE = /\A\.#{NAME_RE_STRING}/.freeze
|
16
|
+
ID_TAG_RE = /\A##{NAME_RE_STRING}/.freeze
|
17
17
|
end
|
18
18
|
end
|
@@ -6,19 +6,20 @@ module Bade
|
|
6
6
|
|
7
7
|
class Parser
|
8
8
|
module LineIndicatorRegexps
|
9
|
-
IMPORT = /\Aimport
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
9
|
+
IMPORT = /\Aimport /.freeze
|
10
|
+
YIELD = /\Ayield(!?)/.freeze
|
11
|
+
MIXIN_DECL = /\Amixin #{NAME_RE_STRING}/.freeze
|
12
|
+
MIXIN_CALL = /\A\+#{NAME_RE_STRING}/.freeze
|
13
|
+
BLOCK_DECLARATION = /\Ablock #{NAME_RE_STRING}/.freeze
|
14
|
+
HTML_COMMENT = %r{\A//! }.freeze
|
15
|
+
NORMAL_COMMENT = %r{\A//}.freeze
|
16
|
+
TEXT_BLOCK_START = /\A\|( ?)/.freeze
|
17
|
+
INLINE_HTML = /\A</.freeze
|
18
|
+
CODE_BLOCK = /\A-/.freeze
|
19
|
+
OUTPUT_BLOCK = /\A(\??)(&?)=/.freeze
|
20
|
+
DOCTYPE = /\Adoctype\s/i.freeze
|
21
|
+
TAG_CLASS_START_BLOCK = /\A\./.freeze
|
22
|
+
TAG_ID_START_BLOCK = /\A#/.freeze
|
22
23
|
end
|
23
24
|
|
24
25
|
def reset(lines = nil, stacks = nil)
|
@@ -135,6 +136,11 @@ module Bade
|
|
135
136
|
@line = $'
|
136
137
|
parse_import
|
137
138
|
|
139
|
+
when LineIndicatorRegexps::YIELD
|
140
|
+
@line = $'
|
141
|
+
node = append_node(:yield, add: true)
|
142
|
+
node.conditional = $1.nil?
|
143
|
+
|
138
144
|
when LineIndicatorRegexps::MIXIN_DECL
|
139
145
|
# Mixin declaration
|
140
146
|
@line = $'
|
@@ -195,12 +201,8 @@ module Bade
|
|
195
201
|
@line = $' if $1
|
196
202
|
parse_tag($&)
|
197
203
|
|
198
|
-
when LineIndicatorRegexps::TAG_CLASS_START_BLOCK
|
199
|
-
# Found class
|
200
|
-
parse_tag 'div'
|
201
|
-
|
202
|
-
when LineIndicatorRegexps::TAG_ID_START_BLOCK
|
203
|
-
# Found id name -> implicit div
|
204
|
+
when LineIndicatorRegexps::TAG_CLASS_START_BLOCK, LineIndicatorRegexps::TAG_ID_START_BLOCK
|
205
|
+
# Found a class or id selector.
|
204
206
|
parse_tag 'div'
|
205
207
|
|
206
208
|
else
|
@@ -6,18 +6,19 @@ module Bade
|
|
6
6
|
|
7
7
|
class Parser
|
8
8
|
module MixinRegexps
|
9
|
-
TEXT_START = /\A
|
10
|
-
BLOCK_EXPANSION = /\A:\s
|
11
|
-
OUTPUT_CODE = /\A(&?)
|
9
|
+
TEXT_START = /\A /.freeze
|
10
|
+
BLOCK_EXPANSION = /\A:\s+/.freeze
|
11
|
+
OUTPUT_CODE = /\A(&?)=/.freeze
|
12
12
|
|
13
|
-
PARAMS_END = /\A\s*\)
|
13
|
+
PARAMS_END = /\A\s*\)/.freeze
|
14
14
|
|
15
|
-
PARAMS_END_SPACES = /^\s
|
16
|
-
PARAMS_ARGS_DELIMITER = /\A\s
|
15
|
+
PARAMS_END_SPACES = /^\s*$/.freeze
|
16
|
+
PARAMS_ARGS_DELIMITER = /\A\s*,/.freeze
|
17
17
|
|
18
|
-
PARAMS_PARAM_NAME = /\A\s*#{NAME_RE_STRING}
|
19
|
-
PARAMS_BLOCK_NAME = /\A\s*&#{NAME_RE_STRING}
|
18
|
+
PARAMS_PARAM_NAME = /\A\s*#{NAME_RE_STRING}/.freeze
|
19
|
+
PARAMS_BLOCK_NAME = /\A\s*&#{NAME_RE_STRING}/.freeze
|
20
20
|
PARAMS_KEY_PARAM_NAME = CODE_ATTR_RE
|
21
|
+
PARAMS_PARAM_DEFAULT_START = /\A\s*=/.freeze
|
21
22
|
end
|
22
23
|
|
23
24
|
def parse_mixin_call(mixin_name)
|
@@ -64,7 +65,7 @@ module Bade
|
|
64
65
|
@line = $'
|
65
66
|
attr_node = append_node(:mixin_key_param)
|
66
67
|
attr_node.name = fixed_trailing_colon($1)
|
67
|
-
attr_node.value = parse_ruby_code(ParseRubyCodeRegexps::END_PARAMS_ARG)
|
68
|
+
attr_node.value = parse_ruby_code(ParseRubyCodeRegexps::END_PARAMS_ARG, allow_multiline: true)
|
68
69
|
|
69
70
|
when MixinRegexps::PARAMS_ARGS_DELIMITER
|
70
71
|
# args delimiter
|
@@ -83,7 +84,7 @@ module Bade
|
|
83
84
|
|
84
85
|
else
|
85
86
|
attr_node = append_node(:mixin_param)
|
86
|
-
attr_node.value = parse_ruby_code(ParseRubyCodeRegexps::END_PARAMS_ARG)
|
87
|
+
attr_node.value = parse_ruby_code(ParseRubyCodeRegexps::END_PARAMS_ARG, allow_multiline: true)
|
87
88
|
end
|
88
89
|
end
|
89
90
|
end
|
@@ -114,7 +115,12 @@ module Bade
|
|
114
115
|
|
115
116
|
when MixinRegexps::PARAMS_PARAM_NAME
|
116
117
|
@line = $'
|
117
|
-
append_node(:mixin_param, value: $1)
|
118
|
+
attr_node = append_node(:mixin_param, value: $1)
|
119
|
+
|
120
|
+
if @line =~ MixinRegexps::PARAMS_PARAM_DEFAULT_START
|
121
|
+
@line = $'
|
122
|
+
attr_node.default_value = parse_ruby_code(ParseRubyCodeRegexps::END_PARAMS_ARG)
|
123
|
+
end
|
118
124
|
|
119
125
|
when MixinRegexps::PARAMS_BLOCK_NAME
|
120
126
|
@line = $'
|