2 # -*- coding: utf-8 -*-
14 #sys.stdin = codecs.getreader('utf_8')(sys.stdin)
15 #sys.stdout = codecs.getwriter('utf_8')(sys.stdout)
17 alist = ["a", "a:href", "a:name", "b", "br" ]
20 tag_filter = HTMLTagFilter.HTMLTagFilter(HTMLTagFilter.DENY_ALLOW, alist, dlist)
21 path_to_index = "./_markup_index"
23 class _InputStream(object):
24 """InputStream base class."""
33 """function for iterator"""
37 class Markupper(object):
41 self._input_iter = None
46 def index_add(self, key, val):
48 Add key and value to index.
56 self._index[key] = val
62 return self._index[key]
64 def index_haskey(self, key):
65 return self._index.has_key(key)
67 def markup(self, input_iter, release="0"):
71 @param input_iter: iterator to use as input
72 @type input_iter: iterator
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" ]
79 # tag_filter = HTMLTagFilter.HTMLTagFilter(HTMLTagFilter.DENY_ALLOW, alist, dlist)
80 self._release = release
82 self.index_add("figs", [])
85 for line in self.input_iter:
86 # line = self._default_markup_rule(line)
88 if re.search(ur"^☆{{{$", line):
91 elif re.search(ur"^☆image_dir:", line):
92 self._image_dir = re.search(ur"^☆image_dir:\s*(.*)$", line).group(1)
94 elif re.search(ur"^☆image_border:\s(on|On|ON)", line):
95 self._image_border = 1
97 elif re.search(ur"^☆comment\s{{{$", line):
100 elif re.search(ur"^☆\*", line):
101 self._anchor = re.sub(ur"^☆\*", "", line).strip()
103 elif re.search(ur"^☆clear\s+", line):
106 elif re.search(ur"^・", line):
109 elif re.search(ur"^[0-9]\.", line):
112 elif re.search(ur"^☆begin-column:", line):
113 self._begin_column(line)
115 elif re.search(ur"^☆end-column", line):
116 self._end_column(line)
118 elif re.search(ur"^☆begin-note:", line):
119 self._begin_note(line)
121 elif re.search(ur"^☆end-note", line):
124 elif re.search(ur"^☆space", line):
127 elif re.search(ur"^☆call_tables", line):
128 self._call_tables(line)
130 elif re.search(ur"^●", line):
133 elif re.search(ur"^○", line):
136 elif re.search(ur"^◇", line):
139 elif re.search(ur"^☆----", line):
142 elif re.search(ur"^☆\+---", line):
145 elif re.search(ur"^☆表", line):
148 elif re.search(ur"^☆図", line):
151 elif re.search(ur"^☆写真", line):
154 elif re.search(ur"^☆リスト", line):
157 elif re.search(ur"^☆実行例", line):
160 elif re.search(ur"^☆flow", line):
164 if re.search(ur"^ ", line):
165 self._paragraph(line)
169 if re.search(r"^\s*$", line):
177 def _clear(self, line):
178 print """<div style="clear:left;"> </div>
181 def _head_l(self, line):
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)
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)
192 line = re.sub(ur"^●(.*)$", ur"<h3>\1</h3>", line)
195 def _head_m(self, line):
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)
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)
206 line = re.sub(ur"^○(.*)$", ur"<h4>\1</h4>", line)
209 def _head_s(self, line):
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)
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)
220 line = re.sub(ur"^◇(.*)$", ur"<h5>\1</h5>", line)
223 def _paragraph(self, line):
224 line = self._default_markup_rule(line)
225 line = "<p>" + line + "</p>"
228 def _newpage(self, line):
229 line = re.sub(ur"☆----.*-{0,1}", u"<hr>", line)
232 def load_index(self, path_to_index):
236 @param path_to_index: index db's path
237 @type path_to_index: string
241 index_file = open(path_to_index, "r")
242 self._index_past = pickle.load(index_file)
245 sys.stderr.write("warn: cannot read index file,\n")
247 def save_index(self, path_to_index):
251 @param path_to_index: index db's path
252 @type path_to_index: string
256 index_file = open(path_to_index, "w")
257 pickle.dump(self._index, index_file)
260 sys.stderr.write("warn: cannot write index file,\n")
262 def make_hashlist(self, path_to_hashfile):
266 @param path_to_hashfile: hashfile's path
267 @type path_to_hashfile: string
270 file_img_hash = open(path_to_hashfile, "r")
272 sys.stderr.write("cannot open file: %s" % path_img_hash)
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]
281 def _call_tagles(self):
284 def _escape(self, line):
285 line = re.sub(ur"&", ur"&", line)
286 line = re.sub(ur"<", ur"<", line)
287 line = re.sub(ur">", ur">", line)
290 def _default_markup_rule(self, line):
292 apply default markup rules.
294 @param line: string to apply markup
297 line = self._escape(line)
300 # line = tag_filter.apply(line)
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)
317 if re.search(ur"^☆#", line):
323 def _ulist(self, line):
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()
332 def _olist(self, line):
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()
342 def _begin_column(self, line):
343 """Proccess column"""
345 str_title = re.search(ur"^☆begin-column:(.*)$", line).group(1)
346 except AttributeError:
350 <div class="column" style="background:#DDDDDD;font-size:85%%;padding:8px;">
355 def _end_column(self, line):
360 def _begin_note(self, line):
363 str_title = re.search(ur"^☆begin-note:(.*)$", line).group(1)
364 except AttributeError:
368 <div class="column" style="background:#F0F8FF;border:1px solid gray; font-size:85%%;padding:8px 8px 4px;margin-bottom: 1em;">
370 if len(str_title.strip()) > 0:
371 html = html + "<strong>%s</strong>" % (str_title)
374 def _end_note(self, line):
379 def _list_start(self):
385 def _list(self, line):
387 str_title = re.search(ur"^☆((リスト|実行例).*)$", line).group(1)
388 except AttributeError:
390 print "<p class='caption'><b>%s</b></p>" % (str_title)
391 print self._list_start()
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):
403 print self._list_end()
405 def _code(self, line):
406 print self._list_start()
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)
415 if re.search(ur"^☆\+---$", line):
418 print self._list_end()
420 def _inline(self, line):
421 for line in self.input_iter:
423 if re.search(ur"^☆}}}", line):
427 def _comment(self, line):
428 for line in self.input_iter:
430 if re.search(ur"^☆}}}", line):
433 def _space(self, line):
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;">
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;">
443 flow_footer = """</div>
451 arrow = '<div style="margin:1em auto;"><img src="%s"></div>\n' % (down_arrow,)
453 rex_title = re.compile(ur"^☆flow\s+(.*)$")
454 if rex_title.search(line):
455 title = rex_title.search(line).group(1)
459 rex_file = re.compile(ur"^([^:]*):(.*)$")
461 for line in self.input_iter:
462 if re.search(r"^\s*$", line):
464 match = rex_file.search(line)
466 file = os.path.join(self._image_dir, match.group(1))
467 cap = self._default_markup_rule(match.group(2))
470 fig = self._anchored_fig(file, cap)
471 outputs.append(flow_item % (fig, cap))
474 print flow_title % (title,)
475 print arrow.join(outputs)
479 def _fig_start(self, cap="", styles=[], width=0, height=0):
480 params = dict(style="", tablewidth="")
482 params["style"] = "width:%d;" % (width,)
483 params["tablewidth"] = 'width="%d"' % (width,)
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">
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">
494 return """<table %(tablewidth)s align="center" border="0" cellpadding="0" cellspacing="0">
495 <tr> <td valign="top" align="center">
498 def _fig_end(self, cap="", styles=[]):
499 return """</td> </tr>
500 <tr> <td><span style="font-size: 80%%; font-weight: bold;">
506 def _get_png_geom(self, filepath):
507 s = filepath.split('.')
509 if (ext == 'JPG') or (ext == 'jpg'):
510 (w, h) = getjpggeom.get_jpeg_geometory(filepath)
513 desc = deterfile.file(filepath)
516 m = re.match(r"([0-9]+)\s*x\s*([0-9]+)", desc[1])
518 err = ", ".join(desc)
519 raise Exception("deterfile error: %s, file: %s . " % (err,filepath))
523 return (int(w), int(h))
527 def _fig(self, line):
529 str_title = re.search(ur"^☆(図.*)$", line).group(1)
530 except AttributeError:
532 if str_title.find(u"図*") == 0:
533 str_title = str_title.replace(u"図*", "")
534 line = self.input_iter.next()
536 if line.find("@") == 0:
537 styles = line.strip().replace("@", "").split(",")
538 line = self.input_iter.next()
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)
557 geom = self._get_png_geom(imgname_s)
559 sys.stderr.write(str(e) + "\nline: " + line.encode("utf-8"))
565 print self._fig_start("", styles, width=w, height=h)
567 print self._fig_start("", styles)
568 print self._anchored_fig(imgname, str_title, imgname_s)
569 print self._fig_end(str_title, styles);
571 dic = self.index("figs")
574 dic.append(imgname_s)
576 def _photo(self, line):
578 str_title = re.search(ur"^☆(写真.*)$", line).group(1)
579 except AttributeError:
581 if str_title.find(u"写真*") == 0:
582 str_title = str_title.replace(u"写真*", "")
583 line = self.input_iter.next()
585 if line.find("@") == 0:
586 styles = line.strip().replace("@", "").split(",")
587 line = self.input_iter.next()
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)
605 geom = self._get_png_geom(imgname_s)
609 print self._fig_start("", styles, width=w, height=h)
611 print self._fig_start("", styles)
612 print self._anchored_fig(imgname, str_title, imgname_s)
613 print self._fig_end(str_title, styles);
615 dic = self.index("figs")
618 dic.append(imgname_s)
621 def _anchored_fig(self, file, alt, file_s=""):
624 file_s = re.sub(r"(.[A-Za-z0-9_]+)$", r"_s\1", file)
626 if not os.path.isfile(file_s):
629 alt = re.sub(r"""<[A-Za-z0-9!/]+.*?>""", "", alt)
631 ret = """<a href="%s">
632 <img src="%s" alt="%s">
634 """ % (file, file_s, alt)
640 def _fig_release(self, line):
642 str_title = re.search(ur"^☆(図.*)$", line).group(1)
643 except AttributeError:
645 print self._fig_start()
647 line = self.input_iter.next()
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)
662 hash = self.hashlist.get(imgname, "")
663 hash_s = self.hashlist.get(imgname_s, "")
667 print """<a href="/blob.pl?id=%s">
668 <slash type="image" id="%s" title="%s">
670 """ % (hash, hash_s, str_title)
673 dic = self.index("figs")
676 dic.append(imgname_s)
678 print self._fig_end(str_title);
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>
686 def _table_end(self, footnote=""):
687 return "</table>\n%s</div>\n" % (footnote,)
689 def _table(self, line):
691 self._table_buf1 = ""
694 str_title = re.search(ur"^☆(表.*)$", line).group(1)
695 fig_name = re.search(ur"^☆(表[0-9A-Z]*)", line).group(1)
696 except AttributeError:
699 if str_title.find(u"表*") == 0:
700 str_title = str_title.replace(u"表*", "")
702 print self._table_start(str_title)
703 self._table_buf1 = self._table_start(str_title)
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):
713 if re.search(ur"^※", line):
714 footnote = re.search(ur"^(※.*)$", line).group(1)
716 if re.search(ur"^〓", line):
717 line = re.sub(ur"^〓", "", line)
721 table_contents.append([])
723 for item in line.split("\t"):
728 while table_contents[num_row-n][num_col]["item"] == "":
730 table_contents[num_row-n][num_col]["row"] += 1
736 while table_contents[num_row][num_col-n]["item"] == "":
738 table_contents[num_row][num_col-n]["col"] += 1
744 while table_contents[num_row-n][num_col]["item"] == "":
746 table_contents[num_row-n][num_col]["row"] += 1
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})
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
759 for row_item in table_contents:
761 for item in row_item:
762 if item["item"] == "":
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"])
770 line = line + item["item"]
771 line = line + "</" + item["tag"] + ">"
772 line = line + "</tr>\n"
774 self._table_buf1 = self._table_buf1 + line
776 # line = "<tr><th>" + re.sub(ur"^〓", "", line) + "</th></tr>"
777 # line = line.replace("\t", "</th><th>")
780 # line = "<tr><td>" + line + "</td></tr>"
781 # line = line.replace("\t", "</td><td>")
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
789 self.index_add("tables", {fig_name:self._table_buf1})
791 def _call_tables(self, line):
793 fig_name = re.search(ur"^☆call_tables\((表[0-9A-Z]+)", line).group(1)
794 except AttributeError:
796 print self.index("tables")[fig_name]