serbea 0.4.1 → 0.6.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: 2403adca3b4cbb2e82ad7bb758df50c04257d45f1b303a1a9b03a15453d66953
4
- data.tar.gz: 1ccfc568da131dd13d9cc627b05fb13577854d4edfbf2ea0a3353b69b097a5f2
3
+ metadata.gz: edd4caa76947988e564a917a9457014cfe194d53ec8b0edf1aae5479ea8b9cf4
4
+ data.tar.gz: e93987c1eb193535cf47fc7dc57b412407d5ad6a832bc8ffd5966bc7bbc5c322
5
5
  SHA512:
6
- metadata.gz: 22633765cd7a2ce0020cdd27708e2bc349cc9ccd168d1d15f7f135926d4a0333098fa05ebd34b7f77811371620f01860d7876935e0be47160e03714f8efc01d6
7
- data.tar.gz: 9c5a097fe9fdb43738e3d61f3d61d973d15bff640ad3ae85cc9fb670e61c4a31154f67522bf9651f65ec6a1e67bf755d1b50ea6bc2508b42dfe9dd6f24c627d3
6
+ metadata.gz: e59b9abc02d1f2a272bef3adf5239fb385bde5924ad4c3a2bb2f8efe6ec11caab6cf2a4b2901fc9ea59821e119b8ea7fb9dc700a4e22773b535633284da89afe
7
+ data.tar.gz: 1bddcc5a82fa3cd62ceead72600ec621e6fcad08d2e3a6c58041cca972505917c19f89b2861514599feef93f9449c0eec78b7fbb69de97135fd2aefebcc4bab8
@@ -1,6 +1,5 @@
1
1
  require "tilt"
2
2
  require "tilt/erubi"
3
- require "erubi/capture_end"
4
3
 
5
4
  require "serbea/helpers"
6
5
  require "serbea/pipeline"
@@ -10,7 +9,7 @@ require "serbea/component_renderer"
10
9
  module Tilt
11
10
  class SerbeaTemplate < ErubiTemplate
12
11
  def prepare
13
- @options.merge!(outvar: "@_erbout", engine_class: Serbea::TemplateEngine)
12
+ @options.merge!(outvar: "@_erbout", bufval: "Serbea::Buffer.new", engine_class: Serbea::TemplateEngine)
14
13
  super
15
14
  end
16
15
 
@@ -1,9 +1,12 @@
1
+ require "serbea/rouge_lexer"
2
+
1
3
  module Bridgetown
2
4
  class SerbeaView < RubyTemplateView
3
5
  include Serbea::Helpers
4
6
 
5
- def partial(partial_name, options = {})
7
+ def partial(partial_name, options = {}, &block)
6
8
  options.merge!(options[:locals]) if options[:locals]
9
+ options[:content] = capture(&block) if block
7
10
 
8
11
  partial_segments = partial_name.split("/")
9
12
  partial_segments.last.sub!(%r!^!, "_")
@@ -13,22 +16,19 @@ module Bridgetown
13
16
  site.in_source_dir(site.config[:partials_dir], "#{partial_name}.serb")
14
17
  ).render(self, options)
15
18
  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)
19
+
20
+ def markdownify(input = nil, &block)
21
+ content = Bridgetown::Utils.reindent_for_markdown(
22
+ block.nil? ? input.to_s : capture(&block)
23
+ )
24
24
  converter = site.find_converter_instance(Bridgetown::Converters::Markdown)
25
- md_output = converter.convert(content).strip
26
- @_erbout << md_output
25
+ converter.convert(content).strip
27
26
  end
28
27
  end
29
28
 
30
29
  module Converters
31
30
  class SerbeaTemplates < Converter
31
+ priority :highest
32
32
  input :serb
33
33
 
34
34
  # Logic to do the Serbea content conversion.
@@ -51,6 +51,22 @@ module Bridgetown
51
51
  serb_renderer.render(serb_view)
52
52
  end
53
53
  end
54
+
55
+ def matches(ext, convertible = nil)
56
+ if convertible
57
+ if convertible.data[:template_engine] == "serbea" ||
58
+ (convertible.data[:template_engine].nil? &&
59
+ @config[:template_engine] == "serbea")
60
+ return true
61
+ end
62
+ end
63
+
64
+ super(ext)
65
+ end
66
+
67
+ def output_ext(ext)
68
+ ext == ".serb" ? ".html" : ext
69
+ end
54
70
  end
55
71
  end
56
72
  end
@@ -1,16 +1,28 @@
1
+ require "active_support/core_ext/string/output_safety"
2
+
1
3
  module Serbea
2
4
  module Helpers
3
5
  def self.included(mod)
4
6
  Serbea::Pipeline.deny_value_method %i(escape h prepend append assign_to)
5
7
  end
6
8
 
7
- def capture(obj=nil)
9
+ def capture(obj = nil, &block)
8
10
  previous_buffer_state = @_erbout
9
- @_erbout = +""
10
- result = obj ? yield(obj) : yield
11
+ @_erbout = Serbea::Buffer.new
12
+
13
+ # For compatibility with ActionView, not used by Bridgetown normally
14
+ previous_ob_state = @output_buffer
15
+ @output_buffer = Serbea::Buffer.new
16
+
17
+ result = instance_exec(obj, &block)
18
+ if @output_buffer != ""
19
+ # use Rails' ActionView buffer if present
20
+ result = @output_buffer
21
+ end
11
22
  @_erbout = previous_buffer_state
12
-
13
- result.respond_to?(:html_safe) ? result.html_safe : result
23
+ @output_buffer = previous_ob_state
24
+
25
+ result.html_safe
14
26
  end
15
27
 
16
28
  def pipeline(context, value)
@@ -22,10 +34,15 @@ module Serbea
22
34
  end
23
35
 
24
36
  def h(input)
25
- Erubi.h(input)
37
+ ERB::Util.h(input.to_s)
26
38
  end
27
39
  alias_method :escape, :h
28
40
 
41
+ def safe(input)
42
+ input.to_s.html_safe
43
+ end
44
+ alias_method :raw, :safe
45
+
29
46
  def prepend(old_string, new_string)
30
47
  "#{new_string}#{old_string}"
31
48
  end
@@ -1,3 +1,5 @@
1
+ require "active_support/core_ext/string/output_safety"
2
+
1
3
  module Serbea
2
4
  class Pipeline
3
5
  def self.exec(template, input: (no_input_passed = true; nil), include_helpers: nil)
@@ -27,11 +29,24 @@ module Serbea
27
29
  end
28
30
  def self.output_processor
29
31
  @output_processor ||= lambda do |input|
30
- # no-op
31
- input
32
+ (!input.html_safe? && self.autoescape) ? ERB::Util.h(input) : input.html_safe
32
33
  end
33
34
  end
34
35
 
36
+ def self.autoescape=(config_boolean)
37
+ @autoescape = config_boolean
38
+ end
39
+ def self.autoescape
40
+ @autoescape.nil? ? true : @autoescape
41
+ end
42
+
43
+ def self.raise_on_missing_filters=(config_boolean)
44
+ @raise_on_missing_filters = config_boolean
45
+ end
46
+ def self.raise_on_missing_filters
47
+ @raise_on_missing_filters ||= false
48
+ end
49
+
35
50
  def self.deny_value_method(name)
36
51
  value_methods_denylist.merge Array(name)
37
52
  end
@@ -70,7 +85,7 @@ module Serbea
70
85
  end
71
86
  else
72
87
  "Serbea warning: Filter not found: #{name}".tap do |warning|
73
- raise_on_missing_filters ? raise(warning) : STDERR.puts(warning)
88
+ self.class.raise_on_missing_filters ? raise(warning) : STDERR.puts(warning)
74
89
  end
75
90
  end
76
91
 
@@ -78,9 +93,7 @@ module Serbea
78
93
  end
79
94
 
80
95
  def to_s
81
- self.class.output_processor.call @value.to_s
96
+ self.class.output_processor.call(@value.is_a?(String) ? @value : @value.to_s)
82
97
  end
83
-
84
- def raise_on_missing_filters; false; end
85
98
  end
86
99
  end
@@ -16,17 +16,7 @@ module Serbea
16
16
 
17
17
  new.compile(template, source)
18
18
  end
19
-
20
- # def cache_fragment(block, name = {}, options = nil)
21
- # @view.fragment_for(block, name, options) do
22
- # eval("_hamlout.buffer", block.binding)
23
- # end
24
- # end
25
19
  end
26
20
  end
27
21
 
28
22
  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,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rouge"
4
+
5
+ module Rouge
6
+ module Lexers
7
+ class Serbea < TemplateLexer
8
+ title "Serbea"
9
+ desc "Embedded Ruby Serbea template files"
10
+
11
+ tag 'serb'
12
+
13
+ filenames '*.serb'
14
+
15
+ def initialize(opts={})
16
+ @ruby_lexer = Ruby.new(opts)
17
+
18
+ super(opts)
19
+ end
20
+
21
+ start do
22
+ parent.reset!
23
+ @ruby_lexer.reset!
24
+ end
25
+
26
+ open = /{%%|{%=|{%#|{%-|{%|{{/
27
+ close = /%%}|-%}|%}|}}/
28
+
29
+ state :root do
30
+ rule %r/{%#/, Comment, :comment
31
+
32
+ rule open, Comment::Preproc, :ruby
33
+
34
+ rule %r/.+?(?=#{open})|.+/m do
35
+ delegate parent
36
+ end
37
+ end
38
+
39
+ state :comment do
40
+ rule close, Comment, :pop!
41
+ rule %r/.+?(?=#{close})|.+/m, Comment
42
+ end
43
+
44
+ state :ruby do
45
+ rule close, Comment::Preproc, :pop!
46
+
47
+ rule %r/.+?(?=#{close})|.+/m do
48
+ delegate @ruby_lexer
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,5 +1,15 @@
1
1
  module Serbea
2
- class TemplateEngine < Erubi::CaptureEndEngine
2
+ class Buffer < String
3
+ def concat_to_s(input)
4
+ concat input.to_s
5
+ end
6
+
7
+ alias_method :safe_append=, :concat_to_s
8
+ alias_method :append=, :concat_to_s
9
+ alias_method :safe_expr_append=, :concat_to_s
10
+ end
11
+
12
+ class TemplateEngine < Erubi::Engine
3
13
  FRONT_MATTER_REGEXP = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m.freeze
4
14
 
5
15
  def self.render_directive=(directive)
@@ -21,14 +31,14 @@ module Serbea
21
31
  end
22
32
 
23
33
  def initialize(input, properties={})
24
- properties[:regexp] = /{%(\:?={1,2}|-|\#|%|\:)?(.*?)([-=])?%}([ \t]*\r?\n)?/m
34
+ properties[:regexp] = /{%(={1,2}|-|\#|%)?(.*?)([-=])?%}([ \t]*\r?\n)?/m
25
35
  properties[:strip_front_matter] = true unless properties.key?(:strip_front_matter)
26
36
  super process_serbea_input(input, properties), properties
27
37
  end
28
38
 
29
39
  def add_postamble(postamble)
30
40
  src << postamble
31
- src << "@_erbout.html_safe" if postamble.respond_to?(:html_safe)
41
+ src << "#{@bufvar}.html_safe"
32
42
 
33
43
  src.gsub!("__RAW_START_PRINT__", "{{")
34
44
  src.gsub!("__RAW_END_PRINT__", "}}")
@@ -91,7 +101,7 @@ module Serbea
91
101
 
92
102
  pipeline_suffix = processed_filters ? ") %}" : ")) %}"
93
103
 
94
- subs = subs.sub("{{", "{%= pipeline(self, (").sub("}}", pipeline_suffix).gsub("__PIPE_C__", '\|')
104
+ subs = subs.sub("{{", "{%= pipeline(self, (").sub("}}", pipeline_suffix).gsub("__PIPE_C__", '|')
95
105
 
96
106
  buff << subs
97
107
 
@@ -140,7 +150,7 @@ module Serbea
140
150
  end
141
151
 
142
152
  if includes_block
143
- buff << "{%:= #{self.class.render_directive}#{pieces.join(" ")} %}"
153
+ buff << "{%= #{self.class.render_directive}#{pieces.join(" ")} %}"
144
154
  else
145
155
  pieces.last << ")"
146
156
  buff << "{%= #{self.class.render_directive}#{pieces.join(" ")} %}"
@@ -149,7 +159,7 @@ module Serbea
149
159
  buff << "\n{% %}" # preserve original directive line length
150
160
  end
151
161
  else
152
- buff << "{%: end %}"
162
+ buff << "{% end %}"
153
163
  end
154
164
  end
155
165
  end
@@ -158,26 +168,27 @@ module Serbea
158
168
  end
159
169
 
160
170
  private
161
-
162
- # Handle the {%:= and {%:== tags
163
- # Carried over from the Erubi class but with changed indicators
164
- def handle(indicator, code, tailch, rspace, lspace)
165
- case indicator
166
- when ':=', ':=='
167
- rspace = nil if tailch && !tailch.empty?
168
- add_text(lspace) if lspace
169
- escape_capture = !((indicator == ':=') ^ @escape_capture)
170
- src << "begin; (#{@bufstack} ||= []) << #{@bufvar}; #{@bufvar} = #{@bufval}; #{@bufstack}.last << #{@escapefunc if escape_capture}((" << code
171
- add_text(rspace) if rspace
172
- when ':'
173
- rspace = nil if tailch && !tailch.empty?
174
- add_text(lspace) if lspace
175
- result = @yield_returns_buffer ? " #{@bufvar}; " : ""
176
- src << result << code << ")).to_s; ensure; #{@bufvar} = #{@bufstack}.pop; end;"
177
- add_text(rspace) if rspace
171
+
172
+ def add_code(code)
173
+ @src << code
174
+ @src << ";#{@bufvar};" if code.strip.split(".").first == "end"
175
+ @src << ';' unless code[Erubi::RANGE_LAST] == "\n"
176
+ end
177
+
178
+ # pulled from Rails' ActionView
179
+ BLOCK_EXPR = %r!\s*((\s+|\))do|\{)(\s*\|[^|]*\|)?\s*\Z!.freeze
180
+
181
+ def add_expression(indicator, code)
182
+ if BLOCK_EXPR.match?(code)
183
+ src << "#{@bufvar}.append= " << code
178
184
  else
179
185
  super
180
186
  end
181
187
  end
188
+
189
+ # Don't allow == to output escaped strings, as that's the opposite of Rails
190
+ def add_expression_result_escaped(code)
191
+ add_expression_result(code)
192
+ end
182
193
  end # class
183
194
  end
@@ -1,3 +1,3 @@
1
1
  module Serbea
2
- VERSION = "0.4.1"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -17,5 +17,6 @@ Gem::Specification.new do |spec|
17
17
  spec.require_paths = ["lib"]
18
18
 
19
19
  spec.add_runtime_dependency("erubi", "~> 1.9")
20
+ spec.add_runtime_dependency("activesupport", "~> 6.0")
20
21
  spec.add_runtime_dependency("tilt", "~> 2.0")
21
22
  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.4.1
4
+ version: 0.6.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-30 00:00:00.000000000 Z
11
+ date: 2020-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: erubi
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '6.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '6.0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: tilt
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -54,6 +68,7 @@ files:
54
68
  - lib/serbea/helpers.rb
55
69
  - lib/serbea/pipeline.rb
56
70
  - lib/serbea/rails_support.rb
71
+ - lib/serbea/rouge_lexer.rb
57
72
  - lib/serbea/template_engine.rb
58
73
  - lib/version.rb
59
74
  - serbea.gemspec