mdextab 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ module Mdextab
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,67 @@
1
+ require 'yaml'
2
+ require 'erubis'
3
+
4
+ module Mdextab
5
+ module Yamlx
6
+ extend self
7
+
8
+ def loadSetting(yamlfname , auxiliaryYamlFname, erubyfname , hs={})
9
+ if yamlfname
10
+ begin
11
+ obj = YAML.load_file(yamlfname)
12
+ rescue RuntimeError => ex
13
+ obj = {}
14
+ end
15
+ obj = {} unless obj
16
+ else
17
+ obj = {}
18
+ end
19
+
20
+ if auxiliaryYamlFname
21
+ begin
22
+ obj2 = YAML.load_file(auxiliaryYamlFname)
23
+ rescue RuntimeError => ex
24
+ obj2 = {}
25
+ end
26
+ obj2 = {} unless obj2
27
+ else
28
+ obj2 = {}
29
+ end
30
+ obj3 = obj.merge(obj2)
31
+
32
+ str = File.read(erubyfname)
33
+ Erubis::Eruby.new(str).result(obj3).split("\n")
34
+ # File.readlines( erubyfname ).map{|x| Erubis::Eruby.new(x).result(obj3)}
35
+ end
36
+
37
+ def getContent( fname , hash = {} )
38
+ if File.exist?( fname )
39
+ fpath = fname
40
+ else
41
+ fpath = File.join( Dir.pwd , fname )
42
+ end
43
+ str = File.read( fpath )
44
+ eruby = Erubis::Eruby.new( str )
45
+ eruby.result( hash )
46
+ end
47
+
48
+ def changeContext( obj )
49
+ obj_new = {}
50
+ obj.each{|k,v|
51
+ if v.class == Hash
52
+ if v["path"]
53
+ hs = {}
54
+ v.each{|k2,v2|
55
+ hs[k2]=v2 if k2 != "path"
56
+ }
57
+ obj_new[k] = get_content( v["path"] , hs )
58
+ end
59
+ end
60
+ }
61
+ obj_new.each{|k3,v3|
62
+ obj[k3] = v3
63
+ }
64
+ obj_new
65
+ end
66
+ end
67
+ end
data/lib/mdextab.rb ADDED
@@ -0,0 +1,615 @@
1
+ require "mdextab/version"
2
+
3
+ require 'mdextab/loggerx'
4
+ require 'mdextab/token'
5
+ require 'mdextab/table'
6
+ require 'mdextab/tbody'
7
+ require 'mdextab/td'
8
+ require 'mdextab/th'
9
+ require 'mdextab/token'
10
+ require 'mdextab/tr'
11
+ require 'mdextab/yamlx'
12
+
13
+ require 'byebug'
14
+
15
+ module Mdextab
16
+ class Error < StandardError; end
17
+
18
+ class Mdextab
19
+ def initialize(opt, fname, o_fname, yamlfname, auxiliaryYamlFname=nil)
20
+ @fname = fname
21
+ @yamlfname = yamlfname
22
+ @auxiliaryYamlFname = auxiliaryYamlFname
23
+
24
+ @envStruct = Struct.new("Env" , :table, :star, :curState)
25
+ @env = nil
26
+ @envs = []
27
+
28
+ @exit_nil=1
29
+ @exit_exception=2
30
+ @exit_next_state=3
31
+ @exit_unknown=4
32
+ @exit_table_end=5
33
+ @exit_cannot_find_file=6
34
+ @exit_cannot_write_file=7
35
+ @exit_else=8
36
+ @exit_illeagal_state=90
37
+
38
+ @logger = Loggerx.new("log.txt")
39
+ # @logger.level = Logger::WARN
40
+ # @logger.level = Logger::INFO
41
+ @logger.level = Logger::DEBUG if opt["debug"]
42
+
43
+ # UNKNOWN > FATAL > ERROR > WARN > INFO > DEBUG
44
+ # @logger.datetime_format = '%Y-%m-%d %H:%M:%S'
45
+ @logger.datetime_format = ''
46
+ #logger.formatter = proc do |severity, datetime, progname, msg|
47
+ # ">>>>>> #{msg}\n"
48
+ #end
49
+ unless File.exist?(fname)
50
+ mes="Can't find #{fname}"
51
+ if @logger
52
+ @logger.error(mes)
53
+ else
54
+ STDERR.puts(mes)
55
+ end
56
+ exit(@exit_cannot_find_file)
57
+ end
58
+
59
+ begin
60
+ @output = File.open(o_fname, 'w')
61
+ rescue => ex
62
+ mes2="Can't write #{o_fname}"
63
+ if @logger
64
+ @logger.error(mes2)
65
+ else
66
+ STDERR.puts(mes2)
67
+ end
68
+ exit(@exit_cannot_write_file)
69
+ end
70
+
71
+ @fname = fname
72
+ @state = {
73
+ START: {TABLE_START: :IN_TABLE , ELSE: :OUT_OF_TABLE, STAR_START: :START, STAR_END: :START},
74
+ OUT_OF_TABLE: {TABLE_START: :IN_TABLE , ELSE: :OUT_OF_TABLE, STAR_START: :OUT_OF_TABLE, STAR_END: :OUT_OF_TABLE, TD: :OUT_OF_TABLE },
75
+ IN_TABLE: {TBODY_START: :IN_TABLE_BODY, TABLE_END: :OUT_OF_TABLE, ELSE: :IN_TABLE, TD: :IN_TD_NO_TBODY, TH: :IN_TH_NO_TBODY, TABLE_START: :IN_TABLE, STAR_START: :IN_TABLE, STAR_END: :IN_TABLE},
76
+ IN_TABLE_BODY: { TH: :IN_TH , TD: :IN_TD , ELSE: :IN_TABLE_BODY, TABLE_START: :IN_TABLE_BODY, TBODY_END: :IN_TABLE, TABLE_END: :OUT_OF_TABLE, STAR_START: :IN_TABLE_BODY, STAR_END: :IN_TABLE_BODY},
77
+ IN_TH: {ELSE: :IN_TH, TH: :IN_TH, TD: :IN_TD, TABLE_START: :IN_TH, STAR_START: :IN_TH, STAR_END: :IN_TH},
78
+ IN_TH_NO_TBODY: {ELSE: :IN_TH_NO_TBODY, TH: :IN_TH_NO_TBODY, TD: :IN_TD_NO_TBODY, TABLE_START: :IN_TH_NO_TBODY, STAR_START: :IN_TH_NO_TBODY, STAR_END: :IN_TH_NO_TBODY},
79
+ IN_TD: {ELSE: :IN_TD, TH: :IN_TH, TD: :IN_TD, TBODY_END: :IN_TABLE, TABLE_START: :IN_TD, STAR_START: :IN_TD, START_END: :IN_TD},
80
+ IN_TD_NO_TBODY: {ELSE: :IN_TD_NO_TBODY, TH: :IN_TH_NO_TBODY, TD: :IN_TD_NO_TBODY, TABLE_START: :IN_TD_NO_TBODY, TABLE_END: :OUT_OF_TABLE, TBODY_END: :IN_TABLE, STAR_START: :IN_TD_NO_TBODY, STAR_END: :IN_TD_NO_TBODY},
81
+ }
82
+
83
+ end
84
+
85
+ def getToken(l, lineno)
86
+ case l
87
+ when /^\*S(.+)$/
88
+ content = $1
89
+ ret = Token.new(:STAR_START, {content: content, lineno: lineno})
90
+ when /^\*E(.+)$/
91
+ content = $1
92
+ ret = Token.new(:STAR_END, {content: content, lineno: lineno})
93
+ when /^\s*<table/
94
+ if /^\s*<table>\s*$/.match?(l)
95
+ @logger.debug(%Q!T1 :TABLE_START attr: nil!)
96
+ ret = Token.new(:TABLE_START, {lineno: lineno})
97
+ elsif (m=/^\s*<table\s+(.+)>\s*$/.match(l))
98
+ @logger.debug(%Q!T2 :TABLE_START attr: #{m[1]}!)
99
+ ret = Token.new(:TABLE_START, {attr: m[1], lineno: lineno})
100
+ else
101
+ @logger.debug("E002 l=#{l}")
102
+ ret = nil
103
+ end
104
+ when /^\s*<tbody/
105
+ if /^\s*<tbody>\s*$/.match?(l)
106
+ ret = Token.new(:TBODY_START, {lineno: lineno})
107
+ else
108
+ @logger.debug("E003 l=#{l}")
109
+ ret = nil
110
+ end
111
+
112
+ when /^\s*(\:+)(.*)$/
113
+ nth = $1.size
114
+ cont = $2
115
+ if (m=/^th(.*)/.match(cont))
116
+ cont2 = m[1]
117
+ @logger.debug( %Q!cont2=#{cont2}! )
118
+ if (m2=/^\s(.*)/.match(cont2))
119
+ cont3 = m2[1]
120
+ if (m3=/^([^<]*)>(.*)$/.match(cont3))
121
+ attr = m3[1]
122
+ cont4 = m3[2]
123
+ @logger.debug( %Q!1 :TH , { nth: #{nth} , attr: #{attr} , content: #{cont4}}! )
124
+ ret = Token.new(:TH , { nth: nth , attr: attr , content: cont4, lineno: lineno})
125
+ else
126
+ # error
127
+ #ret = nil
128
+ @logger.debug( %Q!2 :ELSE , { nth: #{nth} , attr: nil , content: #{cont}}! )
129
+ ret = Token.new(:ELSE , { nth: nth , attr: nil , content: cont, lineno: lineno})
130
+ end
131
+ elsif (m=/^>(.*)$/.match(cont2))
132
+ cont3 = m[1]
133
+ @logger.debug( %Q!3 :TH , { nth: #{nth} , attr: nil , content: #{cont3}}! )
134
+ ret = Token.new(:TH , { nth: nth , attr: nil , content: cont3, lineno: lineno})
135
+ else
136
+ @logger.debug( %Q!4 :ELSE , { nth: #{nth} , attr: nil , content: #{cont}}! )
137
+ ret = Token.new(:ELSE , { nth: nth , attr: nil , content: cont, lineno: lineno})
138
+ end
139
+ elsif (m=/^([^<]*)>(.*)$/.match(cont))
140
+ attr = m[1]
141
+ cont2 = m[2]
142
+ @logger.debug( %Q!5 :TD , { nth: #{nth} , attr: #{attr} , content: #{cont2}}! )
143
+ ret = Token.new(:TD , {nth: nth , attr: attr , content: cont2, lineno: lineno})
144
+ else
145
+ @logger.debug( %Q!6 :TD , { nth: #{nth} , attr: #{attr} , content: #{cont}}! )
146
+ ret = Token.new(:TD , { nth: nth , attr: attr , content: cont , lineno: lineno})
147
+ end
148
+ when /^\s*<\/table/
149
+ if /^\s*<\/table>\s*$/.match?(l)
150
+ ret = Token.new(:TABLE_END, {lineno: lineno})
151
+ else
152
+ @logger.debug("E000 l=#{l}")
153
+ ret = nil
154
+ end
155
+ when /^\s*<\/tbody/
156
+ if /^\s*<\/tbody>\s*$/.match?(l)
157
+ ret = Token.new(:TBODY_END, {lineno: lineno})
158
+ else
159
+ @logger.debug("E001 l=#{l}")
160
+ ret = nil
161
+ end
162
+ else
163
+ ret = Token.new(:ELSE, {content: l, lineno: lineno})
164
+ end
165
+
166
+ ret
167
+ end
168
+
169
+ def parse
170
+ @env = getNewEnv()
171
+ lineno=0
172
+ Yamlx.loadSetting(@yamlfname , @auxiliaryYamlFname, @fname).each{ |l|
173
+ lineno += 1
174
+ token = getToken(l, lineno)
175
+ kind = token.kind
176
+
177
+ @logger.debug("kind=#{kind}")
178
+ @logger.debug(%Q!(source)#{lineno}:#{l}!)
179
+ if @env.curState == nil
180
+ @logger.error("(script)#{__LINE__}| @env.curState=nil")
181
+ else
182
+ @logger.debug("(script)#{__LINE__}| @env.curState=#{@env.curState}")
183
+ end
184
+ # debug_envs(5, token)
185
+
186
+ ret = processOneLine(@env.curState, token, l, lineno)
187
+ unless ret
188
+ @logger.error("processOneLine returns nil")
189
+ exit(@exit_next_state)
190
+ end
191
+ @env.curState = ret
192
+
193
+ v=@env.curState
194
+ v="nil" unless v
195
+ @logger.debug("NEXT kind=#{kind} @env.curState=#{v}")
196
+ @logger.debug("-----")
197
+ }
198
+ checkEnvs
199
+ end
200
+
201
+
202
+ def getNextState(token, line)
203
+ kind = token.kind
204
+ @logger.debug("#{__LINE__}|@env.curState=#{@env.curState} #{@env.curState.class}")
205
+ tmp = @state[@env.curState]
206
+ if tmp == nil
207
+ @logger.error(%Q!kind=#{kind}!)
208
+ @logger.error("=== tmp == nil")
209
+ exit(@exit_nil)
210
+ else
211
+ @logger.debug("tmp=#{tmp}")
212
+ end
213
+ @logger.debug("#{__LINE__}|kind=#{kind}")
214
+
215
+ begin
216
+ nextState = tmp[kind]
217
+ @logger.debug("#{__LINE__}|nextState=#{nextState}")
218
+ rescue
219
+ @logger.fatal(@env.curState)
220
+ @logger.fatal(kind)
221
+ @logger.fatal(nextState)
222
+ @logger.fatal("+++")
223
+ exit(@exit_exception)
224
+ end
225
+ @logger.debug("#{__LINE__}|nextState=#{nextState}")
226
+ nextState
227
+ end
228
+
229
+ def debug_envs(n, token)
230
+ @logger.debug( "***#{n}")
231
+ @envs.each_with_index{|x,ind|
232
+ @logger.debug( "@envs[#{ind}]=#{@envs[ind]}")
233
+ }
234
+ @logger.debug( "******#{n}")
235
+ @logger.debug( "getNewEnv 1 token.kind=#{token.kind} @env.curState=#{@env.curState}" )
236
+ end
237
+
238
+ def processNestedTableStart(token, lineno)
239
+ if @env.table.tbody == nil
240
+ @env.table.add_tbody(lineno)
241
+ end
242
+ @logger.debug( "B getNewEnv 1 token.kind=#{token.kind} token.opt[:lineno]=#{token.opt[:lineno]} @env.curState=#{@env.curState}" )
243
+ @env = getNewEnv(:OUT_OF_TABLE)
244
+ @env.table = Table.new(token.opt[:lineno], @logger, token.opt[:attr])
245
+ @logger.debug( "getNewEnv 3 token.kind=#{token.kind} @env.curState=#{@env.curState}" )
246
+ end
247
+
248
+ def processTableEnd(token)
249
+ #byebug
250
+ prevEnv = peekPrevEnv()
251
+ if prevEnv
252
+ tmp_table = @env.table
253
+
254
+ @logger.debug( "B getPrevEnv 1 token.kind=#{token.kind} token.opt[:lineno]=#{token.opt[:lineno]} @env.curState=#{@env.curState}" )
255
+ @logger.debug( "@envs.size=#{@envs.size}")
256
+ @env = getPrevEnv()
257
+ @return_from_nested_env = true
258
+ @logger.debug( "getPrevEnv 1 token.kind=#{token.kind} token.opt[:lineno]=#{token.opt[:lineno]} @env.curState=#{@env.curState}" )
259
+
260
+ @logger.debug( "0 - processTableEnd @env.curState=#{@env.curState} @return_from_nested_env=#{@return_from_nested_env}")
261
+ @logger.debug( tmp_table )
262
+ case @env.curState
263
+ when :IN_TD
264
+ @env.table.tdAppend(tmp_table, @env.star)
265
+ when :IN_TD_NO_TBODY
266
+ @env.table.tdAppend(tmp_table, @env.star)
267
+ when :IN_TH
268
+ @env.table.thAppend(tmp_table, @env.star)
269
+ when :IN_TH_NO_TBODY
270
+ @env.table.thAppend(tmp_table,@env.star)
271
+ when :IN_TABLE
272
+ if @env.table == nil
273
+ @logger.fatal( "In processNestedTableEnv: @env.table=nil token.kind=#{token.kind} token.opt[:lineno]=#{token.opt[:lineno]} @env.curState=#{@env.curState}" )
274
+ raise
275
+ end
276
+ @env.table.add(tmp_table)
277
+ when :IN_TABLE_BODY
278
+ @env.table.add(tmp_table)
279
+ when :START
280
+ # do nothing?
281
+ else
282
+ v = @env.curState
283
+ v = "nil" unless v
284
+ @logger.error("E100 @env.curState=#{v}")
285
+ @logger.error("@env.table=#{@env.table}")
286
+ exit(@exit_table_end)
287
+ end
288
+ else
289
+ @logger.debug( "1 - processTableEnd @env.curState=#{@env.curState} @return_from_nested_env~#{@return_from_nested_env}")
290
+ @output.puts(@env.table.end)
291
+ end
292
+ end
293
+
294
+ def outputInElse(str)
295
+ if @env.star
296
+ if str.match?(/^\s*$/)
297
+ @logger.debug("InElse do nothing")
298
+ else
299
+ @output.puts(str)
300
+ end
301
+ else
302
+ @output.puts(str)
303
+ end
304
+ end
305
+
306
+ def tableThAppendInElse(str)
307
+ if @env.star
308
+ if str.match?(/^\s*$/)
309
+ @logger.debug("ThAppend InElse")
310
+ else
311
+ @env.table.thAppend(str,@env.star)
312
+ end
313
+ else
314
+ @env.table.thAppend(str,@env.star)
315
+ end
316
+ end
317
+
318
+ def tableTdAppendInElse(str)
319
+ if @env.star
320
+ if str.match?(/^\s*$/)
321
+ @logger.debug("TdAppend InElse")
322
+ else
323
+ @env.table.tdAppend(str,@env.star)
324
+ end
325
+ else
326
+ @env.table.tdAppend(str,@env.star)
327
+ end
328
+ end
329
+
330
+ def processOneLine(curState, token, line, lineno)
331
+ @return_from_nested_env = false
332
+ case @env.curState
333
+ when :START
334
+ case token.kind
335
+ when :TABLE_START
336
+ @env.table = Table.new(lineno, @logger,token.opt[:attr])
337
+ when :ELSE
338
+ # threw
339
+ outputInElse(token.opt[:content])
340
+ when :STAR_START
341
+ @env.star = true
342
+ outputInElse('*'+token.opt[:content])
343
+ when :STAR_END
344
+ @env.star = false
345
+ outputInElse('*'+token.opt[:content])
346
+ outputInElse(token.opt[:content])
347
+ else
348
+ @logger.error( ":START [unknown]")
349
+ exit(@exit_unknown)
350
+ end
351
+ when :OUT_OF_TABLE
352
+ case token.kind
353
+ when :TABLE_START
354
+ @env.table = Table.new(lineno, @logger,token.opt[:attr])
355
+ when :ELSE
356
+ outputInElse(token.opt[:content])
357
+ when :STAR_START
358
+ @env.star = true
359
+ outputInElse('*'+token.opt[:content])
360
+ when :STAR_END
361
+ @env.star = false
362
+ outputInElse('*'+token.opt[:content])
363
+ outputInElse(token.opt[:content])
364
+ when :TD
365
+ # treat as :ELSE
366
+ outputInElse(":" + token.opt[:content])
367
+ else
368
+ @logger.error( ":OUT_OF_TABLE [unknown]")
369
+ exit(@exit_unknown)
370
+ end
371
+ when :IN_TABLE
372
+ case token.kind
373
+ when :TBODY_START
374
+ @env.table.add_tbody(lineno)
375
+ when :TABLE_END
376
+ processTableEnd(token)
377
+ when :ELSE
378
+ outputInElse(token.opt[:content])
379
+ when :TD
380
+ @logger.debug(token)
381
+ @env.table.add_tbody(lineno)
382
+ @env.table.add_td(lineno, token.opt[:content], token.opt[:nth], token.opt[:attr],@env.star)
383
+ when :TH
384
+ @env.table.add_tbody(lineno)
385
+ @env.table.add_th(lineno, token.opt[:content], token.opt[:nth], token.opt[:attr],@env.star)
386
+ when :TABLE_START
387
+ processNestedTableStart(token, lineno)
388
+ when :STAR_START
389
+ @env.star = true
390
+ outputInElse('*'+token.opt[:content])
391
+ when :STAR_END
392
+ @env.star = false
393
+ outputInElse('*'+token.opt[:content])
394
+ else
395
+ @logger.error( ":IN_TABLE [unknown]")
396
+ exit(@exit_unknown)
397
+ end
398
+ when :IN_TABLE_BODY
399
+ case token.kind
400
+ when :TH
401
+ @env.table.add_th(lineno, token.opt[:content], token.opt[:nth], token.opt[:attr],@env.star)
402
+ when :TD
403
+ @logger.debug(token)
404
+ @env.table.add_td(lineno, token.opt[:content], token.opt[:nth], token.opt[:attr],@env.star)
405
+ when :ELSE
406
+ outputInElse(token.opt[:content])
407
+ when :TABLE_START
408
+ processNestedTableStart(token, lineno)
409
+ when :TBODY_END
410
+ # processTableEnd(token)
411
+ when :TABLE_END
412
+ processTableEnd(token)
413
+ when :STAR_START
414
+ @env.star = true
415
+ outputInElse('*'+token.opt[:content])
416
+ when :STAR_END
417
+ @env.star = false
418
+ outputInElse('*'+token.opt[:content])
419
+ else
420
+ @logger.error( ":IN_TABLE_BODY [unknown]")
421
+ exit(@exit_unknown)
422
+ #
423
+ end
424
+ when :IN_TH
425
+ case token.kind
426
+ when :ELSE
427
+ tableThAppendInElse(token.opt[:content])
428
+ when :TH
429
+ @env.table.add_th(lineno, token.opt[:content], token.opt[:nth], token.opt[:attr],@env.star)
430
+ when :TD
431
+ @env.table.add_td(lineno, token.opt[:content], token.opt[:nth], token.opt[:attr],@env.star)
432
+ when :TABLE_START
433
+ processNestedTableStart(token, lineno)
434
+ =begin
435
+ # debug_envs(3, token)
436
+ @env = getNewEnv(:OUT_OF_TABLE)
437
+ @env.table = Table.new(lineno, @logger,token.opt[:attr])
438
+ @logger.debug( "getNewEnv 2 token.kind=#{token.kind} @env.curState=#{@env.curState}" )
439
+ # debug_envs(4, token)
440
+ =end
441
+ when :STAR_START
442
+ @env.star = true
443
+ tableThAppendInElse('*'+token.opt[:content])
444
+ when :STAR_END
445
+ @env.star = false
446
+ tableThAppendInElse('*'+token.opt[:content])
447
+ else
448
+ @logger.error( ":IN_TH [unknown]")
449
+ exit(@exit_unknown)
450
+ #
451
+ end
452
+ when :IN_TH_NO_TBODY
453
+ case token.kind
454
+ when :ELSE
455
+ tableThAppendInElse(token.opt[:content])
456
+ when :TH
457
+ @env.table.add_th(lineno, token.opt[:content], token.opt[:nth], token.opt[:attr],@env.star)
458
+ when :TD
459
+ @env.table.add_td(lineno, token.opt[:content], token.opt[:nth], token.opt[:attr],@env.star)
460
+ when :TABLE_START
461
+ processNestedTableStart(token, lineno)
462
+ =begin
463
+ # debug_envs(3, token)
464
+ @env = getNewEnv(:OUT_OF_TABLE)
465
+ @env.table = Table.new(lineno, @logger,token.opt[:attr])
466
+ @logger.debug( "getNewEnv 2 token.kind=#{token.kind} @env.curState=#{@env.curState}" )
467
+ # debug_envs(4, token)
468
+ =end
469
+ when :STAR_START
470
+ @env.star = true
471
+ tableThAppendInElse('*'+token.opt[:content])
472
+ when :STAR_END
473
+ @env.star = false
474
+ tableThAppendInElse('*'+token.opt[:content])
475
+ else
476
+ @logger.error( ":IN_TH_NO_TBODY [unknown]")
477
+ exit(@exit_unknown)
478
+ #
479
+ end
480
+ when :IN_TD
481
+ case token.kind
482
+ when :ELSE
483
+ tableTdAppendInElse(token.opt[:content])
484
+ when :TH
485
+ @env.table.add_th(lineno, token.opt[:content], token.opt[:nth], token.opt[:attr],@env.star)
486
+ when :TD
487
+ @env.table.add_td(lineno, token.opt[:content], token.opt[:nth], token.opt[:attr],@env.star)
488
+ when :TBODY_END
489
+ @env.table.tbody_end()
490
+ when :TABLE_START
491
+ processNestedTableStart(token, lineno)
492
+ when :STAR_START
493
+ @env.star = true
494
+ tableTdAppendInElse('*'+token.opt[:content])
495
+ when :STAR_END
496
+ @env.star = false
497
+ tableTdAppendInElse('*'+token.opt[:content])
498
+ else
499
+ @logger.error( ":IN_TD [unknown]")
500
+ exit(@exit_unknown)
501
+ #
502
+ end
503
+ when :IN_TD_NO_TBODY
504
+ case token.kind
505
+ when :ELSE
506
+ tableTdAppendInElse(token.opt[:content])
507
+ when :TH
508
+ @env.table.add_th(lineno, token.opt[:content], token.opt[:nth], token.opt[:attr],@env.star)
509
+ when :TD
510
+ @env.table.add_td(lineno, token.opt[:content], token.opt[:nth], token.opt[:attr],@env.star)
511
+ when :TABLE_START
512
+ processNestedTableStart(token, lineno)
513
+ when :TABLE_END
514
+ processTableEnd(token)
515
+ when :TBODY_END
516
+ @env.table.tbody_end()
517
+ when :STAR_START
518
+ @env.star = true
519
+ tableTdAppendInElse('*'+token.opt[:content])
520
+ when :STAR_END
521
+ @env.star = false
522
+ tableTdAppendInElse('*'+token.opt[:content])
523
+ else
524
+ @logger.error( ":IN_TD_NO_TBODY [unknown]")
525
+ exit(@exit_unknown)
526
+ #
527
+ end
528
+ else
529
+ @logger.error( "unknown state")
530
+ exit(@exit_unknown)
531
+ #
532
+ end
533
+
534
+ unless @return_from_nested_env
535
+ nextState = getNextState(token, line)
536
+ @logger.debug("#{__LINE__}|nextState=#{nextState}")
537
+ else
538
+ nextState = @env.curState
539
+ end
540
+ nextState
541
+ end
542
+
543
+ def end
544
+ @output.close
545
+ end
546
+
547
+ def getNewEnv(state=:START)
548
+ new_env = @envStruct.new
549
+ @envs << new_env
550
+ new_env.curState = state
551
+ if @env
552
+ new_env.star = @env.star
553
+ else
554
+ new_env.star = false
555
+ end
556
+ new_env
557
+ end
558
+
559
+ def getCurState
560
+ ret = @env.curState
561
+ end
562
+
563
+ def getPrevEnv()
564
+ @envs.pop
565
+ @envs.last
566
+ end
567
+
568
+ def peekPrevEnv()
569
+ if @envs.size > 1
570
+ @envs[@envs.size-2]
571
+ else
572
+ nil
573
+ end
574
+ end
575
+
576
+ def checkEnvs
577
+ case @env.curState
578
+ when :OUT_OF_TABLE
579
+ if @envs.size > 1
580
+ @logger.info("illeagal nested env after parsing|:OUT_OF_TABLE")
581
+ @logger.fatal("@envs.size=#{@envs.size} :TABLE_START #{@env.table.lineno}" )
582
+ @envs.map{ |x|
583
+ @logger.fatal("== @envs.curState=#{x.curState} :TABLE_START #{x.table.lineno}")
584
+ }
585
+ @logger.fatal("== @env.table")
586
+ @logger.info(@env.table)
587
+ raise
588
+ end
589
+ when :START
590
+ if @envs.size > 1
591
+ @logger.fatal("illeagal nested env after parsing|:START")
592
+ @logger.fatal("@envs.size=#{@envs.size}")
593
+ @envs.map{ |x|
594
+ @logger.fatal("== @envs.curState=#{x.curState} :TABLE_START #{x.table.lineno}")
595
+ }
596
+ @logger.fatal("== @env.table")
597
+ @logger.fatal(@env.table)
598
+ raise
599
+ end
600
+ else
601
+ @logger.fatal("illeagal state after parsing(#{@env.curState}|#{@env.curState.class})")
602
+ @logger.fatal("@envs.size=#{@envs.size}")
603
+ @logger.fatal("== @env.curState=#{@env.curState}")
604
+ @envs.map{ |x|
605
+ @logger.fatal("== @envs.curState=#{x.curState} #{@fname}:#{x.table.lineno}")
606
+ }
607
+ # @logger.fatal("== @env.table")
608
+ # @logger.fatal(@env.table)
609
+ # raise
610
+ @logger.fatal("")
611
+ exit(@exit_illeagal_state)
612
+ end
613
+ end
614
+ end
615
+ end