zakuro 0.0.3 → 0.1.4

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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +102 -42
  3. data/doc/operation.md +25 -0
  4. data/doc/operation/csv/month.csv +202 -0
  5. data/doc/operation/operation.xlsx +0 -0
  6. data/doc/operation/transfer.rb +77 -0
  7. data/lib/zakuro/calculation/base/multi_gengou.rb +101 -0
  8. data/lib/zakuro/calculation/base/multi_gengou_roller.rb +218 -0
  9. data/lib/zakuro/calculation/base/year.rb +107 -0
  10. data/lib/zakuro/calculation/cycle/abstract_remainder.rb +459 -0
  11. data/lib/zakuro/calculation/cycle/abstract_solar_term.rb +173 -0
  12. data/lib/zakuro/calculation/cycle/zodiac.rb +106 -0
  13. data/lib/zakuro/calculation/monthly/first_day.rb +45 -0
  14. data/lib/zakuro/calculation/monthly/initialized_month.rb +125 -0
  15. data/lib/zakuro/calculation/monthly/month.rb +187 -0
  16. data/lib/zakuro/calculation/monthly/month_label.rb +88 -0
  17. data/lib/zakuro/calculation/monthly/operated_month.rb +209 -0
  18. data/lib/zakuro/calculation/range/full_range.rb +210 -0
  19. data/lib/zakuro/calculation/range/operated_range.rb +144 -0
  20. data/lib/zakuro/calculation/range/operated_solar_terms.rb +201 -0
  21. data/lib/zakuro/calculation/range/transfer/western_date_allocation.rb +82 -0
  22. data/lib/zakuro/calculation/range/transfer/year_boundary.rb +146 -0
  23. data/lib/zakuro/calculation/specifier/single_day.rb +109 -0
  24. data/lib/zakuro/calculation/summary/single.rb +129 -0
  25. data/lib/zakuro/condition.rb +16 -13
  26. data/lib/zakuro/era/japan/gengou.rb +106 -0
  27. data/lib/zakuro/era/japan/gengou/parser.rb +167 -0
  28. data/lib/zakuro/era/japan/gengou/type.rb +178 -0
  29. data/lib/zakuro/era/japan/gengou/validator.rb +236 -0
  30. data/lib/zakuro/era/japan/reki.rb +91 -0
  31. data/lib/zakuro/era/{gengou → japan/yaml}/set-001-until-south.yaml +0 -0
  32. data/lib/zakuro/era/{gengou → japan/yaml}/set-002-from-north.yaml +0 -0
  33. data/lib/zakuro/era/{gengou → japan/yaml}/set-003-modern.yaml +0 -0
  34. data/lib/zakuro/era/western.rb +1 -1
  35. data/lib/zakuro/merchant.rb +2 -2
  36. data/lib/zakuro/operation/month/parser.rb +373 -0
  37. data/lib/zakuro/operation/month/type.rb +453 -0
  38. data/lib/zakuro/operation/month/validator.rb +802 -0
  39. data/lib/zakuro/operation/operation.rb +66 -0
  40. data/lib/zakuro/operation/yaml/month.yaml +6452 -0
  41. data/lib/zakuro/output/error.rb +7 -4
  42. data/lib/zakuro/output/logger.rb +50 -47
  43. data/lib/zakuro/output/response.rb +146 -143
  44. data/lib/zakuro/result/core.rb +52 -0
  45. data/lib/zakuro/result/data.rb +187 -0
  46. data/lib/zakuro/result/operation.rb +114 -0
  47. data/lib/zakuro/result/result.rb +37 -0
  48. data/lib/zakuro/{output → tools}/stringifier.rb +16 -9
  49. data/lib/zakuro/tools/typeof.rb +33 -0
  50. data/lib/zakuro/version.rb +1 -1
  51. data/lib/zakuro/version/abstract_version.rb +1 -1
  52. data/lib/zakuro/version/context.rb +23 -0
  53. data/lib/zakuro/version/senmyou/cycle/remainder.rb +63 -0
  54. data/lib/zakuro/version/senmyou/cycle/solar_term.rb +31 -0
  55. data/lib/zakuro/version/senmyou/monthly/lunar_phase.rb +186 -182
  56. data/lib/zakuro/version/senmyou/range/annual_range.rb +167 -0
  57. data/lib/zakuro/version/senmyou/senmyou.rb +10 -4
  58. data/lib/zakuro/version/senmyou/stella/lunar_orbit.rb +6 -6
  59. data/lib/zakuro/version/senmyou/stella/solar_average.rb +103 -152
  60. data/lib/zakuro/version/senmyou/stella/solar_location.rb +213 -0
  61. data/lib/zakuro/version/senmyou/stella/solar_orbit.rb +3 -184
  62. data/lib/zakuro/version/senmyou/stella/winter_solstice.rb +4 -4
  63. data/lib/zakuro/version/version_class_resolver.rb +62 -0
  64. data/lib/zakuro/version_factory.rb +3 -3
  65. metadata +53 -24
  66. data/lib/zakuro/cycle/abstract_remainder.rb +0 -456
  67. data/lib/zakuro/cycle/zodiac.rb +0 -103
  68. data/lib/zakuro/era/japan.rb +0 -664
  69. data/lib/zakuro/output/result.rb +0 -225
  70. data/lib/zakuro/version/senmyou/base/era.rb +0 -83
  71. data/lib/zakuro/version/senmyou/base/multi_gengou.rb +0 -98
  72. data/lib/zakuro/version/senmyou/base/multi_gengou_roller.rb +0 -205
  73. data/lib/zakuro/version/senmyou/base/remainder.rb +0 -60
  74. data/lib/zakuro/version/senmyou/base/solar_term.rb +0 -66
  75. data/lib/zakuro/version/senmyou/base/year.rb +0 -104
  76. data/lib/zakuro/version/senmyou/monthly/month.rb +0 -122
  77. data/lib/zakuro/version/senmyou/summary/annual_range.rb +0 -187
  78. data/lib/zakuro/version/senmyou/summary/full_range.rb +0 -224
  79. data/lib/zakuro/version/senmyou/summary/specifier.rb +0 -100
@@ -0,0 +1,236 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../western'
4
+ require_relative './type'
5
+ require 'yaml'
6
+
7
+ # :nodoc:
8
+ module Zakuro
9
+ #
10
+ # Japan 和暦
11
+ #
12
+ module Japan
13
+ #
14
+ # Validator yaml解析
15
+ #
16
+ module Validator
17
+ # :reek:TooManyInstanceVariables { max_instance_variables: 5 }
18
+
19
+ #
20
+ # Set 元号セット情報の検証/展開
21
+ #
22
+ class Set
23
+ # @return [String] 元号セットID
24
+ attr_reader :id
25
+ # @return [String] 元号セット名
26
+ attr_reader :name
27
+ # @return [String] 終了日
28
+ attr_reader :end_date
29
+ # @return [Array<Hash<String, String>>] 元号情報
30
+ attr_reader :list
31
+
32
+ #
33
+ # 初期化
34
+ #
35
+ # @param [Hash<String, Object>] hash 元号セット情報
36
+ #
37
+ def initialize(hash:)
38
+ @id = hash['id']
39
+ @name = hash['name']
40
+ @end_date = hash['end_date']
41
+ @list = hash['list']
42
+ end
43
+
44
+ # :reek:TooManyStatements { max_statements: 6 }
45
+
46
+ #
47
+ # 検証する
48
+ #
49
+ # @return [Array<String>] 不正メッセージ
50
+ #
51
+ def validate
52
+ failed = []
53
+ failed.push("invalid id. #{id}") unless id?
54
+
55
+ failed.push("invalid name. #{name}") unless name?
56
+
57
+ failed.push("invalid end_date. #{end_date}") unless western_date?
58
+
59
+ failed |= validate_list
60
+ failed
61
+ end
62
+
63
+ #
64
+ # IDを検証する
65
+ #
66
+ # @return [True] 正しい
67
+ # @return [False] 正しくない
68
+ #
69
+ def id?
70
+ return false unless @id
71
+
72
+ @id.is_a?(Integer)
73
+ end
74
+
75
+ #
76
+ # 元号セット名を検証する
77
+ #
78
+ # @return [True] 正しい
79
+ # @return [False] 正しくない
80
+ #
81
+ def name?
82
+ return false unless @name
83
+
84
+ @name.is_a?(String)
85
+ end
86
+
87
+ #
88
+ # 日付文字列を検証する
89
+ #
90
+ # @return [True] 正しい
91
+ # @return [False] 正しくない
92
+ #
93
+ def western_date?
94
+ Western::Calendar.valid_date_string(str: @end_date)
95
+ end
96
+
97
+ #
98
+ # 元号情報を検証する
99
+ #
100
+ # @return [True] 正しい
101
+ # @return [False] 正しくない
102
+ #
103
+ def list?
104
+ return false unless @list
105
+
106
+ @list.is_a?(Array)
107
+ end
108
+
109
+ #
110
+ # 元号情報を検証する
111
+ #
112
+ # @return [True] 正しい
113
+ # @return [False] 正しくない
114
+ #
115
+ def validate_list
116
+ return ["invalid list. #{@list.class}"] unless list?
117
+
118
+ failed = []
119
+ list.each_with_index do |li, index|
120
+ failed |= Gengou.new(hash: li, index: index).validate
121
+ end
122
+ failed
123
+ end
124
+ end
125
+
126
+ # :reek:TooManyInstanceVariables { max_instance_variables: 5 }
127
+
128
+ #
129
+ # Gengou 元号情報
130
+ #
131
+ class Gengou
132
+ # @return [Integer] 要素位置
133
+ attr_reader :index
134
+ # @return [String] 元号名
135
+ attr_reader :name
136
+ # @return [String] 開始日
137
+ attr_reader :start_date
138
+ # @return [String] 元旦
139
+ attr_reader :new_year_date
140
+ # @return [String] 開始年
141
+ attr_reader :start_year
142
+
143
+ #
144
+ # 初期化
145
+ #
146
+ # @param [Hash<String, Strin>] hash 元号情報
147
+ # @param [Integer] index (元号セット内での)元号の要素位置
148
+ #
149
+ def initialize(hash:, index:)
150
+ @index = index
151
+ @name = hash['name']
152
+ @start_date = hash['start_date']
153
+ @new_year_date = hash['new_year_date']
154
+ @start_year = hash['start_year']
155
+ end
156
+
157
+ # :reek:TooManyStatements { max_statements: 7 }
158
+
159
+ #
160
+ # 検証する
161
+ #
162
+ # @return [Array<String>] 不正メッセージ
163
+ #
164
+ def validate
165
+ prefix = "list[#{index}]. "
166
+ failed = []
167
+
168
+ failed.push(prefix + "invalid name. #{@name}") unless name?
169
+
170
+ failed.push(prefix + "invalid start_date. #{@start_date}") unless start_date?
171
+
172
+ failed.push(prefix + "invalid start_year. #{@start_year}") unless year?
173
+
174
+ failed.push(prefix + "invalid new_year_date. #{@new_year_date}") unless new_year_date?
175
+
176
+ failed
177
+ end
178
+
179
+ #
180
+ # 元号名を検証する
181
+ #
182
+ # @return [True] 正しい
183
+ # @return [False] 正しくない
184
+ #
185
+ def name?
186
+ return false unless @name
187
+
188
+ @name.is_a?(String)
189
+ end
190
+
191
+ #
192
+ # 開始日文字列を検証する
193
+ #
194
+ # @return [True] 正しい
195
+ # @return [False] 正しくない
196
+ #
197
+ def start_date?
198
+ Western::Calendar.valid_date_string(str: @start_date)
199
+ end
200
+
201
+ #
202
+ # 元旦文字列を検証する
203
+ #
204
+ # @return [True] 正しい
205
+ # @return [False] 正しくない
206
+ #
207
+ def new_year_date?
208
+ Western::Calendar.valid_date_string(str: @new_year_date)
209
+ end
210
+
211
+ #
212
+ # 元号年を検証する
213
+ #
214
+ # @return [True] 正しい
215
+ # @return [False] 正しくない
216
+ #
217
+ def year?
218
+ return true unless @start_year
219
+
220
+ @start_year.is_a?(Integer)
221
+ end
222
+ end
223
+
224
+ #
225
+ # 検証する
226
+ #
227
+ # @param [Hash<String, Object>] yaml_hash yaml取得結果
228
+ #
229
+ # @return [Array<String>] 不正メッセージ
230
+ #
231
+ def self.run(yaml_hash:)
232
+ Set.new(hash: yaml_hash).validate
233
+ end
234
+ end
235
+ end
236
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../western'
4
+
5
+ # :nodoc:
6
+ module Zakuro
7
+ #
8
+ # Japan 和暦
9
+ #
10
+ module Japan
11
+ #
12
+ # Reki 暦
13
+ #
14
+ module Reki
15
+ #
16
+ # Range 暦(範囲)
17
+ #
18
+ class Range
19
+ # @return [String] 暦のクラス名
20
+ # version 以下を参照
21
+ attr_reader :class_name
22
+ # @return [Western::Calendar] 暦の開始日
23
+ attr_reader :start_date
24
+
25
+ #
26
+ # 初期化
27
+ #
28
+ # @param [String] class_name 暦のクラス名
29
+ # @param [Western::Calendar] start_date 暦の開始日
30
+ #
31
+ def initialize(class_name:, start_date:)
32
+ @class_name = class_name
33
+ @start_date = start_date
34
+ end
35
+ end
36
+
37
+ LIST = [
38
+ Range.new(
39
+ class_name: 'Zakuro::Genka::Gateway',
40
+ start_date: Western::Calendar.new(year: 445, month: 1, day: 24)
41
+ ),
42
+ Range.new(
43
+ class_name: 'Zakuro::Gihou::Gateway',
44
+ start_date: Western::Calendar.new(year: 698, month: 2, day: 16)
45
+ ),
46
+ Range.new(
47
+ class_name: 'Zakuro::Taien::Gateway',
48
+ start_date: Western::Calendar.new(year: 764, month: 2, day: 7)
49
+ ),
50
+ Range.new(
51
+ class_name: 'Zakuro::Senmyou::Gateway',
52
+ start_date: Western::Calendar.new(year: 862, month: 2, day: 3)
53
+ ),
54
+ Range.new(
55
+ class_name: 'Zakuro::Joukyou::Gateway',
56
+ start_date: Western::Calendar.new(year: 1685, month: 2, day: 4)
57
+ ),
58
+ Range.new(
59
+ class_name: 'Zakuro::Houryaku::Gateway',
60
+ start_date: Western::Calendar.new(year: 1755, month: 2, day: 11)
61
+ ),
62
+ Range.new(
63
+ class_name: 'Zakuro::Kansei::Gateway',
64
+ start_date: Western::Calendar.new(year: 1798, month: 2, day: 16)
65
+ ),
66
+ Range.new(
67
+ class_name: 'Zakuro::Tenpou::Gateway',
68
+ start_date: Western::Calendar.new(year: 1844, month: 2, day: 18)
69
+ ),
70
+ Range.new(
71
+ class_name: 'Zakuro::Gregorio::Gateway',
72
+ start_date: Western::Calendar.new(year: 1872, month: 12, day: 9)
73
+ )
74
+ ].freeze
75
+
76
+ #
77
+ # 指定した日付から対象の暦を引き当てる
78
+ #
79
+ # @param [Western::Calendar] date 日付
80
+ #
81
+ # @return [String] 暦のクラス名
82
+ #
83
+ def self.class_name(date: Western::Calendar.new)
84
+ LIST.reverse_each do |range|
85
+ return range.class_name if date >= range.start_date
86
+ end
87
+ raise ArgumentError, "invalid date: #{date.format}"
88
+ end
89
+ end
90
+ end
91
+ end
@@ -109,7 +109,7 @@ module Zakuro
109
109
  end
110
110
  end
111
111
 
112
- # :reek:TooManyMethods { max_methods: 17 }
112
+ # :reek:TooManyMethods { max_methods: 18 }
113
113
 
114
114
  #
115
115
  # Calendar 年月日情報(西暦)
@@ -22,7 +22,7 @@ module Zakuro
22
22
  #
23
23
  def initialize(condition: {})
24
24
  failed = Condition.validate(hash: condition)
25
- raise ZakuroError, failed.join('\n') unless failed.empty?
25
+ raise Output::ZakuroError, failed.join('\n') unless failed.empty?
26
26
 
27
27
  @condition = Condition.new(hash: condition)
28
28
  end
@@ -36,7 +36,7 @@ module Zakuro
36
36
  #
37
37
  def offer(condition: {})
38
38
  failed = Condition.validate(hash: condition)
39
- raise ZakuroError, failed.join('\n') unless failed.empty?
39
+ raise Output::ZakuroError, failed.join('\n') unless failed.empty?
40
40
 
41
41
  @condition.rewrite(hash: condition)
42
42
 
@@ -0,0 +1,373 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require_relative '../../era/western'
5
+ require_relative './validator'
6
+ require_relative './type'
7
+
8
+ # :nodoc:
9
+ module Zakuro
10
+ #
11
+ # Operation 運用
12
+ #
13
+ module Operation
14
+ #
15
+ # TypeParser 型ごと変換
16
+ #
17
+ module TypeParser
18
+ #
19
+ # 無効値かを判定する
20
+ #
21
+ # @param [String] str 文字列
22
+ #
23
+ # @return [True] 無効値
24
+ # @return [False] 有効値
25
+ #
26
+ def self.invalid?(str:)
27
+ str == '-'
28
+ end
29
+
30
+ def self.text(str:)
31
+ return '' if invalid?(str: str)
32
+
33
+ str
34
+ end
35
+
36
+ #
37
+ # 有効行を変換する
38
+ #
39
+ # @param [String] str 文字列
40
+ #
41
+ # @return [True] 有効
42
+ # @return [False] 無効
43
+ #
44
+ def self.modified?(str:)
45
+ str == 'true'
46
+ end
47
+
48
+ #
49
+ # 月を変換する
50
+ #
51
+ # @param [String] str 文字列
52
+ #
53
+ # @return [Integer] 月
54
+ #
55
+ def self.month_number(str:)
56
+ return -1 if invalid?(str: str)
57
+
58
+ str.to_i
59
+ end
60
+
61
+ #
62
+ # 閏有無を変換する
63
+ #
64
+ # @param [String] str 文字列
65
+ #
66
+ # @return [True] 閏あり
67
+ # @return [True] 閏なし/閏設定なし
68
+ #
69
+ def self.month_leaped(str:)
70
+ str == 'true'
71
+ end
72
+
73
+ #
74
+ # 西暦日を変換する
75
+ #
76
+ # @param [String] str 文字列
77
+ #
78
+ # @return [Western::Calendar] 西暦日
79
+ #
80
+ def self.western_date(str:)
81
+ return Western::Calendar.new if invalid?(str: str)
82
+
83
+ Western::Calendar.parse(str: str)
84
+ end
85
+
86
+ #
87
+ # 日(差分)を変換する
88
+ #
89
+ # @param [String] str 文字列
90
+ #
91
+ # @return [Integer] 日(差分)
92
+ #
93
+ def self.days(str:)
94
+ return INVALID_DAY_VALUE if invalid?(str: str)
95
+
96
+ str.to_i
97
+ end
98
+
99
+ def self.solar_term_index(str:)
100
+ return -1 if invalid?(str: str)
101
+
102
+ str.to_i
103
+ end
104
+ end
105
+
106
+ #
107
+ # MonthParser 月情報解析(yaml)
108
+ #
109
+ module MonthParser
110
+ #
111
+ # 実行する
112
+ #
113
+ # @return [Array<MonthHistory>] 変更履歴
114
+ #
115
+ def self.run(filepath:)
116
+ hash = YAML.load_file(filepath)
117
+
118
+ failed = Validator.run(yaml_hash: hash)
119
+
120
+ raise ArgumentError, failed.join("\n") unless failed.empty?
121
+
122
+ load(yaml_hash: hash)
123
+ end
124
+
125
+ #
126
+ # 設定ファイルを読み込む
127
+ #
128
+ # @param [Hash] yaml_hash 設定ファイルテキスト
129
+ #
130
+ # @return [Array<MonthHistory>] 変更履歴
131
+ #
132
+ def self.load(yaml_hash: {})
133
+ histories = create_histories(yaml_hash: yaml_hash)
134
+
135
+ annotation_parser = AnnotationParser.new(yaml_hash: yaml_hash)
136
+ annotation_parser.create
137
+
138
+ add_annotations(histories: histories, annotation_parser: annotation_parser)
139
+ end
140
+
141
+ #
142
+ # 変更履歴を読み込む
143
+ #
144
+ # @param [Hash] yaml_hash 設定ファイルテキスト
145
+ #
146
+ # @return [Array<MonthHistory>] 変更履歴
147
+ #
148
+ def self.create_histories(yaml_hash: {})
149
+ result = []
150
+ yaml_hash.each do |month|
151
+ next unless Operation::TypeParser.modified?(str: month['modified'])
152
+
153
+ result.push(
154
+ create_history(yaml_hash: month)
155
+ )
156
+ end
157
+ result
158
+ end
159
+ private_class_method :create_histories
160
+
161
+ def self.create_history(yaml_hash: {})
162
+ diffs = MonthDiffsParser.create(yaml_hash: yaml_hash['diffs'])
163
+
164
+ western_date = Operation::TypeParser.western_date(str: yaml_hash['western_date'])
165
+ reference = Reference.new(page: yaml_hash['page'].to_i, number: yaml_hash['number'].to_i,
166
+ japan_date: yaml_hash['japan_date'])
167
+ MonthHistory.new(id: yaml_hash['id'],
168
+ parent_id: Operation::TypeParser.text(str: yaml_hash['parent_id']),
169
+ reference: reference,
170
+ western_date: western_date,
171
+ diffs: diffs)
172
+ end
173
+ private_class_method :create_history
174
+
175
+ def self.add_annotations(annotation_parser:, histories: [])
176
+ result = []
177
+ histories.each do |history|
178
+ id = history.id
179
+ result.push(
180
+ MonthHistory.new(
181
+ id: id, parent_id: history.parent_id, reference: history.reference,
182
+ western_date: history.western_date,
183
+ annotations: annotation_parser.specify(id: id),
184
+ diffs: history.diffs
185
+ )
186
+ )
187
+ end
188
+
189
+ result
190
+ end
191
+ private_class_method :add_annotations
192
+
193
+ def self.create_history_annnotations(history:, annotations: {}, relations: {})
194
+ history_id = history.id
195
+ history_annotations = []
196
+ [history_id, relations.fetch(history_id, '')].each do |id|
197
+ add_annotation(history_annotations: history_annotations,
198
+ annotations: annotations, id: id)
199
+ end
200
+
201
+ history_annotations
202
+ end
203
+
204
+ def self.add_annotation(history_annotations: [], annotations: {}, id: '')
205
+ annotation = annotations.fetch(id, Annotation.new)
206
+ return if annotation.invalid?
207
+
208
+ history_annotations.push(annotation)
209
+ end
210
+ private_class_method :add_annotation
211
+ end
212
+
213
+ #
214
+ # AnnotationParser 注釈解析
215
+ #
216
+ class AnnotationParser
217
+ # @return [Hash<String, Annotation>] 注釈
218
+ attr_reader :annotations
219
+ # @return [Hash<String, String>] 関連注釈の対応関係
220
+ attr_reader :relations
221
+
222
+ #
223
+ # 初期化
224
+ #
225
+ # @param [Hash] yaml_hash 設定ファイルテキスト
226
+ #
227
+ def initialize(yaml_hash: {})
228
+ @annotations = {}
229
+ @relations = {}
230
+ @yaml_hash = yaml_hash
231
+ end
232
+
233
+ #
234
+ # 注釈を生成する
235
+ #
236
+ def create
237
+ @yaml_hash.each do |month|
238
+ AnnotationParser.resolve_history(
239
+ hash: month, annotations: @annotations, relations: @relations
240
+ )
241
+ end
242
+ end
243
+
244
+ #
245
+ # 月別履歴情報から注釈情報を取り出す
246
+ #
247
+ # @param [<Type>] hash 月別履歴情報yaml
248
+ # @param [Hash<String, Annotation>] annotations 注釈
249
+ # @param [Hash<String, String>] relations 関連注釈の対応関係
250
+ #
251
+ def self.resolve_history(hash: {}, annotations: {}, relations: {})
252
+ id = hash['id']
253
+ annotations[id] = Annotation.new(
254
+ id: id,
255
+ description: Operation::TypeParser.text(str: hash['description']),
256
+ note: Operation::TypeParser.text(str: hash['note'])
257
+ )
258
+ relation_id = hash['relation_id']
259
+
260
+ return if Operation::TypeParser.invalid?(str: relation_id)
261
+
262
+ relations[id] = relation_id
263
+ end
264
+
265
+ #
266
+ # 注釈を特定する
267
+ #
268
+ # @param [String] id ID
269
+ #
270
+ # @return [Array<Annotation>] 注釈
271
+ #
272
+ def specify(id: '')
273
+ ids = [id, relations.fetch(id, '')]
274
+ specify_by_ids(ids: ids)
275
+ end
276
+
277
+ private
278
+
279
+ def specify_by_ids(ids: [])
280
+ annotations = []
281
+ ids.each do |id|
282
+ add_annotation(id: id, annotations: annotations)
283
+ end
284
+
285
+ annotations
286
+ end
287
+
288
+ def add_annotation(id: '', annotations: [])
289
+ annotation = annotation(id: id)
290
+ return if annotation.invalid?
291
+
292
+ annotations.push(annotation)
293
+ end
294
+
295
+ def annotation(id: '')
296
+ @annotations.fetch(id, Annotation.new)
297
+ end
298
+ end
299
+
300
+ #
301
+ # MonthDiffsParser 月情報(差分)解析
302
+ #
303
+ module MonthDiffsParser
304
+ def self.create(yaml_hash: {})
305
+ Diffs.new(
306
+ month: create_month(yaml_hash: yaml_hash['month']),
307
+ solar_term: create_solar_term(yaml_hash: yaml_hash['solar_term']),
308
+ days: Operation::TypeParser.days(str: yaml_hash['days'])
309
+ )
310
+ end
311
+
312
+ def self.create_solar_term(yaml_hash: {})
313
+ SolarTerm::Direction.new(
314
+ source: create_source_solar_term(yaml_hash: yaml_hash['calc']),
315
+ destination: create_destination_solar_term(yaml_hash: yaml_hash['actual']),
316
+ days: Operation::TypeParser.days(str: yaml_hash['days'])
317
+ )
318
+ end
319
+ private_class_method :create_solar_term
320
+
321
+ def self.create_source_solar_term(yaml_hash: {})
322
+ SolarTerm::Source.new(
323
+ index: Operation::TypeParser.solar_term_index(str: yaml_hash['index']),
324
+ to: Operation::TypeParser.western_date(str: yaml_hash['to']),
325
+ zodiac_name: Operation::TypeParser.text(str: yaml_hash['zodiac_name'])
326
+ )
327
+ end
328
+ private_class_method :create_source_solar_term
329
+
330
+ def self.create_destination_solar_term(yaml_hash: {})
331
+ SolarTerm::Destination.new(
332
+ index: Operation::TypeParser.solar_term_index(str: yaml_hash['index']),
333
+ from: Operation::TypeParser.western_date(str: yaml_hash['from']),
334
+ zodiac_name: Operation::TypeParser.text(str: yaml_hash['zodiac_name'])
335
+ )
336
+ end
337
+ private_class_method :create_destination_solar_term
338
+
339
+ def self.create_month(yaml_hash: {})
340
+ Month.new(
341
+ number: create_month_number(yaml_hash: yaml_hash['number']),
342
+ leaped: create_month_leaped(yaml_hash: yaml_hash['leaped']),
343
+ is_many_days: create_month_day(yaml_hash: yaml_hash['days'])
344
+ )
345
+ end
346
+ private_class_method :create_month
347
+
348
+ def self.create_month_number(yaml_hash: {})
349
+ Number.new(
350
+ calc: Operation::TypeParser.month_number(str: yaml_hash['calc']),
351
+ actual: Operation::TypeParser.month_number(str: yaml_hash['actual'])
352
+ )
353
+ end
354
+ private_class_method :create_month_number
355
+
356
+ def self.create_month_leaped(yaml_hash: {})
357
+ Leaped.new(
358
+ calc: Operation::TypeParser.month_leaped(str: yaml_hash['calc']),
359
+ actual: Operation::TypeParser.month_leaped(str: yaml_hash['actual'])
360
+ )
361
+ end
362
+ private_class_method :create_month_leaped
363
+
364
+ def self.create_month_day(yaml_hash: {})
365
+ Days.new(
366
+ calc: yaml_hash['calc'],
367
+ actual: yaml_hash['actual']
368
+ )
369
+ end
370
+ private_class_method :create_month_day
371
+ end
372
+ end
373
+ end