serbea 0.1.1 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0313ced0cb154585166b76fcc3b65e35dff3bb260666c62ad0b3535d34d62029
4
- data.tar.gz: 877a5c31aa98d2f3794dc8664e3cb5324d035f77e0899521b568d1a1d4c8e674
3
+ metadata.gz: 170e76b3b2d6c6024d9721f95831ebc85dd32fda2bca10f2471546bbc95cc5f7
4
+ data.tar.gz: 5dc3336c8549c6933325646f5a3fecdee6fec520393df8e141f86a3ef4b3f0ae
5
5
  SHA512:
6
- metadata.gz: a5f18dd506a40f8f27798bd9a263f797676ebd83847f264e5540a8304441fbab436e16e5c8180ab64774581e6fee2d53d110e013a03812854cc96b0a739dae89
7
- data.tar.gz: a4dd36aa574393c03cf84e4c846c499609e6e0e9aa1268b5abb1bffdac6cd67c59e3cdd413731a9e7ce8374486f2fc5d05faabecf7836916d9be56fbd9c50ef3
6
+ metadata.gz: a8733456977f41a78a2e4a56bd8d25a4b737abdedf54d19cfbf7ad61f43a9edbbd422e1d81206205df366ef56d751567a87284de9c480887a79cefb0ae51ae1c
7
+ data.tar.gz: 57c097000a365d52fa0ee88ca8472957dccbfc898b2acb6d066f3fea49e865f94033cfcb30b9edc6585a1fb72ab191b524fb631c437b86a16c2a707e078b85ca
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,9 +8,7 @@ module Serbea
8
8
  def handles_encoding?; true; end
9
9
 
10
10
  def compile(template, source)
11
- foo = "self.class.include(SerbeaHelpers)\n" + Tilt::SerbeaTemplate.new { source }.precompiled_template([])
12
- p foo
13
- foo
11
+ "self.class.include(Serbea::Helpers);" + Tilt::SerbeaTemplate.new { source }.precompiled_template([])
14
12
  end
15
13
 
16
14
  def self.call(template, source = nil)
@@ -27,4 +25,8 @@ module Serbea
27
25
  end
28
26
  end
29
27
 
30
- 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,142 @@
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
+ if pieces.last == "do"
104
+ pieces.last.prepend ") "
105
+ buff << "{%:= #{self.class.render_directive}#{pieces.join(" ")} %}"
106
+ else
107
+ pieces.last << ")"
108
+ buff << "{%= #{self.class.render_directive}#{pieces.join(" ")} %}"
109
+ end
110
+ else
111
+ buff << "{%: end %}"
112
+ end
113
+ end
114
+ end
115
+
116
+ buff
117
+ end
118
+
119
+ private
120
+
121
+ # Handle the {%:= and {%:== tags
122
+ # Carried over from the Erubi class but with changed indicators
123
+ def handle(indicator, code, tailch, rspace, lspace)
124
+ case indicator
125
+ when ':=', ':=='
126
+ rspace = nil if tailch && !tailch.empty?
127
+ add_text(lspace) if lspace
128
+ escape_capture = !((indicator == ':=') ^ @escape_capture)
129
+ src << "begin; (#{@bufstack} ||= []) << #{@bufvar}; #{@bufvar} = #{@bufval}; #{@bufstack}.last << #{@escapefunc if escape_capture}((" << code
130
+ add_text(rspace) if rspace
131
+ when ':'
132
+ rspace = nil if tailch && !tailch.empty?
133
+ add_text(lspace) if lspace
134
+ result = @yield_returns_buffer ? " #{@bufvar}; " : ""
135
+ src << result << code << ")).to_s; ensure; #{@bufvar} = #{@bufstack}.pop; end;"
136
+ add_text(rspace) if rspace
137
+ else
138
+ super
139
+ end
140
+ end
141
+ end # class
142
+ end
@@ -1,3 +1,3 @@
1
1
  module Serbea
2
- VERSION = "0.1.1"
2
+ VERSION = "0.3.0"
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.1
4
+ version: 0.3.0
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-11 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