serbea 0.1.2 → 0.3.1

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: 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