ykutils 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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