semantic_date_time_tags 0.1.19 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +30 -0
- data/.rubocop.yml +6 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +3 -1
- data/Gemfile.lock +147 -108
- data/Guardfile +4 -2
- data/README.md +1 -1
- data/Rakefile +7 -5
- data/lib/semantic_date_time_tags.rb +3 -1
- data/lib/semantic_date_time_tags/engine.rb +4 -2
- data/lib/semantic_date_time_tags/format_parser.rb +30 -29
- data/lib/semantic_date_time_tags/railtie.rb +5 -3
- data/lib/semantic_date_time_tags/tag.rb +46 -58
- data/lib/semantic_date_time_tags/tag/date.rb +8 -9
- data/lib/semantic_date_time_tags/tag/date_range.rb +22 -20
- data/lib/semantic_date_time_tags/tag/date_time.rb +14 -15
- data/lib/semantic_date_time_tags/tag/time.rb +8 -9
- data/lib/semantic_date_time_tags/version.rb +3 -1
- data/lib/semantic_date_time_tags/view_helpers.rb +8 -8
- data/semantic_date_time_tags.gemspec +19 -16
- data/test/semantic_date_time_tags/format_parser_test.rb +43 -43
- data/test/semantic_date_time_tags/semantic_date_range_test.rb +71 -0
- data/test/semantic_date_time_tags/semantic_date_tag_test.rb +61 -0
- data/test/semantic_date_time_tags/semantic_date_time_tag_test.rb +49 -0
- data/test/semantic_date_time_tags/semantic_time_tag_test.rb +90 -0
- data/test/test_helper.rb +10 -13
- metadata +23 -17
- data/.coveralls.yml +0 -1
- data/.travis.yml +0 -13
- data/test/semantic_date_time_tags/view_helpers_test.rb +0 -224
@@ -1,5 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "action_view"
|
3
5
|
|
4
6
|
module SemanticDateTimeTags
|
5
7
|
class FormatParser < Struct.new(:format, :str)
|
@@ -8,7 +10,7 @@ module SemanticDateTimeTags
|
|
8
10
|
def to_html
|
9
11
|
processed_str = str
|
10
12
|
(
|
11
|
-
formatting_components.flatten.inject(
|
13
|
+
formatting_components.flatten.inject("") do |res, comp|
|
12
14
|
regexp = Regexp.new(get_regexp_for_component(comp))
|
13
15
|
if match = processed_str.match(regexp)
|
14
16
|
res += get_tag_for_match(match[0], comp)
|
@@ -19,38 +21,37 @@ module SemanticDateTimeTags
|
|
19
21
|
).html_safe
|
20
22
|
end
|
21
23
|
|
22
|
-
private
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
24
|
+
private
|
25
|
+
def formatting_components
|
26
|
+
format.scan(/(%-?[[:word:]]|.+?(?=%))/)
|
27
|
+
end
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
29
|
+
def get_tag_for_match(match, comp)
|
30
|
+
content_tag :span, match, class: get_classes_for_component(comp)
|
31
|
+
end
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
def get_tag_for_str(str)
|
34
|
+
return "" unless str.present?
|
35
|
+
content_tag :span, str, class: "str"
|
36
|
+
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
def get_regexp_for_component(comp)
|
39
|
+
case comp
|
40
|
+
when /%-?[[:word:]]/ then "([[:word:]]+)"
|
41
|
+
else "(#{comp})"
|
42
|
+
end
|
41
43
|
end
|
42
|
-
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
45
|
+
def get_classes_for_component(comp)
|
46
|
+
case comp
|
47
|
+
when /%-?[YCy]/ then ["year", comp[/[[:word:]]/]]
|
48
|
+
when /%-?[mBbh]/ then ["month", comp[/[[:word:]]/]]
|
49
|
+
when /%-?[aAdej]/ then ["day", comp[/[[:word:]]/]]
|
50
|
+
when /%-?[HKIl]/ then ["hours", comp[/[[:word:]]/]]
|
51
|
+
when /%-?[M]/ then ["minutes", comp[/[[:word:]]/]]
|
52
|
+
when /%-?[pP]/ then ["ampm", comp[/[[:word:]]/]]
|
53
|
+
when /\W+/ then ["sep"]
|
54
|
+
end
|
53
55
|
end
|
54
|
-
end
|
55
56
|
end
|
56
57
|
end
|
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "semantic_date_time_tags/view_helpers"
|
4
|
+
require "rails/railtie"
|
3
5
|
|
4
6
|
module SemanticDateTimeTags
|
5
7
|
class Railtie < Rails::Railtie
|
@@ -7,4 +9,4 @@ module SemanticDateTimeTags
|
|
7
9
|
ActionView::Base.send :include, ViewHelpers
|
8
10
|
end
|
9
11
|
end
|
10
|
-
end
|
12
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "action_view"
|
4
|
+
require "i18n"
|
3
5
|
|
4
6
|
module SemanticDateTimeTags
|
5
7
|
class Tag
|
@@ -10,24 +12,18 @@ module SemanticDateTimeTags
|
|
10
12
|
attr_accessor :options
|
11
13
|
attr_accessor :output_buffer
|
12
14
|
|
13
|
-
# =====================================================================
|
14
|
-
|
15
15
|
def initialize(obj, options = {})
|
16
16
|
@obj = obj
|
17
17
|
@options = options.except(*%i(scope))
|
18
18
|
end
|
19
19
|
|
20
|
-
# ---------------------------------------------------------------------
|
21
|
-
|
22
20
|
def to_html
|
23
21
|
raise NotImplementedError
|
24
22
|
end
|
25
23
|
|
26
|
-
# ---------------------------------------------------------------------
|
27
|
-
|
28
24
|
def dom_classes
|
29
25
|
[
|
30
|
-
|
26
|
+
"semantic",
|
31
27
|
locale_class,
|
32
28
|
am_pm_class,
|
33
29
|
type_class,
|
@@ -47,39 +43,39 @@ module SemanticDateTimeTags
|
|
47
43
|
|
48
44
|
def current_date_class
|
49
45
|
return unless [::Date, ::DateTime].any? { |c| obj.instance_of? c }
|
50
|
-
|
46
|
+
"current_date" if obj.today?
|
51
47
|
end
|
52
48
|
|
53
49
|
def current_year_class
|
54
50
|
return unless [::Date, ::DateTime].any? { |c| obj.instance_of? c }
|
55
|
-
|
51
|
+
"current_year" if obj.year == ::Date.today.year
|
56
52
|
end
|
57
53
|
|
58
54
|
def whole_hour_class
|
59
55
|
return unless [::Time, ::DateTime].any? { |c| obj.instance_of? c }
|
60
|
-
|
56
|
+
"whole_hour" unless obj.min > 0
|
61
57
|
end
|
62
58
|
|
63
59
|
def whole_minute_class
|
64
60
|
return unless [::Time, ::DateTime].any? { |c| obj.instance_of? c }
|
65
|
-
|
61
|
+
"whole_minute" unless obj.sec > 0
|
66
62
|
end
|
67
63
|
|
68
64
|
def noon_class
|
69
65
|
return unless [::Time, ::DateTime].any? { |c| obj.instance_of? c }
|
70
|
-
|
66
|
+
"noon" if obj == obj.noon
|
71
67
|
end
|
72
68
|
|
73
69
|
def midnight_class
|
74
70
|
return unless [::Time, ::DateTime].any? { |c| obj.instance_of? c }
|
75
|
-
|
71
|
+
"midnight" if obj == obj.midnight
|
76
72
|
end
|
77
73
|
|
78
74
|
def am_pm_class
|
79
75
|
return unless [::Time, ::DateTime].any? { |c| obj.instance_of? c }
|
80
76
|
case
|
81
|
-
when (0..11).cover?(obj.hour) then
|
82
|
-
else
|
77
|
+
when (0..11).cover?(obj.hour) then "am"
|
78
|
+
else "pm"
|
83
79
|
end
|
84
80
|
end
|
85
81
|
|
@@ -87,57 +83,49 @@ module SemanticDateTimeTags
|
|
87
83
|
I18n.locale.to_s
|
88
84
|
end
|
89
85
|
|
90
|
-
# ---------------------------------------------------------------------
|
91
|
-
|
92
86
|
def dom_data
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
private # =============================================================
|
97
|
-
|
98
|
-
def scope
|
99
|
-
raise NotImplementedError
|
87
|
+
options.fetch(:data, {})
|
88
|
+
.merge(in_words: in_words, format: format.to_s)
|
100
89
|
end
|
101
90
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
else format
|
91
|
+
private
|
92
|
+
def scope
|
93
|
+
raise NotImplementedError
|
106
94
|
end
|
107
|
-
end
|
108
95
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
def localized_obj
|
116
|
-
I18n.l obj, format: format
|
117
|
-
end
|
96
|
+
def format_string
|
97
|
+
case format
|
98
|
+
when Symbol then I18n.t(scope)[format]
|
99
|
+
else format
|
100
|
+
end
|
101
|
+
end
|
118
102
|
|
119
|
-
|
103
|
+
def format
|
104
|
+
options.fetch :format, :full
|
105
|
+
end
|
120
106
|
|
121
|
-
|
122
|
-
|
123
|
-
|
107
|
+
def localized_obj
|
108
|
+
I18n.l obj, format: format
|
109
|
+
end
|
124
110
|
|
125
|
-
|
111
|
+
def tag_name
|
112
|
+
options.fetch :tag_name, :time
|
113
|
+
end
|
126
114
|
|
127
|
-
|
128
|
-
|
129
|
-
|
115
|
+
def in_words
|
116
|
+
[noon_in_words, midnight_in_words].reject(&:blank?).join(" ")
|
117
|
+
end
|
130
118
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
119
|
+
def noon_in_words
|
120
|
+
return unless [::Time, ::DateTime].any? { |c| obj.instance_of? c }
|
121
|
+
return unless obj == obj.noon
|
122
|
+
I18n.t :noon, scope: %i(time in_words)
|
123
|
+
end
|
136
124
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
125
|
+
def midnight_in_words
|
126
|
+
return unless [::Time, ::DateTime].any? { |c| obj.instance_of? c }
|
127
|
+
return unless obj == obj.midnight
|
128
|
+
I18n.t :midnight, scope: %i(time in_words)
|
129
|
+
end
|
142
130
|
end
|
143
131
|
end
|
@@ -1,18 +1,18 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../format_parser"
|
2
4
|
|
3
5
|
module SemanticDateTimeTags
|
4
6
|
class Tag
|
5
7
|
class Date < Tag
|
6
8
|
def initialize(obj, options = {})
|
7
|
-
raise
|
9
|
+
raise "object must be Date or DateTime" unless [::Date, ::DateTime].any? { |c| obj.instance_of? c }
|
8
10
|
|
9
11
|
options = options.except(*%i(separator))
|
10
12
|
|
11
13
|
super(obj, options)
|
12
14
|
end
|
13
15
|
|
14
|
-
# ---------------------------------------------------------------------
|
15
|
-
|
16
16
|
def to_html
|
17
17
|
if tag_name == :time
|
18
18
|
datetime = obj.acts_like?(:time) ? obj.xmlschema : obj.iso8601
|
@@ -27,11 +27,10 @@ module SemanticDateTimeTags
|
|
27
27
|
content_tag(tag_name, options.except(*%i(format))) { value }.html_safe
|
28
28
|
end
|
29
29
|
|
30
|
-
private
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
30
|
+
private
|
31
|
+
def scope
|
32
|
+
"date.formats"
|
33
|
+
end
|
35
34
|
end
|
36
35
|
end
|
37
36
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SemanticDateTimeTags
|
2
4
|
class Tag
|
3
5
|
class DateRange < Tag
|
@@ -9,11 +11,9 @@ module SemanticDateTimeTags
|
|
9
11
|
@date_from = date_from
|
10
12
|
@date_to = date_to
|
11
13
|
@options = options
|
12
|
-
@separator = options.delete(:separator) ||
|
14
|
+
@separator = options.delete(:separator) || " – "
|
13
15
|
end
|
14
16
|
|
15
|
-
# ---------------------------------------------------------------------
|
16
|
-
|
17
17
|
def spans_years?
|
18
18
|
return false if date_to.nil?
|
19
19
|
date_from.year != date_to.year
|
@@ -46,37 +46,39 @@ module SemanticDateTimeTags
|
|
46
46
|
(date_from.to_datetime.hour >= 12 && date_to.to_datetime.hour >= 12)
|
47
47
|
end
|
48
48
|
|
49
|
-
# ---------------------------------------------------------------------
|
50
|
-
|
51
49
|
def dom_classes
|
52
50
|
res = []
|
53
|
-
res <<
|
54
|
-
res <<
|
55
|
-
res <<
|
56
|
-
res <<
|
57
|
-
res <<
|
58
|
-
res <<
|
59
|
-
res <<
|
60
|
-
res <<
|
51
|
+
res << "date_range"
|
52
|
+
res << "same_year" unless spans_years?
|
53
|
+
res << "current_year" if both_in_current_year?
|
54
|
+
res << "same_month" unless spans_months?
|
55
|
+
res << "more_than_a_week" unless within_a_week?
|
56
|
+
res << "same_day" if same_day?
|
57
|
+
res << "same_time" if same_time?
|
58
|
+
res << "same_meridian" if same_meridian?
|
61
59
|
res
|
62
60
|
end
|
63
61
|
|
64
|
-
|
62
|
+
def dom_data
|
63
|
+
options.fetch(:data, {})
|
64
|
+
end
|
65
65
|
|
66
66
|
def to_html
|
67
|
+
from_options = options.merge(class: "from").except(:data, :time_data).merge(data: options.fetch(:time_data, {}))
|
67
68
|
from = case date_from
|
68
|
-
when ::DateTime then SemanticDateTimeTags::Tag::DateTime.new(date_from,
|
69
|
-
when ::Date then SemanticDateTimeTags::Tag::Date.new(date_from.to_date,
|
69
|
+
when ::DateTime then SemanticDateTimeTags::Tag::DateTime.new(date_from, from_options).to_html
|
70
|
+
when ::Date then SemanticDateTimeTags::Tag::Date.new(date_from.to_date, from_options).to_html
|
70
71
|
end
|
71
72
|
|
72
|
-
sep = content_tag(:span, @separator, class:
|
73
|
+
sep = content_tag(:span, @separator, class: "date_range_separator")
|
73
74
|
|
75
|
+
to_options = options.merge(class: "to").except(:data, :time_data).merge(data: options.fetch(:time_data, {}))
|
74
76
|
to = case date_to
|
75
|
-
when ::DateTime then SemanticDateTimeTags::Tag::DateTime.new(date_to,
|
76
|
-
when ::Date then SemanticDateTimeTags::Tag::Date.new(date_to.to_date,
|
77
|
+
when ::DateTime then SemanticDateTimeTags::Tag::DateTime.new(date_to, to_options).to_html
|
78
|
+
when ::Date then SemanticDateTimeTags::Tag::Date.new(date_to.to_date, to_options).to_html
|
77
79
|
end
|
78
80
|
|
79
|
-
content_tag(:span, class: dom_classes) { [from, sep, to].join.html_safe }.html_safe
|
81
|
+
content_tag(:span, class: dom_classes, data: dom_data) { [from, sep, to].join.html_safe }.html_safe
|
80
82
|
end
|
81
83
|
end
|
82
84
|
end
|
@@ -1,18 +1,18 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../format_parser"
|
2
4
|
|
3
5
|
module SemanticDateTimeTags
|
4
6
|
class Tag
|
5
7
|
class DateTime < Tag
|
6
8
|
def initialize(obj, options = {})
|
7
|
-
raise
|
9
|
+
raise "object must be DateTime" unless obj.instance_of?(::DateTime)
|
8
10
|
|
9
11
|
options = options.except(*%i(separator))
|
10
12
|
|
11
13
|
super(obj, options)
|
12
14
|
end
|
13
15
|
|
14
|
-
# ---------------------------------------------------------------------
|
15
|
-
|
16
16
|
def to_html
|
17
17
|
if tag_name == :time
|
18
18
|
datetime = obj.acts_like?(:time) ? obj.xmlschema : obj.iso8601
|
@@ -27,19 +27,18 @@ module SemanticDateTimeTags
|
|
27
27
|
time_tag(obj, options.except(*%i(format))) { value }.html_safe
|
28
28
|
end
|
29
29
|
|
30
|
-
private
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
30
|
+
private
|
31
|
+
def scope
|
32
|
+
"date_time.formats"
|
33
|
+
end
|
35
34
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
35
|
+
def localized_obj
|
36
|
+
format_string = case format
|
37
|
+
when Symbol then I18n.t(format, scope: scope, locale: I18n.locale)
|
38
|
+
else format
|
39
|
+
end
|
40
|
+
I18n.l(obj, format: format_string)
|
40
41
|
end
|
41
|
-
I18n.l(obj, format: format_string)
|
42
|
-
end
|
43
42
|
end
|
44
43
|
end
|
45
44
|
end
|
@@ -1,15 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../format_parser"
|
2
4
|
|
3
5
|
module SemanticDateTimeTags
|
4
6
|
class Tag
|
5
7
|
class Time < Tag
|
6
8
|
def initialize(obj, options = {})
|
7
|
-
raise
|
9
|
+
raise "object must be Time" unless obj.instance_of?(::Time)
|
8
10
|
super(obj, options)
|
9
11
|
end
|
10
12
|
|
11
|
-
# ---------------------------------------------------------------------
|
12
|
-
|
13
13
|
def to_html
|
14
14
|
if tag_name == :time
|
15
15
|
datetime = obj.acts_like?(:time) ? obj.xmlschema : obj.iso8601
|
@@ -24,11 +24,10 @@ module SemanticDateTimeTags
|
|
24
24
|
content_tag(tag_name, options.except(*%i(format))) { value }.html_safe
|
25
25
|
end
|
26
26
|
|
27
|
-
private
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
27
|
+
private
|
28
|
+
def scope
|
29
|
+
"time.formats"
|
30
|
+
end
|
32
31
|
end
|
33
32
|
end
|
34
33
|
end
|