serbea 0.1.2 → 0.3.1

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: c4839efc17aef1ac9f742179335e692cdb592555453b06230309e0411b21d2d6
4
- data.tar.gz: 147247721c682b47baf20c74864f488e877ae7ab1b1625c7c5866f3e9111008a
3
+ metadata.gz: 9dfc45d5f8581d988481bf56c492498b5bbd8b08186910c655e6fa0964fe48dc
4
+ data.tar.gz: a25507d87ae9eeed0f575cdc5825212ca5d3bfadd1fbe388b7dfc219b53d721d
5
5
  SHA512:
6
- metadata.gz: 2f816f6c1551f0173fd101d945d7e6d9ee1b3f7f928df5d3ada210ce00c721d61c43fb891ac9600f68e33cab219d55e81cd686df2ea52038db4b9268139db9da
7
- data.tar.gz: 621c7813892d0ee0b0837f9cbb60eb0dd85c397992389f929070b25aa79b475bfe8c476ce3a13a430773228447093d8f34e7bf4814ce11757201a6cd20adc1b2
6
+ metadata.gz: 3da42d61791e24028f5ac9c68c24c6cf73d98f7568ffa87fb04cca4c8f45b77d9dddc4a68025cbbd7e9f58429ccaa95e79eecdae249b7a272d424cf32648ed36
7
+ data.tar.gz: 216bdddc4a48696fabac9321e9f6d25b63e15adda17a22041f23b7963fd7a807a7840ddfb4e289349309361d8f6285801f651822b0ec86538d07980c54c3fb8b
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,183 +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 initialize(context, value)
33
- @context = context
34
- @value = value
35
- end
36
-
37
- def filter(sym, *aargs)
38
- if @value.respond_to?(sym)
39
- @value = @value.send(sym, *aargs)
40
- elsif @context.respond_to?(sym)
41
- @value = @context.send(sym, @value, *aargs)
42
- else
43
- "Serbea warning: Filter not found: #{sym}".tap do |warning|
44
- raise_on_missing_filters ? raise(warning) : puts(warning)
45
- end
46
- end
47
-
48
- self
49
- end
50
-
51
- def to_s
52
- @value.to_s
53
- end
54
-
55
- def raise_on_missing_filters; false; end
56
- end
57
-
58
- class ComponentRenderer
59
- include SerbeaHelpers
60
-
61
- def initialize(variables = {})
62
- @variables = variables
63
- end
64
-
65
- def respond_to_missing?(key)
66
- @variables.key?(key)
67
- end
68
-
69
- def method_missing(key)
70
- @variables[key] if respond_to_missing?(key)
71
- end
72
- end
73
- end
74
-
75
- class SerbeaEngine < Erubi::CaptureEndEngine
76
- FRONT_MATTER_REGEXP = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m.freeze
77
-
78
- def self.has_yaml_header?(template)
79
- template.lines.first&.match? %r!\A---\s*\r?\n!
80
- end
81
-
82
- def initialize(input, properties={})
83
- properties[:regexp] = /{%(\:?={1,2}|-|\#|%|\:)?(.*?)([-=])?%}([ \t]*\r?\n)?/m
84
- properties[:strip_front_matter] = true unless properties.key?(:strip_front_matter)
85
- super process_serbea_input(input, properties), properties
86
- end
87
-
88
- def add_postamble(postamble)
89
- src << postamble
90
- src << "@_erbout.html_safe" if postamble.respond_to?(:html_safe)
91
-
92
- src.gsub!("__RAW_START_PRINT__", "{{")
93
- src.gsub!("__RAW_END_PRINT__", "}}")
94
- src.gsub!("__RAW_START_EVAL__", "{%")
95
- src.gsub!("__RAW_END_EVAL__", "%}")
96
- end
97
-
98
- def process_serbea_input(template, properties)
99
- buff = ""
100
-
101
- string = template.dup
102
- if properties[:strip_front_matter] && self.class.has_yaml_header?(string)
103
- if string = string.match(FRONT_MATTER_REGEXP)
104
- string = string.post_match
105
- # yaml_data = SafeYAML.load(template.captures[0])
106
- end
107
- end
108
-
109
- until string.empty?
110
- text, code, string = string.partition(/{% raw %}.*?{% endraw %}/m)
111
-
112
- buff << text
113
- if code.length > 0
114
- buff << code.
115
- sub("{% raw %}", "").
116
- sub("{% endraw %}", "").
117
- gsub("{{", "__RAW_START_PRINT__").
118
- gsub("}}", "__RAW_END_PRINT__").
119
- gsub("{%", "__RAW_START_EVAL__").
120
- gsub("%}", "__RAW_END_EVAL__")
121
- end
122
- end
123
-
124
- string = buff
125
- buff = ""
126
- until string.empty?
127
- text, code, string = string.partition(/{{.*?}}/m)
128
-
129
- buff << text
130
- if code.length > 0
131
- processed_filters = false
132
-
133
- code = code.gsub('\|', "__PIPE_C__")
134
-
135
- subs = code.gsub(/ *\| +(.*?) ([^|}]*)/) do
136
- args = $2
137
- args = nil if args.strip == ""
138
- prefix = processed_filters ? ")" : "))"
139
- processed_filters = true
140
- "#{prefix}.filter(:#{$1.chomp(":")}" + (args ? ", #{args}" : "")
141
- end
142
-
143
- pipeline_suffix = processed_filters ? ") %}" : ")) %}"
144
-
145
- buff << subs.sub("{{", "{%= pipeline(self, (").sub("}}", pipeline_suffix).gsub("__PIPE_C__", '\|')
146
- end
147
- end
148
-
149
- # puts buff
150
- buff
151
- end # method
152
-
153
- private
154
-
155
- # Handle the <%:= and <%:== tags
156
- # Carried over from the Erubi class but with changed indicators
157
- def handle(indicator, code, tailch, rspace, lspace)
158
- case indicator
159
- when ':=', ':=='
160
- rspace = nil if tailch && !tailch.empty?
161
- add_text(lspace) if lspace
162
- escape_capture = !((indicator == ':=') ^ @escape_capture)
163
- src << "begin; (#{@bufstack} ||= []) << #{@bufvar}; #{@bufvar} = #{@bufval}; #{@bufstack}.last << #{@escapefunc if escape_capture}((" << code
164
- add_text(rspace) if rspace
165
- when ':'
166
- rspace = nil if tailch && !tailch.empty?
167
- add_text(lspace) if lspace
168
- result = @yield_returns_buffer ? " #{@bufvar}; " : ""
169
- src << result << code << ")).to_s; ensure; #{@bufvar} = #{@bufstack}.pop; end;"
170
- add_text(rspace) if rspace
171
- else
172
- super
173
- end
174
- end
175
- end # class
5
+ require "serbea/helpers"
6
+ require "serbea/component_renderer"
7
+ require "serbea/pipeline"
8
+ require "serbea/template_engine"
176
9
 
177
10
  module Tilt
178
11
  class SerbeaTemplate < ErubiTemplate
179
12
  def prepare
180
- @options.merge!(outvar: "@_erbout", engine_class: SerbeaEngine)
13
+ @options.merge!(outvar: "@_erbout", engine_class: Serbea::TemplateEngine)
181
14
  super
182
15
  end
183
16
 
@@ -187,7 +20,7 @@ module Tilt
187
20
  end
188
21
  end
189
22
 
190
- Tilt.register Tilt::SerbeaTemplate, "serb" #, "serbea"
23
+ Tilt.register Tilt::SerbeaTemplate, "serb"
191
24
 
192
25
  if defined?(Rails::Railtie)
193
26
  class Railtie < ::Rails::Railtie
@@ -198,3 +31,7 @@ if defined?(Rails::Railtie)
198
31
  end
199
32
  end
200
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,25 @@
1
+ module Serbea
2
+ module Helpers
3
+ def capture(obj=nil)
4
+ previous_buffer_state = @_erbout
5
+ @_erbout = +""
6
+ result = obj ? yield(obj) : yield
7
+ @_erbout = previous_buffer_state
8
+
9
+ result.respond_to?(:html_safe) ? result.html_safe : result
10
+ end
11
+
12
+ def pipeline(context, value)
13
+ Pipeline.new(context, value)
14
+ end
15
+
16
+ def helper(name, &block)
17
+ self.class.send(:define_method, name, &block)
18
+ end
19
+
20
+ def h(input)
21
+ Erubi.h(input)
22
+ end
23
+ alias_method :escape, :h
24
+ end
25
+ end
@@ -0,0 +1,38 @@
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 initialize(context, value)
14
+ @context = context
15
+ @value = value
16
+ end
17
+
18
+ def filter(sym, *aargs)
19
+ if @value.respond_to?(sym)
20
+ @value = @value.send(sym, *aargs)
21
+ elsif @context.respond_to?(sym)
22
+ @value = @context.send(sym, @value, *aargs)
23
+ else
24
+ "Serbea warning: Filter not found: #{sym}".tap do |warning|
25
+ raise_on_missing_filters ? raise(warning) : puts(warning)
26
+ end
27
+ end
28
+
29
+ self
30
+ end
31
+
32
+ def to_s
33
+ self.class.output_processor.call @value.to_s
34
+ end
35
+
36
+ def raise_on_missing_filters; false; end
37
+ end
38
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # copied from https://github.com/haml/haml/blob/main/lib/haml/plugin.rb
3
+ # inspired by https://github.com/haml/haml/blob/main/lib/haml/plugin.rb
4
4
  module Serbea
5
5
 
6
6
  # This module makes Serbea work with Rails using the template handler API.
@@ -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)
@@ -25,4 +25,8 @@ module Serbea
25
25
  end
26
26
  end
27
27
 
28
- ActionView::Template.register_template_handler(:serb, Serbea::Plugin)
28
+ ActionView::Template.register_template_handler(:serb, Serbea::Plugin)
29
+
30
+ Serbea::Pipeline.output_processor = lambda do |input|
31
+ input.html_safe? ? input : ActionController::Base.helpers.strip_tags(input)
32
+ end
@@ -0,0 +1,151 @@
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 the pipeline outputs
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 the render directives
86
+ string = buff
87
+ buff = ""
88
+ until string.empty?
89
+ text, code, string = string.partition(/{%@.*?%}/m)
90
+
91
+ buff << text
92
+ if code.length > 0
93
+ code.sub! /^\{%@/, ""
94
+ code.sub! /%}$/, ""
95
+ unless ["end", ""].include? code.strip
96
+ pieces = code.split(" ")
97
+ if pieces[0].start_with?(/[A-Z]/) # Ruby class name
98
+ pieces[0].prepend " "
99
+ pieces[0] << ".new("
100
+ else # string or something else
101
+ pieces[0].prepend "("
102
+ end
103
+
104
+ includes_block = false
105
+ pieces.reverse.each do |piece|
106
+ if piece == "do" && (pieces.last == "do" || pieces.last.end_with?("|"))
107
+ piece.prepend(") ")
108
+ includes_block = true
109
+ break
110
+ end
111
+ end
112
+
113
+ if includes_block
114
+ buff << "{%:= #{self.class.render_directive}#{pieces.join(" ")} %}"
115
+ else
116
+ pieces.last << ")"
117
+ buff << "{%= #{self.class.render_directive}#{pieces.join(" ")} %}"
118
+ end
119
+ else
120
+ buff << "{%: end %}"
121
+ end
122
+ end
123
+ end
124
+
125
+ buff
126
+ end
127
+
128
+ private
129
+
130
+ # Handle the {%:= and {%:== tags
131
+ # Carried over from the Erubi class but with changed indicators
132
+ def handle(indicator, code, tailch, rspace, lspace)
133
+ case indicator
134
+ when ':=', ':=='
135
+ rspace = nil if tailch && !tailch.empty?
136
+ add_text(lspace) if lspace
137
+ escape_capture = !((indicator == ':=') ^ @escape_capture)
138
+ src << "begin; (#{@bufstack} ||= []) << #{@bufvar}; #{@bufvar} = #{@bufval}; #{@bufstack}.last << #{@escapefunc if escape_capture}((" << code
139
+ add_text(rspace) if rspace
140
+ when ':'
141
+ rspace = nil if tailch && !tailch.empty?
142
+ add_text(lspace) if lspace
143
+ result = @yield_returns_buffer ? " #{@bufvar}; " : ""
144
+ src << result << code << ")).to_s; ensure; #{@bufvar} = #{@bufstack}.pop; end;"
145
+ add_text(rspace) if rspace
146
+ else
147
+ super
148
+ end
149
+ end
150
+ end # class
151
+ end
@@ -1,3 +1,3 @@
1
1
  module Serbea
2
- VERSION = "0.1.2"
2
+ VERSION = "0.3.1"
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.2
4
+ version: 0.3.1
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-14 00:00:00.000000000 Z
11
+ date: 2020-09-22 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