rblade 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/LICENSE.md +24 -0
- data/README.md +312 -858
- data/TODO.md +2 -0
- 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_stacks.rb +4 -4
- data/lib/rblade/compiler/tokenizes_statements.rb +17 -11
- data/lib/rblade/compiler.rb +3 -1
- data/lib/rblade/helpers/class_manager.rb +4 -0
- data/lib/rblade/helpers/style_manager.rb +4 -0
- data/lib/rblade/rails_template.rb +8 -5
- data/rblade.gemspec +3 -3
- metadata +10 -4
data/TODO.md
ADDED
@@ -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
|
@@ -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,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
|
@@ -9,19 +9,22 @@ require "rblade/helpers/style_manager"
|
|
9
9
|
module RBlade
|
10
10
|
class RailsTemplate
|
11
11
|
def call(template, source = nil)
|
12
|
+
RBlade::ComponentStore.clear
|
13
|
+
RBlade::StackManager.clear
|
14
|
+
|
12
15
|
unless template.nil?
|
13
16
|
view_name = template.short_identifier
|
14
|
-
.delete_prefix(
|
15
|
-
.delete_suffix(
|
16
|
-
.delete_suffix(
|
17
|
-
.tr(
|
17
|
+
.delete_prefix("app/views/")
|
18
|
+
.delete_suffix(".rblade")
|
19
|
+
.delete_suffix(".html")
|
20
|
+
.tr("/", ".")
|
18
21
|
|
19
22
|
# Let the component store know about the current view for relative components
|
20
23
|
RBlade::ComponentStore.view_name(
|
21
24
|
"view::#{view_name}"
|
22
25
|
)
|
23
26
|
end
|
24
|
-
setup = "_out='';_stacks=[];"
|
27
|
+
setup = "_out='';_stacks=[];$_once_tokens=[];"
|
25
28
|
code = RBlade::Compiler.compileString(source || template.source)
|
26
29
|
setdown = "RBlade::StackManager.get(_stacks) + _out"
|
27
30
|
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.4.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)/}) }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rblade
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simon J
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-07-
|
11
|
+
date: 2024-07-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -66,7 +66,8 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '7.0'
|
69
|
-
description:
|
69
|
+
description: RBlade is a simple, yet powerful templating engine for Ruby on Rails,
|
70
|
+
inspired by Laravel Blade.
|
70
71
|
email: 2857218+mwnciau@users.noreply.github.com
|
71
72
|
executables: []
|
72
73
|
extensions: []
|
@@ -76,8 +77,10 @@ files:
|
|
76
77
|
- ".standard.yml"
|
77
78
|
- CHANGELOG.md
|
78
79
|
- Gemfile
|
80
|
+
- LICENSE.md
|
79
81
|
- README.md
|
80
82
|
- Rakefile
|
83
|
+
- TODO.md
|
81
84
|
- do
|
82
85
|
- docker-compose.yml
|
83
86
|
- lib/rblade.rb
|
@@ -87,9 +90,12 @@ files:
|
|
87
90
|
- lib/rblade/compiler/compiles_echos.rb
|
88
91
|
- lib/rblade/compiler/compiles_ruby.rb
|
89
92
|
- lib/rblade/compiler/compiles_statements.rb
|
93
|
+
- lib/rblade/compiler/compiles_verbatim.rb
|
90
94
|
- lib/rblade/compiler/statements/compiles_conditionals.rb
|
95
|
+
- lib/rblade/compiler/statements/compiles_html_attributes.rb
|
91
96
|
- lib/rblade/compiler/statements/compiles_inline_ruby.rb
|
92
97
|
- lib/rblade/compiler/statements/compiles_loops.rb
|
98
|
+
- lib/rblade/compiler/statements/compiles_once.rb
|
93
99
|
- lib/rblade/compiler/statements/compiles_props.rb
|
94
100
|
- lib/rblade/compiler/statements/compiles_stacks.rb
|
95
101
|
- lib/rblade/compiler/tokenizes_components.rb
|
@@ -125,5 +131,5 @@ requirements: []
|
|
125
131
|
rubygems_version: 3.5.11
|
126
132
|
signing_key:
|
127
133
|
specification_version: 4
|
128
|
-
summary:
|
134
|
+
summary: A component-first templating engine for Rails
|
129
135
|
test_files: []
|