trmnl-liquid 0.2.0 → 0.4.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 +4 -4
- data/lib/trmnl/liquid/fallback.rb +61 -0
- data/lib/trmnl/liquid/filters.rb +138 -21
- data/lib/trmnl/liquid/version.rb +1 -2
- data/lib/trmnl/liquid.rb +1 -0
- data/trmnl-liquid.gemspec +4 -1
- metadata +51 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f21152bc330bde8f49978e8a4680e4e1ef79e19c8dd63e657ada328567c85e1c
|
|
4
|
+
data.tar.gz: 58fc02a7aa0dbbb0e2fcf66d08019e59a76a63cb18f8bacf63e462df4d50f39b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bca98684b5fa6857652231dfbf9ce04cdb49d42feeb0025c3f2862f7eb589d92d1bb42d0142728e12c103fbac42d519a65d87e1cdf4a6b03f6855a9128807745
|
|
7
|
+
data.tar.gz: 0eaad3ce40e20868d4560eacdd1810b1dc19ee8d9676907e87a588141e23949ab80c9bb7fd9daab07da7fea2b69e002311f6e9c83ec33e9880ddb3e6ea63ac06
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module TRMNL
|
|
2
|
+
module Liquid
|
|
3
|
+
# library-native formatting functions that don't rely on ActionView helpers
|
|
4
|
+
module Fallback
|
|
5
|
+
extend self
|
|
6
|
+
|
|
7
|
+
def number_with_delimiter(number, delimiter, separator)
|
|
8
|
+
str = number.to_s
|
|
9
|
+
|
|
10
|
+
# return early if it's not a simple numeric-like string
|
|
11
|
+
return str unless str.match?(/\A-?\d+(\.\d+)?\z/)
|
|
12
|
+
|
|
13
|
+
integer, fractional = str.split('.')
|
|
14
|
+
negative = integer.start_with?('-')
|
|
15
|
+
integer = integer[1..] if negative
|
|
16
|
+
|
|
17
|
+
integer_with_delimiters = integer.reverse.scan(/\d{1,3}/).join(delimiter).reverse
|
|
18
|
+
integer_with_delimiters = "-#{integer_with_delimiters}" if negative
|
|
19
|
+
|
|
20
|
+
if fractional
|
|
21
|
+
integer_with_delimiters + separator + fractional
|
|
22
|
+
else
|
|
23
|
+
integer_with_delimiters
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def number_to_currency(number, unit, delimiter, separator, precision)
|
|
28
|
+
result = number_with_delimiter(number, delimiter, separator)
|
|
29
|
+
dollars, cents = result.split(separator)
|
|
30
|
+
|
|
31
|
+
if precision <= 0
|
|
32
|
+
"#{unit}#{dollars}"
|
|
33
|
+
else
|
|
34
|
+
cents = cents.to_s[0..(precision - 1)].ljust(precision, '0')
|
|
35
|
+
"#{unit}#{dollars}#{separator}#{cents}"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def ordinalize(number)
|
|
40
|
+
suffix =
|
|
41
|
+
if (11..13).include?(number % 100)
|
|
42
|
+
'th'
|
|
43
|
+
else
|
|
44
|
+
case number % 10
|
|
45
|
+
when 1 then 'st'
|
|
46
|
+
when 2 then 'nd'
|
|
47
|
+
when 3 then 'rd'
|
|
48
|
+
else 'th'
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
"#{number}#{suffix}"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def pluralize(count, singular, plural)
|
|
56
|
+
plural ||= "#{singular}s"
|
|
57
|
+
count == 1 ? "1 #{singular}" : "#{count} #{plural}"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
data/lib/trmnl/liquid/filters.rb
CHANGED
|
@@ -1,12 +1,23 @@
|
|
|
1
|
-
require 'action_view'
|
|
2
1
|
require 'date'
|
|
2
|
+
require 'json'
|
|
3
3
|
require 'redcarpet'
|
|
4
4
|
require 'tzinfo'
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
require 'rqrcode'
|
|
6
|
+
require 'securerandom'
|
|
7
|
+
|
|
8
|
+
require_relative 'fallback'
|
|
9
|
+
|
|
10
|
+
# optional
|
|
11
|
+
%w[
|
|
12
|
+
i18n
|
|
13
|
+
action_view
|
|
14
|
+
active_support/core_ext/integer/inflections
|
|
15
|
+
].each do |lib|
|
|
16
|
+
begin
|
|
17
|
+
require lib
|
|
18
|
+
rescue LoadError
|
|
19
|
+
nil
|
|
20
|
+
end
|
|
10
21
|
end
|
|
11
22
|
|
|
12
23
|
module TRMNL
|
|
@@ -36,16 +47,24 @@ module TRMNL
|
|
|
36
47
|
service.render(markdown)
|
|
37
48
|
end
|
|
38
49
|
|
|
39
|
-
def number_with_delimiter(number, delimiter = ',', separator = '
|
|
40
|
-
helpers.
|
|
50
|
+
def number_with_delimiter(number, delimiter = ',', separator = '.')
|
|
51
|
+
if helpers.respond_to?(:number_with_delimiter)
|
|
52
|
+
helpers.number_with_delimiter(number, delimiter: delimiter, separator: separator)
|
|
53
|
+
else
|
|
54
|
+
Fallback.number_with_delimiter(number, delimiter, separator)
|
|
55
|
+
end
|
|
41
56
|
end
|
|
42
57
|
|
|
43
|
-
def number_to_currency(number, unit_or_locale = '$', delimiter = ',', separator = '.')
|
|
44
|
-
|
|
45
|
-
|
|
58
|
+
def number_to_currency(number, unit_or_locale = '$', delimiter = ',', separator = '.', precision = 2)
|
|
59
|
+
if helpers.respond_to?(:number_to_currency)
|
|
60
|
+
cur_switcher = with_i18n(:unit) do |i18n|
|
|
61
|
+
i18n.available_locales.include?(unit_or_locale.to_sym) ? :locale : :unit
|
|
62
|
+
end
|
|
63
|
+
opts = { delimiter:, separator:, precision: }.merge(cur_switcher => unit_or_locale)
|
|
64
|
+
helpers.number_to_currency(number, **opts)
|
|
65
|
+
else
|
|
66
|
+
Fallback.number_to_currency(number, unit_or_locale, delimiter, separator, precision)
|
|
46
67
|
end
|
|
47
|
-
opts = { delimiter:, separator: }.merge(cur_switcher => unit_or_locale)
|
|
48
|
-
helpers.number_to_currency(number, **opts)
|
|
49
68
|
end
|
|
50
69
|
|
|
51
70
|
def l_word(word, locale)
|
|
@@ -61,16 +80,76 @@ module TRMNL
|
|
|
61
80
|
end
|
|
62
81
|
end
|
|
63
82
|
|
|
64
|
-
def
|
|
65
|
-
|
|
83
|
+
def map_to_i(collection)
|
|
84
|
+
collection.map(&:to_i)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def pluralize(singular, count, opts = {})
|
|
88
|
+
plural = opts['plural']
|
|
89
|
+
locale = opts['locale'] || with_i18n(nil) { |i18n| i18n.locale } || 'en'
|
|
90
|
+
|
|
91
|
+
if helpers.respond_to?(:pluralize)
|
|
92
|
+
helpers.pluralize(count, singular, plural: plural, locale: locale)
|
|
93
|
+
else
|
|
94
|
+
Fallback.pluralize(count, singular, plural)
|
|
95
|
+
end
|
|
66
96
|
end
|
|
67
97
|
|
|
68
98
|
def json(obj)
|
|
69
99
|
JSON.generate(obj)
|
|
70
100
|
end
|
|
71
101
|
|
|
102
|
+
def parse_json(obj)
|
|
103
|
+
JSON.parse(obj)
|
|
104
|
+
end
|
|
105
|
+
|
|
72
106
|
def sample(array) = array.sample
|
|
73
107
|
|
|
108
|
+
# source: https://github.com/jekyll/jekyll/blob/40ac06ed3e95325a07868dd2ac419e409af823b6/lib/jekyll/filters.rb#L209
|
|
109
|
+
def where_exp(input, variable, expression)
|
|
110
|
+
return input unless input.respond_to?(:select)
|
|
111
|
+
|
|
112
|
+
input = input.values if input.is_a?(Hash)
|
|
113
|
+
|
|
114
|
+
condition = parse_condition(expression)
|
|
115
|
+
@context.stack do
|
|
116
|
+
input.select do |object|
|
|
117
|
+
@context[variable] = object
|
|
118
|
+
condition.evaluate(@context)
|
|
119
|
+
end
|
|
120
|
+
end || []
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def ordinalize(date_str, strftime_exp)
|
|
124
|
+
date = Date.parse(date_str)
|
|
125
|
+
|
|
126
|
+
ordinal_day = if date.day.respond_to?(:ordinalize)
|
|
127
|
+
date.day.ordinalize
|
|
128
|
+
else
|
|
129
|
+
Fallback.ordinalize(date.day)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
date.strftime(strftime_exp.gsub('<<ordinal_day>>', ordinal_day))
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def qr_code(data, size = 11, level = '')
|
|
136
|
+
level.downcase!
|
|
137
|
+
level = 'h' unless %w[l m q h].include?(level)
|
|
138
|
+
|
|
139
|
+
qrcode = RQRCode::QRCode.new(data, level:)
|
|
140
|
+
qrcode.as_svg(
|
|
141
|
+
color: '000',
|
|
142
|
+
fill: 'fff',
|
|
143
|
+
shape_rendering: 'crispEdges',
|
|
144
|
+
module_size: size,
|
|
145
|
+
standalone: true,
|
|
146
|
+
use_path: true,
|
|
147
|
+
svg_attributes: {
|
|
148
|
+
class: 'qr-code'
|
|
149
|
+
}
|
|
150
|
+
)
|
|
151
|
+
end
|
|
152
|
+
|
|
74
153
|
private
|
|
75
154
|
|
|
76
155
|
def with_i18n(fallback, &block)
|
|
@@ -94,15 +173,53 @@ module TRMNL
|
|
|
94
173
|
end
|
|
95
174
|
end
|
|
96
175
|
|
|
97
|
-
def
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
176
|
+
def parse_condition(exp)
|
|
177
|
+
parser = ::Liquid::Parser.new(exp)
|
|
178
|
+
condition = parse_binary_comparison(parser)
|
|
179
|
+
|
|
180
|
+
parser.consume(:end_of_string)
|
|
181
|
+
condition
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def parse_binary_comparison(parser)
|
|
185
|
+
condition = parse_comparison(parser)
|
|
186
|
+
first_condition = condition
|
|
187
|
+
while (binary_operator = parser.id?('and') || parser.id?('or'))
|
|
188
|
+
child_condition = parse_comparison(parser)
|
|
189
|
+
condition.send(binary_operator, child_condition)
|
|
190
|
+
condition = child_condition
|
|
191
|
+
end
|
|
192
|
+
first_condition
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def parse_comparison(parser)
|
|
196
|
+
left_operand = ::Liquid::Expression.parse(parser.expression)
|
|
197
|
+
operator = parser.consume?(:comparison)
|
|
198
|
+
|
|
199
|
+
# No comparison-operator detected. Initialize a Liquid::Condition using only left operand
|
|
200
|
+
return ::Liquid::Condition.new(left_operand) unless operator
|
|
201
|
+
|
|
202
|
+
# Parse what remained after extracting the left operand and the `:comparison` operator
|
|
203
|
+
# and initialize a Liquid::Condition object using the operands and the comparison-operator
|
|
204
|
+
::Liquid::Condition.new(left_operand, operator, ::Liquid::Expression.parse(parser.expression))
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
class Helpers
|
|
208
|
+
%w[
|
|
209
|
+
::ActionView::Helpers::TextHelper
|
|
210
|
+
::ActionView::Helpers::NumberHelper
|
|
211
|
+
].each do |name|
|
|
212
|
+
begin
|
|
213
|
+
include Object.const_get(name)
|
|
214
|
+
rescue NameError
|
|
215
|
+
next
|
|
102
216
|
end
|
|
103
|
-
Object.new.extend(mod)
|
|
104
217
|
end
|
|
105
218
|
end
|
|
219
|
+
|
|
220
|
+
def helpers
|
|
221
|
+
@helpers ||= Helpers.new
|
|
222
|
+
end
|
|
106
223
|
end
|
|
107
224
|
end
|
|
108
225
|
end
|
data/lib/trmnl/liquid/version.rb
CHANGED
data/lib/trmnl/liquid.rb
CHANGED
data/trmnl-liquid.gemspec
CHANGED
|
@@ -27,7 +27,10 @@ Gem::Specification.new do |spec|
|
|
|
27
27
|
spec.files = Dir["*.gemspec", "lib/**/*"]
|
|
28
28
|
spec.require_paths = ["lib"]
|
|
29
29
|
|
|
30
|
-
spec.add_dependency "
|
|
30
|
+
spec.add_dependency "base64"
|
|
31
31
|
spec.add_dependency "liquid", "~> 5.6"
|
|
32
32
|
spec.add_dependency "redcarpet", "~> 3.6"
|
|
33
|
+
spec.add_dependency "rqrcode", "~> 3.0"
|
|
34
|
+
spec.add_dependency "securerandom", ">= 0.3"
|
|
35
|
+
spec.add_dependency "tzinfo"
|
|
33
36
|
end
|
metadata
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: trmnl-liquid
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- TRMNL
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
|
-
name:
|
|
13
|
+
name: base64
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
|
-
- - "
|
|
16
|
+
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '
|
|
18
|
+
version: '0'
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
|
-
- - "
|
|
23
|
+
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: '
|
|
25
|
+
version: '0'
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: liquid
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -51,6 +51,48 @@ dependencies:
|
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
53
|
version: '3.6'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: rqrcode
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '3.0'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '3.0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: securerandom
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0.3'
|
|
75
|
+
type: :runtime
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0.3'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: tzinfo
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0'
|
|
89
|
+
type: :runtime
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0'
|
|
54
96
|
email:
|
|
55
97
|
- engineering@usetrmnl.com
|
|
56
98
|
executables: []
|
|
@@ -58,6 +100,7 @@ extensions: []
|
|
|
58
100
|
extra_rdoc_files: []
|
|
59
101
|
files:
|
|
60
102
|
- lib/trmnl/liquid.rb
|
|
103
|
+
- lib/trmnl/liquid/fallback.rb
|
|
61
104
|
- lib/trmnl/liquid/file_system.rb
|
|
62
105
|
- lib/trmnl/liquid/filters.rb
|
|
63
106
|
- lib/trmnl/liquid/template_tag.rb
|
|
@@ -87,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
87
130
|
- !ruby/object:Gem::Version
|
|
88
131
|
version: '0'
|
|
89
132
|
requirements: []
|
|
90
|
-
rubygems_version: 3.6.
|
|
133
|
+
rubygems_version: 3.6.9
|
|
91
134
|
specification_version: 4
|
|
92
135
|
summary: Liquid templating engine for TRMNL plugins
|
|
93
136
|
test_files: []
|