mbrao 1.2.3 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/CHANGELOG.md +5 -0
  4. data/doc/ActionView/Template/Handlers/MbraoTemplate.html +87 -20
  5. data/doc/ActionView/Template/Handlers.html +1 -1
  6. data/doc/HTML/Pipeline/KramdownFilter.html +1 -1
  7. data/doc/HTML/Pipeline.html +1 -1
  8. data/doc/HTML.html +1 -1
  9. data/doc/Mbrao/Author.html +337 -67
  10. data/doc/Mbrao/Content.html +1268 -444
  11. data/doc/Mbrao/ContentPublicInterface.html +24 -20
  12. data/doc/Mbrao/Exceptions/InvalidDate.html +1 -1
  13. data/doc/Mbrao/Exceptions/InvalidMetadata.html +1 -1
  14. data/doc/Mbrao/Exceptions/Parsing.html +1 -1
  15. data/doc/Mbrao/Exceptions/Rendering.html +1 -1
  16. data/doc/Mbrao/Exceptions/UnavailableLocalization.html +1 -1
  17. data/doc/Mbrao/Exceptions/Unimplemented.html +1 -1
  18. data/doc/Mbrao/Exceptions/UnknownEngine.html +1 -1
  19. data/doc/Mbrao/Exceptions.html +1 -1
  20. data/doc/Mbrao/Parser.html +11 -11
  21. data/doc/Mbrao/ParsingEngines/Base.html +25 -24
  22. data/doc/Mbrao/ParsingEngines/PlainText.html +17 -16
  23. data/doc/Mbrao/ParsingEngines.html +1 -1
  24. data/doc/Mbrao/PublicInterface/ClassMethods.html +312 -19
  25. data/doc/Mbrao/PublicInterface.html +1 -1
  26. data/doc/Mbrao/RenderingEngines/Base.html +7 -7
  27. data/doc/Mbrao/RenderingEngines/HtmlPipeline.html +27 -15
  28. data/doc/Mbrao/RenderingEngines.html +1 -1
  29. data/doc/Mbrao/Validations/ClassMethods.html +21 -21
  30. data/doc/Mbrao/Validations.html +1 -1
  31. data/doc/Mbrao/Version.html +3 -3
  32. data/doc/Mbrao.html +1 -1
  33. data/doc/_index.html +1 -1
  34. data/doc/file.README.html +1 -1
  35. data/doc/index.html +1 -1
  36. data/doc/method_list.html +86 -62
  37. data/doc/top-level-namespace.html +1 -1
  38. data/lib/mbrao/author.rb +18 -4
  39. data/lib/mbrao/content.rb +93 -44
  40. data/lib/mbrao/integrations/rails.rb +12 -5
  41. data/lib/mbrao/parser.rb +23 -0
  42. data/lib/mbrao/parsing_engines/base.rb +12 -11
  43. data/lib/mbrao/parsing_engines/plain_text.rb +29 -23
  44. data/lib/mbrao/rendering_engines/base.rb +4 -4
  45. data/lib/mbrao/rendering_engines/html_pipeline.rb +7 -2
  46. data/lib/mbrao/version.rb +2 -2
  47. data/spec/mbrao/author_spec.rb +32 -16
  48. data/spec/mbrao/content_spec.rb +144 -85
  49. data/spec/mbrao/integrations/rails_spec.rb +14 -0
  50. data/spec/mbrao/parser_spec.rb +19 -19
  51. data/spec/mbrao/parsing_engines/base_spec.rb +12 -12
  52. data/spec/mbrao/parsing_engines/plain_text_spec.rb +21 -21
  53. data/spec/mbrao/rendering_engines/base_spec.rb +2 -2
  54. data/spec/mbrao/rendering_engines/html_pipeline_spec.rb +31 -31
  55. metadata +2 -2
data/lib/mbrao/content.rb CHANGED
@@ -19,7 +19,8 @@ module Mbrao
19
19
  # Gets the title of the content in the desired locales.
20
20
  #
21
21
  # @param locales [String|Array] The desired locales. Can include `*` to match all. If none are specified, the default mbrao locale will be used.
22
- # @return [String|HashWithIndifferentAccess] Return the title of the content in the desired locales. If only one locale is required, then a `String` is returned, else a `HashWithIndifferentAccess` with locales as keys.
22
+ # @return [String|HashWithIndifferentAccess] Return the title of the content in the desired locales. If only one locale is required, then a `String`
23
+ # is returned, else a `HashWithIndifferentAccess` with locales as keys.
23
24
  def get_title(locales = [])
24
25
  filter_attribute_for_locales(@title, locales)
25
26
  end
@@ -28,7 +29,8 @@ module Mbrao
28
29
  #
29
30
  # @param locales [String|Array] The desired locales. Can include `*` to match all. If none are specified, the default mbrao locale will be used.
30
31
  # @param engine [String|Symbol|Object] The engine to use to filter contents.
31
- # @return [String|HashWithIndifferentAccess] Return the body of the content in the desired locales. If only one locale is required, then a `String` is returned, else a `HashWithIndifferentAccess` with locales as keys.
32
+ # @return [String|HashWithIndifferentAccess] Return the body of the content in the desired locales. If only one locale is required, then a `String`
33
+ # is returned, else a `HashWithIndifferentAccess` with locales as keys.
32
34
  def get_body(locales = [], engine = :plain_text)
33
35
  Mbrao::Parser.create_engine(engine).filter_content(self, locales)
34
36
  end
@@ -36,7 +38,8 @@ module Mbrao
36
38
  # Gets the tags of the content in the desired locales.
37
39
  #
38
40
  # @param locales [String|Array] The desired locales. Can include `*` to match all. If none are specified, the default mbrao locale will be used.
39
- # @return [Array|HashWithIndifferentAccess] Return the title of the content in the desired locales. If only one locale is required, then a `Array` is returned, else a `HashWithIndifferentAccess` with locales as keys.
41
+ # @return [Array|HashWithIndifferentAccess] Return the title of the content in the desired locales. If only one locale is required, then a `Array`
42
+ # is returned, else a `HashWithIndifferentAccess` with locales as keys.
40
43
  def get_tags(locales = [])
41
44
  filter_attribute_for_locales(@tags, locales)
42
45
  end
@@ -44,7 +47,8 @@ module Mbrao
44
47
  # Gets the "more link" text of the content in the desired locales.
45
48
  #
46
49
  # @param locales [String|Array] The desired locales. Can include `*` to match all. If none are specified, the default mbrao locale will be used.
47
- # @return [String|HashWithIndifferentAccess] Return the label of the "more link" of the content in the desired locales. If only one locale is required, then a `String` is returned, else a `HashWithIndifferentAccess` with locales as keys.
50
+ # @return [String|HashWithIndifferentAccess] Return the label of the "more link" of the content in the desired locales. If only one locale is required,
51
+ # then a `String` is returned, else a `HashWithIndifferentAccess` with locales as keys.
48
52
  def get_more(locales = [])
49
53
  filter_attribute_for_locales(@more, locales)
50
54
  end
@@ -54,7 +58,8 @@ module Mbrao
54
58
  #
55
59
  # @param attribute [Object|HashWithIndifferentAccess] The desired attribute.
56
60
  # @param locales [String|Array] The desired locales. Can include `*` to match all. If none are specified, the default mbrao locale will be used.
57
- # @return [String|HashWithIndifferentAccess] Return the object for desired locales. If only one locale is available, then only a object is returned, else a `HashWithIndifferentAccess` with locales as keys.
61
+ # @return [String|HashWithIndifferentAccess] Return the object for desired locales. If only one locale is available, then only a object is returned,
62
+ # else a `HashWithIndifferentAccess` with locales as keys.
58
63
  def filter_attribute_for_locales(attribute, locales)
59
64
  locales = ::Mbrao::Content.validate_locales(locales, self)
60
65
 
@@ -70,7 +75,8 @@ module Mbrao
70
75
  #
71
76
  # @param hash [Hash] The hash to handle.
72
77
  # @param locale [String] The list of locale (separated by commas) for which the value is available.
73
- # @param locales [Array] The list of locale for which this value is requested. Can include `*` to match all. If none are specified, the default mbrao locale will be used.
78
+ # @param locales [Array] The list of locale for which this value is requested. Can include `*` to match all. If none are specified, the default mbrao
79
+ # locale will be used.
74
80
  # @param value [Object] The value to add.
75
81
  # @return [Hash] Return the original hash.
76
82
  def append_value_for_locale(hash, locale, locales, value)
@@ -89,13 +95,17 @@ module Mbrao
89
95
  # @attribute locales
90
96
  # @return [Array] A list of locales for this content should be visible. An empty list means that there are no limitations.
91
97
  # @attribute title
92
- # @return [String|HashWithIndifferentAccess] The content's title. Can be a `String` or an `HashWithIndifferentAccess`, if multiple title are specified for multiple locales.
98
+ # @return [String|HashWithIndifferentAccess] The content's title. Can be a `String` or an `HashWithIndifferentAccess`, if multiple title are specified for
99
+ # multiple locales.
93
100
  # @attribute body
94
- # @return [String|HashWithIndifferentAccess] The content's body. Can be a `String` or an `HashWithIndifferentAccess`, if multiple contents are specified for multiple locales.
101
+ # @return [String|HashWithIndifferentAccess] The content's body. Can be a `String` or an `HashWithIndifferentAccess`, if multiple contents are specified
102
+ # for multiple locales.
95
103
  # @attribute tags
96
- # @return [String|HashWithIndifferentAccess] The content's "more link" label. Can be a `String` or an `HashWithIndifferentAccess`, if multiple labels are specified for multiple locales.
104
+ # @return [String|HashWithIndifferentAccess] The content's "more link" label. Can be a `String` or an `HashWithIndifferentAccess`, if multiple labels are
105
+ # specified for multiple locales.
97
106
  # @attribute tags
98
- # @return [Array|HashWithIndifferentAccess] The tags associated with the content. Can be an `Array` or an `HashWithIndifferentAccess`, if multiple tags set are specified for multiple locales.
107
+ # @return [Array|HashWithIndifferentAccess] The tags associated with the content. Can be an `Array` or an `HashWithIndifferentAccess`, if multiple tags set
108
+ # are specified for multiple locales.
99
109
  # @attribute author
100
110
  # @return [Author] The post author.
101
111
  # @attribute created_at
@@ -134,9 +144,10 @@ module Mbrao
134
144
 
135
145
  # Sets the `title` attribute.
136
146
  #
137
- # @param value [String|Hash] The new value for the attribute. If an Hash, keys must be a string with one or locale separated by commas. A empty or "*" will be the default value.
138
- def title=(value)
139
- @title = value.is_a?(Hash) ? value.ensure_hash(:indifferent, nil, :ensure_string) : value.ensure_string
147
+ # @param new_title [String|Hash] The new value for the attribute. If an Hash, keys must be a string with one or locale separated by commas.
148
+ # A empty or "*" will be the default value.
149
+ def title=(new_title)
150
+ @title = is_hash?(new_title) ? new_title.ensure_hash(:indifferent, nil, :ensure_string) : new_title.ensure_string
140
151
  end
141
152
 
142
153
  # Sets the `body` attribute.
@@ -148,33 +159,35 @@ module Mbrao
148
159
 
149
160
  # Sets the `tags` attribute.
150
161
  #
151
- # @param value [Array|Hash] The new value for the attribute. If an Hash, keys must be a string with one or locale separated by commas. A empty or "*" will be the default value.
152
- def tags=(value)
153
- @tags = if value.is_a?(Hash) then
154
- value.ensure_hash(:indifferent) { |v| v.ensure_array(nil, true, true, true, :ensure_string) }
162
+ # @param new_tags [Array|Hash] The new value for the attribute. If an Hash, keys must be a string with one or locale separated by commas.
163
+ # A empty or "*" will be the default value. Tags can also be comma-separated.
164
+ def tags=(new_tags)
165
+ @tags = if is_hash?(new_tags) then
166
+ new_tags.ensure_hash(:indifferent) { |v| parse_tags(v) }
155
167
  else
156
- value.ensure_array(nil, true, true, true, :ensure_string)
168
+ parse_tags(new_tags)
157
169
  end
158
170
  end
159
171
 
160
172
  # Sets the `more` attribute.
161
173
  #
162
- # @param value [String|Hash] The new value for the attribute. If an Hash, keys must be a string with one or locale separated by commas. A empty or "*" will be the default value.
163
- def more=(value)
164
- @more = value.is_a?(Hash) ? value.ensure_hash(:indifferent, nil, :ensure_string) : value.ensure_string
174
+ # @param new_more [String|Hash] The new value for the attribute. If an Hash, keys must be a string with one or locale separated by commas.
175
+ # A empty or "*" will be the default value.
176
+ def more=(new_more)
177
+ @more = is_hash?(new_more) ? new_more.ensure_hash(:indifferent, nil, :ensure_string) : new_more.ensure_string
165
178
  end
166
179
 
167
180
  # Sets the `author` attribute.
168
181
  #
169
- # @param value [Author|Hash|Object] The new value for the attribute.
170
- def author=(value)
171
- if value.is_a?(Mbrao::Author) then
172
- @author = value
173
- elsif value.is_a?(Hash) then
174
- value = value.ensure_hash(:indifferent)
175
- @author = Mbrao::Author.new(value["name"], value["email"], value["website"], value["image"], value["metadata"], value["uid"])
182
+ # @param new_author [Author|Hash|Object|NilClass] The new value for the attribute.
183
+ def author=(new_author)
184
+ if new_author.is_a?(Mbrao::Author) then
185
+ @author = new_author
186
+ elsif is_hash?(new_author) then
187
+ new_author = new_author.ensure_hash(:indifferent)
188
+ @author = Mbrao::Author.create(new_author)
176
189
  else
177
- @author = Mbrao::Author.new(value.ensure_string)
190
+ @author = new_author ? Mbrao::Author.new(new_author.ensure_string) : nil
178
191
  end
179
192
  end
180
193
 
@@ -202,18 +215,32 @@ module Mbrao
202
215
 
203
216
  # Sets the `metadata` attribute.
204
217
  #
205
- # @param value [Hash] The new value for the attribute.
206
- def metadata=(value)
207
- if value.is_a?(Hash) then
208
- @metadata = value.ensure_hash(:indifferent)
218
+ # @param new_metadata [Hash] The new value for the attribute.
219
+ def metadata=(new_metadata)
220
+ if is_hash?(new_metadata) then
221
+ @metadata = new_metadata.ensure_hash(:indifferent)
209
222
  else
210
- @metadata = HashWithIndifferentAccess.new({raw: value})
223
+ @metadata = HashWithIndifferentAccess.new({raw: new_metadata})
211
224
  end
212
225
  end
213
226
 
227
+ # Returns the content as an Hash.
228
+ #
229
+ # @param options [Hash] Options to modify behavior of the serialization.
230
+ # The only supported value are:
231
+ #
232
+ # * `:exclude`, an array of attributes to skip.
233
+ # * `:exclude_empty`, if to exclude nil values. Default is `false`.
234
+ # @return [Hash] An hash with all attributes.
235
+ def as_json(options = {})
236
+ keys = [:uid, :locales, :title, :body, :tags, :more, :author, :created_at, :updated_at, :metadata]
237
+ ::Mbrao::Parser.as_json(self, keys, options)
238
+ end
239
+
214
240
  # Validates locales for attribute retrieval.
215
241
  #
216
- # @param locales [Array] A list of desired locales for an attribute. Can include `*` to match all. If none are specified, the default mbrao locale will be used.
242
+ # @param locales [Array] A list of desired locales for an attribute. Can include `*` to match all. If none are specified, the default mbrao locale will be
243
+ # used.
217
244
  # @param content [Content|nil] An optional content to check for availability
218
245
  # @return [Array] The validated list of locales.
219
246
  def self.validate_locales(locales, content = nil)
@@ -278,21 +305,43 @@ module Mbrao
278
305
  # Extracts a date and time from a value.
279
306
  #
280
307
  # @param value [String|DateTime|Fixnum] The value to parse.
281
- # @return [DateTime] The extract values.
308
+ # @return [DateTime] The extracted value.
282
309
  def extract_datetime(value)
283
310
  begin
284
- if value.is_a?(Date) || value.is_a?(Time) then
285
- value = value.to_datetime
286
- elsif value.to_float > 0 then
287
- value = Time.at(value.to_float).to_datetime
288
- elsif value && !value.is_a?(DateTime) then
289
- value = DateTime.strptime(value.ensure_string, "%Y%m%dT%H%M%S%z")
290
- end
291
-
311
+ value = parse_datetime(value) if value
292
312
  value ? value.utc : nil
293
313
  rescue ArgumentError
294
314
  raise Mbrao::Exceptions::InvalidDate.new
295
315
  end
296
316
  end
317
+
318
+ # Parse a datetime
319
+ # @param value [String|DateTime|Fixnum] The value to parse.
320
+ # @return [DateTime] The extracted value.
321
+ def parse_datetime(value)
322
+ case value.class.to_s
323
+ when "DateTime" then value
324
+ when "Date", "Time" then value.to_datetime
325
+ when "Float", "Fixnum" then
326
+ value.to_float > 0 ? Time.at(value.to_float).to_datetime : nil
327
+ else DateTime.strptime(value.ensure_string, "%Y%m%dT%H%M%S%z")
328
+ end
329
+ end
330
+
331
+ # Extract tags from an array, making sure all the comma separated strings are evaluated.
332
+ #
333
+ # @param value [String|Array] The string or array to parse.
334
+ # @return [Array] The list of tags.
335
+ def parse_tags(value)
336
+ value.ensure_array(nil, true, true, true) { |v| v.ensure_string.split(/\s*,\s*/) }
337
+ end
338
+
339
+ # Check if value is an Hash.
340
+ #
341
+ # @param value [Object] The object to check.
342
+ # @return [Boolean] `true` if value is an Hash, `false` otherwise
343
+ def is_hash?(value)
344
+ value.is_a?(Hash)
345
+ end
297
346
  end
298
347
  end
@@ -17,6 +17,11 @@ module ActionView::Template::Handlers
17
17
  @instance ||= ActionView::Template::Handlers::MbraoTemplate.new
18
18
  end
19
19
 
20
+ # Register Mbrao into Rails.
21
+ def self.register
22
+ ActionView::Template.register_template_handler("emt", instance) if defined?(ActionView) && defined?(Rails) && Rails.version =~ /^[34]/
23
+ end
24
+
20
25
  # Renders a template into a renderer context.
21
26
  #
22
27
  # @param renderer [Object] The renderer context.
@@ -24,11 +29,13 @@ module ActionView::Template::Handlers
24
29
  # @return [String] The rendered template.
25
30
  def render(renderer, template)
26
31
  content = ::Mbrao::Parser.parse(template)
27
- renderer.controller.instance_variable_set(:@mbrao_content, content)
28
- renderer.controller.define_singleton_method(:mbrao_content) { @mbrao_content }
29
- renderer.controller.class.send(:helper_method, :mbrao_content)
32
+ controller = renderer.controller
33
+
34
+ controller.instance_variable_set(:@mbrao_content, content)
35
+ controller.define_singleton_method(:mbrao_content) { @mbrao_content }
36
+ controller.class.send(:helper_method, :mbrao_content)
30
37
 
31
- ::Mbrao::Parser.render(content, {engine: content.metadata[:engine], locale: renderer.controller.params[:locale]})
38
+ ::Mbrao::Parser.render(content, {engine: content.metadata[:engine], locale: controller.params[:locale]})
32
39
  end
33
40
 
34
41
  # Declares support for streaming.
@@ -48,4 +55,4 @@ module ActionView::Template::Handlers
48
55
  end
49
56
  end
50
57
 
51
- ActionView::Template.register_template_handler("emt", ActionView::Template::Handlers::MbraoTemplate.instance) if defined?(ActionView) && defined?(Rails) && Rails.version =~ /^[34]/
58
+ ActionView::Template::Handlers::MbraoTemplate.register
data/lib/mbrao/parser.rb CHANGED
@@ -63,6 +63,29 @@ module Mbrao
63
63
  instance.render(content, options, context)
64
64
  end
65
65
 
66
+ # Returns an object as a JSON compatible hash
67
+ #
68
+ # @param target [Object] The target to serialize.
69
+ # @param keys [Array] The attributes to include in the serialization
70
+ # @param options [Hash] Options to modify behavior of the serialization.
71
+ # The only supported value are:
72
+ #
73
+ # * `:exclude`, an array of attributes to skip.
74
+ # * `:exclude_empty`, if to exclude nil values. Default is `false`.
75
+ # @return [Hash] An hash with all attributes.
76
+ def as_json(target, keys, options = {})
77
+ include_empty = !options[:exclude_empty].to_boolean
78
+ exclude = options[:exclude].ensure_array(nil, true, true, true, :ensure_string)
79
+ keys = keys.ensure_array(nil, true, true, true, :ensure_string)
80
+
81
+ (keys - exclude).reduce({}) {|rv, key|
82
+ value = target.send(key)
83
+ value = value.as_json if value && value.respond_to?(:as_json)
84
+ rv[key] = value if include_empty || !value.is_a?(NilClass)
85
+ rv
86
+ }.deep_stringify_keys
87
+ end
88
+
66
89
  # Instantiates a new engine for rendering or parsing.
67
90
  #
68
91
  # @param cls [String|Symbol|Object] If a `String` or a `Symbol`, then it will be the class of the engine.
@@ -11,29 +11,30 @@ module Mbrao
11
11
  class Base
12
12
  # Parses a whole post content and return its metadata and content parts.
13
13
  #
14
- # @param content [Object] The content to parse.
15
- # @param options [Hash] Options to customize parsing.
14
+ # @param _content [Object] The content to parse.
15
+ # @param _options [Hash] Options to customize parsing.
16
16
  # @return [Array] An array of metadata and contents parts.
17
- def separate_components(content, options = {})
17
+ def separate_components(_content, _options = {})
18
18
  raise Mbrao::Exceptions::Unimplemented.new
19
19
  end
20
20
 
21
21
  # Parses metadata part and returns all valid metadata.
22
22
  #
23
- # @param content [Object] The content to parse.
24
- # @param options [Hash] Options to customize parsing.
23
+ # @param _content [Object] The content to parse.
24
+ # @param _options [Hash] Options to customize parsing.
25
25
  # @return [Hash] All valid metadata for the content.
26
- def parse_metadata(content, options = {})
26
+ def parse_metadata(_content, _options = {})
27
27
  raise Mbrao::Exceptions::Unimplemented.new
28
28
  end
29
29
 
30
30
  # Filters content of a post by locale.
31
31
  #
32
- # @param content [Content] The content to filter.
33
- # @param locales [String|Array] The desired locales. Can include `*` to match all.
34
- # @param options [Hash] Options to customize parsing.
35
- # @return [String|HashWithIndifferentAccess] Return the filtered content in the desired locales. If only one locale is required, then a `String` is returned, else a `HashWithIndifferentAccess` with locales as keys.
36
- def filter_content(content, locales = [], options = {})
32
+ # @param _content [Content] The content to filter.
33
+ # @param _locales [String|Array] The desired locales. Can include `*` to match all.
34
+ # @param _options [Hash] Options to customize parsing.
35
+ # @return [String|HashWithIndifferentAccess] Return the filtered content in the desired locales. If only one locale is required, then a `String` is
36
+ # returned, else a `HashWithIndifferentAccess` with locales as keys.
37
+ def filter_content(_content, _locales = [], _options = {})
37
38
  raise Mbrao::Exceptions::Unimplemented.new
38
39
  end
39
40
 
@@ -15,15 +15,15 @@ module Mbrao
15
15
  # @param options [Hash] Options to customize parsing.
16
16
  # @return [Array] An array of metadata and contents parts.
17
17
  def separate_components(content, options = {})
18
- metadata = nil
19
- content = content.ensure_string.strip
20
- options = sanitize_options(options)
21
- scanner = StringScanner.new(content)
22
- end_tag = options[:meta_tags].last
23
-
24
- if scanner.scan_until(options[:meta_tags].first) && (metadata = scanner.scan_until(end_tag)) then
25
- metadata = metadata.partition(end_tag).first
26
- content = scanner.rest.strip
18
+ metadata, content, scanner, start_tag, end_tag = prepare_for_separation(content, options)
19
+
20
+ if scanner.scan_until(start_tag) then
21
+ metadata = scanner.scan_until(end_tag)
22
+
23
+ if metadata then
24
+ metadata = metadata.partition(end_tag).first
25
+ content = scanner.rest.strip
26
+ end
27
27
  end
28
28
 
29
29
  [metadata.ensure_string.strip, content]
@@ -47,30 +47,31 @@ module Mbrao
47
47
  # @param content [Content] The content to filter.
48
48
  # @param locales [String|Array] The desired locales. Can include `*` to match all. If none are specified, the default Mbrao locale will be requested.
49
49
  # @param options [Hash] Options to customize parsing.
50
- # @return [String|HashWithIndifferentAccess] Return the filtered content in the desired locales. If only one locale is required, then a `String` is returned, else a `HashWithIndifferentAccess` with locales as keys.
50
+ # @return [String|HashWithIndifferentAccess] Return the filtered content in the desired locales. If only one locale is required, then a `String` is
51
+ # returned, else a `HashWithIndifferentAccess` with locales as keys.
51
52
  def filter_content(content, locales = [], options = {})
52
53
  body = content.body.ensure_string.strip
53
- options = sanitize_options(options)
54
+ content_tags = sanitize_tags(options[:content_tags], ["{{content: %ARGS%}}", "{{/content}}"])
54
55
  locales = ::Mbrao::Content.validate_locales(locales, content)
55
56
 
56
57
  # Split the content
57
- result = scan_content(body, options[:content_tags].first, options[:content_tags].last)
58
+ result = scan_content(body, content_tags.first, content_tags.last)
58
59
 
59
60
  # Now filter results
60
61
  perform_filter_content(result, locales)
61
62
  end
62
63
 
63
64
  private
64
- # Sanitizes options.
65
+ # Prepare arguments for separation.
65
66
  #
67
+ # @param content [String] The content to separate.
66
68
  # @param options [Hash] The options to sanitize.
67
- # @return [HashWithIndifferentAccess] The sanitized options.
68
- def sanitize_options(options)
69
- # Tags
70
- options[:meta_tags] = sanitize_tags(options[:meta_tags], ["{{metadata}}", "{{/metadata}}"])
71
- options[:content_tags] = sanitize_tags(options[:content_tags], ["{{content: %ARGS%}}", "{{/content}}"])
69
+ # @return [Array] The sanitized arguments.
70
+ def prepare_for_separation(content, options)
71
+ content = content.ensure_string.strip
72
+ meta_tags = sanitize_tags(options[:meta_tags], ["{{metadata}}", "{{/metadata}}"])
72
73
 
73
- options
74
+ [nil, content.ensure_string.strip, StringScanner.new(content), meta_tags.first, meta_tags.last]
74
75
  end
75
76
 
76
77
  # Sanitizes tag markers.
@@ -135,12 +136,13 @@ module Mbrao
135
136
  def parse_embedded_content(scanner, start_tag, end_tag)
136
137
  rv = ""
137
138
  balance = 1
139
+ embedded_part = scanner.scan_until(end_tag)
138
140
 
139
- while (embedded_part = scanner.scan_until(end_tag)) do
141
+ while balance > 0 && embedded_part do
140
142
  balance += embedded_part.scan(start_tag).count - 1 # -1 Because there is a closure
141
143
  embedded_part = embedded_part.partition(end_tag).first if balance == 0 || !scanner.exist?(end_tag) # This is the last occurrence.
142
144
  rv << embedded_part
143
- break if balance == 0
145
+ embedded_part = scanner.scan_until(end_tag) if balance > 0
144
146
  end
145
147
 
146
148
  rv
@@ -153,10 +155,11 @@ module Mbrao
153
155
  # @return [String|nil] Return the filtered content or `nil` if the content must be hidden.
154
156
  def perform_filter_content(content, locales)
155
157
  content.map { |part|
158
+ part_content = part[0]
156
159
  part_locales = parse_locales(part[1])
157
160
 
158
161
  if locales_valid?(locales, part_locales) then
159
- part[0].is_a?(Array) ? perform_filter_content(part[0], locales) : part[0]
162
+ part_content.is_a?(Array) ? perform_filter_content(part_content, locales) : part_content
160
163
  else
161
164
  nil
162
165
  end
@@ -180,7 +183,10 @@ module Mbrao
180
183
  # @param part_locales[Hash] An hash with valid and invalid locales.
181
184
  # @return [Boolean] `true` if the locales are valid, `false` otherwise.
182
185
  def locales_valid?(locales, part_locales)
183
- locales.include?("*") || part_locales["valid"].include?("*") || ((part_locales["valid"].empty? || (locales & part_locales["valid"]).present?) && (locales & part_locales["invalid"]).blank?)
186
+ valid = part_locales["valid"]
187
+ invalid = part_locales["invalid"]
188
+
189
+ locales.include?("*") || valid.include?("*") || ((valid.empty? || (locales & valid).present?) && (locales & invalid).blank?)
184
190
  end
185
191
  end
186
192
  end
@@ -11,10 +11,10 @@ module Mbrao
11
11
  class Base
12
12
  # Renders a content.
13
13
  #
14
- # @param content [Content|String] The content to parse.
15
- # @param options [Hash] A list of options for renderer.
16
- # @param context [Hash] A context for rendering.
17
- def render(content, options = {}, context = {})
14
+ # @param _content [Content|String] The content to parse.
15
+ # @param _options [Hash] A list of options for renderer.
16
+ # @param _context [Hash] A context for rendering.
17
+ def render(_content, _options = {}, _context = {})
18
18
  raise Mbrao::Exceptions::Unimplemented.new
19
19
  end
20
20
  end
@@ -36,7 +36,9 @@ module Mbrao
36
36
  # A renders which use the [html-pipeline](https://github.com/jch/html-pipeline) gem.
37
37
  #
38
38
  # @attribute default_pipeline
39
- # @return [Array] The default pipeline to use. It should be an array of pairs of `Symbol`, which the first element is the filter (in underscored version and without the filter suffix) and the second is a shortcut to disable the pipeline via options. You can also specify a single element to disable shortcuts.
39
+ # @return [Array] The default pipeline to use. It should be an array of pairs of `Symbol`, which the first element is the filter (in underscored version
40
+ # and without the filter suffix) and the second is a shortcut to disable the pipeline via options.
41
+ # You can also specify a single element to disable shortcuts.
40
42
  # @attribute default_options
41
43
  # @return [Hash] The default options for the renderer.
42
44
  class HtmlPipeline < Mbrao::RenderingEngines::Base
@@ -118,7 +120,10 @@ module Mbrao
118
120
  # @param context [Hash] A context for rendering.
119
121
  # @return [HTML::Pipeline] The pipeline
120
122
  def create_pipeline(options, context)
121
- ::HTML::Pipeline.new(options[:pipeline].map {|f| ::Lazier.find_class(f, "::HTML::Pipeline::%CLASS%Filter", true) }, options[:pipeline_options].merge(context))
123
+ ::HTML::Pipeline.new(
124
+ options[:pipeline].map {|f| ::Lazier.find_class(f, "::HTML::Pipeline::%CLASS%Filter", true) },
125
+ options[:pipeline_options].merge(context)
126
+ )
122
127
  end
123
128
 
124
129
  # Filters pipeline filters basing on the options provided.
data/lib/mbrao/version.rb CHANGED
@@ -14,10 +14,10 @@ module Mbrao
14
14
  MAJOR = 1
15
15
 
16
16
  # The minor version.
17
- MINOR = 2
17
+ MINOR = 3
18
18
 
19
19
  # The patch version.
20
- PATCH = 3
20
+ PATCH = 0
21
21
 
22
22
  # The current version of mbrao.
23
23
  STRING = [MAJOR, MINOR, PATCH].compact.join(".")
@@ -23,40 +23,56 @@ describe Mbrao::Author do
23
23
  end
24
24
 
25
25
  it "creates a author from a hash" do
26
- expect(Mbrao::Author).to receive(:new).with("NAME", "EMAIL", "WEBSITE", "IMAGE", {"other" => "OTHER"}, "UID")
26
+ expect(Mbrao::Author).to receive(:new).with("NAME", "EMAIL", "WEBSITE", "IMAGE", {"other" => "OTHER"}).and_call_original
27
+ expect_any_instance_of(Mbrao::Author).to receive("uid=").with("UID")
27
28
  Mbrao::Author.create({name: "NAME", email: "EMAIL", website: "WEBSITE", image: "IMAGE", other: "OTHER", uid: "UID"})
28
29
  end
29
30
  end
30
31
 
31
32
  describe "#initialize" do
32
33
  it "create a new object" do
33
- reference = Mbrao::Author.new("NAME", "name@example.com", "http://example.com", "http://example.com/image.jpg", {a: {b: :c}})
34
- expect(reference.name).to eq("NAME")
35
- expect(reference.email).to eq("name@example.com")
36
- expect(reference.website).to eq("http://example.com")
37
- expect(reference.image).to eq("http://example.com/image.jpg")
38
- expect(reference.metadata).to eq({"a" => {"b" => :c}})
34
+ subject = Mbrao::Author.new("NAME", "name@example.com", "http://example.com", "http://example.com/image.jpg", {a: {b: :c}})
35
+ expect(subject.name).to eq("NAME")
36
+ expect(subject.email).to eq("name@example.com")
37
+ expect(subject.website).to eq("http://example.com")
38
+ expect(subject.image).to eq("http://example.com/image.jpg")
39
+ expect(subject.metadata).to eq({"a" => {"b" => :c}})
39
40
  end
40
41
 
41
42
  it "make sure that email is valid" do
42
- reference = Mbrao::Author.new("NAME", "INVALID", "http://example.com", "http://example.com/image.jpg", {a: {b: :c}})
43
- expect(reference.email).to be_nil
43
+ subject = Mbrao::Author.new("NAME", "INVALID", "http://example.com", "http://example.com/image.jpg", {a: {b: :c}})
44
+ expect(subject.email).to be_nil
44
45
  end
45
46
 
46
47
  it "make sure that website is a valid URL" do
47
- reference = Mbrao::Author.new("NAME", "name@example.com", "INVALID", "http://example.com/image.jpg", {a: {b: :c}})
48
- expect(reference.website).to be_nil
48
+ subject = Mbrao::Author.new("NAME", "name@example.com", "INVALID", "http://example.com/image.jpg", {a: {b: :c}})
49
+ expect(subject.website).to be_nil
49
50
  end
50
51
 
51
52
  it "make sure that image is a valid URL" do
52
- reference = Mbrao::Author.new("NAME", "name@example.com", "http://example.com", "INVALID", {a: {b: :c}})
53
- expect(reference.image).to be_nil
53
+ subject = Mbrao::Author.new("NAME", "name@example.com", "http://example.com", "INVALID", {a: {b: :c}})
54
+ expect(subject.image).to be_nil
54
55
  end
55
56
 
56
57
  it "make sure that hash is a recursively a HashWithIndifferentAccess" do
57
- reference = Mbrao::Author.new("NAME", "name@example.com", "http://example.com", "http://example.com/image.jpg", {a: {b: :c}})
58
- expect(reference.metadata).to be_a(HashWithIndifferentAccess)
59
- expect(reference.metadata["a"]).to be_a(HashWithIndifferentAccess)
58
+ subject = Mbrao::Author.new("NAME", "name@example.com", "http://example.com", "http://example.com/image.jpg", {a: {b: :c}})
59
+ expect(subject.metadata).to be_a(HashWithIndifferentAccess)
60
+ expect(subject.metadata["a"]).to be_a(HashWithIndifferentAccess)
61
+ end
62
+ end
63
+
64
+ describe "#as_json" do
65
+ it "should return the content as a JSON hash" do
66
+ subject = Mbrao::Author.new("NAME", "name@example.com", "http://example.com", "http://example.com/image.jpg", {a: {b: :c}})
67
+
68
+ expect(subject.as_json).to eq({
69
+ "email" => "name@example.com",
70
+ "image" => "http://example.com/image.jpg",
71
+ "metadata" => {"a" => {"b" => :c}},
72
+ "name" => "NAME",
73
+ "uid" => nil,
74
+ "website" => "http://example.com"
75
+ })
60
76
  end
61
77
  end
62
78
  end