trmnl-liquid 0.2.1 → 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 +134 -21
- data/lib/trmnl/liquid/version.rb +1 -2
- data/lib/trmnl/liquid.rb +1 -0
- data/trmnl-liquid.gemspec +4 -1
- metadata +49 -6
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,8 +80,19 @@ 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)
|
|
@@ -75,6 +105,51 @@ module TRMNL
|
|
|
75
105
|
|
|
76
106
|
def sample(array) = array.sample
|
|
77
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
|
+
|
|
78
153
|
private
|
|
79
154
|
|
|
80
155
|
def with_i18n(fallback, &block)
|
|
@@ -98,15 +173,53 @@ module TRMNL
|
|
|
98
173
|
end
|
|
99
174
|
end
|
|
100
175
|
|
|
101
|
-
def
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
|
106
216
|
end
|
|
107
|
-
Object.new.extend(mod)
|
|
108
217
|
end
|
|
109
218
|
end
|
|
219
|
+
|
|
220
|
+
def helpers
|
|
221
|
+
@helpers ||= Helpers.new
|
|
222
|
+
end
|
|
110
223
|
end
|
|
111
224
|
end
|
|
112
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,7 +1,7 @@
|
|
|
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
|
|
@@ -10,19 +10,19 @@ cert_chain: []
|
|
|
10
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
|