]> git.openstreetmap.org Git - osqa.git/blob - forum/utils/html2text.py
initial import
[osqa.git] / forum / utils / html2text.py
1 # Copyright (c) 2001 Chris Withers\r
2 #\r
3 # This Software is released under the MIT License:\r
4 # http://www.opensource.org/licenses/mit-license.html\r
5 # See license.txt for more details.\r
6 #\r
7 # $Id: html2text.py,v 1.7 2002/12/17 16:56:17 fresh Exp $\r
8 \r
9 import sgmllib\r
10 from string import lower, replace, split, join\r
11 \r
12 class HTML2Text(sgmllib.SGMLParser):\r
13 \r
14     from htmlentitydefs import entitydefs # replace entitydefs from sgmllib\r
15 \r
16     def __init__(self, ignore_tags=(), indent_width=4, page_width=80):\r
17         sgmllib.SGMLParser.__init__(self)\r
18         self.result = ""\r
19         self.indent = 0\r
20         self.ol_number = 0\r
21         self.page_width=page_width\r
22         self.inde_width=indent_width\r
23         self.lines=[]\r
24         self.line=[]\r
25         self.ignore_tags = ignore_tags\r
26 \r
27     def add_text(self,text):\r
28         # convert text into words\r
29         words = split(replace(text,'\n',' '))\r
30         self.line.extend(words)\r
31 \r
32     def add_break(self):\r
33         self.lines.append((self.indent,self.line))\r
34         self.line=[]\r
35 \r
36     def generate(self):\r
37         # join lines with indents\r
38         indent_width = self.inde_width\r
39         page_width = self.page_width\r
40         out_paras=[]\r
41         for indent,line in self.lines+[(self.indent,self.line)]:\r
42 \r
43             i=indent*indent_width\r
44             indent_string = i*' '\r
45             line_width = page_width-i\r
46 \r
47             out_para=''\r
48             out_line=[]\r
49             len_out_line=0\r
50             for word in line:\r
51                 len_word = len(word)\r
52                 if len_out_line+len_word<line_width:\r
53                     out_line.append(word)\r
54                     len_out_line = len_out_line + len_word\r
55                 else:\r
56                     out_para = out_para + indent_string + join(out_line, ' ') + '\n'\r
57                     out_line=[word]\r
58                     len_out_line=len_word\r
59 \r
60             out_para = out_para + indent_string + join(out_line, ' ')\r
61             out_paras.append(out_para)\r
62 \r
63         self.result = join(out_paras,'\n\n')\r
64 \r
65 \r
66     def mod_indent(self,i):\r
67         self.indent = self.indent + i\r
68         if self.indent < 0:\r
69             self.indent = 0\r
70 \r
71     def handle_data(self, data):\r
72         if data:\r
73             self.add_text(data)\r
74 \r
75     def unknown_starttag(self, tag, attrs):\r
76         """ Convert HTML to something meaningful in plain text """\r
77         tag = lower(tag)\r
78 \r
79         if tag not in self.ignore_tags:\r
80             if tag[0]=='h' or tag in ['br','pre','p','hr']:\r
81                 # insert a blank line\r
82                 self.add_break()\r
83 \r
84             elif tag =='img':\r
85                 # newline, text, newline\r
86                 src = ''\r
87 \r
88                 for k, v in attrs:\r
89                     if lower(k) == 'src':\r
90                         src = v\r
91 \r
92                 self.add_break()\r
93                 self.add_text('Image: ' + src)\r
94 \r
95             elif tag =='li':\r
96                 self.add_break()\r
97                 if self.ol_number:\r
98                     # num - text\r
99                     self.add_text(str(self.ol_number) + ' - ')\r
100                     self.ol_number = self.ol_number + 1\r
101                 else:\r
102                     # - text\r
103                     self.add_text('- ')\r
104 \r
105             elif tag in ['dd','dt']:\r
106                 self.add_break()\r
107                 # increase indent\r
108                 self.mod_indent(+1)\r
109 \r
110             elif tag in ['ul','dl','ol']:\r
111                 # blank line\r
112                 # increase indent\r
113                 self.mod_indent(+1)\r
114                 if tag=='ol':\r
115                     self.ol_number = 1\r
116 \r
117     def unknown_endtag(self, tag):\r
118         """ Convert HTML to something meaningful in plain text """\r
119         tag = lower(tag)\r
120 \r
121         if tag not in self.ignore_tags:\r
122             if tag[0]=='h' or tag in ['pre']:\r
123                 # newline, text, newline\r
124                 self.add_break()\r
125 \r
126             elif tag =='li':\r
127                 self.add_break()\r
128 \r
129             elif tag in ['dd','dt']:\r
130                 self.add_break()\r
131                 # descrease indent\r
132                 self.mod_indent(-1)\r
133 \r
134             elif tag in ['ul','dl','ol']:\r
135                 # blank line\r
136                 self.add_break()\r
137                 # decrease indent\r
138                 self.mod_indent(-1)\r
139                 self.ol_number = 0\r
140 \r