serbea 0.1.3 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aecb61cdb61e1b9fce6cc6784ba1e020aaac8e36539033b85f7a7857e17527a7
4
- data.tar.gz: 1baf5cb65378c902583f0e527a26299817c2cff7ee904e3941143faa1eb0ca19
3
+ metadata.gz: fdeba2843c805f483e3514fbceaa63d610ac9b436762b8ff7c34ae6f7f6d8c3a
4
+ data.tar.gz: 325e190e80f4cc5cd777e824c512361a71435b482672c1da8d17bf4ffc4d639c
5
5
  SHA512:
6
- metadata.gz: 1d376bf5d53c9cd3582e339fa652d0f09a6eb803be65226273a8855adac59bf22e5d3ef5dd1d22a6d1185ce3c0a79d331165a364c2fcb3fb0e6180927e05a807
7
- data.tar.gz: a75ddb6a3dcf214760d9ca417b60be208a5f85259debd55a4c683a926a497e3a3a6529200e547108861481487ed9a55549dfacde0eefb76dc5813e2a53932ca0
6
+ metadata.gz: fbfa7787a1ed422c4e1e238f2f328c37586e65d1bcc11458e6650803d8d6bfc21a6204bbdd6fa5e038b15e2120d43d08ef9a327e2ff25500e7bd569078d11a0e
7
+ data.tar.gz: b8789ea01c5eb34aed8ceb0d770b94401d6a7167d0fca38d9892ca79d4be7681b30705fb96061e31a9f52aaf5babaa9af4fa57921cab665c63f414bf286408ae
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(/ *\| +(.*?) ([^|}]*)/) 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,37 @@
1
+ module Serbea
2
+ module Helpers
3
+ def self.included(mod)
4
+ Serbea::Pipeline.deny_value_method %i(prepend append)
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
+ end
37
+ 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.3"
2
+ VERSION = "0.3.2"
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.3
4
+ version: 0.3.2
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-25 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