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.
data/TODO.md ADDED
@@ -0,0 +1,2 @@
1
+ Add @shouldRender? Or say you can use return (return _out) to exit early? @return? @exitComponent?
2
+
@@ -11,7 +11,7 @@ module RBlade
11
11
  # <%% and %%> are escape ERB style tags
12
12
  (<%%)(.+?)(%%>)
13
13
  |
14
- (?:^|[\b\s])(@ruby)\s+(.+?)[\s;]*(@endruby)(?:$|[\b\s])
14
+ \s?(?<!\w)(@ruby)\s+(.+?)[\s;]*(@endruby)(?!\w)\s?
15
15
  |
16
16
  (<%)\s+(.+?)[\s;]*(%>)
17
17
  /xm)
@@ -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 !args.nil?
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
- "break;"
14
- end
15
-
16
- def compileBreakIf args
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
- "_push_#{@push_counter}_name=#{args[0]};_push_#{@push_counter}_buffer=_out;_out='';"
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(_push_#{@push_counter + 1}_name, _out);_out=_push_#{@push_counter + 1}_buffer;"
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
- "_push_#{@push_counter}_name=#{args[0]};_push_#{@push_counter}_buffer=_out;_out='';"
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(_push_#{@push_counter + 1}_name, _out);_out=_push_#{@push_counter + 1}_buffer;"
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
- (?:^|[\b\s])
12
- (@@?)
13
- (\w+(?:::\w+)?)
14
- (?:[ \t]*
15
- (\(.*?\))
16
- )?/mx)
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])
@@ -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
@@ -19,5 +19,9 @@ module RBlade
19
19
  def to_s
20
20
  @classes
21
21
  end
22
+
23
+ def to_str
24
+ to_s
25
+ end
22
26
  end
23
27
  end
@@ -33,5 +33,9 @@ module RBlade
33
33
  def to_s
34
34
  @styles
35
35
  end
36
+
37
+ def to_str
38
+ to_s
39
+ end
36
40
  end
37
41
  end
@@ -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('app/views/')
15
- .delete_suffix('.rblade')
16
- .delete_suffix('.html')
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.3.0"
4
- s.summary = "Blade templates for ruby"
5
- s.description = "A port of the Laravel blade templating engine to ruby"
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.3.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-26 00:00:00.000000000 Z
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: A port of the Laravel blade templating engine to ruby
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: Blade templates for ruby
134
+ summary: A component-first templating engine for Rails
129
135
  test_files: []