serbea 0.1.4 → 0.3.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9c63686513a6572b1d85616db1bb52f366e97e803ec7dc1ef0fa7e11f8af4d4
4
- data.tar.gz: d8b65adfddf004589a625755df7a293bc0b2fe88aaf89fadd00acb18d0aaf152
3
+ metadata.gz: 5d775a1dece2c26b48dca5f3462e92e5220190323f9472511a6bc8229768be0c
4
+ data.tar.gz: c3af48d385fc9d6a171de4989fdddf829a40deffdb8a9c86be62a378e9d85231
5
5
  SHA512:
6
- metadata.gz: 0ea5ba66fc3bfa1fcec0a33fb49dccb9241f0b4f4b4640c87c5d35b3b88f5bf9c47c8c3f8d91e5445536a3490ce9261c97a8445e94525f2117fcce8ad6dbc9a2
7
- data.tar.gz: 0dff40a09f11f71b839d2a7445ab1e9032be49c136074c9efd3a6c8ddbfda00a00a9653609e19c14c4bc8e3c5bb743f259cee55e207db74fb20da3dd889945e9
6
+ metadata.gz: 2366d4e4124ffa50816523d179d0235dbab44ffe2e190c9e913cdda5535b04cd8ede8cdd8082d217b85501f8636381066b2de7dd9b37fd6cde251c771221a295
7
+ data.tar.gz: 5ff94f67a72b57a0015243c8419340745b16f50ce8ad94d69d51d1830434cd4f3f3e6bce39794395d84ecb04b955fb140902331c1f5622e232d6cb35dee4ed7b
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in serbea.gemspec
6
+ gemspec
@@ -1,193 +1,16 @@
1
1
  require "tilt"
2
2
  require "tilt/erubi"
3
- require 'erubi/capture_end'
4
- require "ostruct"
3
+ require "erubi/capture_end"
5
4
 
6
- module SerbeaHelpers
7
- def capture(obj=nil)
8
- previous_buffer_state = @_erbout
9
- @_erbout = +""
10
- result = obj ? yield(obj) : yield
11
- @_erbout = previous_buffer_state
12
-
13
- result.respond_to?(:html_safe) ? result.html_safe : result
14
- end
15
-
16
- def pipeline(context, value)
17
- Serbea::Pipeline.new(context, value)
18
- end
19
-
20
- def helper(name, &block)
21
- self.class.send(:define_method, name, &block)
22
- end
23
-
24
- def h(input)
25
- Erubi.h(input)
26
- end
27
- alias_method :escape, :h
28
- end
29
-
30
- module Serbea
31
- class Pipeline
32
- def self.output_processor=(processor)
33
- @output_processor = processor
34
- end
35
- def self.output_processor
36
- @output_processor ||= lambda do |input|
37
- # no-op
38
- input
39
- end
40
- end
41
-
42
- def initialize(context, value)
43
- @context = context
44
- @value = value
45
- end
46
-
47
- def filter(sym, *aargs)
48
- if @value.respond_to?(sym)
49
- @value = @value.send(sym, *aargs)
50
- elsif @context.respond_to?(sym)
51
- @value = @context.send(sym, @value, *aargs)
52
- else
53
- "Serbea warning: Filter not found: #{sym}".tap do |warning|
54
- raise_on_missing_filters ? raise(warning) : puts(warning)
55
- end
56
- end
57
-
58
- self
59
- end
60
-
61
- def to_s
62
- self.class.output_processor.call @value.to_s
63
- end
64
-
65
- def raise_on_missing_filters; false; end
66
- end
67
-
68
- class ComponentRenderer
69
- include SerbeaHelpers
70
-
71
- def initialize(variables = {})
72
- @variables = variables
73
- end
74
-
75
- def respond_to_missing?(key)
76
- @variables.key?(key)
77
- end
78
-
79
- def method_missing(key)
80
- @variables[key] if respond_to_missing?(key)
81
- end
82
- end
83
- end
84
-
85
- class SerbeaEngine < Erubi::CaptureEndEngine
86
- FRONT_MATTER_REGEXP = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m.freeze
87
-
88
- def self.has_yaml_header?(template)
89
- template.lines.first&.match? %r!\A---\s*\r?\n!
90
- end
91
-
92
- def initialize(input, properties={})
93
- properties[:regexp] = /{%(\:?={1,2}|-|\#|%|\:)?(.*?)([-=])?%}([ \t]*\r?\n)?/m
94
- properties[:strip_front_matter] = true unless properties.key?(:strip_front_matter)
95
- super process_serbea_input(input, properties), properties
96
- end
97
-
98
- def add_postamble(postamble)
99
- src << postamble
100
- src << "@_erbout.html_safe" if postamble.respond_to?(:html_safe)
101
-
102
- src.gsub!("__RAW_START_PRINT__", "{{")
103
- src.gsub!("__RAW_END_PRINT__", "}}")
104
- src.gsub!("__RAW_START_EVAL__", "{%")
105
- src.gsub!("__RAW_END_EVAL__", "%}")
106
- end
107
-
108
- def process_serbea_input(template, properties)
109
- buff = ""
110
-
111
- string = template.dup
112
- if properties[:strip_front_matter] && self.class.has_yaml_header?(string)
113
- if string = string.match(FRONT_MATTER_REGEXP)
114
- string = string.post_match
115
- # yaml_data = SafeYAML.load(template.captures[0])
116
- end
117
- end
118
-
119
- until string.empty?
120
- text, code, string = string.partition(/{% raw %}.*?{% endraw %}/m)
121
-
122
- buff << text
123
- if code.length > 0
124
- buff << code.
125
- sub("{% raw %}", "").
126
- sub("{% endraw %}", "").
127
- gsub("{{", "__RAW_START_PRINT__").
128
- gsub("}}", "__RAW_END_PRINT__").
129
- gsub("{%", "__RAW_START_EVAL__").
130
- gsub("%}", "__RAW_END_EVAL__")
131
- end
132
- end
133
-
134
- string = buff
135
- buff = ""
136
- until string.empty?
137
- text, code, string = string.partition(/{{.*?}}/m)
138
-
139
- buff << text
140
- if code.length > 0
141
- processed_filters = false
142
-
143
- code = code.gsub('\|', "__PIPE_C__")
144
-
145
- subs = code.gsub(/\s*\|\s+(.*?)\s([^|}]*)/) do
146
- args = $2
147
- args = nil if args.strip == ""
148
- prefix = processed_filters ? ")" : "))"
149
- processed_filters = true
150
- "#{prefix}.filter(:#{$1.chomp(":")}" + (args ? ", #{args}" : "")
151
- end
152
-
153
- pipeline_suffix = processed_filters ? ") %}" : ")) %}"
154
-
155
- buff << subs.sub("{{", "{%= pipeline(self, (").sub("}}", pipeline_suffix).gsub("__PIPE_C__", '\|')
156
- end
157
- end
158
-
159
- # puts buff
160
- buff
161
- end # method
162
-
163
- private
164
-
165
- # Handle the <%:= and <%:== tags
166
- # Carried over from the Erubi class but with changed indicators
167
- def handle(indicator, code, tailch, rspace, lspace)
168
- case indicator
169
- when ':=', ':=='
170
- rspace = nil if tailch && !tailch.empty?
171
- add_text(lspace) if lspace
172
- escape_capture = !((indicator == ':=') ^ @escape_capture)
173
- src << "begin; (#{@bufstack} ||= []) << #{@bufvar}; #{@bufvar} = #{@bufval}; #{@bufstack}.last << #{@escapefunc if escape_capture}((" << code
174
- add_text(rspace) if rspace
175
- when ':'
176
- rspace = nil if tailch && !tailch.empty?
177
- add_text(lspace) if lspace
178
- result = @yield_returns_buffer ? " #{@bufvar}; " : ""
179
- src << result << code << ")).to_s; ensure; #{@bufvar} = #{@bufstack}.pop; end;"
180
- add_text(rspace) if rspace
181
- else
182
- super
183
- end
184
- end
185
- end # class
5
+ require "serbea/helpers"
6
+ require "serbea/pipeline"
7
+ require "serbea/template_engine"
8
+ require "serbea/component_renderer"
186
9
 
187
10
  module Tilt
188
11
  class SerbeaTemplate < ErubiTemplate
189
12
  def prepare
190
- @options.merge!(outvar: "@_erbout", engine_class: SerbeaEngine)
13
+ @options.merge!(outvar: "@_erbout", engine_class: Serbea::TemplateEngine)
191
14
  super
192
15
  end
193
16
 
@@ -197,7 +20,7 @@ module Tilt
197
20
  end
198
21
  end
199
22
 
200
- Tilt.register Tilt::SerbeaTemplate, "serb" #, "serbea"
23
+ Tilt.register Tilt::SerbeaTemplate, "serb"
201
24
 
202
25
  if defined?(Rails::Railtie)
203
26
  class Railtie < ::Rails::Railtie
@@ -208,3 +31,7 @@ if defined?(Rails::Railtie)
208
31
  end
209
32
  end
210
33
  end
34
+
35
+ if defined?(Bridgetown)
36
+ require "serbea/bridgetown_support"
37
+ end
@@ -0,0 +1,56 @@
1
+ module Bridgetown
2
+ class SerbeaView < RubyTemplateView
3
+ include Serbea::Helpers
4
+
5
+ def partial(partial_name, options = {})
6
+ options.merge!(options[:locals]) if options[:locals]
7
+
8
+ partial_segments = partial_name.split("/")
9
+ partial_segments.last.sub!(%r!^!, "_")
10
+ partial_name = partial_segments.join("/")
11
+
12
+ Tilt::SerbeaTemplate.new(
13
+ site.in_source_dir(site.config[:partials_dir], "#{partial_name}.serb")
14
+ ).render(self, options)
15
+ end
16
+
17
+ def markdownify
18
+ previous_buffer_state = @_erbout
19
+ @_erbout = +""
20
+ result = yield
21
+ @_erbout = previous_buffer_state
22
+
23
+ content = Bridgetown::Utils.reindent_for_markdown(result)
24
+ converter = site.find_converter_instance(Bridgetown::Converters::Markdown)
25
+ md_output = converter.convert(content).strip
26
+ @_erbout << md_output
27
+ end
28
+ end
29
+
30
+ module Converters
31
+ class SerbeaTemplates < Converter
32
+ input :serb
33
+
34
+ # Logic to do the Serbea content conversion.
35
+ #
36
+ # @param content [String] Content of the file (without front matter).
37
+ # @params convertible [Bridgetown::Page, Bridgetown::Document, Bridgetown::Layout]
38
+ # The instantiated object which is processing the file.
39
+ #
40
+ # @return [String] The converted content.
41
+ def convert(content, convertible)
42
+ serb_view = Bridgetown::SerbeaView.new(convertible)
43
+
44
+ serb_renderer = Tilt::SerbeaTemplate.new(convertible.relative_path) { content }
45
+
46
+ if convertible.is_a?(Bridgetown::Layout)
47
+ serb_renderer.render(serb_view) do
48
+ convertible.current_document_output
49
+ end
50
+ else
51
+ serb_renderer.render(serb_view)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,19 @@
1
+ module Serbea
2
+ class ComponentRenderer
3
+ include Helpers
4
+
5
+ def initialize(variables = {})
6
+ @variables = variables
7
+ end
8
+
9
+ def respond_to_missing?(key, include_private = false)
10
+ @variables.key?(key)
11
+ end
12
+
13
+ def method_missing(key)
14
+ return @variables[key] if respond_to_missing?(key)
15
+
16
+ super
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,46 @@
1
+ module Serbea
2
+ module Helpers
3
+ def self.included(mod)
4
+ Serbea::Pipeline.deny_value_method %i(escape h prepend append map assign)
5
+ end
6
+
7
+ def capture(obj=nil)
8
+ previous_buffer_state = @_erbout
9
+ @_erbout = +""
10
+ result = obj ? yield(obj) : yield
11
+ @_erbout = previous_buffer_state
12
+
13
+ result.respond_to?(:html_safe) ? result.html_safe : result
14
+ end
15
+
16
+ def pipeline(context, value)
17
+ Pipeline.new(context, value)
18
+ end
19
+
20
+ def helper(name, &block)
21
+ self.class.send(:define_method, name, &block)
22
+ end
23
+
24
+ def h(input)
25
+ Erubi.h(input)
26
+ end
27
+ alias_method :escape, :h
28
+
29
+ def prepend(old_string, new_string)
30
+ "#{new_string}#{old_string}"
31
+ end
32
+
33
+ def append(old_string, new_string)
34
+ "#{old_string}#{new_string}"
35
+ end
36
+
37
+ def map(input, block)
38
+ input.map(&block)
39
+ end
40
+
41
+ def assign(input, varname, preserve: false)
42
+ self.instance_variable_set("@#{varname}", input)
43
+ preserve ? input : nil
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,45 @@
1
+ module Serbea
2
+ class Pipeline
3
+ def self.output_processor=(processor)
4
+ @output_processor = processor
5
+ end
6
+ def self.output_processor
7
+ @output_processor ||= lambda do |input|
8
+ # no-op
9
+ input
10
+ end
11
+ end
12
+
13
+ def self.deny_value_method(name)
14
+ value_methods_denylist.merge Array(name)
15
+ end
16
+ def self.value_methods_denylist
17
+ @value_methods_denylist ||= Set.new
18
+ end
19
+
20
+ def initialize(context, value)
21
+ @context = context
22
+ @value = value
23
+ end
24
+
25
+ def filter(name, *args)
26
+ if @value.respond_to?(name) && !self.class.value_methods_denylist.include?(name)
27
+ @value = @value.send(name, *args)
28
+ elsif @context.respond_to?(name)
29
+ @value = @context.send(name, @value, *args)
30
+ else
31
+ "Serbea warning: Filter not found: #{name}".tap do |warning|
32
+ raise_on_missing_filters ? raise(warning) : STDERR.puts(warning)
33
+ end
34
+ end
35
+
36
+ self
37
+ end
38
+
39
+ def to_s
40
+ self.class.output_processor.call @value.to_s
41
+ end
42
+
43
+ def raise_on_missing_filters; false; end
44
+ end
45
+ end
@@ -8,7 +8,7 @@ module Serbea
8
8
  def handles_encoding?; true; end
9
9
 
10
10
  def compile(template, source)
11
- "self.class.include(SerbeaHelpers)\n" + Tilt::SerbeaTemplate.new { source }.precompiled_template([])
11
+ "self.class.include(Serbea::Helpers);" + Tilt::SerbeaTemplate.new { source }.precompiled_template([])
12
12
  end
13
13
 
14
14
  def self.call(template, source = nil)
@@ -0,0 +1,159 @@
1
+ module Serbea
2
+ class TemplateEngine < Erubi::CaptureEndEngine
3
+ FRONT_MATTER_REGEXP = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m.freeze
4
+
5
+ def self.render_directive=(directive)
6
+ @render_directive = directive
7
+ end
8
+ def self.render_directive
9
+ @render_directive ||= "render"
10
+ end
11
+
12
+ def self.has_yaml_header?(template)
13
+ template.lines.first&.match? %r!\A---\s*\r?\n!
14
+ end
15
+
16
+ def initialize(input, properties={})
17
+ properties[:regexp] = /{%(\:?={1,2}|-|\#|%|\:)?(.*?)([-=])?%}([ \t]*\r?\n)?/m
18
+ properties[:strip_front_matter] = true unless properties.key?(:strip_front_matter)
19
+ super process_serbea_input(input, properties), properties
20
+ end
21
+
22
+ def add_postamble(postamble)
23
+ src << postamble
24
+ src << "@_erbout.html_safe" if postamble.respond_to?(:html_safe)
25
+
26
+ src.gsub!("__RAW_START_PRINT__", "{{")
27
+ src.gsub!("__RAW_END_PRINT__", "}}")
28
+ src.gsub!("__RAW_START_EVAL__", "{%")
29
+ src.gsub!("__RAW_END_EVAL__", "%}")
30
+ end
31
+
32
+ def process_serbea_input(template, properties)
33
+ buff = ""
34
+
35
+ string = template.dup
36
+ if properties[:strip_front_matter] && self.class.has_yaml_header?(string)
37
+ if string = string.match(FRONT_MATTER_REGEXP)
38
+ string = string.post_match
39
+ # yaml_data = SafeYAML.load(template.captures[0])
40
+ end
41
+ end
42
+
43
+ # Ensure the raw "tag" will strip out all ERB-style processing
44
+ until string.empty?
45
+ text, code, string = string.partition(/{% raw %}.*?{% endraw %}/m)
46
+
47
+ buff << text
48
+ if code.length > 0
49
+ buff << code.
50
+ sub("{% raw %}", "").
51
+ sub("{% endraw %}", "").
52
+ gsub("{{", "__RAW_START_PRINT__").
53
+ gsub("}}", "__RAW_END_PRINT__").
54
+ gsub("{%", "__RAW_START_EVAL__").
55
+ gsub("%}", "__RAW_END_EVAL__")
56
+ end
57
+ end
58
+
59
+ # Process any pipelines
60
+ string = buff
61
+ buff = ""
62
+ until string.empty?
63
+ text, code, string = string.partition(/{{.*?}}/m)
64
+
65
+ buff << text
66
+ if code.length > 0
67
+ processed_filters = false
68
+
69
+ code = code.gsub('\|', "__PIPE_C__")
70
+
71
+ subs = code.gsub(/\s*\|>?\s+(.*?)\s([^|}]*)/) do
72
+ args = $2
73
+ args = nil if args.strip == ""
74
+ prefix = processed_filters ? ")" : "))"
75
+ processed_filters = true
76
+ "#{prefix}.filter(:#{$1.chomp(":")}" + (args ? ", #{args}" : "")
77
+ end
78
+
79
+ pipeline_suffix = processed_filters ? ") %}" : ")) %}"
80
+
81
+ buff << subs.sub("{{", "{%= pipeline(self, (").sub("}}", pipeline_suffix).gsub("__PIPE_C__", '\|')
82
+ end
83
+ end
84
+
85
+ # Process any directives
86
+ #
87
+ # TODO: allow custom directives! aka
88
+ # {%@something whatever %}
89
+ # {%@script
90
+ # const foo = "really? #{really}!"
91
+ # alert(foo.toLowerCase())
92
+ # %}
93
+ # {%@preact AwesomeChart data={#{ruby_data.to_json}} %}
94
+ string = buff
95
+ buff = ""
96
+ until string.empty?
97
+ text, code, string = string.partition(/{%@.*?%}/m)
98
+
99
+ buff << text
100
+ if code.length > 0
101
+ code.sub! /^\{%@/, ""
102
+ code.sub! /%}$/, ""
103
+ unless ["end", ""].include? code.strip
104
+ pieces = code.split(" ")
105
+ if pieces[0].start_with?(/[A-Z]/) # Ruby class name
106
+ pieces[0].prepend " "
107
+ pieces[0] << ".new("
108
+ else # string or something else
109
+ pieces[0].prepend "("
110
+ end
111
+
112
+ includes_block = false
113
+ pieces.reverse.each do |piece|
114
+ if piece == "do" && (pieces.last == "do" || pieces.last.end_with?("|"))
115
+ piece.prepend(") ")
116
+ includes_block = true
117
+ break
118
+ end
119
+ end
120
+
121
+ if includes_block
122
+ buff << "{%:= #{self.class.render_directive}#{pieces.join(" ")} %}"
123
+ else
124
+ pieces.last << ")"
125
+ buff << "{%= #{self.class.render_directive}#{pieces.join(" ")} %}"
126
+ end
127
+ else
128
+ buff << "{%: end %}"
129
+ end
130
+ end
131
+ end
132
+
133
+ buff
134
+ end
135
+
136
+ private
137
+
138
+ # Handle the {%:= and {%:== tags
139
+ # Carried over from the Erubi class but with changed indicators
140
+ def handle(indicator, code, tailch, rspace, lspace)
141
+ case indicator
142
+ when ':=', ':=='
143
+ rspace = nil if tailch && !tailch.empty?
144
+ add_text(lspace) if lspace
145
+ escape_capture = !((indicator == ':=') ^ @escape_capture)
146
+ src << "begin; (#{@bufstack} ||= []) << #{@bufvar}; #{@bufvar} = #{@bufval}; #{@bufstack}.last << #{@escapefunc if escape_capture}((" << code
147
+ add_text(rspace) if rspace
148
+ when ':'
149
+ rspace = nil if tailch && !tailch.empty?
150
+ add_text(lspace) if lspace
151
+ result = @yield_returns_buffer ? " #{@bufvar}; " : ""
152
+ src << result << code << ")).to_s; ensure; #{@bufvar} = #{@bufstack}.pop; end;"
153
+ add_text(rspace) if rspace
154
+ else
155
+ super
156
+ end
157
+ end
158
+ end # class
159
+ end
@@ -1,3 +1,3 @@
1
1
  module Serbea
2
- VERSION = "0.1.4"
2
+ VERSION = "0.3.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serbea
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bridgetown Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-17 00:00:00.000000000 Z
11
+ date: 2020-09-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: erubi
@@ -45,10 +45,16 @@ extensions: []
45
45
  extra_rdoc_files: []
46
46
  files:
47
47
  - ".gitignore"
48
+ - Gemfile
48
49
  - README.md
49
50
  - Rakefile
50
51
  - lib/serbea.rb
52
+ - lib/serbea/bridgetown_support.rb
53
+ - lib/serbea/component_renderer.rb
54
+ - lib/serbea/helpers.rb
55
+ - lib/serbea/pipeline.rb
51
56
  - lib/serbea/rails_support.rb
57
+ - lib/serbea/template_engine.rb
52
58
  - lib/version.rb
53
59
  - serbea.gemspec
54
60
  homepage: https://github.com/bridgetownrb/serbea