ykutils 0.1.0 → 0.1.1

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.
data/lib/ykutils/stext.rb CHANGED
@@ -1,462 +1,425 @@
1
- # -*- coding utf-8 -*-
2
-
3
- require 'ykutils/debugutils'
4
- require 'ykutils/lines'
5
- require 'ykutils/specfileop'
6
- require 'datastructop'
7
- require 'filex'
8
-
9
- module Ykutils
10
-
11
- class StructuredText
12
- attr_reader :main_ary , :main_hash , :item_ary
13
-
14
- include SpecFileOp
15
- include DataStructOp
16
- include DebugUtils
17
-
18
- def initialize( debug = false )
19
- @text = nil
20
- @fname = nil
21
- @text_ary = []
22
-
23
- debug_utils_init
24
- set_debug( debug )
25
- end
26
-
27
- def load_analyze( fname , subfname = nil )
28
- # puts_current_method
29
- # puts "-0 fname=#{fname}"
30
-
31
- @fname = fname
32
- @text_ary = load(fname)
33
- # @text_ary.each do |x| puts x end
34
- analyze(@text_ary , subfname )
35
- end
36
-
37
- def load( fname )
38
- load_plain_text_file( fname ).collect { |it| it.chomp }
39
- end
40
-
41
- def analyze( line_ary , subfname = nil )
42
-
43
- end
44
-
45
- def dump_to_file( fname )
46
- begin
47
- file = FileX.open( fname , 'w'){ |file|
48
- @text_ary.each do |l|
49
- file.write( l + "\n" )
50
- end
51
- }
52
- rescue => ex
53
- pp ex
54
- pp ex.backtrace
55
- @valid = false
56
- end
57
- end
58
-
59
- end
60
-
61
- class StructuredTextForFtpOp < StructuredText
62
- def analyze( line_ary , fname = nil )
63
- lines = FtpOpLines.new( line_ary )
64
- lines.output_f( fname )
65
-
66
- analyze_sub( lines )
67
- end
68
- end
69
-
70
- class StructuredTextForAccount < StructuredText
71
- attr_reader :main_host_ary , :main_host_hash , :main_domain_ary , :main_domain_hash , :main_sep_ary , :main_sep_hash , :main_host_item_ary
72
-
73
- def initialize
74
- @main_host_item_ary = []
75
-
76
- @main_sep_ary = []
77
- @main_sep_hash = { }
78
-
79
- @main_host_ary = []
80
- @main_host_hash = { }
81
- 1
82
- @main_domain_ary = []
83
- @main_domain_hash = { }
84
- end
85
-
86
- def analyze( line_ary , fname = nil )
87
- lines = AccountLines.new( line_ary )
88
- lines.output_f( fname )
89
-
90
- analyze_sub( lines )
91
- end
92
-
93
- def analyze_sub( lines )
94
- host = StructuredTextForAccountOneLayerHost.new
95
- domain = StructuredTextForAccountOneLayerDomain.new
96
-
97
- while line = lines.get_line
98
- case line["STATUS"]
99
- when AccountLines::HOST_ACCOUNT_START , AccountLines::HOST_ACCOUNT , AccountLines::HOST_ACCOUNT_END
100
- if line["CONTENT"]
101
- key , value = line["CONTENT"].split(":")
102
- end
103
- key.strip! if key
104
- value.strip! if value
105
- host.analyze( line["STATUS"] , line , key , value , @main_host_ary, @main_host_hash )
106
- when AccountLines::DOMAIN_ACCOUNT_START , AccountLines::DOMAIN_ACCOUNT , AccountLines::DOMAIN_ACCOUNT_END
107
- if line["CONTENT"]
108
- key , value = line["CONTENT"].split(":")
109
- end
110
- key.strip! if key
111
- value.strip! if value
112
- domain.analyze( line["STATUS"] , line , key , value , @main_domain_ary, @main_domain_hash )
113
- when AccountLines::SEPARATOR
114
- if line["CONTENT"]
115
- key , value = line["CONTENT"].split(":")
116
- end
117
-
118
- @main_sep_ary << key
119
- @main_sep_hash[key] = { "TITLE" => key }
120
-
121
- else
122
- puts( "Error" )
123
- puts( line["CONTENT"] )
124
- end
125
- end
126
- @main_host_item_ary |= host.item_ary
127
- end
128
-
129
- def sort_by( other )
130
- diff_main_host_ary = @main_host_ary - other.main_host_ary
131
- diff_main_domain_ary = @main_domain_ary - other.main_domain_ary
132
-
133
- n_main_sep_ary = []
134
- n_main_sep_hash = { }
135
- n_main_host_ary = []
136
- n_main_host_hash = { }
137
- n_main_domain_ary = []
138
- n_main_domain_hash = { }
139
-
140
- if other.main_sep_ary.size > 0
141
- @main_sep_ary |= other.main_sep_ary
142
- @main_sep_hash |= n_main_sep_hash
143
- end
144
-
145
- main_host_item_ary = other.main_host_item_ary | @main_host_item_ary
146
-
147
- other.main_host_ary.each do |it|
148
- sort_by_sub(it , @main_host_hash , main_host_item_ary, n_main_host_hash , n_main_host_ary )
149
- end
150
-
151
- diff_main_host_ary.each do |it|
152
- sort_by_sub(it , @main_host_hash , main_host_item_ary , n_main_host_hash, n_main_host_ary )
153
- end
154
-
155
- other.main_domain_ary.each do |it|
156
- sort_by_sub_for_array(it , @main_domain_hash , n_main_domain_hash, n_main_domain_ary )
157
- end
158
-
159
- diff_main_domain_ary.each do |it|
160
- sort_by_sub_for_array(it , @main_domain_hash , n_main_domain_hash, n_main_domain_ary )
161
- end
162
-
163
- @main_host_ary = n_main_host_ary
164
- @main_host_hash = n_main_host_hash
165
- @main_domain_ary = n_main_domain_ary
166
- @main_domain_hash = n_main_domain_hash
167
- end
168
-
169
- def sort_by_sub(it , item_hash , item_ary , n_hash , n_ary )
170
- h = item_hash[it]
171
- if h
172
- n_ary << it
173
- title = h["TITLE"]
174
- hash = h["CONTENT"]
175
- ary = []
176
- if hash
177
- item_ary.each do |ai|
178
- v = hash[ai]
179
- if v
180
- ary << ai
181
- end
182
- end
183
- end
184
- n_hash[it] = { "TITLE" => title , "META" => ary , "CONTENT" => hash }
185
- end
186
- end
187
-
188
- def sort_by_sub_for_array(it , item_hash , n_hash , n_ary )
189
- h = item_hash[it]
190
- if h
191
- n_ary << it
192
- title = h["TITLE"]
193
- ary = h["META"]
194
- hash = h["CONTENT"]
195
-
196
- n_hash[it] = { "TITLE" => title , "META" => ary , "CONTENT" => hash }
197
- end
198
- end
199
-
200
- def dump( file = nil )
201
- dump_ary = []
202
- dump_ary += dump_sub( @main_sep_ary, @main_sep_hash )
203
- dump_ary += dump_sub( @main_host_ary, @main_host_hash )
204
- dump_ary += dump_sub_for_array( @main_domain_ary, @main_domain_hash )
205
-
206
- str = dump_ary.join("\n")
207
-
208
- if file
209
- begin
210
- file.write( str )
211
- file.write( "\n" )
212
- rescue => ex
213
- pp ex
214
- pp ex.backtrace
215
- @valid = false
216
- end
217
- end
218
- str
219
- end
220
-
221
- def dump_sub( ary , hash )
222
- dump_ary = []
223
- ary.each do |it|
224
- h = hash[it]
225
- unless h
226
- next
227
- end
228
- item_ary = h["META"]
229
- title = h["TITLE"]
230
- item_hash = h["CONTENT"]
231
- dump_ary << title
232
-
233
- if item_ary
234
- item_ary.each do |subit|
235
- if item_hash[subit]
236
- dump_ary << item_hash[subit]
237
- end
238
- end
239
- end
240
- end
241
- dump_ary
242
- end
243
-
244
- def dump_sub_for_array( ary , hash )
245
- dump_ary = []
246
- ary.each do |it|
247
- dump_ary += hash[it]["CONTENT"]
248
- end
249
- dump_ary
250
- end
251
-
252
- end
253
-
254
-
255
- class StructuredTextForAccountOneLayer
256
- attr_accessor :item_ary
257
-
258
- def initialize
259
- @item_ary = []
260
- @ary = []
261
- @hash = { }
262
- @title = ""
263
- end
264
- end
265
-
266
- class StructuredTextForAccountOneLayerDomain < StructuredTextForAccountOneLayer
267
- def initialize
268
- super
269
- @line_ary = []
270
- end
271
-
272
- def analyze( status , line , key , value , main_line_ary , main_line_hash )
273
- case status
274
- when AccountLines::DOMAIN_ACCOUNT_START
275
- key.sub!( /^==/ , "" )
276
- @title = line["CONTENT"]
277
- @line_ary << line["CONTENT"]
278
- when AccountLines::DOMAIN_ACCOUNT
279
- @line_ary << line["CONTENT"]
280
- when AccountLines::DOMAIN_ACCOUNT_END
281
- main_line_ary << @title
282
- main_line_hash[@title] = { "TITLE" => @title , "CONTENT" => @line_ary }
283
- @title = ""
284
- @line_ary = []
285
- else
286
- end
287
- end
288
- end
289
-
290
- class StructuredTextForAccountOneLayerHost < StructuredTextForAccountOneLayer
291
-
292
- def initialize
293
- super
294
- end
295
-
296
- def analyze( status , line , key , value , main_ary , main_hash )
297
- case status
298
- when AccountLines::HOST_ACCOUNT_START
299
- @hash[key] = line["CONTENT"]
300
- @title = line["CONTENT"]
301
- when AccountLines::HOST_ACCOUNT
302
- @ary << key
303
- @hash[key] = line["CONTENT"]
304
- when AccountLines::HOST_ACCOUNT_END
305
- main_ary << @title
306
- main_hash[@title] = { "TITLE" => @title , "CONTENT" => @hash , "META" => @ary }
307
-
308
- @item_ary |= @ary
309
- @ary = []
310
- @hash = { }
311
- @title = ""
312
- else
313
- end
314
- end
315
-
316
- end
317
-
318
- class StructuredTextForSimple < StructuredText
319
- class Item
320
- attr_reader :name, :contents
321
- def initialize( name )
322
- @name = name
323
- @contents = []
324
- end
325
-
326
- def add( content )
327
- @contents << content
328
- end
329
- end
330
-
331
- def initialize
332
- @item_ary = {}
333
- end
334
-
335
- def get_event
336
- value = nil
337
- line = @line_ary.shift
338
-
339
- if line
340
- content = line.strip
341
- if content.length == 0
342
- ret = :EMPTY_LINE
343
- value = ""
344
- else
345
- if content =~ /^\-(.*)/
346
- title = $1
347
- if title.length > 0
348
- ret = :TITLE_LINE
349
- value = title
350
- else
351
- ret = :EMPTY_TITLE_LINE
352
- value = ""
353
- end
354
- else
355
- ret = :NON_EMPTY_LINE
356
- value = content
357
- end
358
- end
359
- else
360
- ret = :EOF
361
- end
362
-
363
- [ret,value]
364
- end
365
-
366
- def make_next_state_table
367
- @next_state = {}
368
- @next_state[:NONE] = {}
369
- @next_state[:NONE][:EMPTY_LINE] = :NONE
370
- @next_state[:NONE][:TITLE_LINE] = :ITEM
371
- @next_state[:NONE][:EMPTY_TITLE_LINE] = :END
372
- @next_state[:NONE][:NON_EMPTY_LINE] = :BAD
373
- @next_state[:ITEM] = {}
374
- @next_state[:ITEM][:EMPTY_LINE] = :ITEM
375
- @next_state[:ITEM][:TITLE_LINE] = :ITEM
376
- @next_state[:ITEM][:EMPTY_TITLE_LINE] = :END
377
- @next_state[:ITEM][:NON_EMPTY_LINE] = :ITEM
378
- @next_state[:END] = {}
379
- @next_state[:END][:EMPTY_LINE] = :END
380
- @next_state[:END][:TITLE_LINE] = :BAD
381
- @next_state[:END][:EMPTY_TITLE_LINE] = :BAD
382
- @next_state[:END][:NON_EMPTY_LINE] = :END
383
- end
384
-
385
- def get_next_state( state , event )
386
- if state == :BAD
387
- :BAD
388
- else
389
- @next_state[state][event]
390
- end
391
- end
392
-
393
- def analyze( line_ary , subfname = nil )
394
- @line_ary = line_ary
395
- make_next_state_table
396
- # :NONE
397
- # :ITEM
398
- # :END
399
- # :BAD
400
-
401
- # :EMPTY_LINE
402
- # :TITLE_LINE
403
- # :EMPTY_TITLE_LINE
404
- # :NON_EMPTY_LINE
405
- state = :NONE
406
- event = get_event
407
-
408
- @item_ary = []
409
- item = nil
410
- while state != :BAD and event[0] != :EOF
411
- case state
412
- when :NONE
413
- case event[0]
414
- when :EMPTY_LINE
415
- #
416
- when :TITLE_LINE
417
- @item_ary << (item = Item.new( event[1] ))
418
- when :EMPTY_TITLE_LINE
419
- @item_ary << (item = Item.new( "" ))
420
- when :NON_EMPTY_LINE
421
- item.add( event[1] )
422
- else
423
- #
424
- end
425
- when :ITEM
426
- case event[0]
427
- when :EMPTY_LINE
428
- #
429
- when :TITLE_LINE
430
- @item_ary << (item = Item.new( event[1] ))
431
- when :EMPTY_TITLE_LINE
432
- @item_ary << (item = Item.new( "" ))
433
- when :NON_EMPTY_LINE
434
- item.add( event[1] )
435
- else
436
- #
437
- end
438
- else
439
- case event[0]
440
- when :EMPTY_LINE
441
- #
442
- when :TITLE_LINE
443
- #
444
- when :EMPTY_TITLE_LINE
445
- #
446
- when :NON_EMPTY_LINE
447
- item.add( event[1] )
448
- else
449
- #
450
- end
451
- end
452
-
453
- state = get_next_state( state , event[0] )
454
- event = get_event
455
- end
456
-
457
- @item_ary
458
- end
459
-
460
- end
461
-
462
- end
1
+ # -*- coding utf-8 -*-
2
+
3
+ require "ykutils/debugutils"
4
+ require "ykutils/lines"
5
+ require "ykutils/specfileop"
6
+ require "ykutils/datastructop"
7
+ require "filex"
8
+
9
+ module Ykutils
10
+ class StructuredText
11
+ attr_reader :main_ary, :main_hash, :item_ary
12
+
13
+ include SpecFileOp
14
+ include DataStructOp
15
+ include DebugUtils
16
+
17
+ def initialize(debug = false)
18
+ @text = nil
19
+ @fname = nil
20
+ @text_ary = []
21
+
22
+ debug_utils_init
23
+ set_debug(debug)
24
+ end
25
+
26
+ def load_analyze(fname, subfname = nil)
27
+ # puts_current_method
28
+ # puts "-0 fname=#{fname}"
29
+
30
+ @fname = fname
31
+ @text_ary = load(fname)
32
+ # @text_ary.each do |x| puts x end
33
+ analyze(@text_ary, subfname)
34
+ end
35
+
36
+ def load(fname)
37
+ load_plain_text_file(fname).collect { |it| it.chomp }
38
+ end
39
+
40
+ def analyze(line_ary, subfname = nil); end
41
+
42
+ def dump_to_file(fname)
43
+ file = FileX.open(fname, "w") do |file|
44
+ @text_ary.each do |l|
45
+ file.write(l + "\n")
46
+ end
47
+ end
48
+ rescue StandardError => e
49
+ pp e
50
+ pp e.backtrace
51
+ @valid = false
52
+ end
53
+ end
54
+
55
+ class StructuredTextForFtpOp < StructuredText
56
+ def analyze(line_ary, fname = nil)
57
+ lines = FtpOpLines.new(line_ary)
58
+ lines.output_f(fname)
59
+
60
+ analyze_sub(lines)
61
+ end
62
+ end
63
+
64
+ class StructuredTextForAccount < StructuredText
65
+ attr_reader :main_host_ary, :main_host_hash, :main_domain_ary, :main_domain_hash, :main_sep_ary,
66
+ :main_sep_hash, :main_host_item_ary
67
+
68
+ def initialize
69
+ @main_host_item_ary = []
70
+
71
+ @main_sep_ary = []
72
+ @main_sep_hash = {}
73
+
74
+ @main_host_ary = []
75
+ @main_host_hash = {}
76
+ 1
77
+ @main_domain_ary = []
78
+ @main_domain_hash = {}
79
+ end
80
+
81
+ def analyze(line_ary, fname = nil)
82
+ lines = AccountLines.new(line_ary)
83
+ lines.output_f(fname)
84
+
85
+ analyze_sub(lines)
86
+ end
87
+
88
+ def analyze_sub(lines)
89
+ host = StructuredTextForAccountOneLayerHost.new
90
+ domain = StructuredTextForAccountOneLayerDomain.new
91
+
92
+ while line = lines.get_line
93
+ case line["STATUS"]
94
+ when AccountLines::HOST_ACCOUNT_START, AccountLines::HOST_ACCOUNT, AccountLines::HOST_ACCOUNT_END
95
+ key, value = line["CONTENT"].split(":") if line["CONTENT"]
96
+ key.strip! if key
97
+ value.strip! if value
98
+ host.analyze(line["STATUS"], line, key, value, @main_host_ary, @main_host_hash)
99
+ when AccountLines::DOMAIN_ACCOUNT_START, AccountLines::DOMAIN_ACCOUNT, AccountLines::DOMAIN_ACCOUNT_END
100
+ key, value = line["CONTENT"].split(":") if line["CONTENT"]
101
+ key.strip! if key
102
+ value.strip! if value
103
+ domain.analyze(line["STATUS"], line, key, value, @main_domain_ary, @main_domain_hash)
104
+ when AccountLines::SEPARATOR
105
+ key, value = line["CONTENT"].split(":") if line["CONTENT"]
106
+
107
+ @main_sep_ary << key
108
+ @main_sep_hash[key] = { "TITLE" => key }
109
+ else
110
+ puts("Error")
111
+ puts(line["CONTENT"])
112
+ end
113
+ end
114
+ @main_host_item_ary |= host.item_ary
115
+ end
116
+
117
+ def sort_by(other)
118
+ diff_main_host_ary = @main_host_ary - other.main_host_ary
119
+ diff_main_domain_ary = @main_domain_ary - other.main_domain_ary
120
+
121
+ n_main_sep_ary = []
122
+ n_main_sep_hash = {}
123
+ n_main_host_ary = []
124
+ n_main_host_hash = {}
125
+ n_main_domain_ary = []
126
+ n_main_domain_hash = {}
127
+
128
+ if other.main_sep_ary.size > 0
129
+ @main_sep_ary |= other.main_sep_ary
130
+ @main_sep_hash |= n_main_sep_hash
131
+ end
132
+
133
+ main_host_item_ary = other.main_host_item_ary | @main_host_item_ary
134
+
135
+ other.main_host_ary.each do |it|
136
+ sort_by_sub(it, @main_host_hash, main_host_item_ary, n_main_host_hash, n_main_host_ary)
137
+ end
138
+
139
+ diff_main_host_ary.each do |it|
140
+ sort_by_sub(it, @main_host_hash, main_host_item_ary, n_main_host_hash, n_main_host_ary)
141
+ end
142
+
143
+ other.main_domain_ary.each do |it|
144
+ sort_by_sub_for_array(it, @main_domain_hash, n_main_domain_hash, n_main_domain_ary)
145
+ end
146
+
147
+ diff_main_domain_ary.each do |it|
148
+ sort_by_sub_for_array(it, @main_domain_hash, n_main_domain_hash, n_main_domain_ary)
149
+ end
150
+
151
+ @main_host_ary = n_main_host_ary
152
+ @main_host_hash = n_main_host_hash
153
+ @main_domain_ary = n_main_domain_ary
154
+ @main_domain_hash = n_main_domain_hash
155
+ end
156
+
157
+ def sort_by_sub(it, item_hash, item_ary, n_hash, n_ary)
158
+ h = item_hash[it]
159
+ if h
160
+ n_ary << it
161
+ title = h["TITLE"]
162
+ hash = h["CONTENT"]
163
+ ary = []
164
+ if hash
165
+ item_ary.each do |ai|
166
+ v = hash[ai]
167
+ ary << ai if v
168
+ end
169
+ end
170
+ n_hash[it] = { "TITLE" => title, "META" => ary, "CONTENT" => hash }
171
+ end
172
+ end
173
+
174
+ def sort_by_sub_for_array(it, item_hash, n_hash, n_ary)
175
+ h = item_hash[it]
176
+ if h
177
+ n_ary << it
178
+ title = h["TITLE"]
179
+ ary = h["META"]
180
+ hash = h["CONTENT"]
181
+
182
+ n_hash[it] = { "TITLE" => title, "META" => ary, "CONTENT" => hash }
183
+ end
184
+ end
185
+
186
+ def dump(file = nil)
187
+ dump_ary = []
188
+ dump_ary += dump_sub(@main_sep_ary, @main_sep_hash)
189
+ dump_ary += dump_sub(@main_host_ary, @main_host_hash)
190
+ dump_ary += dump_sub_for_array(@main_domain_ary, @main_domain_hash)
191
+
192
+ str = dump_ary.join("\n")
193
+
194
+ if file
195
+ begin
196
+ file.write(str)
197
+ file.write("\n")
198
+ rescue StandardError => e
199
+ pp e
200
+ pp e.backtrace
201
+ @valid = false
202
+ end
203
+ end
204
+ str
205
+ end
206
+
207
+ def dump_sub(ary, hash)
208
+ dump_ary = []
209
+ ary.each do |it|
210
+ h = hash[it]
211
+ next unless h
212
+
213
+ item_ary = h["META"]
214
+ title = h["TITLE"]
215
+ item_hash = h["CONTENT"]
216
+ dump_ary << title
217
+
218
+ next unless item_ary
219
+
220
+ item_ary.each do |subit|
221
+ dump_ary << item_hash[subit] if item_hash[subit]
222
+ end
223
+ end
224
+ dump_ary
225
+ end
226
+
227
+ def dump_sub_for_array(ary, hash)
228
+ dump_ary = []
229
+ ary.each do |it|
230
+ dump_ary += hash[it]["CONTENT"]
231
+ end
232
+ dump_ary
233
+ end
234
+ end
235
+
236
+ class StructuredTextForAccountOneLayer
237
+ attr_accessor :item_ary
238
+
239
+ def initialize
240
+ @item_ary = []
241
+ @ary = []
242
+ @hash = {}
243
+ @title = ""
244
+ end
245
+ end
246
+
247
+ class StructuredTextForAccountOneLayerDomain < StructuredTextForAccountOneLayer
248
+ def initialize
249
+ super
250
+ @line_ary = []
251
+ end
252
+
253
+ def analyze(status, line, key, _value, main_line_ary, main_line_hash)
254
+ case status
255
+ when AccountLines::DOMAIN_ACCOUNT_START
256
+ key.sub!(/^==/, "")
257
+ @title = line["CONTENT"]
258
+ @line_ary << line["CONTENT"]
259
+ when AccountLines::DOMAIN_ACCOUNT
260
+ @line_ary << line["CONTENT"]
261
+ when AccountLines::DOMAIN_ACCOUNT_END
262
+ main_line_ary << @title
263
+ main_line_hash[@title] = { "TITLE" => @title, "CONTENT" => @line_ary }
264
+ @title = ""
265
+ @line_ary = []
266
+ end
267
+ end
268
+ end
269
+
270
+ class StructuredTextForAccountOneLayerHost < StructuredTextForAccountOneLayer
271
+ def initialize
272
+ super
273
+ end
274
+
275
+ def analyze(status, line, key, _value, main_ary, main_hash)
276
+ case status
277
+ when AccountLines::HOST_ACCOUNT_START
278
+ @hash[key] = line["CONTENT"]
279
+ @title = line["CONTENT"]
280
+ when AccountLines::HOST_ACCOUNT
281
+ @ary << key
282
+ @hash[key] = line["CONTENT"]
283
+ when AccountLines::HOST_ACCOUNT_END
284
+ main_ary << @title
285
+ main_hash[@title] = { "TITLE" => @title, "CONTENT" => @hash, "META" => @ary }
286
+
287
+ @item_ary |= @ary
288
+ @ary = []
289
+ @hash = {}
290
+ @title = ""
291
+ end
292
+ end
293
+ end
294
+
295
+ class StructuredTextForSimple < StructuredText
296
+ class Item
297
+ attr_reader :name, :contents
298
+
299
+ def initialize(name)
300
+ @name = name
301
+ @contents = []
302
+ end
303
+
304
+ def add(content)
305
+ @contents << content
306
+ end
307
+ end
308
+
309
+ def initialize
310
+ @item_ary = {}
311
+ end
312
+
313
+ def get_event
314
+ value = nil
315
+ line = @line_ary.shift
316
+
317
+ if line
318
+ content = line.strip
319
+ if content.length == 0
320
+ ret = :EMPTY_LINE
321
+ value = ""
322
+ elsif content =~ /^-(.*)/
323
+ title = Regexp.last_match(1)
324
+ if title.length > 0
325
+ ret = :TITLE_LINE
326
+ value = title
327
+ else
328
+ ret = :EMPTY_TITLE_LINE
329
+ value = ""
330
+ end
331
+ else
332
+ ret = :NON_EMPTY_LINE
333
+ value = content
334
+ end
335
+ else
336
+ ret = :EOF
337
+ end
338
+
339
+ [ret, value]
340
+ end
341
+
342
+ def make_next_state_table
343
+ @next_state = {}
344
+ @next_state[:NONE] = {}
345
+ @next_state[:NONE][:EMPTY_LINE] = :NONE
346
+ @next_state[:NONE][:TITLE_LINE] = :ITEM
347
+ @next_state[:NONE][:EMPTY_TITLE_LINE] = :END
348
+ @next_state[:NONE][:NON_EMPTY_LINE] = :BAD
349
+ @next_state[:ITEM] = {}
350
+ @next_state[:ITEM][:EMPTY_LINE] = :ITEM
351
+ @next_state[:ITEM][:TITLE_LINE] = :ITEM
352
+ @next_state[:ITEM][:EMPTY_TITLE_LINE] = :END
353
+ @next_state[:ITEM][:NON_EMPTY_LINE] = :ITEM
354
+ @next_state[:END] = {}
355
+ @next_state[:END][:EMPTY_LINE] = :END
356
+ @next_state[:END][:TITLE_LINE] = :BAD
357
+ @next_state[:END][:EMPTY_TITLE_LINE] = :BAD
358
+ @next_state[:END][:NON_EMPTY_LINE] = :END
359
+ end
360
+
361
+ def get_next_state(state, event)
362
+ if state == :BAD
363
+ :BAD
364
+ else
365
+ @next_state[state][event]
366
+ end
367
+ end
368
+
369
+ def analyze(line_ary, _subfname = nil)
370
+ @line_ary = line_ary
371
+ make_next_state_table
372
+ # :NONE
373
+ # :ITEM
374
+ # :END
375
+ # :BAD
376
+
377
+ # :EMPTY_LINE
378
+ # :TITLE_LINE
379
+ # :EMPTY_TITLE_LINE
380
+ # :NON_EMPTY_LINE
381
+ state = :NONE
382
+ event = get_event
383
+
384
+ @item_ary = []
385
+ item = nil
386
+ while state != :BAD and event[0] != :EOF
387
+ case state
388
+ when :NONE
389
+ case event[0]
390
+ when :EMPTY_LINE
391
+ when :TITLE_LINE
392
+ @item_ary << (item = Item.new(event[1]))
393
+ when :EMPTY_TITLE_LINE
394
+ @item_ary << (item = Item.new(""))
395
+ when :NON_EMPTY_LINE
396
+ item.add(event[1])
397
+ end
398
+ when :ITEM
399
+ case event[0]
400
+ when :EMPTY_LINE
401
+ when :TITLE_LINE
402
+ @item_ary << (item = Item.new(event[1]))
403
+ when :EMPTY_TITLE_LINE
404
+ @item_ary << (item = Item.new(""))
405
+ when :NON_EMPTY_LINE
406
+ item.add(event[1])
407
+ end
408
+ else
409
+ case event[0]
410
+ when :EMPTY_LINE
411
+ when :TITLE_LINE
412
+ when :EMPTY_TITLE_LINE
413
+ when :NON_EMPTY_LINE
414
+ item.add(event[1])
415
+ end
416
+ end
417
+
418
+ state = get_next_state(state, event[0])
419
+ event = get_event
420
+ end
421
+
422
+ @item_ary
423
+ end
424
+ end
425
+ end