-
Notifications
You must be signed in to change notification settings - Fork 0
/
html2txt.pl
226 lines (218 loc) · 5.27 KB
/
html2txt.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# html2txt.pl HTML形式データをテキストデータに
# 1997 Sey ([email protected],[email protected])
# jperl html2txt.pl HTMLファイル…
# タグとそれに応じて出力する内容
%out = (
"H1", "\n\n\n\n\n",
"H2", "\n\n\n\n",
"H3", "\n\n\n",
"H4", "\n\n",
"/H1", "\n\n",
"/H2", "\n\n",
"/H3", "\n\n",
"/H4", "\n\n",
"P", "\n\n",
"HR", "\n\n",
"BLOCKQUOTE","\n\n",
"/BLOCKQUOTE","\n\n",
"BR", "\n",
"CENTER","\n",
"/CENTER","\n",
"DIV","\n",
"/DIV","\n",
"/HTML","\n",
"UL", "\n",
"OL", "\n",
"/UL", "\n\n",
"/OL", "\n\n",
"LI", "\no",
"/TABLE","\n",
"TR", "\n",
"/TD", "\t",
"/TH", "\t"
);
# タグ間の文字列の出力を抑制するタグ
# 値:n … 抑制コンテナの開始 c … 〃終了 t … 次のタグまで抑制
%noout = (
"COMMENT","n",
"/COMMENT","c",
"HEAD", "n",
"/HEAD","c",
"TABLE","t",
"TR", "t",
"/TD", "t",
"/TR", "t",
);
# 出力バッファ
$outbuf = "";
# 出力時に連続する空行をまとめるためのカウンタ
$outnl = 0;
# <PRE>中のフラグ
$pre = 0;
# 出力抑制フラグ
$noout = 0;
# 次のタグまでの出力抑制フラグ
$noout1tag = 0;
# 状態
$status = "idle";
# 作業領域
$buf = "";
for(;;)
{
# タグ外の状態
if( $status eq "idle" )
{
# < を検出
if( $buf =~ /^([^<>]*)</ )
# そこまでを出力し、< を検出した状態へ
{
$buf = $';
out($1) if( !$noout && !$noout1tag );
$status = "<";
}
# みつからない
else
# 次の行を読んでつなげる
{ last if( !&readline ); }
}
# < を検出した状態
elsif( $status eq "<" )
{
# <!--
if( $buf =~ /^!--/ )
{ $buf = $'; $status = "!--"; }
# <PRE>
elsif( $buf =~ /^PRE */i )
{ $buf = $'; out("\n"); $pre++; $status = "wait>"; }
# </PRE>
elsif( $buf =~ /^\/PRE */i )
{ $buf = $'; out("\n"); $pre--; $status = "wait>"; }
# それ以外のタグ
elsif( $buf =~ /^[\/\?!]?[a-zA-Z0-9]+/ )
{
$buf = $';
$tagname = $&;
$tagname =~ tr/a-z/A-Z/;
# %outにあれば対応する内容を出力
if( $out{$tagname} ne "" ) {
out($out{$tagname})
}
# なにかタグが来たら$noout1tagはクリア
$noout1tag = 0;
# %nooutにあれば出力抑制フラグをセット
# 抑制を開始するタグ
if( $noout{$tagname} eq "n" )
{ $noout++; }
# 抑制を終了するタグ
elsif( $noout{"$tagname"} eq "c" )
{ $noout--; }
# 次のタグまで抑制するタグ
elsif( $noout{$tagname} eq "t" )
{ $noout1tag = 1; }
$status = "wait>";
}
# タグでないと思われる場合
else
{ out("<"); $status = "idle"; }
}
# タグ中で > を待つ状態
elsif( $status eq "wait>" )
{
# " " で囲まれた文字列
if( $buf =~ /^[^<>\"]*\"[^\"]*\"/ )
{ $buf = $'; }
# > が見つかった
elsif( $buf =~ /^[^<>\"]*>/ )
{ $buf = $'; $status = "idle"; }
# みつからない
else
# 次の行を読んでつなげる
{ last if( !&readline ); }
}
# 注釈状態
elsif( $status eq "!--" )
{
# --> がみつかった
if( $buf =~ /-->/ )
{ $buf = $'; $status = "idle"; }
# みつからない
else
# 次の行を読んでつなげる
{ last if( !&readline ); }
}
}
# end
# 次の行を読んで$bufに連結
sub readline
{
if( $line = <> )
{
# 物理的改行はいったん\x01に変換しておく
$line =~ s/\n/\x01/g;
$buf .= $line;
1;
}
# 終わりなら残りを出力して終了
else
{
out($buf) if( $status eq "idle" );
0;
}
}
# end readline
# 出力
sub out
{
local($string) = @_;
# 特殊記号の変換
$string =~ s/</</g;
$string =~ s/>/>/g;
$string =~ s/"/\"/g;
$string =~ s/&/&/g;
# <PRE>~</PRE>中では物理的改行を復活してそのまま出力
if( $pre )
{
$outbuf =~ s/\x01/\n/g;
$string =~ s/\x01/\n/g;
print $outbuf,$string;
$outbuf = "";
$outnl = 0;
}
else
{
# 物理的改行は除く
$string =~ s/\x01//g;
# 連続する空白はまとめる
$string =~ s/ +/ /g;
# 改行を含むときは改行までをバッファにつなげて出力
if( $string =~ /^.*\n+/ )
{
$string = $outbuf . $&;
$outbuf = $';
# 行末の空白とタブは除く
$string =~ s/[ \t]+\n/\n/;
# 連続する改行はまとめる
$string =~ s/\n{3,}/\n\n/;
# 改行のみの時は前回の改行数を考慮する
if( $string =~ /^\n+/ )
{
# すでに2回以上改行していればもう改行しない
if( $outnl >= 2 )
{ $string =~ s/^\n+//; }
# 一回なら一回だけ
elsif( $outnl == 1 )
{ $string =~ s/^\n+/\n/; }
# カウンタを増やす
$outnl += $string =~ s/\n/\n/g;
}
else
{ $outnl = $string =~ s/\n/\n/g; }
print $string;
}
# 改行を含まない時はバッファにためる
else
{ $outbuf .= $string; }
}
}
# end out
# end html2txt.pl