OSDN Git Service

add wp_imgswap2.py for new OSDN Magazine
[otptools/otptools.git] / markupper.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3  
4 import sys
5 import os
6 import re
7 import codecs
8 import pickle
9
10 import HTMLTagFilter
11 import deterfile
12 import getjpggeom
13
14 #sys.stdin = codecs.getreader('utf_8')(sys.stdin)
15 #sys.stdout = codecs.getwriter('utf_8')(sys.stdout)
16
17 alist = ["a", "a:href", "a:name", "b", "br" ]
18 dlist = ["*"]
19
20 tag_filter = HTMLTagFilter.HTMLTagFilter(HTMLTagFilter.DENY_ALLOW, alist, dlist)
21 path_to_index = "./_markup_index"
22
23 class _InputStream(object):
24     """InputStream base class."""
25     def __init__(self):
26         pass
27
28     def __iter__(self):
29         """return Iterator"""
30         return self
31
32     def next(self):
33         """function for iterator"""
34         pass
35
36
37 class Markupper(object):
38     """
39     """
40     def __init__(self):
41         self._input_iter = None
42         self._index_past = {}
43         self._index = {}
44         self._image_dir = ""
45
46     def index_add(self, key, val):
47         """
48         Add key and value to index.
49
50         @param key:
51          @type key:
52
53         @param val:
54         @key val:
55         """
56         self._index[key] = val
57
58     def index(self, key):
59         """
60         Get index
61         """
62         return self._index[key]
63
64     def index_haskey(self, key):
65         return self._index.has_key(key)
66
67     def markup(self, input_iter, release="0"):
68         """
69         Do markup.
70
71         @param input_iter: iterator to use as input
72         @type input_iter: iterator
73         """
74         self.input_iter = input_iter
75         self._page_counter = 1
76         self._image_border = 0
77         # alist = ["a", "a:href", "a:name", "b", "br" ]
78         # dlist = ["*"]
79         # tag_filter = HTMLTagFilter.HTMLTagFilter(HTMLTagFilter.DENY_ALLOW, alist, dlist)
80         self._release = release
81
82         self.index_add("figs", [])
83
84         self._anchor = ""
85         for line in self.input_iter:
86             # line = self._default_markup_rule(line)
87             # head-of-line rules
88             if re.search(ur"^☆{{{$", line):
89                 self._inline(line)
90                 continue
91             elif re.search(ur"^☆image_dir:", line):
92                 self._image_dir = re.search(ur"^☆image_dir:\s*(.*)$", line).group(1)
93                 continue
94             elif re.search(ur"^☆image_border:\s(on|On|ON)", line):
95                 self._image_border = 1
96                 continue
97             elif re.search(ur"^☆comment\s{{{$", line):
98                 self._comment(line)
99                 continue
100             elif re.search(ur"^☆\*", line):
101                 self._anchor = re.sub(ur"^☆\*", "", line).strip()
102                 continue
103             elif re.search(ur"^☆clear\s+", line):
104                 self._clear(line)
105                 continue
106             elif re.search(ur"^・", line):
107                 self._ulist(line)
108                 continue
109             elif re.search(ur"^[0-9]\.", line):
110                 self._olist(line)
111                 continue
112             elif re.search(ur"^☆begin-column:", line):
113                 self._begin_column(line)
114                 continue
115             elif re.search(ur"^☆end-column", line):
116                 self._end_column(line)
117                 continue
118             elif re.search(ur"^☆begin-note:", line):
119                 self._begin_note(line)
120                 continue
121             elif re.search(ur"^☆end-note", line):
122                 self._end_note(line)
123                 continue
124             elif re.search(ur"^☆space", line):
125                 self._space(line)
126                 continue
127             elif re.search(ur"^☆call_tables", line):
128                 self._call_tables(line)
129                 continue
130             elif re.search(ur"^●", line):
131                 self._head_l(line)
132                 continue
133             elif re.search(ur"^○", line):
134                 self._head_m(line)
135                 continue
136             elif re.search(ur"^◇", line):
137                 self._head_s(line)
138                 continue
139             elif re.search(ur"^☆----", line):
140                 self._newpage(line)
141                 continue
142             elif re.search(ur"^☆\+---", line):
143                 self._code(line)
144                 continue
145             elif re.search(ur"^☆表", line):
146                 self._table(line)
147                 continue
148             elif re.search(ur"^☆図", line):
149                 self._fig(line)
150                 continue
151             elif re.search(ur"^☆写真", line):
152                 self._photo(line)
153                 continue
154             elif re.search(ur"^☆リスト", line):
155                 self._list(line)
156                 continue
157             elif re.search(ur"^☆実行例", line):
158                 self._list(line)
159                 continue
160             elif re.search(ur"^☆flow", line):
161                 self._flow(line)
162                 continue
163
164             if re.search(ur"^ ", line):
165                 self._paragraph(line)
166                 continue
167
168
169             if re.search(r"^\s*$", line):
170                 line = ""
171
172             line = line.strip()
173             print line
174
175         # end-of-loop
176
177     def _clear(self, line):
178         print """<div style="clear:left;"> </div>
179 """
180
181     def _head_l(self, line):
182         line = line.rstrip()
183         if re.search(ur"\*{[a-zA-Z0-9_]*}\s*$", line):
184             self._anchor = re.search(ur"\*\{([a-zA-Z0-9_]*)\}\s*$", line).group(1)
185             line = re.sub(ur"\s*\*\{[a-zA-Z0-9_]*\}\s*$", "", line)
186
187         line = self._default_markup_rule(line)
188         if self._anchor != "":
189             line = re.sub(ur"^●(.*)$", ur'<div id="%s"><h3>\1</h3></div>' % self._anchor, line)
190             self._anchor = ""
191         else:
192             line = re.sub(ur"^●(.*)$", ur"<h3>\1</h3>", line)
193         print line
194
195     def _head_m(self, line):
196         line = line.rstrip()
197         if re.search(ur"\*{[a-zA-Z0-9_]*}\s*$", line):
198             self._anchor = re.search(ur"\*\{([a-zA-Z0-9_]*)\}\s*$", line).group(1)
199             line = re.sub(ur"\s*\*\{[a-zA-Z0-9_]*\}\s*$", "", line)
200
201         line = self._default_markup_rule(line)
202         if self._anchor != "":
203             line = re.sub(ur"^○(.*)$", ur'<div id="%s"><h4>\1</h4></div>' % self._anchor, line)
204             self._anchor = ""
205         else:
206             line = re.sub(ur"^○(.*)$", ur"<h4>\1</h4>", line)
207         print line
208
209     def _head_s(self, line):
210         line = line.rstrip()
211         if re.search(ur"\*{[a-zA-Z0-9_]*}\s*$", line):
212             self._anchor = re.search(ur"\*\{([a-zA-Z0-9_]*)\}\s*$", line).group(1)
213             line = re.sub(ur"\s*\*\{[a-zA-Z0-9_]*\}\s*$", "", line)
214
215         line = self._default_markup_rule(line)
216         if self._anchor != "":
217             line = re.sub(ur"^◇(.*)$", ur'<div id="%s"><h5>\1</h5></div>' % self._anchor, line)
218             self._anchor = ""
219         else:
220             line = re.sub(ur"^◇(.*)$", ur"<h5>\1</h5>", line)
221         print line
222
223     def _paragraph(self, line):
224         line = self._default_markup_rule(line)
225         line = "<p>" + line + "</p>"
226         print line
227
228     def _newpage(self, line):
229         line = re.sub(ur"☆----.*-{0,1}", u"<hr>", line)
230         print line
231
232     def load_index(self, path_to_index):
233         """
234         load index database.
235
236         @param path_to_index: index db's path
237         @type path_to_index: string
238         """
239         # load index
240         try:
241             index_file = open(path_to_index, "r")
242             self._index_past = pickle.load(index_file)
243             index_file.close()
244         except IOError:
245             sys.stderr.write("warn: cannot read index file,\n")
246
247     def save_index(self, path_to_index):
248         """
249         save index database.
250
251         @param path_to_index: index db's path
252         @type path_to_index: string
253         """
254         # save index
255         try:
256             index_file = open(path_to_index, "w")
257             pickle.dump(self._index, index_file)
258             index_file.close()
259         except IOError:
260             sys.stderr.write("warn: cannot write index file,\n")
261
262     def make_hashlist(self, path_to_hashfile):
263         """
264         create hash list.
265
266         @param path_to_hashfile: hashfile's path
267         @type path_to_hashfile: string
268         """
269         try:
270             file_img_hash = open(path_to_hashfile, "r")
271         except IOError:
272             sys.stderr.write("cannot open file: %s" % path_img_hash)
273             return None;
274
275         self.hashlist = {};
276         for line in file_img_hash:
277             splited = line.strip().split("\t", 2)
278             # hashlist's format: <hash> \t <filename>
279             self.hashlist[splited[1]] = splited[0]
280
281     def _call_tagles(self):
282         pass
283
284     def _escape(self, line):
285         line = re.sub(ur"&", ur"&amp;", line)
286         line = re.sub(ur"<", ur"&lt;", line)
287         line = re.sub(ur">", ur"&gt;", line)
288         return line
289
290     def _default_markup_rule(self, line):
291         """
292         apply default markup rules.
293
294         @param line: string to apply markup
295         @type line: string
296         """
297         line = self._escape(line)
298
299         # apply filter
300         # line = tag_filter.apply(line)
301
302         line = re.sub(ur"[★*](動画[0-9〜~、]+)", ur"<b>\1</b>", line)
303         line = re.sub(ur"[★*](表[0-9〜~、]+)", ur"<b>\1</b>", line)
304         line = re.sub(ur"[★*](図[0-9〜~、]+)", ur"<b>\1</b>", line)
305         line = re.sub(ur"[★*](写真[0-9〜~、]+)", ur"<b>\1</b>", line)
306         line = re.sub(ur"[★*](実行例[0-9〜~、]+)", ur"<b>\1</b>", line)
307         line = re.sub(ur"[★*](リスト[0-9~〜、]+)", ur"<b>\1</b>", line)
308         line = re.sub(ur"[★*](コラム[0-9〜~、]+)", ur"<b>\1</b>", line)
309         line = re.sub(ur"[★*]b\[(.*?)\]", ur"<b>\1</b>", line)
310         line = re.sub(ur"[★*]b\{(.*?)\}", ur"<b>\1</b>", line)
311         line = re.sub(ur"[★*]g\[(.*?)]", ur"<span style='color:#F55;font-weight:bold;'>\1</span>", line)
312         line = re.sub(ur"[★*]g{(.*?)}", ur"<span style='color:#F55;font-weight:bold;'>\1</span>", line)
313         line = re.sub(ur"[★*]\[(\S*) (.*?)\]", r'<a href="\1">\2</a>', line)
314         line = re.sub(ur"[★*]\[(\S*)\]", r'<a href="\1">\1</a>', line)
315
316         # comment
317         if re.search(ur"^☆#", line):
318             line = ""
319
320         return line
321
322
323     def _ulist(self, line):
324         """Proccess ul"""
325         print "<ul>"
326         while re.search(ur"^・", line):
327             line = self._default_markup_rule(line)
328             print re.sub(ur"^・(.*)$", ur"<li>\1</li>", line.strip())
329             line = self.input_iter.next()
330         print "</ul>\n"
331
332     def _olist(self, line):
333         """Proccess ul"""
334         print "<ol>"
335         while re.search(ur"^[0-9]+\.", line):
336             line = self._default_markup_rule(line)
337             print re.sub(ur"^[0-9]+\.(.*)$", ur"<li>\1</li>", line.strip())
338             line = self.input_iter.next()
339         print "</ol>\n"
340
341
342     def _begin_column(self, line):
343         """Proccess column"""
344         try:
345             str_title = re.search(ur"^☆begin-column:(.*)$", line).group(1)
346         except AttributeError:
347             str_title = ""
348
349         html = """
350 <div class="column" style="background:#DDDDDD;font-size:85%%;padding:8px;"> 
351 <h4>%s</h4>
352     """ % (str_title)
353         print html
354
355     def _end_column(self, line):
356         print """
357 </div>
358     """
359
360     def _begin_note(self, line):
361         """Proccess note"""
362         try:
363             str_title = re.search(ur"^☆begin-note:(.*)$", line).group(1)
364         except AttributeError:
365             str_title = ""
366
367         html = """
368 <div class="column" style="background:#F0F8FF;border:1px solid gray; font-size:85%%;padding:8px 8px 4px;margin-bottom: 1em;"> 
369 """
370         if len(str_title.strip()) > 0:
371             html = html + "<strong>%s</strong>" % (str_title)
372         print html
373
374     def _end_note(self, line):
375         print """
376 </div>
377     """
378
379     def _list_start(self):
380         return "<pre>"
381
382     def _list_end(self):
383         return "</pre>"
384
385     def _list(self, line):
386         try:
387             str_title = re.search(ur"^☆((リスト|実行例).*)$", line).group(1)
388         except AttributeError:
389             str_title = ""
390         print "<p class='caption'><b>%s</b></p>" % (str_title)
391         print self._list_start()
392
393         for line in self.input_iter:
394             line = line.strip("\n\r")
395             line = self._escape(line)
396             line = re.sub(ur"[★*]b\[(.*?)]", ur"<b>\1</b>", line)
397             line = re.sub(ur"[★*]b{(.*?)}", ur"<b>\1</b>", line)
398             line = re.sub(ur"[★*]g\[(.*?)]", ur"<span style='color:#F55;font-weight:bold;'>\1</span>", line)
399             line = re.sub(ur"[★*]g{(.*?)}", ur"<span style='color:#F55;font-weight:bold;'>\1</span>", line)
400             if re.search(ur"""^☆\+---""", line):
401                 break
402             print line
403         print self._list_end()
404
405     def _code(self, line):
406         print self._list_start()
407
408         for line in self.input_iter:
409             line = self._escape(line)
410             line = re.sub(ur"[★*]b\[(.*?)]", ur"<b>\1</b>", line)
411             line = re.sub(ur"[★*]b{(.*?)}", ur"<b>\1</b>", line)
412             line = re.sub(ur"[★*]g\[(.*?)]", ur"<span style='color:#F55;font-weight:bold;'>\1</span>", line)
413             line = re.sub(ur"[★*]g{(.*?)}", ur"<span style='color:#F55;font-weight:bold;'>\1</span>", line)
414
415             if re.search(ur"^☆\+---$", line):
416                 break
417             print line,
418         print self._list_end()
419
420     def _inline(self, line):
421         for line in self.input_iter:
422             line = line.strip()
423             if re.search(ur"^☆}}}", line):
424                 break
425             print line
426
427     def _comment(self, line):
428         for line in self.input_iter:
429             line = line.strip()
430             if re.search(ur"^☆}}}", line):
431                 break
432
433     def _space(self, line):
434         print "<br><br>"
435
436     def _flow(self, line):
437         down_arrow = "http://static.sourceforge.jp/crystal/22x22/actions/1downarrow.png"
438         flow_header = """<div style="text-align:center; border: 1px solid; background-color:#EFF2F0; width:90%; margin: 0 auto 1em;">
439 """
440         flow_title = """<div style="text-align:left; padding:4px 4px 4px 1em; margin-bottom: 1em; border-bottom: 1px solid; font-weight: bold; background-color:#BCD;">
441 %s
442 </div>"""
443         flow_footer = """</div>
444 """
445         flow_item = """<div>
446 %s
447 <p>%s</p>
448 </div>
449
450 """
451         arrow = '<div style="margin:1em auto;"><img src="%s"></div>\n' % (down_arrow,)
452
453         rex_title = re.compile(ur"^☆flow\s+(.*)$")
454         if rex_title.search(line):
455             title = rex_title.search(line).group(1)
456         else:
457             title = ""
458
459         rex_file = re.compile(ur"^([^:]*):(.*)$")
460         outputs = []
461         for line in self.input_iter:
462             if re.search(r"^\s*$", line):
463                 break
464             match = rex_file.search(line)
465             if match:
466                 file = os.path.join(self._image_dir, match.group(1))
467                 cap = self._default_markup_rule(match.group(2))
468             else:
469                 continue
470             fig = self._anchored_fig(file, cap)
471             outputs.append(flow_item % (fig, cap))
472
473         print flow_header
474         print flow_title % (title,)
475         print arrow.join(outputs)
476         print flow_footer
477         
478
479     def _fig_start(self, cap="", styles=[], width=0, height=0):
480         params = dict(style="", tablewidth="")
481         if width != 0:
482             params["style"] = "width:%d;" % (width,)
483             params["tablewidth"] = 'width="%d"' % (width,)
484
485         if "lfloat" in styles:
486             return """<table %(tablewidth)s align="center" border="0" cellpadding="0" cellspacing="0" style="float:left; padding-left: 0.5em; %(style)s">
487     <tr> <td valign="top" align="center">
488     """ % params
489         elif "left" in styles:
490             return """<table %(tablewidth)s border="0" cellpadding="0" cellspacing="0" style="padding-left: 0.5em; %(style)s">
491     <tr> <td valign="top" align="center">
492     """ %params
493         else:
494             return """<table %(tablewidth)s align="center" border="0" cellpadding="0" cellspacing="0">
495     <tr> <td valign="top" align="center">
496     """ % params
497
498     def _fig_end(self, cap="", styles=[]):
499         return """</td> </tr>
500     <tr> <td><span style="font-size: 80%%; font-weight: bold;">
501     %s
502     </span></td> </tr>
503     </table>
504     """ % (cap)
505
506     def _get_png_geom(self, filepath):
507         s = filepath.split('.')
508         ext = s[-1]
509         if (ext == 'JPG') or (ext == 'jpg'):
510             (w, h) = getjpggeom.get_jpeg_geometory(filepath)
511             return (w, h)
512         else:
513             desc = deterfile.file(filepath)
514
515         try:
516             m = re.match(r"([0-9]+)\s*x\s*([0-9]+)", desc[1])
517         except IndexError:
518             err = ", ".join(desc)
519             raise Exception("deterfile error: %s, file: %s . " % (err,filepath))
520         if m:
521             w = m.group(1)
522             h = m.group(2)
523             return (int(w), int(h))
524         else:
525             return None
526
527     def _fig(self, line):
528         try:
529             str_title = re.search(ur"^☆(図.*)$", line).group(1)
530         except AttributeError:
531             str_title = ""
532         if str_title.find(u"図*") == 0:
533             str_title = str_title.replace(u"図*", "")
534         line = self.input_iter.next()
535         styles = []
536         if line.find("@") == 0:
537             styles = line.strip().replace("@", "").split(",")
538             line = self.input_iter.next()
539
540         imgname = ""
541         imgname_s = ""
542         hash = ""
543         hash_s = ""
544         match_o1 = re.search(ur"<([^,]*?)>", line)
545         match_o2 = re.search(ur"<(.*?),\s*(.*?)>", line)
546         if not match_o1 == None:
547             imgname = match_o1.group(1)
548             imgname = os.path.join(self._image_dir, imgname)
549             imgname_s = re.sub(r"(.[A-Za-z0-9_]+)$", r"_s\1", imgname)
550         elif not match_o2 == None:
551             imgname = match_o2.group(1)
552             imgname = os.path.join(self._image_dir, imgname)
553             imgname_s = match_o2.group(2)
554             imgname_s = os.path.join(self._image_dir, imgname_s)
555
556         try:
557             geom = self._get_png_geom(imgname_s)
558         except Exception, e:
559             sys.stderr.write(str(e) + "\nline: " + line.encode("utf-8"))
560             sys.exit(-1)
561
562         if geom:
563             w = geom[0]
564             h = geom[1]
565             print self._fig_start("", styles, width=w, height=h)
566         else:
567             print self._fig_start("", styles)
568         print self._anchored_fig(imgname, str_title, imgname_s)
569         print self._fig_end(str_title, styles);
570
571         dic = self.index("figs")
572         dic.append(imgname)
573         if imgname_s != "":
574             dic.append(imgname_s)
575
576     def _photo(self, line):
577         try:
578             str_title = re.search(ur"^☆(写真.*)$", line).group(1)
579         except AttributeError:
580             str_title = ""
581         if str_title.find(u"写真*") == 0:
582             str_title = str_title.replace(u"写真*", "")
583         line = self.input_iter.next()
584         styles = []
585         if line.find("@") == 0:
586             styles = line.strip().replace("@", "").split(",")
587             line = self.input_iter.next()
588
589         imgname = ""
590         imgname_s = ""
591         hash = ""
592         hash_s = ""
593         match_o1 = re.search(ur"<([^,]*?)>", line)
594         match_o2 = re.search(ur"<(.*?),\s*(.*?)>", line)
595         if not match_o1 == None:
596             imgname = match_o1.group(1)
597             imgname = os.path.join(self._image_dir, imgname)
598             imgname_s = re.sub(r"(.[A-Za-z0-9_]+)$", r"_s\1", imgname)
599         elif not match_o2 == None:
600             imgname = match_o2.group(1)
601             imgname = os.path.join(self._image_dir, imgname)
602             imgname_s = match_o2.group(2)
603             imgname_s = os.path.join(self._image_dir, imgname_s)
604
605         geom = self._get_png_geom(imgname_s)
606         if geom:
607             w = geom[0]
608             h = geom[1]
609             print self._fig_start("", styles, width=w, height=h)
610         else:
611             print self._fig_start("", styles)
612         print self._anchored_fig(imgname, str_title, imgname_s)
613         print self._fig_end(str_title, styles);
614
615         dic = self.index("figs")
616         dic.append(imgname)
617         if imgname_s != "":
618             dic.append(imgname_s)
619
620         
621     def _anchored_fig(self, file, alt, file_s=""):
622
623         if file_s == "":
624             file_s = re.sub(r"(.[A-Za-z0-9_]+)$", r"_s\1", file)
625
626         if not os.path.isfile(file_s):
627             file_s = file
628
629         alt = re.sub(r"""<[A-Za-z0-9!/]+.*?>""", "", alt)
630
631         ret = """<a href="%s">
632   <img src="%s" alt="%s">
633 </a>
634 """ % (file, file_s, alt)
635
636
637         return ret
638         
639
640     def _fig_release(self, line):
641         try:
642             str_title = re.search(ur"^☆(図.*)$", line).group(1)
643         except AttributeError:
644             str_title = ""
645         print self._fig_start()
646
647         line = self.input_iter.next()
648         imgname = ""
649         imgname_s = ""
650         hash = ""
651         hash_s = ""
652         match_o1 = re.search(ur"<([^,]*?)>", line)
653         match_o2 = re.search(ur"<(.*?),\s*(.*?)>", line)
654         if not match_o1 == None:
655             imgname = match_o1.group(1)
656             imgname_s = re.sub(r"(.[A-Za-z0-9_]+)$", r"_s\1", match_o1.group(1))
657         elif not match_o2 == None:
658             imgname = match_o1.group(1)
659             imgname_s = match_o1.group(2)
660
661
662         hash = self.hashlist.get(imgname, "")
663         hash_s = self.hashlist.get(imgname_s, "")
664         if hash_s == "":
665             hash_s = hash
666
667         print """<a href="/blob.pl?id=%s">
668      <slash type="image" id="%s" title="%s">
669      </a>
670      """ % (hash, hash_s, str_title)
671         
672
673         dic = self.index("figs")
674         dic.append(imgname)
675         if imgname_s != "":
676             dic.append(imgname_s)
677
678         print self._fig_end(str_title);
679
680
681     def _table_start(self, cap):
682         return """<div style="width:90%%; margin-left:auto;margin-right:auto;"><table align="center" border="1" class="table" width="100%%">
683     <caption><b>%s</b></caption>
684     """ % cap
685
686     def _table_end(self, footnote=""):
687         return "</table>\n%s</div>\n" % (footnote,)
688
689     def _table(self, line):
690         str_title = ""
691         self._table_buf1 = ""
692
693         try:
694             str_title = re.search(ur"^☆(表.*)$", line).group(1)
695             fig_name =  re.search(ur"^☆(表[0-9A-Z]*)", line).group(1)
696         except AttributeError:
697             str_title = ""
698             fig_name = ""
699         if str_title.find(u"表*") == 0:
700             str_title = str_title.replace(u"表*", "")
701
702         print self._table_start(str_title)
703         self._table_buf1 =  self._table_start(str_title)
704
705         num_row = 0
706         table_contents = []
707         footnote = ""
708         for line in self.input_iter:
709             line = line.strip(" \n")
710             line = self._default_markup_rule(line)
711             if re.search(ur"^\s*$", line):
712                 break
713             if re.search(ur"^※", line):
714                 footnote = re.search(ur"^(※.*)$", line).group(1)
715                 break
716             if re.search(ur"^〓", line):
717                 line = re.sub(ur"^〓", "", line)
718                 tag_mode = "th"
719             else:
720                 tag_mode = "td"
721             table_contents.append([])
722             num_col = 0
723             for item in line.split("\t"):
724                 if item == "":
725                     if num_col == 0:
726                         n = 1
727                         try:
728                             while table_contents[num_row-n][num_col]["item"] == "":
729                                 n += 1
730                             table_contents[num_row-n][num_col]["row"] += 1
731                         except IndexError:
732                             pass
733                     else:
734                         n = 1
735                         try:
736                             while table_contents[num_row][num_col-n]["item"] == "":
737                                 n += 1
738                             table_contents[num_row][num_col-n]["col"] += 1
739                         except IndexError:
740                             pass
741                 if item == u"↓":
742                     n = 1
743                     try:
744                         while table_contents[num_row-n][num_col]["item"] == "":
745                             n += 1
746                         table_contents[num_row-n][num_col]["row"] += 1
747                         item = ""
748                     except IndexError:
749                         pass
750
751                 if re.search(r'^".*"$', item):
752                     item = re.search(r'^"(.*)"$', item).group(1)
753                     table_contents[num_row].append({"tag":"th","item":item,"row":1,"col":1})
754                 else:
755                     table_contents[num_row].append({"tag":tag_mode,"item":item,"row":1,"col":1})
756                 num_col = num_col + 1
757             num_row = num_row + 1
758
759         for row_item in table_contents:
760             line = "<tr>"
761             for item in row_item:
762                 if item["item"] == "":
763                     continue
764                 line = line + "<" + item["tag"]
765                 if not item["row"] == 1:
766                     line = line + (' rowspan="%s"' % item["row"])
767                 if not item["col"] == 1:
768                     line = line + (' colspan="%s"' % item["col"])
769                 line = line +  ">"
770                 line = line + item["item"]
771                 line = line + "</" + item["tag"] + ">"
772             line = line + "</tr>\n"
773             print line,
774             self._table_buf1 = self._table_buf1 + line
775
776             # line = "<tr><th>" + re.sub(ur"^〓", "", line) + "</th></tr>"
777             # line = line.replace("\t", "</th><th>")
778             # print line
779             # else:
780             # line = "<tr><td>" + line + "</td></tr>"
781             # line = line.replace("\t", "</td><td>")
782             # print line
783
784         print self._table_end(footnote)
785         self._table_buf1 =  self._table_buf1 + self._table_end()
786         if self.index_haskey("tables"):
787             self.index("tables")[fig_name] = self._table_buf1
788         else:
789             self.index_add("tables", {fig_name:self._table_buf1})
790
791     def _call_tables(self, line):
792         try:
793             fig_name =  re.search(ur"^☆call_tables\((表[0-9A-Z]+)", line).group(1)
794         except AttributeError:
795             return
796         print self.index("tables")[fig_name]