joys 0.1.1 → 0.1.3

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.
@@ -0,0 +1,156 @@
1
+ # frozen_string_literal: true
2
+ # lib/joys/styles.rb - Simplified Component Styling
3
+ require 'fileutils'
4
+ require 'set'
5
+ module Joys
6
+ module Styles
7
+ def self.compile_component_styles(comp_name, base_css, media_queries, scoped)
8
+ scope_prefix = scoped ? ".#{comp_name.tr('_', '-')} " : ""
9
+ processed_base_css = base_css.map { |css| scope_css(css, scope_prefix) }
10
+ processed_media_queries = {}
11
+
12
+ # FIX: Actually iterate over the media_queries parameter
13
+ media_queries.each do |key, css_rules|
14
+ scoped_rules = css_rules.map { |css| scope_css(css, scope_prefix) }
15
+ processed_media_queries[key] = scoped_rules
16
+ end
17
+
18
+ Joys.compiled_styles[comp_name] = {
19
+ base_css: processed_base_css,
20
+ media_queries: processed_media_queries,
21
+ container_queries: {} # Keep this for compatibility, but media_queries contains all now
22
+ }.freeze
23
+ end
24
+
25
+ private
26
+
27
+ def self.render_consolidated_styles(used_components)
28
+ return "" if used_components.empty?
29
+ cache_key = used_components.to_a.sort.join(',')
30
+ return Joys.consolidated_cache[cache_key] if Joys.consolidated_cache.key?(cache_key)
31
+ buffer = String.new(capacity: 4096)
32
+ min_queries = Hash.new { |h,k| h[k] = [] }
33
+ max_queries = Hash.new { |h,k| h[k] = [] }
34
+ minmax_queries = []
35
+ container_min_queries = Hash.new { |h,k| h[k] = [] }
36
+ container_max_queries = Hash.new { |h,k| h[k] = [] }
37
+ container_minmax_queries = []
38
+ container_named_queries = Hash.new { |h,k| h[k] = {min: Hash.new { |h,k| h[k] = [] }, max: Hash.new { |h,k| h[k] = [] }, minmax: []} }
39
+ seen_base = Set.new
40
+
41
+ used_components.each do |comp|
42
+ styles = Joys.compiled_styles[comp] || next
43
+ styles[:base_css].each do |rule|
44
+ next if seen_base.include?(rule)
45
+ buffer << rule
46
+ seen_base << rule
47
+ end
48
+ styles[:media_queries].each do |key, rules|
49
+ case key
50
+ # FIX: Updated regex patterns to match the actual key formats
51
+ when /^m-min-(\d+)$/
52
+ min_queries[$1.to_i].concat(rules)
53
+ when /^m-max-(\d+)$/
54
+ max_queries[$1.to_i].concat(rules)
55
+ when /^m-minmax-(\d+)-(\d+)$/
56
+ minmax_queries << { min: $1.to_i, max: $2.to_i, css: rules }
57
+ when /^c-min-(\d+)$/
58
+ container_min_queries[$1.to_i].concat(rules)
59
+ when /^c-max-(\d+)$/
60
+ container_max_queries[$1.to_i].concat(rules)
61
+ when /^c-minmax-(\d+)-(\d+)$/
62
+ container_minmax_queries << { min: $1.to_i, max: $2.to_i, css: rules }
63
+ when /^c-([^-]+)-min-(\d+)$/
64
+ name, size = $1, $2.to_i
65
+ container_named_queries[name][:min][size].concat(rules)
66
+ when /^c-([^-]+)-max-(\d+)$/
67
+ name, size = $1, $2.to_i
68
+ container_named_queries[name][:max][size].concat(rules)
69
+ when /^c-([^-]+)-minmax-(\d+)-(\d+)$/
70
+ name, min_size, max_size = $1, $2.to_i, $3.to_i
71
+ container_named_queries[name][:minmax] << { min: min_size, max: max_size, css: rules }
72
+ end
73
+ end
74
+ end
75
+
76
+ max_queries.sort.reverse.each do |bp, rules|
77
+ buffer << "@media (max-width: #{bp}px){"
78
+ rules.uniq.each { |r| buffer << r }
79
+ buffer << "}"
80
+ end
81
+ min_queries.sort.each do |bp, rules|
82
+ buffer << "@media (min-width: #{bp}px){"
83
+ rules.uniq.each { |r| buffer << r }
84
+ buffer << "}"
85
+ end
86
+ minmax_queries.sort_by { |q| [q[:min], q[:max]] }.each do |q|
87
+ buffer << "@media (min-width: #{q[:min]}px) and (max-width: #{q[:max]}px){"
88
+ q[:css].uniq.each { |r| buffer << r }
89
+ buffer << "}"
90
+ end
91
+ container_max_queries.sort.reverse.each do |size, rules|
92
+ buffer << "@container (max-width: #{size}px){"
93
+ rules.uniq.each { |r| buffer << r }
94
+ buffer << "}"
95
+ end
96
+ container_min_queries.sort.each do |size, rules|
97
+ buffer << "@container (min-width: #{size}px){"
98
+ rules.uniq.each { |r| buffer << r }
99
+ buffer << "}"
100
+ end
101
+ container_minmax_queries.sort_by { |q| [q[:min], q[:max]] }.each do |q|
102
+ buffer << "@container (min-width: #{q[:min]}px) and (max-width: #{q[:max]}px){"
103
+ q[:css].uniq.each { |r| buffer << r }
104
+ buffer << "}"
105
+ end
106
+ container_named_queries.each do |name, queries|
107
+ queries[:max].sort.reverse.each do |size, rules|
108
+ buffer << "@container #{name} (max-width: #{size}px){"
109
+ rules.uniq.each { |r| buffer << r }
110
+ buffer << "}"
111
+ end
112
+ queries[:min].sort.each do |size, rules|
113
+ buffer << "@container #{name} (min-width: #{size}px){"
114
+ rules.uniq.each { |r| buffer << r }
115
+ buffer << "}"
116
+ end
117
+ queries[:minmax].sort_by { |q| [q[:min], q[:max]] }.each do |q|
118
+ buffer << "@container #{name} (min-width: #{q[:min]}px) and (max-width: #{q[:max]}px){"
119
+ q[:css].uniq.each { |r| buffer << r }
120
+ buffer << "}"
121
+ end
122
+ end
123
+ buffer.freeze.tap { |css| Joys.consolidated_cache[cache_key] = css }
124
+ end
125
+
126
+ def self.render_external_styles(used_components)
127
+ return "" if used_components.empty?
128
+ cache_key = used_components.to_a.sort.join(',')
129
+ css_filename = "#{cache_key}.css"
130
+ #css_filename = "#{Digest::SHA256.hexdigest(cache_key)[0..12]}.css"
131
+ css_path = Joys.css_path || "public/css"
132
+ full_path = File.join(css_path, css_filename)
133
+ FileUtils.mkdir_p(css_path)
134
+ unless File.exist?(full_path)
135
+ css_content = render_consolidated_styles(used_components)
136
+ File.write(full_path, css_content)
137
+ end
138
+ "<link rel=\"stylesheet\" href=\"/css/#{css_filename}\">"
139
+ end
140
+
141
+ def self.scope_css(css, scope_prefix)
142
+ return css if scope_prefix.empty?
143
+ selectors = css.split(',')
144
+ scoped_selectors = selectors.map do |selector|
145
+ selector.strip!
146
+ if match = selector.match(/^\s*\.([a-zA-Z][\w-]*)/)
147
+ #if selector.match(/^\s*\.([a-zA-Z][\w-]*)/)
148
+ "#{scope_prefix}#{selector}"
149
+ else
150
+ selector
151
+ end
152
+ end
153
+ scoped_selectors.join(', ')
154
+ end
155
+ end
156
+ end
data/lib/joys/tags.rb ADDED
@@ -0,0 +1,124 @@
1
+ # lib/joys/tags.rb
2
+ require_relative "hugdown"
3
+ module Joys
4
+ module Tags
5
+ VOID_TAGS = %w[area base br col embed hr img input link meta param source track wbr].freeze
6
+ TAGS = %w[
7
+ a abbr address article aside audio b bdi bdo blockquote body button canvas
8
+ caption cite code colgroup data datalist dd del details dfn dialog div dl dt
9
+ em fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header hgroup
10
+ html i iframe ins kbd label legend li main map mark menu meter nav noscript
11
+ object ol optgroup option output p picture pre progress q rp rt ruby s samp
12
+ script section select small span strong style sub summary sup table tbody td
13
+ template textarea tfoot th thead time title tr u ul var video
14
+ ].freeze
15
+ BOOLEAN_ATTRS = %w[
16
+ disabled readonly read_only multiple checked selected
17
+ auto_focus autofocus no_validate novalidate form_novalidate formnovalidate
18
+ hidden required open reversed scoped seamless muted auto_play autoplay
19
+ controls loop default inert item_scope itemscope
20
+ ].to_set.freeze
21
+
22
+ CLS = ' class="'.freeze
23
+ QUO = '"'.freeze
24
+ BC = '>'.freeze
25
+ BO = '<'.freeze
26
+ GTS = '</'.freeze
27
+ EQ = '="'.freeze
28
+
29
+ VOID_TAGS.each do |tag|
30
+ define_method(tag) do |cs: nil, **attrs|
31
+ class_string = case cs
32
+ when String, Symbol then cs.to_s
33
+ when Array then cs.compact.reject { |c| c == false }.map(&:to_s).join(" ")
34
+ else ""
35
+ end
36
+
37
+ @bf << BO << tag
38
+ @bf << CLS << class_string << QUO unless class_string.empty?
39
+
40
+ attrs.each do |k, v|
41
+ key = k.to_s
42
+
43
+ if v.is_a?(Hash) && (key == "data" || key.start_with?("aria"))
44
+ prefix = key.tr('_', '-')
45
+ v.each do |sk, sv|
46
+ next if sv.nil? || sv == false # Skip nil and boolean false
47
+ attr_name = "#{prefix}-#{sk.to_s.tr('_', '-')}"
48
+ @bf << " #{attr_name}#{EQ}#{CGI.escapeHTML(sv.to_s)}#{QUO}"
49
+ end
50
+ else
51
+ next if v.nil?
52
+
53
+ if BOOLEAN_ATTRS.include?(key)
54
+ @bf << " #{key.tr('_', '')}" if v
55
+ elsif v == false
56
+ next
57
+ else
58
+ attr_name = key.tr('_', '-')
59
+ @bf << " #{attr_name}#{EQ}#{CGI.escapeHTML(v.to_s)}#{QUO}"
60
+ end
61
+ end
62
+ end
63
+
64
+ @bf << BC
65
+ nil
66
+ end
67
+ end
68
+
69
+ TAGS.each do |tag|
70
+ define_method(tag) do |content = nil, cs: nil, raw: false, **attrs, &block|
71
+ class_string = case cs
72
+ when String, Symbol then cs.to_s
73
+ when Array then cs.compact.reject { |c| c == false }.map(&:to_s).join(" ")
74
+ else ""
75
+ end
76
+
77
+ @bf << BO << tag
78
+ @bf << CLS << class_string << QUO unless class_string.empty?
79
+
80
+ attrs.each do |k, v|
81
+ key = k.to_s
82
+
83
+ if v.is_a?(Hash) && (key == "data" || key.start_with?("aria"))
84
+ prefix = key.tr('_', '-')
85
+ v.each do |sk, sv|
86
+ next if sv.nil? || sv == false # Skip nil and boolean false
87
+ attr_name = "#{prefix}-#{sk.to_s.tr('_', '-')}"
88
+ @bf << " #{attr_name}#{EQ}#{CGI.escapeHTML(sv.to_s)}#{QUO}"
89
+ end
90
+ else
91
+ next if v.nil?
92
+
93
+ if BOOLEAN_ATTRS.include?(key)
94
+ @bf << " #{key.tr('_', '')}" if v
95
+ elsif v == false
96
+ next
97
+ else
98
+ attr_name = key.tr('_', '-')
99
+ @bf << " #{attr_name}#{EQ}#{CGI.escapeHTML(v.to_s)}#{QUO}"
100
+ end
101
+ end
102
+ end
103
+
104
+ @bf << BC
105
+
106
+ if block
107
+ instance_eval(&block)
108
+ elsif content
109
+ @bf << (raw ? content.to_s : CGI.escapeHTML(content.to_s))
110
+ end
111
+
112
+ @bf << GTS << tag << BC
113
+ nil
114
+ end
115
+ define_method("#{tag}!") do |content = nil, cs: nil, **attrs, &block|
116
+ send(tag, content, cs: cs, raw: true, **attrs, &block)
117
+ end
118
+ define_method("#{tag}?") do |content = nil, cs: nil, **attrs, &block|
119
+ parsed_content = Joys::Config.markup_parser.call(content.to_s)
120
+ send(tag, parsed_content, cs: cs, raw: true, **attrs, &block)
121
+ end
122
+ end
123
+ end
124
+ end
data/lib/joys/toys.rb ADDED
@@ -0,0 +1,328 @@
1
+ # Define a cycle helper that keeps its state per-key
2
+ # frozen_string_literal: true
3
+ # lib/joys/toys.rb - Intelligent Core Extensions
4
+ module Joys
5
+ module Toys
6
+ module CoreExtensions
7
+ module Numeric
8
+
9
+ # 3127613.filesize(:kb) => "3.0 GB", 1536.filesize => "1.5 KB"
10
+ def filesize(unit = :bytes)
11
+ # Convert input to bytes first
12
+ bytes = case unit
13
+ when :bytes, :b then self
14
+ when :kb then self * 1024
15
+ when :mb then self * 1024 * 1024
16
+ when :gb then self * 1024 * 1024 * 1024
17
+ when :tb then self * 1024 * 1024 * 1024 * 1024
18
+ else self
19
+ end
20
+
21
+ # Then convert bytes to human readable
22
+ return "#{bytes} B" if bytes < 1024
23
+
24
+ units = [
25
+ [1024**4, 'TB'],
26
+ [1024**3, 'GB'],
27
+ [1024**2, 'MB'],
28
+ [1024, 'KB']
29
+ ]
30
+ units.each do |threshold, suffix|
31
+ if bytes >= threshold
32
+ value = bytes.to_f / threshold
33
+ formatted = value % 1 == 0 ? value.to_i.to_s : "%.1f" % value
34
+ return "#{formatted} #{suffix}"
35
+ end
36
+ end
37
+
38
+ "#{bytes} B"
39
+ end
40
+ # 21 => "21st", 102 => "102nd"
41
+ def ordinal
42
+ return self.to_s if self < 0
43
+
44
+ suffix = case self.to_i % 100
45
+ when 11, 12, 13 then 'th'
46
+ else
47
+ case self.to_i % 10
48
+ when 1 then 'st'
49
+ when 2 then 'nd'
50
+ when 3 then 'rd'
51
+ else 'th'
52
+ end
53
+ end
54
+ "#{self}#{suffix}"
55
+ end
56
+
57
+ # 1200 => "1.2K", 1000000 => "1M", 1500000000 => "1.5B"
58
+ def compact
59
+ return self.to_s if self.abs < 1000
60
+
61
+ units = [
62
+ [1_000_000_000_000, 'T'],
63
+ [1_000_000_000, 'B'],
64
+ [1_000_000, 'M'],
65
+ [1_000, 'K']
66
+ ]
67
+
68
+ units.each do |threshold, suffix|
69
+ if self.abs >= threshold
70
+ value = self.to_f / threshold
71
+ formatted = value % 1 == 0 ? value.to_i.to_s : "%.1f" % value
72
+ return "#{formatted}#{suffix}"
73
+ end
74
+ end
75
+
76
+ self.to_s
77
+ end
78
+
79
+ # 42 => "forty-two", 123 => "one hundred twenty-three"
80
+ def spell
81
+ return 'zero' if self == 0
82
+ return self.to_s if self < 0 || self >= 1_000_000
83
+
84
+ ones = %w[zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen]
85
+ tens = %w[zero ten twenty thirty forty fifty sixty seventy eighty ninety]
86
+
87
+ num = self.to_i
88
+ result = []
89
+
90
+ # Thousands
91
+ if num >= 1000
92
+ result << ones[num / 1000] + ' thousand'
93
+ num %= 1000
94
+ end
95
+
96
+ # Hundreds
97
+ if num >= 100
98
+ result << ones[num / 100] + ' hundred'
99
+ num %= 100
100
+ end
101
+
102
+ # Tens and ones
103
+ if num >= 20
104
+ ten_part = tens[num / 10]
105
+ one_part = num % 10 > 0 ? ones[num % 10] : nil
106
+ result << [ten_part, one_part].compact.join('-')
107
+ elsif num > 0
108
+ result << ones[num]
109
+ end
110
+
111
+ result.join(' ')
112
+ end
113
+
114
+ # 4 => "IV", 1994 => "MCMXCIV"
115
+ def roman
116
+ return '' if self <= 0 || self >= 4000
117
+
118
+ values = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
119
+ numerals = %w[M CM D CD C XC L XL X IX V IV I]
120
+
121
+ result = ''
122
+ num = self.to_i
123
+
124
+ values.each_with_index do |value, index|
125
+ count = num / value
126
+ result += numerals[index] * count
127
+ num -= value * count
128
+ end
129
+
130
+ result
131
+ end
132
+
133
+ # 10.20.cash('€') => "10.20€", 10.20.cash('$') => "$10.20"
134
+ def cash(currency = '$')
135
+ formatted = "%.2f" % self
136
+
137
+ # Currency positioning logic
138
+ case currency.to_s
139
+ when '$', '¥', '₩', '₹', '₪' # Prefix currencies
140
+ "#{currency}#{formatted}"
141
+ when '€', '£', '₽', 'kr', 'zł' # Suffix currencies
142
+ "#{formatted}#{currency}"
143
+ else # Unknown - default to prefix
144
+ "#{currency}#{formatted}"
145
+ end
146
+ end
147
+ end
148
+
149
+ module String
150
+ # "hello world-foo" => "Hello World Foo" (smart about separators)
151
+ def title
152
+ self.split(/[\s\-_]+/).map(&:capitalize).join(' ')
153
+ end
154
+
155
+ # "John Wesley Doe" => "JWD"
156
+ def initials
157
+ self.split(/\s+/).map { |word| word[0]&.upcase }.compact.join
158
+ end
159
+
160
+ # "hello_world" => "HelloWorld"
161
+ def camel
162
+ self.split(/[\s\-_]+/).map.with_index { |word, i|
163
+ i == 0 ? word.downcase : word.capitalize
164
+ }.join
165
+ end
166
+
167
+ # "HelloWorld" => "hello_world"
168
+ def snake
169
+ self.gsub(/([A-Z])/, '_\1').downcase.sub(/^_/, '')
170
+ end
171
+
172
+ # "Hello World!" => "hello-world"
173
+ def slug
174
+ self.downcase
175
+ .gsub(/[^\w\s\-]/, '') # Remove special chars except spaces/hyphens
176
+ .strip
177
+ .gsub(/[\s\-_]+/, '-') # Convert spaces/underscores to hyphens
178
+ .gsub(/\-+/, '-') # Collapse multiple hyphens
179
+ .gsub(/^\-|\-$/, '') # Remove leading/trailing hyphens
180
+ end
181
+
182
+ # "1234567890" => "(123) 456-7890"
183
+ def phone
184
+ digits = self.gsub(/\D/, '')
185
+ return self if digits.length != 10
186
+
187
+ "(#{digits[0..2]}) #{digits[3..5]}-#{digits[6..9]}"
188
+ end
189
+
190
+ # "Long text here".snip(10) => "Long te..." (smart ellipsis)
191
+ def snip(length, ellipsis = '...')
192
+ return self if self.length <= length
193
+ return self if length < ellipsis.length + 1 # Don't make it longer!
194
+
195
+ # Smart truncation - try to break on word boundary near the limit
196
+ if length > 10
197
+ word_break = self[0..length-ellipsis.length].rindex(/\s/)
198
+ if word_break && word_break > length * 0.7 # Only if reasonably close
199
+ return self[0..word_break-1] + ellipsis
200
+ end
201
+ end
202
+
203
+ self[0..length-ellipsis.length-1] + ellipsis
204
+ end
205
+
206
+ # "hello world".hilite("world") => "hello <mark>world</mark>"
207
+ def hilite(term)
208
+ return self if term.nil? || term.empty?
209
+ self.gsub(/(#{Regexp.escape(term)})/i, '<mark>\1</mark>')
210
+ end
211
+
212
+ # "Secret info here".redact(/\w{6,}/) => "****** info ****"
213
+ def redact(pattern = /\w{4,}/)
214
+ self.gsub(pattern) { |match| '*' * match.length }
215
+ end
216
+ end
217
+
218
+ module Time
219
+ # 2.hours.ago.ago => "2h ago" (smart recent time)
220
+ def ago(format = :short)
221
+ diff = ::Time.now - self
222
+ return 'just now' if diff < 60
223
+
224
+ case format
225
+ when :short
226
+ case diff
227
+ when 0...3600 then "#{(diff/60).to_i}m ago"
228
+ when 3600...86400 then "#{(diff/3600).to_i}h ago"
229
+ when 86400...2592000 then "#{(diff/86400).to_i}d ago"
230
+ else strftime('%b %d')
231
+ end
232
+ when :long
233
+ case diff
234
+ when 0...3600 then "#{(diff/60).to_i} minutes ago"
235
+ when 3600...86400 then "#{(diff/3600).to_i} hours ago"
236
+ when 86400...2592000 then "#{(diff/86400).to_i} days ago"
237
+ else strftime('%B %d, %Y')
238
+ end
239
+ end
240
+ end
241
+ end
242
+
243
+ module Date
244
+ # Date.today.weekday => "Mon", Date.today.weekday(:long) => "Monday"
245
+ def weekday(format = :short)
246
+ format == :long ? strftime('%A') : strftime('%a')
247
+ end
248
+
249
+ # Date.new(2024,6,15).season => "Summer"
250
+ def season
251
+ month = self.month
252
+ case month
253
+ when 12, 1, 2 then 'Winter'
254
+ when 3, 4, 5 then 'Spring'
255
+ when 6, 7, 8 then 'Summer'
256
+ when 9, 10, 11 then 'Fall'
257
+ end
258
+ end
259
+
260
+ # Date.today.smart => "Today", Date.yesterday.smart => "Yesterday"
261
+ def smart
262
+ today = Date.today
263
+ return 'Today' if self == today
264
+ return 'Yesterday' if self == today - 1
265
+ return 'Tomorrow' if self == today + 1
266
+
267
+ # This year - show month/day
268
+ if self.year == today.year
269
+ strftime('%b %d')
270
+ else
271
+ strftime('%b %d, %Y')
272
+ end
273
+ end
274
+
275
+ # Date.today.schedule("+2d") => 2 days from now, Date.today.schedule("-1w") => 1 week ago
276
+ def schedule(offset_string)
277
+ match = offset_string.match(/([+-]?)(\d+)([dwmyh])/)
278
+ return self unless match
279
+
280
+ sign, amount, unit = match.captures
281
+ multiplier = sign == '-' ? -1 : 1
282
+ amount = amount.to_i * multiplier
283
+
284
+ case unit
285
+ when 'd' # days
286
+ self + amount
287
+ when 'w' # weeks
288
+ self + (amount * 7)
289
+ when 'm' # months
290
+ self >> amount # Use Ruby's month arithmetic
291
+ when 'y' # years
292
+ self >> (amount * 12)
293
+ when 'h' # hours (convert to datetime)
294
+ (self.to_time + (amount * 3600)).to_date
295
+ else
296
+ self
297
+ end
298
+ end
299
+ end
300
+
301
+ module Integer
302
+ # 7265.duration => "2h 1m", 90.duration => "1m 30s"
303
+ def duration(format = :short)
304
+ seconds = self
305
+ return '0s' if seconds == 0
306
+
307
+ hours = seconds / 3600
308
+ minutes = (seconds % 3600) / 60
309
+ secs = seconds % 60
310
+
311
+ parts = []
312
+ parts << "#{hours}h" if hours > 0
313
+ parts << "#{minutes}m" if minutes > 0
314
+ parts << "#{secs}s" if secs > 0 && hours == 0 # Only show seconds if under 1 hour
315
+
316
+ parts.join(' ')
317
+ end
318
+ end
319
+ end
320
+ end
321
+ end
322
+
323
+ # Apply the extensions
324
+ Numeric.include Joys::Toys::CoreExtensions::Numeric
325
+ String.include Joys::Toys::CoreExtensions::String
326
+ Time.include Joys::Toys::CoreExtensions::Time
327
+ Date.include Joys::Toys::CoreExtensions::Date
328
+ Integer.include Joys::Toys::CoreExtensions::Integer
data/lib/joys/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Joys
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.3"
5
5
  end
data/lib/joys.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "joys/version"
4
-
5
- module Joys
6
- class Error < StandardError; end
7
- # Your code goes here...
8
- end
4
+ require_relative "joys/core"
5
+ require_relative "joys/helpers"
6
+ require_relative "joys/styles"
7
+ require_relative "joys/tags"
8
+ require_relative "joys/config"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: joys
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Garcia
@@ -18,15 +18,26 @@ executables: []
18
18
  extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
- - ".DS_Store"
22
21
  - CHANGELOG.md
23
22
  - CODE_OF_CONDUCT.md
24
23
  - LICENSE
25
24
  - LICENSE.txt
26
25
  - README.md
27
26
  - Rakefile
27
+ - joys-0.1.0.gem
28
+ - joys-0.1.1.gem
29
+ - joys-0.1.2.gem
28
30
  - lib/.DS_Store
29
31
  - lib/joys.rb
32
+ - lib/joys/cli.rb
33
+ - lib/joys/config.rb
34
+ - lib/joys/core.rb
35
+ - lib/joys/data.rb
36
+ - lib/joys/helpers.rb
37
+ - lib/joys/ssg.rb
38
+ - lib/joys/styles.rb
39
+ - lib/joys/tags.rb
40
+ - lib/joys/toys.rb
30
41
  - lib/joys/version.rb
31
42
  - sig/joys.rbs
32
43
  homepage: https://github.com/activestylus/joys.git
data/.DS_Store DELETED
Binary file