rblade 0.2.5 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/LICENSE.md +24 -0
- data/README.md +1257 -0
- data/TODO.md +2 -0
- data/lib/rblade/compiler/compiles_components.rb +34 -60
- data/lib/rblade/compiler/compiles_ruby.rb +1 -1
- data/lib/rblade/compiler/compiles_statements.rb +15 -1
- data/lib/rblade/compiler/compiles_verbatim.rb +29 -0
- data/lib/rblade/compiler/statements/compiles_conditionals.rb +26 -0
- data/lib/rblade/compiler/statements/compiles_html_attributes.rb +21 -0
- data/lib/rblade/compiler/statements/compiles_loops.rb +18 -30
- data/lib/rblade/compiler/statements/compiles_once.rb +57 -0
- data/lib/rblade/compiler/statements/compiles_props.rb +2 -2
- data/lib/rblade/compiler/statements/compiles_stacks.rb +4 -4
- data/lib/rblade/compiler/tokenizes_components.rb +7 -2
- data/lib/rblade/compiler/tokenizes_statements.rb +17 -11
- data/lib/rblade/compiler.rb +3 -1
- data/lib/rblade/component_store.rb +73 -14
- data/lib/rblade/helpers/attributes_manager.rb +6 -19
- data/lib/rblade/helpers/class_manager.rb +4 -0
- data/lib/rblade/helpers/style_manager.rb +4 -0
- data/lib/rblade/rails_template.rb +18 -2
- data/lib/rblade/railtie.rb +2 -1
- data/rblade.gemspec +3 -3
- metadata +11 -4
data/TODO.md
ADDED
@@ -9,13 +9,13 @@ module RBlade
|
|
9
9
|
|
10
10
|
def compile!(tokens)
|
11
11
|
tokens.each do |token|
|
12
|
-
if [:component, :component_start, :component_end].none? token.type
|
12
|
+
if [:component, :component_start, :component_end, :component_unsafe_end].none? token.type
|
13
13
|
next
|
14
14
|
end
|
15
15
|
|
16
16
|
token.value = if token.type == :component_start
|
17
17
|
compile_token_start token
|
18
|
-
elsif token.type == :component_end
|
18
|
+
elsif token.type == :component_end || token.type == :component_unsafe_end
|
19
19
|
compile_token_end token
|
20
20
|
else
|
21
21
|
compile_token_start(token) + compile_token_end(token)
|
@@ -30,11 +30,15 @@ module RBlade
|
|
30
30
|
|
31
31
|
@component_stack << {
|
32
32
|
name: token.value[:name],
|
33
|
-
attributes: token.value[:attributes],
|
34
33
|
index: @component_count
|
35
34
|
}
|
36
35
|
|
37
|
-
|
36
|
+
attributes = compile_attributes token.value[:attributes]
|
37
|
+
|
38
|
+
code = "_c#{@component_count}_swap=_out;_out='';"
|
39
|
+
code << "_c#{@component_count}_attr={#{attributes.join(",")}};"
|
40
|
+
|
41
|
+
code
|
38
42
|
end
|
39
43
|
|
40
44
|
def compile_token_end token
|
@@ -42,72 +46,42 @@ module RBlade
|
|
42
46
|
if component.nil?
|
43
47
|
raise StandardError.new "Unexpected closing tag (#{token.value[:name]})"
|
44
48
|
end
|
45
|
-
if token.value[:name] != component[:name]
|
49
|
+
if token.type == :component_end && token.value[:name] != component[:name]
|
46
50
|
raise StandardError.new "Unexpected closing tag (#{token.value[:name]}) expecting #{component[:name]}"
|
47
51
|
end
|
48
52
|
|
49
|
-
|
50
|
-
|
51
|
-
code
|
52
|
-
code << "_stacks=[];"
|
53
|
-
code << "attributes=RBlade::AttributesManager.new(attributes);"
|
54
|
-
code << ComponentStore.fetchComponent(token.value[:name])
|
55
|
-
code << "RBlade::StackManager.get(_stacks) + _out;end;"
|
56
|
-
code << "_slot=_out;_out=_comp_#{component[:index]}_swap;"
|
57
|
-
code << "_out<<_component(_slot,{#{attributes[:arguments].join(",")}});"
|
53
|
+
code = "_slot=_out;_out=_c#{component[:index]}_swap;"
|
54
|
+
code << "_out<<#{ComponentStore.component(component[:name])}(_slot,_c#{component[:index]}_attr);"
|
55
|
+
code << "_slot=nil;_c#{component[:index]}_swap=nil;"
|
58
56
|
|
59
57
|
code
|
60
58
|
end
|
61
59
|
|
62
|
-
def
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
attributes.each do |attribute|
|
67
|
-
if attribute[:type] == "class"
|
68
|
-
attribute_arguments.push "'class': RBlade::ClassManager.new(#{attribute[:value]})"
|
69
|
-
attribute_assignments.push "_class = attributes[:class];"
|
70
|
-
|
71
|
-
next
|
72
|
-
end
|
73
|
-
if attribute[:type] == "style"
|
74
|
-
attribute_arguments.push "'style': RBlade::StyleManager.new(#{attribute[:value]})"
|
75
|
-
attribute_assignments.push "_style = attributes[:style];"
|
76
|
-
|
77
|
-
next
|
78
|
-
end
|
79
|
-
if attribute[:type] == "attributes"
|
80
|
-
attribute_arguments.push "**(#{attribute[:value]}).to_h"
|
81
|
-
|
82
|
-
next
|
83
|
-
end
|
84
|
-
|
85
|
-
if attribute[:type] == "string"
|
86
|
-
attribute_arguments.push "'#{attribute[:name]}': '#{RBlade.escape_quotes(attribute[:value])}'"
|
87
|
-
end
|
88
|
-
|
89
|
-
if attribute[:type] == "ruby"
|
90
|
-
attribute_arguments.push "'#{attribute[:name]}': (#{attribute[:value]})"
|
91
|
-
end
|
92
|
-
|
93
|
-
if attribute[:type] == "pass_through"
|
94
|
-
attribute_arguments.push "#{attribute[:name]}:"
|
95
|
-
end
|
96
|
-
|
97
|
-
if attribute[:type] == "empty"
|
98
|
-
attribute_arguments.push "'#{attribute[:name]}': true"
|
99
|
-
end
|
100
|
-
|
101
|
-
variable_name = attribute[:name]&.tr("-", "_")
|
102
|
-
if !variable_name.nil? && variable_name.match(/^[A-Za-z_][A-Za-z0-9_]*$/)
|
103
|
-
keywords = %w[__FILE__ __LINE__ alias and begin BEGIN break case class def defined? do else elsif end END ensure false for if in module next nil not or redo rescue retry return self super then true undef unless until when while yield attributes _out slot]
|
104
|
-
next if keywords.include? variable_name
|
60
|
+
def get_method_name name
|
61
|
+
name.gsub(/[^a-zA-Z0-9_]/, "_")
|
62
|
+
end
|
105
63
|
|
106
|
-
|
64
|
+
def compile_attributes attributes
|
65
|
+
attributes.map do |attribute|
|
66
|
+
case attribute[:type]
|
67
|
+
when "class"
|
68
|
+
"'class': RBlade::ClassManager.new(#{attribute[:value]})"
|
69
|
+
when "style"
|
70
|
+
"'style': RBlade::StyleManager.new(#{attribute[:value]})"
|
71
|
+
when "attributes"
|
72
|
+
"**(#{attribute[:value]})"
|
73
|
+
when "string"
|
74
|
+
"'#{attribute[:name]}': '#{RBlade.escape_quotes(attribute[:value])}'"
|
75
|
+
when "ruby"
|
76
|
+
"'#{attribute[:name]}': (#{attribute[:value]})"
|
77
|
+
when "pass_through"
|
78
|
+
"#{attribute[:name]}:"
|
79
|
+
when "empty"
|
80
|
+
"'#{attribute[:name]}': true"
|
81
|
+
else
|
82
|
+
raise StandardError.new "Component compiler: unexpected attribute type (#{attribute[:type]})"
|
107
83
|
end
|
108
84
|
end
|
109
|
-
|
110
|
-
{arguments: attribute_arguments, assignments: attribute_assignments}
|
111
85
|
end
|
112
86
|
end
|
113
87
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require "rblade/compiler/statements/compiles_conditionals"
|
2
|
+
require "rblade/compiler/statements/compiles_html_attributes"
|
2
3
|
require "rblade/compiler/statements/compiles_inline_ruby"
|
3
4
|
require "rblade/compiler/statements/compiles_loops"
|
5
|
+
require "rblade/compiler/statements/compiles_once"
|
4
6
|
require "rblade/compiler/statements/compiles_props"
|
5
7
|
require "rblade/compiler/statements/compiles_stacks"
|
6
8
|
|
@@ -43,7 +45,7 @@ module RBlade
|
|
43
45
|
private
|
44
46
|
|
45
47
|
def getHandler(name)
|
46
|
-
handler_class, handler_method = @@statement_handlers[name]
|
48
|
+
handler_class, handler_method = @@statement_handlers[name.tr("_", "").downcase]
|
47
49
|
|
48
50
|
if !handler_class&.method_defined?(handler_method)
|
49
51
|
raise StandardError.new "Unhandled statement: @#{name}"
|
@@ -65,6 +67,7 @@ module RBlade
|
|
65
67
|
"breakif" => [CompilesLoops, :compileBreakIf],
|
66
68
|
"case" => [CompilesConditionals, :compileCase],
|
67
69
|
"checked" => [CompilesConditionals, :compileChecked],
|
70
|
+
"class" => [CompilesHtmlAttributes, :compileClass],
|
68
71
|
"disabled" => [CompilesConditionals, :compileDisabled],
|
69
72
|
"else" => [CompilesConditionals, :compileElse],
|
70
73
|
"elsif" => [CompilesConditionals, :compileElsif],
|
@@ -75,27 +78,38 @@ module RBlade
|
|
75
78
|
"endcase" => [CompilesStatements, :compileEnd],
|
76
79
|
"endeach" => [CompilesStatements, :compileEnd],
|
77
80
|
"endeachelse" => [CompilesStatements, :compileEnd],
|
81
|
+
"endenv" => [CompilesStatements, :compileEnd],
|
78
82
|
"endfor" => [CompilesStatements, :compileEnd],
|
79
83
|
"endforelse" => [CompilesStatements, :compileEnd],
|
80
84
|
"endif" => [CompilesStatements, :compileEnd],
|
85
|
+
"endonce" => [CompilesStatements, :compileEnd],
|
81
86
|
"endprepend" => [CompilesStacks, :compileEndPrepend],
|
87
|
+
"endprependonce" => [CompilesOnce, :compileEndPrependOnce],
|
88
|
+
"endproduction" => [CompilesStatements, :compileEnd],
|
82
89
|
"endpush" => [CompilesStacks, :compileEndPush],
|
90
|
+
"endpushonce" => [CompilesOnce, :compileEndPushOnce],
|
83
91
|
"endunless" => [CompilesStatements, :compileEnd],
|
84
92
|
"enduntil" => [CompilesStatements, :compileEnd],
|
85
93
|
"endwhile" => [CompilesStatements, :compileEnd],
|
94
|
+
"env" => [CompilesConditionals, :compileEnv],
|
86
95
|
"for" => [CompilesLoops, :compileFor],
|
87
96
|
"forelse" => [CompilesLoops, :compileForElse],
|
88
97
|
"if" => [CompilesConditionals, :compileIf],
|
89
98
|
"next" => [CompilesLoops, :compileNext],
|
90
99
|
"nextif" => [CompilesLoops, :compileNextIf],
|
100
|
+
"once" => [CompilesOnce, :compileOnce],
|
91
101
|
"prepend" => [CompilesStacks, :compilePrepend],
|
102
|
+
"prependonce" => [CompilesOnce, :compilePrependOnce],
|
103
|
+
"production" => [CompilesConditionals, :compileProduction],
|
92
104
|
"props" => [CompilesProps, :compileProps],
|
93
105
|
"push" => [CompilesStacks, :compilePush],
|
106
|
+
"pushonce" => [CompilesOnce, :compilePushOnce],
|
94
107
|
"readonly" => [CompilesConditionals, :compileReadonly],
|
95
108
|
"required" => [CompilesConditionals, :compileRequired],
|
96
109
|
"ruby" => [CompilesInlineRuby, :compile],
|
97
110
|
"selected" => [CompilesConditionals, :compileSelected],
|
98
111
|
"stack" => [CompilesStacks, :compileStack],
|
112
|
+
"style" => [CompilesHtmlAttributes, :compileStyle],
|
99
113
|
"unless" => [CompilesConditionals, :compileUnless],
|
100
114
|
"until" => [CompilesLoops, :compileUntil],
|
101
115
|
"when" => [CompilesConditionals, :compileWhen],
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module RBlade
|
2
|
+
class CompilesVerbatim
|
3
|
+
def compile!(tokens)
|
4
|
+
tokens.map! do |token|
|
5
|
+
next(token) if token.type != :unprocessed
|
6
|
+
|
7
|
+
segments = token.value.split(/\s?(?<!\w)(@verbatim)(?!\w)\s?(.+?)\s?(?<!\w)@end_?verbatim(?!\w)\s?/mi)
|
8
|
+
|
9
|
+
i = 0
|
10
|
+
while i < segments.count
|
11
|
+
if segments[i] == "@verbatim"
|
12
|
+
segments.delete_at i
|
13
|
+
segments[i] = Token.new(type: :raw_text, value: segments[i])
|
14
|
+
|
15
|
+
i += 1
|
16
|
+
elsif !segments[i].nil? && segments[i] != ""
|
17
|
+
segments[i] = Token.new(type: :unprocessed, value: segments[i])
|
18
|
+
|
19
|
+
i += 1
|
20
|
+
else
|
21
|
+
segments.delete_at i
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
segments
|
26
|
+
end.flatten!
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -88,6 +88,32 @@ module RBlade
|
|
88
88
|
|
89
89
|
"if #{args[0]};_out<<'selected';end;"
|
90
90
|
end
|
91
|
+
|
92
|
+
def compileEnv args
|
93
|
+
if args&.count != 1
|
94
|
+
raise StandardError.new "Env statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
95
|
+
end
|
96
|
+
|
97
|
+
environments = args[0].strip
|
98
|
+
|
99
|
+
"if Array.wrap(#{environments}).include?(Rails.env);"
|
100
|
+
end
|
101
|
+
|
102
|
+
def compileProduction args
|
103
|
+
unless args.nil?
|
104
|
+
raise StandardError.new "Production statement: wrong number of arguments (given #{args.count}, expecting 1)"
|
105
|
+
end
|
106
|
+
|
107
|
+
"if Rails.env.production?;"
|
108
|
+
end
|
109
|
+
|
110
|
+
def compileOnce args
|
111
|
+
if args&.count&.> 1
|
112
|
+
raise StandardError.new "Production statement: wrong number of arguments (given #{args.count}, expecting 0 or 1)"
|
113
|
+
end
|
114
|
+
|
115
|
+
args[0].nil? ? "" : args[0]
|
116
|
+
end
|
91
117
|
end
|
92
118
|
end
|
93
119
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RBlade
|
2
|
+
class CompilesStatements
|
3
|
+
class CompilesHtmlAttributes
|
4
|
+
def compileClass args
|
5
|
+
if args&.count != 1
|
6
|
+
raise StandardError.new "Class statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
7
|
+
end
|
8
|
+
|
9
|
+
"_out<<'class=\"'<<RBlade::ClassManager.new(#{args[0]})<<'\"';"
|
10
|
+
end
|
11
|
+
|
12
|
+
def compileStyle args
|
13
|
+
if args&.count != 1
|
14
|
+
raise StandardError.new "Style statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
15
|
+
end
|
16
|
+
|
17
|
+
"_out<<'style=\"'<<RBlade::StyleManager.new(#{args[0]})<<'\"';"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -6,40 +6,40 @@ module RBlade
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def compileBreak args
|
9
|
-
if
|
10
|
-
raise StandardError.new "Break statement: wrong number of arguments (given #{args&.count}, expecting 0)"
|
9
|
+
if args&.count&.> 1
|
10
|
+
raise StandardError.new "Break statement: wrong number of arguments (given #{args&.count}, expecting 0 or 1)"
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
if args&.count != 1
|
18
|
-
raise StandardError.new "Break statement: wrong number of arguments (given #{args&.count}, expecting 1)"
|
13
|
+
if args.nil?
|
14
|
+
"break;"
|
15
|
+
else
|
16
|
+
"if #{args[0]};break;end;"
|
19
17
|
end
|
20
|
-
|
21
|
-
"if #{args[0]};break;end;"
|
22
18
|
end
|
23
19
|
|
24
20
|
def compileEach args
|
25
|
-
if args
|
21
|
+
if args.nil? || args.count > 2
|
26
22
|
raise StandardError.new "Each statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
27
23
|
end
|
24
|
+
# Allow variables to be a key, value pair
|
25
|
+
args = args.join ","
|
28
26
|
|
29
|
-
variables, collection = args
|
27
|
+
variables, collection = args.split(" in ")
|
30
28
|
|
31
29
|
"#{collection}.each do |#{variables}|;"
|
32
30
|
end
|
33
31
|
|
34
32
|
def compileEachElse args
|
35
|
-
if args
|
36
|
-
raise StandardError.new "Each
|
33
|
+
if args.nil? || args.count > 2
|
34
|
+
raise StandardError.new "Each statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
37
35
|
end
|
36
|
+
# Allow variables to be a key, value pair
|
37
|
+
args = args.join ","
|
38
38
|
@loop_else_counter += 1
|
39
39
|
|
40
|
-
variables, collection = args
|
40
|
+
variables, collection = args.split(" in ")
|
41
41
|
|
42
|
-
"_looped_#{@loop_else_counter}=
|
42
|
+
"_looped_#{@loop_else_counter}=false;#{collection}.each do |#{variables}|;_looped_#{@loop_else_counter}=true;"
|
43
43
|
end
|
44
44
|
|
45
45
|
def compileFor args
|
@@ -56,13 +56,13 @@ module RBlade
|
|
56
56
|
end
|
57
57
|
@loop_else_counter += 1
|
58
58
|
|
59
|
-
"_looped_#{@loop_else_counter}=
|
59
|
+
"_looped_#{@loop_else_counter}=false;for #{args[0]};_looped_#{@loop_else_counter}=true;"
|
60
60
|
end
|
61
61
|
|
62
62
|
def compileEmpty
|
63
63
|
@loop_else_counter -= 1
|
64
64
|
|
65
|
-
"end;if _looped_#{@loop_else_counter + 1};"
|
65
|
+
"end;if !_looped_#{@loop_else_counter + 1};"
|
66
66
|
end
|
67
67
|
|
68
68
|
def compileNext args
|
@@ -73,19 +73,7 @@ module RBlade
|
|
73
73
|
if args.nil?
|
74
74
|
"next;"
|
75
75
|
else
|
76
|
-
"next #{args[0]};"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def compileNextIf args
|
81
|
-
if args.nil? || args.count > 2
|
82
|
-
raise StandardError.new "For statement: wrong number of arguments (given #{args&.count || 0}, expecting 1 or 2)"
|
83
|
-
end
|
84
|
-
|
85
|
-
if args.count == 1
|
86
76
|
"if #{args[0]};next;end;"
|
87
|
-
else
|
88
|
-
"if #{args[0]};next #{args[1]};end;"
|
89
77
|
end
|
90
78
|
end
|
91
79
|
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module RBlade
|
2
|
+
class CompilesStatements
|
3
|
+
class CompilesOnce
|
4
|
+
def initialize
|
5
|
+
@once_counter = 0
|
6
|
+
end
|
7
|
+
|
8
|
+
def compileOnce args
|
9
|
+
if args&.count&.> 1
|
10
|
+
raise StandardError.new "Once statement: wrong number of arguments (given #{args.count}, expecting 0 or 1)"
|
11
|
+
end
|
12
|
+
|
13
|
+
once_id = args.nil? ? ":_#{@once_counter += 1}" : args[0]
|
14
|
+
|
15
|
+
"unless $_once_tokens.include? #{once_id};$_once_tokens<<#{once_id};"
|
16
|
+
end
|
17
|
+
|
18
|
+
def compilePushOnce args
|
19
|
+
if args&.count != 1 && args&.count != 2
|
20
|
+
raise StandardError.new "Push once statement: wrong number of arguments (given #{args.count}, expecting 1 or 2)"
|
21
|
+
end
|
22
|
+
@once_counter += 1
|
23
|
+
once_id = args[1].nil? ? ":_#{@once_counter}" : args[1]
|
24
|
+
|
25
|
+
"unless $_once_tokens.include? #{once_id};$_once_tokens<<#{once_id};" \
|
26
|
+
<< "_p1_#{@once_counter}=#{args[0]};_p1_#{@once_counter}_b=_out;_out='';"
|
27
|
+
end
|
28
|
+
|
29
|
+
def compileEndPushOnce args
|
30
|
+
if !args.nil?
|
31
|
+
raise StandardError.new "End push once statement: wrong number of arguments (given #{args&.count}, expecting 0)"
|
32
|
+
end
|
33
|
+
|
34
|
+
"RBlade::StackManager.push(_p1_#{@once_counter}, _out);_out=_p1_#{@once_counter}_b;end;"
|
35
|
+
end
|
36
|
+
|
37
|
+
def compilePrependOnce args
|
38
|
+
if args&.count != 1 && args&.count != 2
|
39
|
+
raise StandardError.new "Prepend once statement: wrong number of arguments (given #{args.count}, expecting 1 or 2)"
|
40
|
+
end
|
41
|
+
@once_counter += 1
|
42
|
+
once_id = args[1].nil? ? ":_#{@once_counter}" : args[1]
|
43
|
+
|
44
|
+
"unless $_once_tokens.include? #{once_id};$_once_tokens<<#{once_id};" \
|
45
|
+
<< "_p1_#{@once_counter}=#{args[0]};_p1_#{@once_counter}_b=_out;_out='';"
|
46
|
+
end
|
47
|
+
|
48
|
+
def compileEndPrependOnce args
|
49
|
+
if !args.nil?
|
50
|
+
raise StandardError.new "End prepend once statement: wrong number of arguments (given #{args&.count}, expecting 0)"
|
51
|
+
end
|
52
|
+
|
53
|
+
"RBlade::StackManager.prepend(_p1_#{@once_counter}, _out);_out=_p1_#{@once_counter}_b;end;"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -11,9 +11,9 @@ module RBlade
|
|
11
11
|
props = extractProps args[0]
|
12
12
|
props.map do |key, value|
|
13
13
|
if value == "_required"
|
14
|
-
"if !defined?(#{key})&&!attributes.has?(:'#{RBlade
|
14
|
+
"if !defined?(#{key})&&!attributes.has?(:'#{RBlade.escape_quotes(key)}');raise \"Props statement: #{key} is not defined\";end;#{key.sub(/[^a-zA-Z0-9_]/, "_")}=attributes.default(:'#{RBlade.escape_quotes(key)}');"
|
15
15
|
else
|
16
|
-
"#{key.sub
|
16
|
+
"#{key.sub(/[^a-zA-Z0-9_]/, "_")}=attributes.default(:'#{RBlade.escape_quotes(key)}',#{value});"
|
17
17
|
end
|
18
18
|
end.join
|
19
19
|
end
|
@@ -23,7 +23,7 @@ module RBlade
|
|
23
23
|
else
|
24
24
|
@push_counter += 1
|
25
25
|
|
26
|
-
"
|
26
|
+
"_p_#{@push_counter}=#{args[0]};_p_#{@push_counter}_b=_out;_out='';"
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -34,7 +34,7 @@ module RBlade
|
|
34
34
|
|
35
35
|
@push_counter -= 1
|
36
36
|
|
37
|
-
"RBlade::StackManager.prepend(
|
37
|
+
"RBlade::StackManager.prepend(_p_#{@push_counter + 1}, _out);_out=_p_#{@push_counter + 1}_b;"
|
38
38
|
end
|
39
39
|
|
40
40
|
def compilePush args
|
@@ -47,7 +47,7 @@ module RBlade
|
|
47
47
|
else
|
48
48
|
@push_counter += 1
|
49
49
|
|
50
|
-
"
|
50
|
+
"_p_#{@push_counter}=#{args[0]};_p_#{@push_counter}_b=_out;_out='';"
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
@@ -58,7 +58,7 @@ module RBlade
|
|
58
58
|
|
59
59
|
@push_counter -= 1
|
60
60
|
|
61
|
-
"RBlade::StackManager.push(
|
61
|
+
"RBlade::StackManager.push(_p_#{@push_counter + 1}, _out);_out=_p_#{@push_counter + 1}_b;"
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
@@ -6,7 +6,7 @@ module RBlade
|
|
6
6
|
tokens.map! do |token|
|
7
7
|
next(token) if token.type != :unprocessed
|
8
8
|
|
9
|
-
segments =
|
9
|
+
segments = tokenizeComponentTags token.value
|
10
10
|
|
11
11
|
i = 0
|
12
12
|
while i < segments.count
|
@@ -15,6 +15,9 @@ module RBlade
|
|
15
15
|
|
16
16
|
segments.delete_at i + 1
|
17
17
|
i += 1
|
18
|
+
elsif segments[i] == "<//>"
|
19
|
+
segments[i] = Token.new(type: :component_unsafe_end)
|
20
|
+
i += 1
|
18
21
|
elsif segments[i] == "<" && segments[i + 1]&.match(/x[-:]/)
|
19
22
|
name = segments[i + 1][2..]
|
20
23
|
raw_attributes = (segments[i + 2] != ">") ? tokenizeAttributes(segments[i + 2]) : nil
|
@@ -97,7 +100,7 @@ module RBlade
|
|
97
100
|
attributes
|
98
101
|
end
|
99
102
|
|
100
|
-
def
|
103
|
+
def tokenizeComponentTags value
|
101
104
|
value.split(%r/
|
102
105
|
# Opening and self-closing tags
|
103
106
|
(?:
|
@@ -147,6 +150,8 @@ module RBlade
|
|
147
150
|
\s*
|
148
151
|
>
|
149
152
|
)
|
153
|
+
|
|
154
|
+
(<\/\/>)
|
150
155
|
/xm)
|
151
156
|
end
|
152
157
|
|
@@ -8,12 +8,23 @@ module RBlade
|
|
8
8
|
next(token) if token.type != :unprocessed
|
9
9
|
|
10
10
|
segments = token.value.split(/
|
11
|
-
|
12
|
-
(
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
\s?(?<!\w)
|
12
|
+
(?:
|
13
|
+
(?:
|
14
|
+
(@@)
|
15
|
+
(\w+(?!\w))
|
16
|
+
)
|
17
|
+
|
|
18
|
+
(?:
|
19
|
+
(@)
|
20
|
+
(\w+(?!\w))
|
21
|
+
(?:[ \t]*
|
22
|
+
(\(.*?\))
|
23
|
+
)?
|
24
|
+
)
|
25
|
+
)
|
26
|
+
\s?
|
27
|
+
/mx)
|
17
28
|
|
18
29
|
parseSegments! segments
|
19
30
|
end.flatten!
|
@@ -35,11 +46,6 @@ module RBlade
|
|
35
46
|
elsif segment == "@"
|
36
47
|
tokenizeStatement! segments, i
|
37
48
|
|
38
|
-
# Remove trailing whitespace if it exists, but don't double dip when another statement follows
|
39
|
-
if !segments[i + 1].nil? && segments[i + 1].match(/^\s/) && (segments[i + 1].length > 1 || segments[i + 2].nil?)
|
40
|
-
segments[i + 1].slice! 0, 1
|
41
|
-
end
|
42
|
-
|
43
49
|
i += 1
|
44
50
|
elsif !segments[i].nil? && segments[i] != ""
|
45
51
|
segments[i] = Token.new(type: :unprocessed, value: segments[i])
|
data/lib/rblade/compiler.rb
CHANGED
@@ -2,6 +2,7 @@ require "rblade/compiler/compiles_comments"
|
|
2
2
|
require "rblade/compiler/compiles_components"
|
3
3
|
require "rblade/compiler/compiles_echos"
|
4
4
|
require "rblade/compiler/compiles_ruby"
|
5
|
+
require "rblade/compiler/compiles_verbatim"
|
5
6
|
require "rblade/compiler/compiles_statements"
|
6
7
|
require "rblade/compiler/tokenizes_components"
|
7
8
|
require "rblade/compiler/tokenizes_statements"
|
@@ -22,6 +23,7 @@ module RBlade
|
|
22
23
|
def self.compileString(string_template)
|
23
24
|
tokens = [Token.new(:unprocessed, string_template)]
|
24
25
|
|
26
|
+
CompilesVerbatim.new.compile! tokens
|
25
27
|
CompilesComments.new.compile! tokens
|
26
28
|
CompilesRuby.new.compile! tokens
|
27
29
|
TokenizesComponents.new.tokenize! tokens
|
@@ -36,8 +38,8 @@ module RBlade
|
|
36
38
|
def self.compileAttributeString(string_template)
|
37
39
|
tokens = [Token.new(:unprocessed, string_template)]
|
38
40
|
|
39
|
-
CompilesRuby.compile! tokens
|
40
41
|
CompilesComments.compile!(tokens)
|
42
|
+
CompilesRuby.compile! tokens
|
41
43
|
CompilesEchos.compile!(tokens)
|
42
44
|
|
43
45
|
compileTokens tokens
|