serbea 0.4.0 → 0.5.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: 18caf5a2b809d0cf64dc3d6ed6b05186ec6c1cdbb6faf4c3c8f01ec607f65918
4
- data.tar.gz: f94c3df3de70cbfbac1cd481ee41706beff8a0cfc78a23ee54b13ec4345d39fe
3
+ metadata.gz: ce17e2b60c2abf63a033d8d358686d4df115e87a4c149ba3c625a403863e129c
4
+ data.tar.gz: a3901a5286afc92e84b2ecc29b2622e80a592f0d0d9de46a7aa58d836e150c65
5
5
  SHA512:
6
- metadata.gz: 27f9d07b128e5b7537be078b8056add0da4caed1304375a3f2decbd00d14232a60ade8d07817f7c520f2479f78957aff9774ba980391edd4643bb1c4b72454b2
7
- data.tar.gz: dfe541a83671109526c0b9069ef2054dfb9a57c21474180d572ccba8cfcf13b3b59cab5a58e3e9b70e3952ca00ff46ab239a0fdf5f260a07e7956d646ef059b9
6
+ metadata.gz: 52aadba5419583064f26be67a99805ea66af5798b3bd3a34604967c91fdee3f2e6010ba692b6f70a2de798fa5d899bb7760fd3a76975e415932e5922c7f21c6a
7
+ data.tar.gz: 4bc3fcfa08bb021ceb68ae675f4f47d4fd72a2e1cdd71fe68d8b4e435493238c49f205f10ccc52e0980d160a226433af19b70d39d18bc3d73b30c9afb8be0698
@@ -10,7 +10,7 @@ require "serbea/component_renderer"
10
10
  module Tilt
11
11
  class SerbeaTemplate < ErubiTemplate
12
12
  def prepare
13
- @options.merge!(outvar: "@_erbout", engine_class: Serbea::TemplateEngine)
13
+ @options.merge!(outvar: "@_erbout", bufval: "Serbea::Buffer.new", engine_class: Serbea::TemplateEngine)
14
14
  super
15
15
  end
16
16
 
@@ -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
@@ -4,12 +4,22 @@ module Serbea
4
4
  Serbea::Pipeline.deny_value_method %i(escape h prepend append assign_to)
5
5
  end
6
6
 
7
- def capture(obj=nil)
7
+ def capture(obj = nil, &block)
8
8
  previous_buffer_state = @_erbout
9
- @_erbout = +""
10
- result = obj ? yield(obj) : yield
9
+ @_erbout = Serbea::Buffer.new
10
+
11
+ # For compatibility with ActionView, not used by Bridgetown normally
12
+ previous_ob_state = @output_buffer
13
+ @output_buffer = Serbea::Buffer.new
14
+
15
+ result = instance_exec(obj, &block)
16
+ if @output_buffer != ""
17
+ # use Rails' ActionView buffer if present
18
+ result = @output_buffer
19
+ end
11
20
  @_erbout = previous_buffer_state
12
-
21
+ @output_buffer = previous_ob_state
22
+
13
23
  result.respond_to?(:html_safe) ? result.html_safe : result
14
24
  end
15
25
 
@@ -22,7 +32,8 @@ module Serbea
22
32
  end
23
33
 
24
34
  def h(input)
25
- Erubi.h(input)
35
+ result = Erubi.h(input)
36
+ result.respond_to?(:html_safe) ? result.html_safe : result
26
37
  end
27
38
  alias_method :escape, :h
28
39
 
@@ -32,6 +32,13 @@ module Serbea
32
32
  end
33
33
  end
34
34
 
35
+ def self.raise_on_missing_filters=(config_boolean)
36
+ @raise_on_missing_filters = config_boolean
37
+ end
38
+ def self.raise_on_missing_filters
39
+ @raise_on_missing_filters ||= false
40
+ end
41
+
35
42
  def self.deny_value_method(name)
36
43
  value_methods_denylist.merge Array(name)
37
44
  end
@@ -70,7 +77,7 @@ module Serbea
70
77
  end
71
78
  else
72
79
  "Serbea warning: Filter not found: #{name}".tap do |warning|
73
- raise_on_missing_filters ? raise(warning) : STDERR.puts(warning)
80
+ self.class.raise_on_missing_filters ? raise(warning) : STDERR.puts(warning)
74
81
  end
75
82
  end
76
83
 
@@ -80,7 +87,5 @@ module Serbea
80
87
  def to_s
81
88
  self.class.output_processor.call @value.to_s
82
89
  end
83
-
84
- def raise_on_missing_filters; false; end
85
90
  end
86
91
  end
@@ -27,6 +27,8 @@ end
27
27
 
28
28
  ActionView::Template.register_template_handler(:serb, Serbea::Plugin)
29
29
 
30
- Serbea::Pipeline.output_processor = lambda do |input|
31
- input.html_safe? ? input : ActionController::Base.helpers.strip_tags(input)
30
+ if defined?(ActionController::Base)
31
+ Serbea::Pipeline.output_processor = lambda do |input|
32
+ input.html_safe? ? input : ActionController::Base.helpers.strip_tags(input)
33
+ end
32
34
  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" if postamble.respond_to?(:html_safe)
32
42
 
33
43
  src.gsub!("__RAW_START_PRINT__", "{{")
34
44
  src.gsub!("__RAW_END_PRINT__", "}}")
@@ -76,6 +86,7 @@ module Serbea
76
86
 
77
87
  buff << text
78
88
  if code.length > 0
89
+ original_line_length = code.lines.size
79
90
  processed_filters = false
80
91
 
81
92
  code = code.gsub('\|', "__PIPE_C__")
@@ -90,7 +101,13 @@ module Serbea
90
101
 
91
102
  pipeline_suffix = processed_filters ? ") %}" : ")) %}"
92
103
 
93
- buff << subs.sub("{{", "{%= pipeline(self, (").sub("}}", pipeline_suffix).gsub("__PIPE_C__", '\|')
104
+ subs = subs.sub("{{", "{%= pipeline(self, (").sub("}}", pipeline_suffix).gsub("__PIPE_C__", '|')
105
+
106
+ buff << subs
107
+
108
+ (original_line_length - subs.lines.size).times do
109
+ buff << "\n{% %}" # preserve original line length
110
+ end
94
111
  end
95
112
  end
96
113
 
@@ -113,6 +130,8 @@ module Serbea
113
130
  code.sub! /^\{%@/, ""
114
131
  code.sub! /%}$/, ""
115
132
  unless ["end", ""].include? code.strip
133
+ original_line_length = code.lines.size
134
+
116
135
  pieces = code.split(" ")
117
136
  if pieces[0].start_with?(/[A-Z]/) # Ruby class name
118
137
  pieces[0].prepend " "
@@ -131,13 +150,16 @@ module Serbea
131
150
  end
132
151
 
133
152
  if includes_block
134
- buff << "{%:= #{self.class.render_directive}#{pieces.join(" ")} %}"
153
+ buff << "{%= #{self.class.render_directive}#{pieces.join(" ")} %}"
135
154
  else
136
155
  pieces.last << ")"
137
156
  buff << "{%= #{self.class.render_directive}#{pieces.join(" ")} %}"
138
157
  end
158
+ (original_line_length - 1).times do
159
+ buff << "\n{% %}" # preserve original directive line length
160
+ end
139
161
  else
140
- buff << "{%: end %}"
162
+ buff << "{% end %}"
141
163
  end
142
164
  end
143
165
  end
@@ -146,26 +168,27 @@ module Serbea
146
168
  end
147
169
 
148
170
  private
149
-
150
- # Handle the {%:= and {%:== tags
151
- # Carried over from the Erubi class but with changed indicators
152
- def handle(indicator, code, tailch, rspace, lspace)
153
- case indicator
154
- when ':=', ':=='
155
- rspace = nil if tailch && !tailch.empty?
156
- add_text(lspace) if lspace
157
- escape_capture = !((indicator == ':=') ^ @escape_capture)
158
- src << "begin; (#{@bufstack} ||= []) << #{@bufvar}; #{@bufvar} = #{@bufval}; #{@bufstack}.last << #{@escapefunc if escape_capture}((" << code
159
- add_text(rspace) if rspace
160
- when ':'
161
- rspace = nil if tailch && !tailch.empty?
162
- add_text(lspace) if lspace
163
- result = @yield_returns_buffer ? " #{@bufvar}; " : ""
164
- src << result << code << ")).to_s; ensure; #{@bufvar} = #{@bufstack}.pop; end;"
165
- 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
166
184
  else
167
185
  super
168
186
  end
169
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
170
193
  end # class
171
194
  end
@@ -1,3 +1,3 @@
1
1
  module Serbea
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.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.4.0
4
+ version: 0.5.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
@@ -54,6 +54,7 @@ files:
54
54
  - lib/serbea/helpers.rb
55
55
  - lib/serbea/pipeline.rb
56
56
  - lib/serbea/rails_support.rb
57
+ - lib/serbea/rouge_lexer.rb
57
58
  - lib/serbea/template_engine.rb
58
59
  - lib/version.rb
59
60
  - serbea.gemspec