comfortable_mexican_sofa 2.0.13 → 2.0.14

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: b4189f8584e5fbfcc3083d72b892dee0d17407e1893674eed30927e6e5c6d336
4
- data.tar.gz: '02964679fbddf7a9f1c46dc35482d11a6a3736409a32daa4a137d0600a921d3d'
3
+ metadata.gz: 7cc4680084f0e38ab3a3e902264eb28487be58a3cfb10abb3722ead0a917e7c4
4
+ data.tar.gz: 7fe8523b33056e692bb8f3ee552517adbd994dfcf3e830466ff078e72e646439
5
5
  SHA512:
6
- metadata.gz: 47387e45ccebcad1bc3429c6b64633dfd9cc8f0810f7c28745dc578f391404e57a16fb8bd1ecd221acdd6701710aded9ee318eb2b110f7d7374e63063fc472b0
7
- data.tar.gz: d16d2d2aaeb92e761c6b3559816f33e1339dd239f8691d6b8194bc5cf60d67ec0dbe34aae18ee2cc2a4f1bf24b15edc4105812bcd4427d04b048a850bc339819
6
+ metadata.gz: e01f50e27b67203265c0d4683ae78d50644a5f64a8a4ea9898f3e94b163c5990c04b83b4d25133ecc8c531ceadadd87a32d249724211562622d5341ede61bd5b
7
+ data.tar.gz: 26695cba7cf37dcc11ce3955d8dca504231bcaf33b62e736c7eff19304ffe0f0ad920fa12d62f3bda92f0bea087bc25e309ca7ce6c2ddc60a43cdedd7dc008f9
data/.travis.yml CHANGED
@@ -1,8 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.3.6
4
- - 2.4.3
5
- - 2.5.0
3
+ - 2.3.7
4
+ - 2.4.4
5
+ - 2.5.1
6
6
  - ruby-head
7
7
  gemfile:
8
8
  - test/gemfiles/5.2.gemfile
@@ -23,7 +23,7 @@ class Comfy::Admin::Cms::FilesController < Comfy::Admin::Cms::BaseController
23
23
  case params[:type]
24
24
  when "image"
25
25
  file_scope.with_images.collect do |file|
26
- { thumb: url_for(file.attachment.variant(Comfy::Cms::File::VARIANT_SIZE[:redactor])),
26
+ { thumb: url_for(file.attachment.variant(combine_options: Comfy::Cms::File::VARIANT_SIZE[:redactor])),
27
27
  image: url_for(file.attachment),
28
28
  title: file.label }
29
29
  end
@@ -1,7 +1,7 @@
1
1
  %li{data: {id: file.id}}
2
2
  :ruby
3
3
  file_tag = cms_file_link_tag(file)
4
- thumb_url = url_for(file.attachment.variant(Comfy::Cms::File::VARIANT_SIZE[:thumb])) if file.attachment.image?
4
+ thumb_url = url_for(file.attachment.variant(combine_options: Comfy::Cms::File::VARIANT_SIZE[:thumb])) if file.attachment.image?
5
5
  .row
6
6
  .col-md-5.item
7
7
  .item-controls.d-none.d-lg-block
@@ -1,8 +1,10 @@
1
1
  .fragment-attachments
2
2
  - attachments.each do |attachment|
3
3
  :ruby
4
- thumb_url = url_for(attachment.variant(Comfy::Cms::File::VARIANT_SIZE[:thumb])) if attachment.image?
5
- filename = attachment.filename.to_s
4
+ thumb_url = if attachment.image?
5
+ url_for(attachment.variant(combine_options: Comfy::Cms::File::VARIANT_SIZE[:thumb]))
6
+ end
7
+ filename = attachment.filename.to_s
6
8
  truncated_filename = truncate(filename, length: 40, omission: "...#{filename.last(10)}")
7
9
 
8
10
  link_data = {
@@ -2,78 +2,116 @@
2
2
 
3
3
  require "strscan"
4
4
 
5
- module ComfortableMexicanSofa::Content::ParamsParser
5
+ class ComfortableMexicanSofa::Content::ParamsParser
6
6
 
7
7
  class Error < StandardError; end
8
8
 
9
- STRING_LITERAL = %r{'[^']*'|"[^"]*"}
10
- IDENTIFIER = %r{[a-z0-9][\w\-/.]*}i
11
- COLON = %r{:}
12
- COMMA = %r{,}
9
+ STRING_LITERAL = %r{'[^']*'|"[^"]*"}
10
+ IDENTIFIER = %r{[a-z0-9][\w\-/.]*}i
11
+ HASH_KEY = %r{#{IDENTIFIER}:}
12
+ COMMA = %r{,}
13
+ HASH_OPEN = %r{\{}
14
+ HASH_CLOSE = %r{\}}
15
+ ARRAY_OPEN = %r{\[}
16
+ ARRAY_CLOSE = %r{\]}
13
17
 
14
- # @param [String] text
18
+ # @param <String> string
19
+ def initialize(string = "")
20
+ @string = string
21
+ end
22
+
23
+ # Takes CMS content tag parameters and converts them into array of strings,
24
+ # hashes and arrays.
25
+ #
15
26
  # @return [Array<String, {String => String}>]
16
27
  # @raise [Error] if the given `text` is malformed.
17
28
  #
18
29
  # @example
19
- # parse("happy greeting name:Joe show:true")
20
- # #=> ['happy', 'greeting', {'name' => 'Joe', 'show' => 'true'}]
21
- def self.parse(text)
22
- parse_token_groups(split_on_commas(tokenize(text.to_s)))
30
+ # new("a, b, c").parse
31
+ # #=> ["a", "b", "c"]
32
+ #
33
+ # new("a, b: c, d: e").parse
34
+ # #=> ["a", {"b" => "c", "d" => "e"}]
35
+ #
36
+ # new("a, b: {c: [d, e]}").parse
37
+ # #=> ["a", {"b" => {"c" => ["d", "e"]}}]
38
+ #
39
+ def params
40
+ @tokens = tokenize(@string)
41
+ parse_params
23
42
  end
24
43
 
25
- # @param [Enumerable<Array<(Symbol, String)>>] token_groups
26
- # @return [Array<String, {String => String}>]
27
- def self.parse_token_groups(token_groups)
28
- token_groups.each_with_object([]) do |tokens, params|
29
- case tokens.count
30
- when 1
31
- params << parse_string_param(tokens[0])
32
- when 3
33
- param = parse_key_value_param(tokens)
34
- if params.last.is_a?(Hash)
35
- params.last.update(param)
36
- else
37
- params << param
38
- end
39
- else
40
- raise Error, "Unexpected tokens found: #{tokens}"
41
- end
44
+ private
45
+
46
+ # Contructs root-level list of arguments sent via content tag
47
+ def parse_params
48
+ params = []
49
+ while (token = @tokens.shift)
50
+ params << parse_value(token)
42
51
  end
52
+ params
43
53
  end
44
54
 
45
- # @param [(:string, String)] token
46
- # @return [String]
47
- # @raise [Error] if `token[0] != :string`.
48
- def self.parse_string_param(token)
49
- type, value = token
50
- raise Error, "Unexpected token: #{token}" unless type == :string
51
- value
55
+ # Gets token value. Will trigger parsing of hash and array structures
56
+ def parse_value(token)
57
+ case token&.first
58
+ when :string
59
+ token[1]
60
+ when :hash_key
61
+ @tokens.unshift(token)
62
+ parse_hash
63
+ when :hash_open
64
+ parse_hash
65
+ when :array_open
66
+ parse_array
67
+ else
68
+ raise Error, "Invalid params: #{@string}"
69
+ end
52
70
  end
53
71
 
54
- # @param [((:string, String), (:colon, String), (:string, String))] tokens
55
- # @return [{String => String}]
56
- # @raise [Error] if `tokens[0][0] != :string`, or `tokens[1][0] != :colon`,
57
- # or `tokens[2][0] != :string`.
58
- def self.parse_key_value_param(tokens)
59
- (key_type, key_value), (col_type, _col_value), (val_type, val_value) = tokens
60
- unless key_type == :string && col_type == :colon && val_type == :string
61
- raise Error, "Unexpected tokens: #{tokens}"
72
+ # Hash constructor method. Will handle nested hashes as well
73
+ def parse_hash
74
+ opens = 1
75
+ hash = {}
76
+
77
+ while (token = @tokens.shift)
78
+ case token&.first
79
+ when :hash_key
80
+ hash[token[1]] = parse_value(@tokens.shift)
81
+ when :hash_close
82
+ opens -= 1
83
+ when :hash_open
84
+ opens += 1
85
+ else
86
+ raise Error, "Invalid params: #{@string}"
87
+ end
88
+
89
+ return hash if opens.zero?
62
90
  end
63
- { key_value => val_value }
91
+
92
+ # We're can't really detect unclosed hashes as we can construct them without
93
+ # opening brakets. For example, `a: b, c: d` is same as `{a: b, c: d}` and
94
+ # `{a: b, c: d` is also ends up to be a valid hash. It will error out if
95
+ # unclosed hash is followed by some other unexpected token. Like: `{a: b, c`
96
+ hash
64
97
  end
65
98
 
66
- # Splits tokens on commas. The result contains no `:comma` tokens.
67
- #
68
- # @param [Enumerable<(Symbol, String)>] tokens
69
- # @return [Enumerable<Array<(Symbol, String)>>] Token groups.
70
- def self.split_on_commas(tokens)
71
- slices = tokens.slice_after do |token|
72
- token[0] == :comma
73
- end
74
- slices.map do |expression|
75
- expression.reject { |t| t[0] == :comma }
99
+ # Array construction method. Will handle nested arrays
100
+ def parse_array
101
+ opens = 1
102
+ array = []
103
+ while (token = @tokens.shift)
104
+ case token&.first
105
+ when :array_close
106
+ opens -= 1
107
+ else
108
+ array << parse_value(token)
109
+ end
110
+
111
+ return array if opens.zero?
76
112
  end
113
+
114
+ raise Error, "Unclosed array param: #{@string}"
77
115
  end
78
116
 
79
117
  # Tokenizing input string into a list of touples
@@ -81,22 +119,30 @@ module ComfortableMexicanSofa::Content::ParamsParser
81
119
  #
82
120
  # @param [String] args_string
83
121
  # @return [Array<String>] tokens
84
- def self.tokenize(args_string)
122
+ def tokenize(args_string)
85
123
  args_string = args_string.tr("“”‘’", %q(""''))
86
124
  ss = StringScanner.new(args_string)
87
125
  tokens = []
88
126
  loop do
89
127
  ss.skip(%r{\s*})
90
128
  break if ss.eos?
129
+
130
+ # commas are just separators like spaces
131
+ next if ss.scan(COMMA)
132
+
91
133
  tokens <<
92
134
  if (t = ss.scan(STRING_LITERAL)) then [:string, t[1...-1]]
135
+ elsif (t = ss.scan(HASH_KEY)) then [:hash_key, t[0...-1]]
93
136
  elsif (t = ss.scan(IDENTIFIER)) then [:string, t]
94
- elsif (t = ss.scan(COLON)) then [:colon, t]
95
- elsif (t = ss.scan(COMMA)) then [:comma, t]
137
+ elsif (t = ss.scan(HASH_OPEN)) then [:hash_open, t]
138
+ elsif (t = ss.scan(HASH_CLOSE)) then [:hash_close, t]
139
+ elsif (t = ss.scan(ARRAY_OPEN)) then [:array_open, t]
140
+ elsif (t = ss.scan(ARRAY_CLOSE)) then [:array_close, t]
96
141
  else
97
142
  raise Error, "Unexpected char: #{ss.getch}"
98
143
  end
99
144
  end
145
+
100
146
  tokens
101
147
  end
102
148
 
@@ -122,7 +122,7 @@ class ComfortableMexicanSofa::Content::Renderer
122
122
  # @type [ComfortableMexicanSofa::Content::Tag]
123
123
  tag = klass.new(
124
124
  context: @context,
125
- params: ComfortableMexicanSofa::Content::ParamsParser.parse(token[:tag_params]),
125
+ params: ComfortableMexicanSofa::Content::ParamsParser.new(token[:tag_params]).params,
126
126
  source: token[:source]
127
127
  )
128
128
  nodes.last << tag
@@ -3,11 +3,7 @@
3
3
  # Tag for text content that is going to be rendered using text input with date widget
4
4
  # {{ cms:date identifier }}
5
5
  #
6
- class ComfortableMexicanSofa::Content::Tag::Date < ComfortableMexicanSofa::Content::Tag::Fragment
7
-
8
- def content
9
- fragment.datetime
10
- end
6
+ class ComfortableMexicanSofa::Content::Tag::Date < ComfortableMexicanSofa::Content::Tag::Datetime
11
7
 
12
8
  def form_field(object_name, view, index)
13
9
  name = "#{object_name}[fragments_attributes][#{index}][datetime]"
@@ -1,14 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Tag for text content that is going to be rendered using text input with datetime widget
4
- # {{ cms:datetime identifier }}
4
+ # {{ cms:datetime identifier, strftime: "at %I:%M%p" }}
5
+ #
6
+ # `strftime` - Format datetime string during rendering
5
7
  #
6
8
  class ComfortableMexicanSofa::Content::Tag::Datetime < ComfortableMexicanSofa::Content::Tag::Fragment
7
9
 
10
+ attr_reader :strftime
11
+
12
+ def initialize(context:, params: [], source: nil)
13
+ super
14
+ @strftime = options["strftime"]
15
+ end
16
+
8
17
  def content
9
18
  fragment.datetime
10
19
  end
11
20
 
21
+ def render
22
+ if strftime.present?
23
+ content.strftime(strftime)
24
+ else
25
+ content.to_s
26
+ end
27
+ end
28
+
12
29
  def form_field(object_name, view, index)
13
30
  name = "#{object_name}[fragments_attributes][#{index}][datetime]"
14
31
  options = { id: form_field_id, class: "form-control", data: { "cms-datetime" => true } }
@@ -13,7 +13,7 @@ module ComfortableMexicanSofa::Content::Tag::Mixins
13
13
  return "" unless file
14
14
 
15
15
  if variant_attrs.present? && attachment.image?
16
- file = file.variant(variant_attrs)
16
+ file = file.variant(combine_options: variant_attrs)
17
17
  end
18
18
 
19
19
  url = rails_blob_path(file)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ComfortableMexicanSofa
4
4
 
5
- VERSION = "2.0.13"
5
+ VERSION = "2.0.14"
6
6
 
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: comfortable_mexican_sofa
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.13
4
+ version: 2.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oleg Khabarov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-13 00:00:00.000000000 Z
11
+ date: 2018-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_link_to