rblade 0.3.0 → 0.5.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 +15 -0
- data/LICENSE.md +24 -0
- data/README.md +311 -864
- data/TODO.md +2 -0
- data/lib/rblade/compiler/compiles_components.rb +29 -11
- data/lib/rblade/compiler/compiles_echos.rb +4 -4
- 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 +6 -22
- data/lib/rblade/compiler/statements/compiles_once.rb +57 -0
- data/lib/rblade/compiler/statements/compiles_props.rb +23 -4
- data/lib/rblade/compiler/statements/compiles_stacks.rb +4 -4
- data/lib/rblade/compiler/tokenizes_statements.rb +17 -11
- data/lib/rblade/compiler.rb +12 -1
- data/lib/rblade/helpers/attributes_manager.rb +7 -1
- data/lib/rblade/helpers/class_manager.rb +4 -0
- data/lib/rblade/helpers/html_string.rb +4 -0
- data/lib/rblade/helpers/slot_manager.rb +23 -0
- data/lib/rblade/helpers/stack_manager.rb +4 -0
- data/lib/rblade/helpers/style_manager.rb +4 -0
- data/lib/rblade/rails_template.rb +9 -5
- data/rblade.gemspec +3 -3
- metadata +12 -4
data/TODO.md
ADDED
@@ -26,17 +26,16 @@ module RBlade
|
|
26
26
|
private
|
27
27
|
|
28
28
|
def compile_token_start token
|
29
|
-
|
30
|
-
|
31
|
-
@component_stack << {
|
29
|
+
component = {
|
32
30
|
name: token.value[:name],
|
33
|
-
index: @
|
31
|
+
index: @component_stack.count
|
34
32
|
}
|
33
|
+
@component_stack << component
|
35
34
|
|
36
35
|
attributes = compile_attributes token.value[:attributes]
|
37
36
|
|
38
|
-
code = "_c#{
|
39
|
-
code << "_c#{
|
37
|
+
code = "_c#{component[:index]}_swap=_out;_out='';"
|
38
|
+
code << "_c#{component[:index]}_attr={#{attributes.join(",")}};"
|
40
39
|
|
41
40
|
code
|
42
41
|
end
|
@@ -50,15 +49,34 @@ module RBlade
|
|
50
49
|
raise StandardError.new "Unexpected closing tag (#{token.value[:name]}) expecting #{component[:name]}"
|
51
50
|
end
|
52
51
|
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
namespace = nil
|
53
|
+
name = component[:name]
|
54
|
+
if name.match '::'
|
55
|
+
namespace, name = component[:name].split("::")
|
56
|
+
end
|
57
|
+
|
58
|
+
code = if namespace == 'slot'
|
59
|
+
compile_slot_end name, component
|
60
|
+
else
|
61
|
+
compile_component_end component
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def compile_slot_end name, component
|
66
|
+
parent = @component_stack.last
|
67
|
+
|
68
|
+
code = "_c#{parent[:index]}_attr[:'#{RBlade.escape_quotes(name)}']=RBlade::SlotManager.new(_out,_c#{component[:index]}_attr);"
|
69
|
+
code << "_out=_c#{component[:index]}_swap;_c#{component[:index]}_swap=nil;_c#{component[:index]}_attr=nil;"
|
56
70
|
|
57
71
|
code
|
58
72
|
end
|
59
73
|
|
60
|
-
def
|
61
|
-
|
74
|
+
def compile_component_end component
|
75
|
+
code = "_slot=RBlade::SlotManager.new(_out);_out=_c#{component[:index]}_swap;"
|
76
|
+
code << "_out<<#{ComponentStore.component(component[:name])}(_slot,_c#{component[:index]}_attr);"
|
77
|
+
code << "_slot=nil;_c#{component[:index]}_swap=nil;_c#{component[:index]}_attr=nil;"
|
78
|
+
|
79
|
+
code
|
62
80
|
end
|
63
81
|
|
64
82
|
def compile_attributes attributes
|
@@ -8,8 +8,8 @@ module RBlade
|
|
8
8
|
private
|
9
9
|
|
10
10
|
def compile_regular_echos!(tokens)
|
11
|
-
compile_echos! tokens, "{{", "}}", "
|
12
|
-
compile_echos! tokens, "<%=", "%>", "
|
11
|
+
compile_echos! tokens, "{{", "}}", "RBlade.e"
|
12
|
+
compile_echos! tokens, "<%=", "%>", "RBlade.e"
|
13
13
|
end
|
14
14
|
|
15
15
|
def compile_unsafe_echos!(tokens)
|
@@ -35,8 +35,8 @@ module RBlade
|
|
35
35
|
segments.delete_at i
|
36
36
|
segments.delete_at i + 1
|
37
37
|
segment_value = "_out<<"
|
38
|
-
|
39
|
-
segment_value <<= if !wrapper_function.nil?
|
38
|
+
|
39
|
+
segment_value <<= if !wrapper_function.nil?
|
40
40
|
wrapper_function + "(" + segments[i] + ");"
|
41
41
|
else
|
42
42
|
"(" + segments[i] + ").to_s;"
|
@@ -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,19 +6,15 @@ 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
|
@@ -77,19 +73,7 @@ module RBlade
|
|
77
73
|
if args.nil?
|
78
74
|
"next;"
|
79
75
|
else
|
80
|
-
"next #{args[0]};"
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def compileNextIf args
|
85
|
-
if args.nil? || args.count > 2
|
86
|
-
raise StandardError.new "For statement: wrong number of arguments (given #{args&.count || 0}, expecting 1 or 2)"
|
87
|
-
end
|
88
|
-
|
89
|
-
if args.count == 1
|
90
76
|
"if #{args[0]};next;end;"
|
91
|
-
else
|
92
|
-
"if #{args[0]};next #{args[1]};end;"
|
93
77
|
end
|
94
78
|
end
|
95
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
|
@@ -10,14 +10,23 @@ module RBlade
|
|
10
10
|
|
11
11
|
props = extractProps args[0]
|
12
12
|
props.map do |key, value|
|
13
|
+
compiled_code = ""
|
13
14
|
if value == "_required"
|
14
|
-
"if !
|
15
|
+
compiled_code << "if !attributes.has?(:'#{RBlade.escape_quotes(key)}');raise \"Props statement: #{key} is not defined\";end;"
|
16
|
+
end
|
17
|
+
if isValidVariableName key
|
18
|
+
compiled_code << "#{key}=attributes[:'#{RBlade.escape_quotes(key)}'].nil? ? #{value} : attributes[:'#{RBlade.escape_quotes(key)}'];"
|
19
|
+
compiled_code << "attributes.delete :'#{RBlade.escape_quotes(key)}';"
|
15
20
|
else
|
16
|
-
|
21
|
+
compiled_code << "attributes.default(:'#{RBlade.escape_quotes(key)}', #{value});"
|
17
22
|
end
|
23
|
+
|
24
|
+
compiled_code
|
18
25
|
end.join
|
19
26
|
end
|
20
27
|
|
28
|
+
private
|
29
|
+
|
21
30
|
def extractProps prop_string
|
22
31
|
if !prop_string.start_with?("{") || !prop_string.end_with?("}")
|
23
32
|
raise StandardError.new "Props statement: expecting hash as parameter"
|
@@ -31,9 +40,9 @@ module RBlade
|
|
31
40
|
|
32
41
|
key, value = prop.split(/^
|
33
42
|
(?:
|
34
|
-
(
|
43
|
+
'(.+)':
|
35
44
|
|
|
36
|
-
(
|
45
|
+
"(.+)":
|
37
46
|
|
|
38
47
|
([^ :]+):
|
39
48
|
|
|
@@ -56,6 +65,16 @@ module RBlade
|
|
56
65
|
|
57
66
|
props
|
58
67
|
end
|
68
|
+
|
69
|
+
RUBY_RESERVED_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].freeze
|
70
|
+
|
71
|
+
def isValidVariableName key
|
72
|
+
return false unless key.match?(/^[a-zA-Z_][a-zA-Z0-9_]*$/)
|
73
|
+
|
74
|
+
return false if RUBY_RESERVED_KEYWORDS.include? key
|
75
|
+
|
76
|
+
true
|
77
|
+
end
|
59
78
|
end
|
60
79
|
end
|
61
80
|
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
|
@@ -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,9 +2,11 @@ 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"
|
9
|
+
require "rblade/helpers/html_string"
|
8
10
|
|
9
11
|
Token = Struct.new(:type, :value)
|
10
12
|
|
@@ -18,10 +20,19 @@ module RBlade
|
|
18
20
|
string.gsub(/['\\\x0]/, '\\\\\0')
|
19
21
|
end
|
20
22
|
|
23
|
+
def self.e string
|
24
|
+
if string.is_a? HtmlString
|
25
|
+
string
|
26
|
+
else
|
27
|
+
h(string)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
21
31
|
class Compiler
|
22
32
|
def self.compileString(string_template)
|
23
33
|
tokens = [Token.new(:unprocessed, string_template)]
|
24
34
|
|
35
|
+
CompilesVerbatim.new.compile! tokens
|
25
36
|
CompilesComments.new.compile! tokens
|
26
37
|
CompilesRuby.new.compile! tokens
|
27
38
|
TokenizesComponents.new.tokenize! tokens
|
@@ -36,8 +47,8 @@ module RBlade
|
|
36
47
|
def self.compileAttributeString(string_template)
|
37
48
|
tokens = [Token.new(:unprocessed, string_template)]
|
38
49
|
|
39
|
-
CompilesRuby.compile! tokens
|
40
50
|
CompilesComments.compile!(tokens)
|
51
|
+
CompilesRuby.compile! tokens
|
41
52
|
CompilesEchos.compile!(tokens)
|
42
53
|
|
43
54
|
compileTokens tokens
|
@@ -1,5 +1,7 @@
|
|
1
|
+
require "rblade/helpers/html_string"
|
2
|
+
|
1
3
|
module RBlade
|
2
|
-
class AttributesManager
|
4
|
+
class AttributesManager < HtmlString
|
3
5
|
@attributes = {}
|
4
6
|
def initialize attributes
|
5
7
|
@attributes = attributes
|
@@ -33,6 +35,10 @@ module RBlade
|
|
33
35
|
end.join " "
|
34
36
|
end
|
35
37
|
|
38
|
+
def to_str
|
39
|
+
to_s
|
40
|
+
end
|
41
|
+
|
36
42
|
def only(keys)
|
37
43
|
keys = if keys.is_a? Array
|
38
44
|
keys.map(&:to_sym)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "rblade/helpers/attributes_manager"
|
2
|
+
require "rblade/helpers/html_string"
|
3
|
+
|
4
|
+
module RBlade
|
5
|
+
class SlotManager < HtmlString
|
6
|
+
def initialize content, attributes = nil
|
7
|
+
@content = content
|
8
|
+
@attributes = attributes && AttributesManager.new(attributes)
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
@content
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_str
|
16
|
+
to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
def attributes
|
20
|
+
@attributes
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -3,25 +3,29 @@ require "rblade/compiler"
|
|
3
3
|
require "rblade/component_store"
|
4
4
|
require "rblade/helpers/attributes_manager"
|
5
5
|
require "rblade/helpers/class_manager"
|
6
|
+
require "rblade/helpers/slot_manager"
|
6
7
|
require "rblade/helpers/stack_manager"
|
7
8
|
require "rblade/helpers/style_manager"
|
8
9
|
|
9
10
|
module RBlade
|
10
11
|
class RailsTemplate
|
11
12
|
def call(template, source = nil)
|
13
|
+
RBlade::ComponentStore.clear
|
14
|
+
RBlade::StackManager.clear
|
15
|
+
|
12
16
|
unless template.nil?
|
13
17
|
view_name = template.short_identifier
|
14
|
-
.delete_prefix(
|
15
|
-
.delete_suffix(
|
16
|
-
.delete_suffix(
|
17
|
-
.tr(
|
18
|
+
.delete_prefix("app/views/")
|
19
|
+
.delete_suffix(".rblade")
|
20
|
+
.delete_suffix(".html")
|
21
|
+
.tr("/", ".")
|
18
22
|
|
19
23
|
# Let the component store know about the current view for relative components
|
20
24
|
RBlade::ComponentStore.view_name(
|
21
25
|
"view::#{view_name}"
|
22
26
|
)
|
23
27
|
end
|
24
|
-
setup = "_out='';_stacks=[];"
|
28
|
+
setup = "_out='';_stacks=[];$_once_tokens=[];"
|
25
29
|
code = RBlade::Compiler.compileString(source || template.source)
|
26
30
|
setdown = "RBlade::StackManager.get(_stacks) + _out"
|
27
31
|
setup + ComponentStore.get + code + setdown
|
data/rblade.gemspec
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "rblade"
|
3
|
-
s.version = "0.
|
4
|
-
s.summary = "
|
5
|
-
s.description = "
|
3
|
+
s.version = "0.5.0"
|
4
|
+
s.summary = "A component-first templating engine for Rails"
|
5
|
+
s.description = "RBlade is a simple, yet powerful templating engine for Ruby on Rails, inspired by Laravel Blade."
|
6
6
|
s.authors = ["Simon J"]
|
7
7
|
s.email = "2857218+mwnciau@users.noreply.github.com"
|
8
8
|
s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|storage)/}) }
|