root/lang/perl/chalow/trunk/chalow @ 24140

Revision 12510, 42.9 kB (checked in by woremacx, 5 years ago)

import chalow-1.0 as trunk

  • Property svn:executable set to *
Line 
1#!/usr/bin/perl
2# $Id: chalow,v 1.1 2007-10-19 22:07:25+09 tatsuoyamashita Exp tatsuoyamashita $
3#
4# chalow - CHAngeLog On the Web - convert ChangeLog to HTML files
5#
6# This is free software with ABSOLUTELY NO WARRANTY.
7# ̵����̵��ڡ������ (see http://nais.to/~yto/doc/zb/0002.html)
8#
9# chalow �ۡ�������: http://chalow.org/
10use strict;
11use Getopt::Long;
12use POSIX qw(strftime ceil);
13use Time::Local;                # for ��
14use HTML::Template;
15use ChangeLogReader;
16
17my $version = '1.0';
18
19# ���߻������my $what_time_is_it_now = strftime "%Y-%m-%d %H:%M", localtime;
20my $dcdate = strftime "%Y-%m-%dT%H:%M:%S+09:00", localtime;
21my ($current_ym) = ($what_time_is_it_now =~ /^(\d+-\d+)/); # ����### �桼������ obsolete
22
23# ��ʬ��home page URL --- ��������ƥ�졼�Ȥ������my $home_page_url = "http://chalow.org/";
24# ��ʬ�Υۡ��ࡼ�ڡ����θƤ�� --- �������Ʊ��y $home_page_name = "chalow home page";
25
26
27### �桼������
28## �ǥե����� (�桼�����ե���������ꤵ���ʤ��Ȥ�)
29# �������
30my $changelog_name = "ChangeLog";
31# ��ưʸ����
32my $auto_replace = '
33s!(<blockquote>)!</p>$1<p>!g;
34s!(</blockquote>)!</p>$1<p>!g;
35';
36# CSS �ե�����y $css_file;
37# RSS�ե�����
38my $rss_filename = "cl.rdf";
39# RSS�˺ǶᲿ�ʬɽ�����뤫(0�ξ���$opt_topn �����)
40my $rss_topn = 0;
41# ����å����ڡ���(index.html)�ǺǶᲿ�ʬ������뤫
42my $opt_topn = 5;
43# ���θ���(Mon, Tue, ...)������뤫 (1:yes or 0:no)
44my $show_day_of_week = 1;
45# �������ǡ��������������������������뤫 (1:yes or 0:no)
46my $reverse_order_days = 0;
47
48# ����å����ڡ����Υƥ�졼��my $index_page_template = << "___INDEX_PAGE_TEMPLATE"
49<html lang="ja"><head>
50<meta http-equiv="Content-Type" content="text/html;charset=EUC-JP">
51<TMPL_IF name=css_file>
52 <link rel=stylesheet href="<TMPL_VAR name=css_file>" media=all>
53</TMPL_IF>
54<link rel="alternate" type="application/rss+xml" title="RSS"
55 href="<TMPL_VAR name=rss_file>">
56<title><TMPL_VAR name=cl_name></title>
57</head><body>
58<a href="<TMPL_VAR name=rss_file>">RSS</a>
59<h1><a href="index.html"><TMPL_VAR name=cl_name></a></h1>
60<p class="calendar"><TMPL_VAR name=ym> / <TMPL_VAR name=day_list></p>
61<p>last update: <TMPL_VAR name=lastupdate></p>
62<p class="calendar"><TMPL_VAR name=month_page_list></p>
63<p>recent <TMPL_VAR name=ndays> days</p>
64<TMPL_LOOP name=entries><TMPL_VAR name=content></TMPL_LOOP>
65<TMPL_VAR name=signature>
66</div></body></html>
67___INDEX_PAGE_TEMPLATE
68    ;
69
70# �������Υƥ�졼��my $month_page_template = << "___MONTH_PAGE_TEMPLATE"
71<html lang="ja"><head>
72<meta http-equiv="Content-Type" content="text/html;charset=EUC-JP">
73<TMPL_IF name=css_file>
74 <link rel=stylesheet href="<TMPL_VAR name=css_file>" media=all>
75</TMPL_IF>
76<link rel="alternate" type="application/rss+xml" title="RSS"
77 href="<TMPL_VAR name=rss_file>">
78<title><TMPL_VAR name=cl_name> / <TMPL_VAR name=ym></title>
79</head><body>
80<TMPL_IF name=back><a href="<TMPL_VAR name=back>.html">Prev Month</a></TMPL_IF>
81<TMPL_IF name=next> / <a href="<TMPL_VAR name=next>.html">Next Month</a></TMPL_IF>
82<h1><a href="index.html"><TMPL_VAR name=cl_name></a> <TMPL_VAR name=ym></h1>
83<p class="calendar"><TMPL_VAR name=day_list></p>
84<p class="calendar"><TMPL_VAR name=month_page_list></p>
85<TMPL_LOOP name=entries><TMPL_VAR name=content></TMPL_LOOP>
86<p>last update: <TMPL_VAR name=lastupdate></p>
87<TMPL_VAR name=signature>
88</div></body></html>
89___MONTH_PAGE_TEMPLATE
90    ;
91
92# ��ڡ����Υƥ�졼��my $day_page_template = << "___DAY_PAGE_TEMPLATE"
93<html lang="ja"><head>
94<meta http-equiv="Content-Type" content="text/html;charset=EUC-JP">
95<TMPL_IF name=css_file>
96 <link rel=stylesheet href="<TMPL_VAR name=css_file>" media=all>
97</TMPL_IF>
98<link rel="alternate" type="application/rss+xml" title="RSS"
99 href="<TMPL_VAR name=rss_file>">
100<title><TMPL_VAR name=cl_name> / <TMPL_VAR name=ymd></title>
101</head><body>
102<TMPL_IF name=back><a href="<TMPL_VAR name=back>.html">Prev Day</a></TMPL_IF>
103<TMPL_IF name=next> / <a href="<TMPL_VAR name=next>.html">Next Day</a></TMPL_IF>
104<h1><a href="index.html"><TMPL_VAR name=cl_name></a></h1>
105<TMPL_VAR name=content> 
106<p class="calendar"><a href="<TMPL_VAR name=ym>.html"><TMPL_VAR name=ym></a>
107 / <TMPL_VAR name=day_list></p>
108<p class="calendar"><TMPL_VAR name=month_page_list></p>
109<p>last update: <TMPL_VAR name=lastupdate></p>
110<TMPL_VAR name=signature>
111</div></body></html>
112___DAY_PAGE_TEMPLATE
113    ;
114
115# �����ƥ������Υƥ�졼��my $item_page_template = << "___PAGE_TEMPLATE"
116<html lang="ja"><head>
117<meta http-equiv="Content-Type" content="text/html;charset=EUC-JP">
118<TMPL_IF name=css_file>
119 <link rel=stylesheet href="<TMPL_VAR name=css_file>" media=all>
120</TMPL_IF>
121<link rel="alternate" type="application/rss+xml" title="RSS"
122 href="<TMPL_VAR name=rss_file>">
123<title><TMPL_VAR name=header_text></title>
124</head><body>
125<TMPL_IF name=back><a href="<TMPL_VAR name=back>.html">Prev</a></TMPL_IF>
126<TMPL_IF name=next> / <a href="<TMPL_VAR name=next>.html">Next</a></TMPL_IF>
127/ <a href="index.html"><TMPL_VAR name=cl_name></a>
128<h1><TMPL_VAR name=header><TMPL_VAR name=cat></h1>
129<div class="day">
130<a href="<TMPL_VAR name=ymd>.html"><TMPL_VAR name=ymd></a>
131<div class="body">
132<!-- start:<TMPL_VAR name=ymdi> -->
133<div class="section">
134<p><TMPL_VAR name=content></p>
135<TMPL_IF name=referrer>
136 <div class="referer"><span>Referrer (Inside):
137 <TMPL_VAR name=referrer></span></div>
138</TMPL_IF>
139<p><a href="<TMPL_VAR name=ymdi>.html">permlink</a></p>
140</div>
141<!-- end:<TMPL_VAR name=ymdi> -->
142</div></div>
143<!--<p>last update: <TMPL_VAR name=lastupdate></p>-->
144<TMPL_VAR name=signature>
145</div></body></html>
146___PAGE_TEMPLATE
147    ;
148
149# ���ƥ��������Υƥ�졼��my $cat_page_template = << "TMPL"
150<html lang="ja"><head>
151<meta http-equiv="Content-Type" content="text/html;charset=EUC-JP">
152<TMPL_IF name=css_file>
153 <link rel=stylesheet href="<TMPL_VAR name=css_file>" media=all>
154</TMPL_IF>
155<link rel="alternate" type="application/rss+xml" title="RSS"
156 href="<TMPL_VAR name=rss_file>">
157<title><TMPL_VAR name=cat_name> / <TMPL_VAR name=cl_name></title>
158</head><body>
159<TMPL_IF name=page_list><TMPL_VAR name=page_list></TMPL_IF>
160<h1><TMPL_VAR name=cat_name> -
161 <a href="index.html"><TMPL_VAR name=cl_name></a></h1>
162<div>
163<TMPL_LOOP name=entries>
164 <div class="day"><h2><span class="date"><TMPL_VAR name=eh></span></h2>
165 <div class="body"><TMPL_VAR name=cont></div></div>
166</TMPL_LOOP>
167<p>last update: <TMPL_VAR name=lastupdate></p>
168<TMPL_VAR name=signature>
169</div></body></html>
170TMPL
171    ;
172
173# item �Υƥ�졼��my $item_template = << "EACHITEM"
174<!-- start:<TMPL_VAR name=ymdi> -->
175<div class="section">
176<p><TMPL_VAR name=header><TMPL_VAR name=cat><TMPL_VAR name=content></p>
177<TMPL_IF name=referrer>
178 <div class="referer"><span>Referrer (Inside):
179 <TMPL_VAR name=referrer></span></div>
180</TMPL_IF>
181</div>
182<!-- end:<TMPL_VAR name=ymdi> -->
183EACHITEM
184    ;
185
186# entry (date) �Υƥ�졼��my $entry_template = << "DAYENTRY"
187<div class="day">
188<h2><span class="date"><TMPL_VAR name=header></span></h2>
189<div class="body">
190<TMPL_IF name=message_top><TMPL_VAR name=message_top></TMPL_IF>
191<TMPL_IF name=same_date><div class="calendar"><TMPL_VAR name=same_date></div>
192</TMPL_IF>
193<TMPL_VAR name=content>
194<TMPL_IF name=referrer>
195 <div class="referer"><span>Referrer (Inside):
196 <TMPL_VAR name=referrer></span></div>
197</TMPL_IF>
198<TMPL_IF name=message_bottom><TMPL_VAR name=message_bottom></TMPL_IF>
199</div>
200</div>
201DAYENTRY
202    ;
203
204# RSS�ե������ƥ�졼��my $rss_template = << "RDFSTR"
205<?xml version="1.0" encoding="utf-8"?>
206<rdf:RDF
207 xmlns="http://purl.org/rss/1.0/"
208 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
209 xmlns:dc="http://purl.org/dc/elements/1.1/"
210 xmlns:content="http://purl.org/rss/1.0/modules/content/"
211 xmlns:admin="http://webns.net/mvcb/"
212 xml:lang="ja">
213<channel rdf:about="<TMPL_VAR name=clog_url_pref><TMPL_VAR name=rss_file>">
214 <title><TMPL_VAR name=changelog_name></title>
215 <link><TMPL_VAR name=clog_url></link>
216 <description><TMPL_VAR name=changelog_description></description>
217 <dc:language>ja</dc:language>
218 <dc:date><TMPL_VAR name=dcdate></dc:date>
219 <admin:generatorAgent rdf:resource="<TMPL_VAR name=generatorAgent>"/>
220 <items>
221 <rdf:Seq><TMPL_LOOP name=items>
222  <rdf:li rdf:resource="<TMPL_VAR name=permlink>"/></TMPL_LOOP>
223 </rdf:Seq>
224 </items>
225</channel>
226<TMPL_LOOP name=items>
227<item rdf:about="<TMPL_VAR name=permlink>">
228 <title><TMPL_VAR name=itemheader></title>
229 <link><TMPL_VAR name=permlink></link>
230 <description>
231  <TMPL_VAR name=itemcontent>
232 </description>
233 <dc:creator><TMPL_VAR name=itemauthor></dc:creator>
234 <dc:date><TMPL_VAR name=item_dcdate></dc:date>
235 <content:encoded>
236  <![CDATA[<TMPL_VAR name=itemcontentencoded>]]>
237 </content:encoded>
238</item>
239</TMPL_LOOP>
240</rdf:RDF>
241RDFSTR
242        ;
243
244# ɽ������������'>' or '|') ����� (1:YES, 0:NO)
245my $remove_quote_mark = 0;
246
247# �����򥫥����ɽ���ˤ��뤫 (1:YES, 0:NO)
248my $calendar_style = 0;
249
250# �����ƥ��å���Υե����ޥåȤ�����뤫
251# (0:"* HOGE:", 1:"* HOGE", 2:"HOGE:",3:"HOGE")
252my $item_header_style = 0;
253# item header ��h3 ��������� (1:YES, 0:NO) - tDiary �Ȥθߴ���Τ���y $use_h3_for_item_header = 0;
254# item header ����ε������󥫡�����뤫 (1:YES, 0:NO)
255my $use_item_anchor = 1;
256# item header ����ε������ �������������(���֥����ȥ����)�����������������# ���󥫡�ʸ����ꤷ�ޤ����ʤ���span class="panchor">_</span>�פ���ꤹ�����ơ��ޤˤ��Ƥϼ�ưŪ�˲����󥫡����Ĥ��褦�ˤʤ�
257# ������tDiary ��skel/conf.rhtml ��)
258my $item_header_mark = '<span class="sanchor">*</span>';
259
260# ¾���������� (��) �ؤΥ�����뤫 (1:YES, 0:NO)
261my $same_date_jump = 1;
262# # �ƥ����ƥ����Ҽ��������뤫 (1:YES, 0:NO)
263# my $show_author_name = 0;
264
265# RSS ��Ϥ��뤫 (1:YES, 0:NO)
266my $output_rss = 1;
267# ������ for RSS : �: "����Τ��줳�졣"
268my $changelog_description = "";
269# ChangeLog �������RL (�� URL �򶯤��侩) - RSS �����#my $clog_url = "http://chalow.net/";
270my $clog_url = "./";
271
272# ����ե�����cl.itemlist) ��뤫 (1:YES, 0:NO)
273my $output_itemlist = 1;
274# ���Ф��� (JavaScript �ե������ǽ�Ϥ����� $latest_titles_num = 10;
275
276# ����Ȥ˥ڡ�����뤫 (0:NO, 1:YES) --- obsolete
277my $day_page_mode = 0;
278# ��������������̡����ڡ���ñ��(0:��1:�, 2:�����ƥ�my $page_mode = 0;
279
280# ���ƥ���������뤫 (0:NO, 1:YES)
281my $output_cat_pages = 1;
282# ���ƥ���������Υ�����ξ�
283# ($output_cat_pages = 1 �ΤȤ��Τ���� $cat_page_entry_max = 10;
284# ���ƥ���itemɽ���Τ���CGI��ꤹ�����ƥ�����%%CAT%% ��֤�������# ($output_cat_pages = 0 �ΤȤ��Τ���� $cat_page_cgi = "clsearch.cgi?cat=%%CAT%%";
285#my $cat_page_cgi = "";
286
287# �ե������ǽ��ФƤ���<!-- ReplaceOnce -->�פ����������y $replace_once = "";
288
289# UTF8 mode (0:OFF, 1:ON)
290my $utf8_mode = 0;
291
292# Read More mode (0:OFF, 1:ON)
293my $readmore_mode = 1;
294# Read More tag
295my $readmore_tag = "====";
296
297### chalow ��ڤΤ���TML �ΰ����˥���������롣�Ǥ����ä��ʤ��ǡ�
298my $signature = qq(<p class="footer">Powered by
299<a href="http://chalow.org/">chalow</a></p>);
300
301### ���ޥ�饤���topt::Long::Configure('bundling');
302my ($opt_topn_tmp, $outputdir, $quiet_mode, $opt_css_file, $debug_mode,
303    $update_by_size, $conf_file, $stop_date);
304my $gor = GetOptions('n|top-n=n'   => \$opt_topn_tmp,
305                     'o|output-dir=s'   => \$outputdir,
306                     'c|configure-file=s' => \$conf_file,
307                     's|stop-date=s' => \$stop_date,
308                     'u|update-by-size' => \$update_by_size,
309                     'C|css=s' => \$opt_css_file,
310                     'q|quiet' => \$quiet_mode,
311                     '8|utf8' => \$utf8_mode,
312                     'd|debug' => \$debug_mode);
313
314if (@ARGV == 0 or $gor == 0) {
315    print << "USAGE";
316usage: chalow [options] <file> [file]...
317    -n, --top-n=NUM             write NUM days to "index.html"
318    -o, --output-dir=DIR        directory to output
319    -c, --configure-file=FILE   configure file
320    -s, --stop-date=DATE        date to stop processing
321    -u, --update-by-size        overwrite only if sizes are different
322    -C, --css=FILE              css file
323    -q, --quiet                 quiet mode
324    -8, --utf8                  utf8 mode
325    -d, --debug                 debug mode
326USAGE
327    ;
328    exit;
329}
330
331# �桼�����ե�������߹���(�ե���������ꤵ�����Ȥ��Τ�
332if ($conf_file ne "") {
333    open(CONF, $conf_file) or die "Can't open $conf_file : $!\n";
334    binmode(CONF);
335    my $conf = join('', <CONF>);
336#    $conf = Jcode->new($conf)->euc; # del 050412
337    eval $conf;
338    die qq(error in "$conf_file" (obsolete variable?): $@\n) if ($@);
339}
340
341$outputdir = "." if (not defined $outputdir);
342
343# �桼�����ե������ꥳ�ޥ�饤���ͥ������
344$opt_topn = $opt_topn_tmp if (defined $opt_topn_tmp);
345$css_file = $opt_css_file if (defined $opt_css_file);
346
347# ����������ä�����ͤˤ��롣����Ȥ�����
348# �˻Ȥ����顣
349$stop_date =~ s/-//g;
350
351my $latest_item_list;
352my $category_list;
353
354my $clog_url_pref = $clog_url;
355$clog_url_pref =~ s!/[^/]+html?$!/!;
356$clog_url_pref .= "/" unless ($clog_url_pref =~ m!/$!);
357# SPEC:   $clog_url                 $clog_url_pref
358# http://chalow.net/           -> http://chalow.net/
359# http://chalow.net/index.html -> http://chalow.net/
360# http://chalow.net            -> http://chalow.net/
361
362my %month_page;                 # ���Υڡ���
363my %category_item;              # ���ƥ����ڡ���� item
364my %inside_ref;                 # �������ˤ������顼
365
366#my %all_entries;                # hash for all ChangeLog entries
367# {XXXX-XX-XX}{"eh"} - Entry header
368# {XXXX-XX-XX}{1,2,3,...}{"ho"} - Item header (original text)
369# {XXXX-XX-XX}{1,2,3,...}{"co"} - Item content (original text)
370# {XXXX-XX-XX}{1,2,3,...}{"cat"} - Category (array)
371# {XXXX-XX-XX}{1,2,3,...}{"a"} - Author
372# {XXXX-XX-XX}{"message-top"} - Pragma item
373# {XXXX-XX-XX}{"message-bottom"} - Pragma item
374# {XXXX-XX-XX}{curid} - Item ID manager
375# {XXXX-XX-XX}{1,2,3,...}{"h"} - �����ƥ��å�# {XXXX-XX-XX}{1,2,3,...}{"c"} - �̣
376
377my $cl = ChangeLogReader->new(stop_date => $stop_date);
378
379for my $fname (@ARGV) {
380    print "reading \"$fname\"\n" if (!defined $quiet_mode);
381    $cl->store_changelog_file($fname);
382}
383
384print "done.\nconverting\n" if (!defined $quiet_mode);
385
386foreach my $ymd (reverse sort keys %{$cl->{all}}) {
387    parse_entry($ymd, \%{$cl->{all}->{$ymd}});
388}
389
390print "done.\n" if (!defined $quiet_mode);
391
392# ����������Ƥ���
393my $month_page_list = make_month_page_list($cl->{STAT}->{ym});
394
395# ��������������Ƥ���
396my $current_day_list = make_day_list_str($current_ym);
397
398### ��(1)
399write_rss_file() if ($output_rss); # RSS �ե�������
400write_itemlist_file() if ($output_itemlist); # ����ե�����temlist)���write_latest_item_list_file();      # �Ƕ��������rite_category_list_file();  # ���ƥ�������### HTML ���Τ����롼��foreach my $ymd (sort keys %{$cl->{all}}) {
401    my $e = $cl->{all}->{$ymd};
402    my @items;
403    foreach my $i (sort {$b <=> $a} keys %{$e}) {
404        next if ($i !~ /^\d/);
405        push @items, make_item_html($e, $ymd, $i);
406    }
407    my ($y, $m, $d) = ($ymd =~ /^(\d{4})-(\d\d)-(\d\d)$/);
408    $month_page{"$y-$m"}{$ymd}{str} = make_entry_html($e, $ymd, \@items);
409}
410
411### ��(2) HTML �ե��������write_index_page();
412write_month_page();
413write_day_page() if ($day_page_mode or $page_mode >= 1);
414write_item_page() if ($page_mode == 2);
415write_category_page() if ($output_cat_pages);
416
417print "done.\n" if (!defined $quiet_mode);
418
419exit;
420
421
422### ������ѡ������Ƴ������ub parse_entry {
423    my ($ymd, $ent) = @_;
424    for (my $i = $ent->{curid}; $i >= 1; $i--) {
425        my $c = $ent->{$i}->{co};
426        $c =~ s/^\s*\n//g if ($use_h3_for_item_header == 1);
427        $ent->{$i}{h} = okikae($ent->{$i}{ho}, $ymd, $i);
428        $ent->{$i}{c} = okikae($c, $ymd, $i);
429    }
430}
431
432
433### ʸ���������
434sub okikae {
435    local ($_) = shift;
436    my ($ymd, $i) = @_;         # �����˻Ȥ��뤫��
437
438    escape_string(\$_);
439
440    # ��������γ�� - parse_entry �ˤ��ä�����escape���Ԥʤ�    # ������褤�Ȼפä��ΤǤ�������(5.1.19)
441    while (/\[((\d\d\d\d-\d\d)-\d\d(-\d+)?)\]/g) {
442        $inside_ref{$1}{"$ymd-$i"}++;
443    }
444
445    s/&/&amp;/go;
446    s/\]>/\]&gt;/go;
447#    s/>/&gt;/go;               # > �� &.. �ˤʤ���URL �Ȥ����ޥå����
448#    s/"/&quot;/go;             # ";
449    ### "<" ��֤������롣
450    s|<(/?[a-z!]+)|&lt;$1|gio;
451#    s|<(/?[a-z]+)|&lt;$1|gio;  # ������(<!-- -->) ������������Ϥ���   # �������ޥ����Υҥ� <s></s> �����
452    # s|<(/?[a-rt-z]+)|&lt;$1|gi; <b> �����
453    # s|<(/?[ac-z]+)|&lt;$1|gi; (��� = <br> �ʤɤ���
454    ### Read More ###
455    s!^$readmore_tag$(.*)$!<div class="readmore">$1</div>!sm;
456
457    ### ʸ���ȿ����Hiki �ε�ˡ��ѡ�
458    s!'''(.+?)'''!<strong>$1</strong>!gms;
459    s!''(.+?)''!<em>$1</em>!gms;
460    s!==(\S.+?)==!<s>$1</s>!gms;
461    s!^\-{4}!<hr>!gms;
462
463    ### URL��Hiki �ε�ˡ��ѡ�
464    s!\[\[(.+?)\s*\|\s*(.+?)\]\]!get_link_str($1, $2)!gmse;
465
466    ### ɽ��Hiki �ε�ˡ��ѡ�
467    s!(^(\|\|[^\n]+\n)+)!'<table><tr>'.
468        (join("<tr>", (map {join('<td>', split(/\|\|/ ,$_))} split(/\n/, $1))))
469            .'</table>'!gsme;
470
471    ### ��quote): ">>" ��"<<" �ǰϤ�   s!^>>\n!<blockquote>!gm;
472    s!^<<\n!</blockquote>!gm;
473
474    ### ��quote): "| ..." �� "> ..."
475    if ($remove_quote_mark == 1) {
476        my $a;
477        s!((^((\||>)[^\n]*)\n)+)!'<blockquote>'.($a = $1,
478            $a =~ s{^(\||>)\s?}{}gm, $a).'</blockquote>'!gme;
479    } else {
480        s!((^((\||>)[^\n]*)\n)+)!<blockquote>$1</blockquote>!gmx;
481    }
482
483    ### ���ǻ��ȥ���
484    # date ref : [YYYY-MM-DD]
485    $_ = datestr2anchor($_);
486
487    ### URLɽ����ef ��    # URL : http://....
488    # ���ɽ����http://www.din.or.jp/~ohzaki/perl.htm#httpURL ����
489    # �Хå��������������URL��Ǥβ��Ԥ�б� 021025
490    #my $URLCHARS = "[-_.!~*'()a-zA-Z0-9;/?:@&=+,%\#\$]";
491    my $URLCHARS = "[-_.!~*'a-zA-Z0-9;/?:@&=+,%\#\$]";
492    my $URLDELIM = "\\\\\\n *";
493    s{(?<![\"\=|])((s?https?|ftp)://($URLCHARS+)($URLDELIM($URLCHARS+))*)}
494    {'<a href="'.join('', split(/$URLDELIM/, $1)).'">'.
495         join('', split(/\\/, $1)).'</a>'}gem; #")};
496
497    ### ����Υ��ڡ�����&nbsp; ��֤������롣
498    s!^( +)!{"&nbsp;" x length($1)}!gme;
499    s!^(</?blockquote>)( +)!{"$1" . ("&nbsp;" x length($2))}!gme;
500
501    ### ��ưʸ����Ŭ�
502    eval $auto_replace;
503
504    # �ƹԤι��<br> �����   # memo: ���pre �ǰϤ��������v0.23 �����᤿
505#print "1[$_]\n";
506    s!$!<br>!gsm;
507    s!<br>$!!;
508#print "2[$_]\n";
509
510    unescape_string(\$_);       # �ץ饰����ӽФ����ʤ�
511
512    s!</pre><br>!</pre>!g;      # ad hoc
513
514    return $_;
515}
516
517
518### �����ƥ�HTML��Ѵ�
519sub make_item_html {
520    my ($e, $ymd, $i) = @_;
521
522    ### item header
523    my $ih = make_item_header_html($e->{$i}{h}, $ymd."-".$i);
524
525    ### ���ƥ���   my $catstr = make_cat_link_html($e->{$i}{cat});
526
527    ### �������ˤ������顼
528    my @inside_refs = get_inside_ref("$ymd-$i");
529   
530    ### item �δ��    my $item_url = datestr2url("$ymd-$i");
531    my $item_ymdi = $ymd."-".$i;
532    (my $item_id = $ymd.$i) =~ s/-//g; # Ex. "200309241"
533   
534    ### item ��Ȥ߾夲
535    my $t = HTML::Template->new(scalarref => \$item_template,
536                                die_on_bad_params => 0);
537    my $ccc = $e->{$i}{c};
538    if ($page_mode == 2 and $readmore_mode) {
539        if ($ccc =~ s!(<div class="readmore">.*</div>)$!!sm) {
540            my $readmore_str = $1;
541            $t->param(readmore => $readmore_str);
542        }
543    }
544    $t->param(content => $ccc);
545    $t->param(header => $ih);
546    $t->param(cat => $catstr);
547    $t->param(author => $e->{$i}{a});
548    $t->param(referrer => join(" ", @inside_refs));
549    $t->param(id => $item_id);
550    $t->param(ymdi => $item_ymdi);
551    $t->param(url => $item_url);
552    $t->param(rss_file => $rss_filename); # 050821
553    my $this_item = $t->output();
554
555    if ($output_cat_pages == 1) { # ���ƥ����ڡ�������Ȥ��ν�
556        my $ent_h = make_entry_header_html($e->{eh}, $ymd);
557        foreach (@{$e->{$i}{cat}}) {
558            # ���ƥ����ڡ�����--stop-date ����������Τ��
559            push @{$category_item{$_}}, {eh=>$ent_h, cont=>$this_item};
560        }
561    }
562    return $this_item;
563}
564
565
566### �����HTML��Ѵ�
567sub make_entry_html {
568    my ($e, $ymd, $itemsp) = @_;
569
570    ### entry header
571    my $ent_h = make_entry_header_html($e->{eh}, $ymd);
572
573    my ($y, $m, $d) = ($ymd =~ /^(\d{4})-(\d\d)-(\d\d)$/);
574
575    ### ¾���������� (��) �ؤΥ������   my @same_dates;
576    if ($same_date_jump == 1) {
577        if (defined $cl->{STAT}->{md}{"$m-$d"}) {
578            my @ys = sort keys %{$cl->{STAT}->{md}{"$m-$d"}};
579            @same_dates = map {"<a href=\"".datestr2url("$_-$m-$d").
580                                   "\">$_</a>"} grep {$_ != $y} @ys;
581        }
582    }
583
584    ### �������ˤ������顼
585    my @inside_refs = get_inside_ref("$ymd");
586
587    ### entry �δ��    my $entry_url = datestr2url($ymd);
588    my $entry_ymd = $ymd;
589#    my $entry_id = $ymd; $entry_id =~ s/-//g; # Ex. "20030924"
590    (my $entry_id = $ymd) =~ s/-//g; # Ex. "20030924"
591
592    ### �������߾夲
593    my $t = HTML::Template->new(scalarref => \$entry_template,
594                                die_on_bad_params => 0);
595    $t->param(header => $ent_h);
596    $t->param(message_top => $e->{"message-top"});
597    $t->param(message_bottom => $e->{"message-bottom"});
598    $t->param(referrer => join(" ", @inside_refs));
599    $t->param(same_date => join(" ", @same_dates));
600    $t->param(id => $entry_id);
601    $t->param(ymd => $entry_ymd);
602    $t->param(url => $entry_url);
603    $t->param(rss_file => $rss_filename); # 050821
604    $t->param(content => @{[join('', @{$itemsp})]});
605    return $t->output();
606}
607
608
609### ���ƥ����ڡ���(ex: cat_life.html)��롣
610sub write_category_page {
611    my @cat_list = keys %category_item;
612
613    foreach my $catname (@cat_list) {
614
615        my @ents = sort {$b->{eh} cmp $a->{eh}} @{$category_item{$catname}};
616
617        my $n = $cat_page_entry_max;
618        my $num_of_old_pages = int(@ents / $n);
619
620        my @fnames;
621        for (my $i = 0; $i <= $num_of_old_pages; $i++) {
622            $fnames[$i] = get_category_filename($catname);
623            my $suffix = ($i == 0) ? "" : "-".($i+1);
624            $fnames[$i] =~ s/\.html$/$suffix.html/;
625        }
626
627        for (my $i = 0; $i <= $num_of_old_pages; $i++) {
628
629            ### �ڡ�����Ȥ߾夲
630            my $t = HTML::Template->new(scalarref => \$cat_page_template,
631                                        loop_context_vars => 1,
632                                        die_on_bad_params => 0);
633            $t->param(cl_name => $changelog_name);
634            $t->param(css_file => $css_file);
635            $t->param(lastupdate => $what_time_is_it_now);
636            $t->param(signature => $signature);
637
638            $t->param(cat_name => $catname);
639            $t->param(ym => $current_ym);
640            $t->param(day_list => $current_day_list);
641            $t->param(latest_item_list => $latest_item_list);
642            $t->param(category_list => $category_list);
643            $t->param(rss_file => $rss_filename); # 050821
644            $t->param(entries => [grep /^.+$/, @ents[$i*$n...($i+1)*$n-1]]);
645
646            my @page_list;
647            my $back_page_url;
648            my $next_page_url;
649            if ($num_of_old_pages > 0) {
650                for (my $j = 0; $j <= $num_of_old_pages; $j++) {
651                    $page_list[$j] = ($i == $j) ? $j+1 :
652                        qq(<a href="$fnames[$j]">@{[$j+1]}</a>);
653                    $back_page_url = $fnames[$j] if ($j == $i - 1);
654                    $next_page_url = $fnames[$j] if ($j == $i + 1);
655                }
656            }
657
658            $t->param(page_list => join(" ",@page_list));
659            $t->param(first_page => $fnames[0]);
660            $t->param(back => $back_page_url);
661            $t->param(next => $next_page_url);
662            $t->param(page_id => $i + 1);
663            $t->param(page_num => $num_of_old_pages + 1);
664
665            my $ostr = $t->output();
666
667            ### �ե��������            output_to_file("$outputdir/".$fnames[$i], \$ostr);
668        }
669    }
670}
671
672
673### �����ƥ�����(ex: 2001-01-01-1.html)��롣
674sub write_item_page {
675    my @day_list = reverse sort keys %{$cl->{all}};
676
677    for (my $idx = 0; $idx < @day_list; $idx++) {
678        my ($ymd, $ym) = ($day_list[$idx] =~ /^((\d+-\d+)-\d+)/);
679        my $ent = $cl->{all}->{$ymd};
680
681        for (my $i = $ent->{curid}; $i >= 1; $i--) {
682            my $item = $ent->{$i};
683            my $ymdi = "$ymd-$i";
684
685            ### ���ƥ���    my $catstr = make_cat_link_html($ent->{$i}{cat});
686
687            ### �������ˤ������顼
688            my @inside_refs = get_inside_ref("$ymdi");
689
690            ### item �δ��           my $item_url = datestr2url("$ymdi");
691            my $item_ymdi = $ymdi;
692            my $item_id = $ymdi; $item_id =~ s/-//g; # Ex. "200309241"
693
694            # ����ڡ���
695            my $ymdi_before;
696            my $ymdi_after;
697            if ($i > 1) {
698                $ymdi_before = $ymd."-".($i-1);
699            } elsif ($idx < @day_list - 1) {
700                my $day_b = $day_list[$idx + 1];
701                $ymdi_before = $day_b."-".$cl->{all}->{$day_b}{curid};
702            }
703            if ($i != $ent->{curid}) {
704                $ymdi_after = $ymd."-".($i+1);
705            } elsif ($idx > 0) {
706                my $day_a = $day_list[$idx - 1];
707                $ymdi_after = $day_a."-1";
708            }
709
710            ### �ڡ�����Ȥ߾夲
711            my $t = HTML::Template->new(scalarref => \$item_page_template,
712                                        loop_context_vars => 1,
713                                        die_on_bad_params => 0);
714
715            $t->param(cl_name => $changelog_name);
716            $t->param(css_file => $css_file);
717            $t->param(lastupdate => $what_time_is_it_now);
718            $t->param(signature => $signature);
719
720            $t->param(ymd => $ymd);
721            $t->param(ym => $ym);
722
723            $t->param(month_page_list => $month_page_list);
724            $t->param(latest_item_list => $latest_item_list);
725            $t->param(category_list => $category_list);
726            $t->param(back => $ymdi_before);
727            $t->param(next => $ymdi_after);
728
729            my $ccc = $item->{c}; $ccc =~ s!^<br>!!g;# ad hoc
730            $t->param(content => $ccc);
731            $t->param(header_text => $item->{ho});
732            $t->param(header => $item->{h});
733            $t->param(cat => $catstr);
734            $t->param(author => $item->{a});
735            $t->param(referrer => join(" ", @inside_refs));
736            $t->param(id => $item_id); # 200101011
737            $t->param(ymdi => $item_ymdi); # 2001-01-01-1
738            $t->param(url => $item_url); # 2001-01-01-1.html
739            $t->param(rss_file => $rss_filename); # 050821
740           
741            my $ostr = $t->output();
742
743            ### �ե��������          output_to_file("$outputdir/$ymdi.html", \$ostr);
744        }
745    }
746}
747
748
749### ��ڡ���(ex: 2001-01-01.html)��롣
750sub write_day_page {
751    return if ($day_page_template eq ""); # tmpl������������5.1.19)
752
753    my @day_list = reverse sort keys %{$cl->{all}};
754
755    for (my $idx = 0; $idx < @day_list; $idx++) {
756
757        my ($ymd, $ym) = ($day_list[$idx] =~ /^((\d+-\d+)-\d+)/);
758
759        # �����ڡ���
760        my $day_before = $day_list[$idx + 1] if ($idx < @day_list - 1);
761        my $day_after = $day_list[$idx - 1] if ($idx > 0);
762
763        # ��ؤΥ��� (����)
764        my $day_list = make_day_list_str($ym);
765
766        ### �ڡ�����Ȥ߾夲
767        my $t = HTML::Template->new(scalarref => \$day_page_template,
768                                    loop_context_vars => 1,
769                                    die_on_bad_params => 0);
770        $t->param(cl_name => $changelog_name);
771        $t->param(css_file => $css_file);
772        $t->param(lastupdate => $what_time_is_it_now);
773        $t->param(signature => $signature);
774
775        $t->param(ymd => $ymd);
776        $t->param(ym => $ym);
777        $t->param(day_list => $day_list);
778        $t->param(month_page_list => $month_page_list);
779        $t->param(latest_item_list => $latest_item_list);
780        $t->param(category_list => $category_list);
781        $t->param(rss_file => $rss_filename); # 050821
782        $t->param(back => $day_before);
783        $t->param(next => $day_after);
784        $t->param(content => $month_page{$ym}{$ymd}{str});
785
786        my $ostr = $t->output();
787
788        ### �ե��������  output_to_file("$outputdir/$ymd.html", \$ostr);
789    }
790}
791
792
793### ������(ex: 2001-01.html)��롣
794sub write_month_page {
795    return if ($month_page_template eq ""); # tmpl������������5.1.19)
796
797    my @month_list = reverse sort keys %month_page;
798    for (my $idx = 0; $idx < @month_list; $idx++) {
799        my $ym = $month_list[$idx];
800
801        # �����my $m_before = $month_list[$idx + 1] if ($idx < @month_list - 1);
802        my $m_after = $month_list[$idx - 1] if ($idx > 0);
803
804        # ��������
805        my $day_list = make_day_list_str($ym);
806
807        ### ����Υ�����
808        my @cont;
809        if ($reverse_order_days) { # �߽����ο������Τ�����0.11 �����)
810            @cont = reverse sort keys %{$month_page{$ym}};
811        } else {                # �������θŤ��Τ���    @cont = sort keys %{$month_page{$ym}};
812        }
813        my @contlist = map {{content => $month_page{$ym}{$_}{str}}} @cont;
814
815        ### �ڡ�����Ȥ߾夲
816        my $t = HTML::Template->new(scalarref => \$month_page_template,
817                                    loop_context_vars => 1,
818                                    die_on_bad_params => 0);
819        $t->param(cl_name => $changelog_name);
820        $t->param(css_file => $css_file);
821        $t->param(lastupdate => $what_time_is_it_now);
822        $t->param(signature => $signature);
823
824        $t->param(ym => $ym);
825        $t->param(day_list => $day_list);
826        $t->param(month_page_list => $month_page_list);
827        $t->param(latest_item_list => $latest_item_list);
828        $t->param(category_list => $category_list);
829        $t->param(rss_file => $rss_filename); # 050821
830        $t->param(back => $m_before);
831        $t->param(next => $m_after);
832        $t->param(entries => \@contlist);
833
834        my $ostr = $t->output();
835
836        output_to_file("$outputdir/$ym.html", \$ostr);
837    }
838}
839
840
841### ����å����ڡ���(index.html)���ub write_index_page {
842    ### �Ƕ�������������å����ڡ����˺ܤ��뤿����
843    my @recent = (reverse sort keys %{$cl->{all}})[0..$opt_topn];
844
845    my @top_n_entries;
846
847    for (my $i = 0; $i < $opt_topn and $recent[$i]; $i++) {
848        my $ymd = $recent[$i];
849        my ($ym, $d) = ($ymd =~ /^(\d{4}-\d\d)-(\d\d)$/);
850#       $top_n_str .= $month_page{$ym}{$ymd}{str};
851        push @top_n_entries, {content => $month_page{$ym}{$ymd}{str}};
852    }
853    my ($ymd, $ym, $d) = ($recent[0] =~ /^((\d{4}-\d\d)-(\d\d))$/);
854
855    # ��������
856    my $day_list = make_day_list_str($ym);
857
858    ### �ڡ�����Ȥ߾夲
859    my $t = HTML::Template->new(scalarref => \$index_page_template,
860                                loop_context_vars => 1,
861                                die_on_bad_params => 0);
862    $t->param(cl_name => $changelog_name);
863    $t->param(css_file => $css_file);
864    $t->param(lastupdate => $what_time_is_it_now);
865    $t->param(signature => $signature);
866
867    $t->param(ymd => $ymd);     # �ǿ��������
868    $t->param(ym => $ym);       # �ǿ��������   $t->param(ndays => $opt_topn);
869    $t->param(day_list => $day_list);
870    $t->param(month_page_list => $month_page_list);
871    $t->param(latest_item_list => $latest_item_list);
872    $t->param(category_list => $category_list);
873    $t->param(rss_file => $rss_filename); # 050821
874    $t->param(entries => \@top_n_entries);
875
876    my $ostr = $t->output();
877
878    output_to_file("$outputdir/index.html", \$ostr);
879}
880
881
882### �������
883sub make_month_page_list {
884    my ($month_page) = @_;
885    my @month_list = sort keys %{$month_page};
886    my ($start_year) = ($month_list[0] =~ /^(\d\d\d\d)/);
887    my ($end_year) = ($month_list[$#month_list] =~ /^(\d\d\d\d)/);
888    my $month_page_list = "";
889    for (my $y = $end_year; $y >= $start_year; $y--) { # year loop
890        $month_page_list .= "$y : ";
891        for (my $m = 1; $m <= 12; $m++) { # month loop 
892            my $m0 = sprintf "%02d", $m;
893            if (defined $month_page->{"$y-$m0"}) {
894                $month_page_list .= "<a href=\"$y-$m0.html\">$m0</a> ";
895            } else {
896                $month_page_list .= "$m0 ";
897            }
898        }
899        $month_page_list .= "<br>\n";
900    }
901    return $month_page_list;
902}
903
904
905### ����������� - ʸ�����
906sub make_day_list_str {
907    my ($ym) = @_;
908    if ($calendar_style == 1) {
909        return make_calendar_table($ym, make_day_list($ym));
910    } else {
911        return join(" ", @{make_day_list($ym)});
912    }
913}
914
915# ����������� - �ꥹ�ȤؤΥݥ��󥿤��
916my %daylist;
917sub make_day_list {     
918    my ($ym) = @_;
919    my $lday = get_last_day_of_month($ym);
920    return $daylist{$ym} if (defined $daylist{$ym}); # cache
921    for (my $d = 1; $d <= $lday; $d++) {
922        my $day = ($d < 10) ? "0".$d : $d;
923        if (defined $cl->{all}->{$ym."-".$day}) {
924            my $day_url = datestr2url($ym."-".$day);
925            push @{$daylist{$ym}}, qq(<a href="$day_url">$day</a>);
926        } else {
927            push @{$daylist{$ym}}, $day;
928        }
929    }
930    return $daylist{$ym};
931}
932
933# ������� - ���������������ub make_calendar_table {
934    my ($ym, $dlistp) = @_;
935    my ($y, $m) = split("-", $ym);
936    my $offset = (localtime timelocal(0, 0, 0, 1, $m - 1, $y))[6];
937   
938    my $week = 0;
939    my @cal;
940    for (my $i = 0; $i < 42; $i++) {
941        my $day = ($i < $offset) ? " " : $dlistp->[$i - $offset];
942        last if (not $day);
943        $day =~ s/^0//;
944        $day =~ s/>0([1-9])</>$1</;
945        $cal[$week] .= qq(<td align="center">$day</td>);
946        $week++ if (($i + 1) % 7 == 0);
947    }
948
949    my @wn = ("S", "M", "T", "W", "T", "F", "S");
950#    my @wn = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
951
952    my $rv = << "CAL"
953<table>
954<caption><a href="$ym.html">$ym</a></caption>
955<tr>
956@{[join "", map {qq(<th align="center">$_</th>)} @wn]}
957</tr>
958@{[join "", map {"<tr>$_</tr>"} @cal]}
959</table>
960CAL
961    ;
962
963    return $rv;
964}
965
966
967### anchor, img ����ʸ������
968sub get_link_str {
969    my ($a, $b) = @_;
970    if ($a =~ /\.(jpg|jpeg|png|gif)$/i) { # [[http://nais.to/|image/nais.jpg]]
971        return qq(<a href="$b"><img src="$a" alt="��"></a>);
972    } elsif ($b =~ /\.(jpg|jpeg|png|gif)$/i) { # [[����|image/sp.jpg]]
973        return qq(<img src="$b" alt="$a">);
974    } else {                    # [[�ȥåץڡ���|http://nais.to/]]
975        return qq(<a href="$b">$a</a>);
976    }
977}
978
979
980### ǯ����ϤȤ�����Ϥ�����nce 021001
981# RETURN VALUES
982#     the text name of the day of the week.  Mon, Tue, Wed, ...
983# EXAMPLES
984#     get_day_of_week(1, 12, 2002), get_day_of_week("2002-12-01")
985sub get_day_of_week {
986    my ($d, $m, $y) = @_;
987    ($y, $m, $d) = split("-", $d) unless (defined $m);
988    my $WEEKDAY = (localtime timelocal(0, 0, 0, $d, $m - 1, $y))[6];
989    return ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")[$WEEKDAY];
990}
991
992
993### ǯ�����Ȥ����η��ǽ����Ϥ�����nce 030105
994# EXAMPLES
995#     get_last_day_of_month(12, 2002), get_last_day_of_month("2002-12")
996sub get_last_day_of_month {
997    my ($m, $y) = @_;
998    ($y, $m) = split("-", $m) unless (defined $y);
999    return (31, ((($y % 4 == 0) and ($y % 100)) or ($y % 400 == 0)) ? 29 : 28,
1000            31, 30, 31, 30, 31, 31, 30, 31, 30, 31)[$m - 1];
1001}
1002
1003
1004### RSS �ե�������Ϥ���ub write_rss_file {
1005    my $rdfseq;
1006    my $rdfitem;
1007    my $ctr = ($rss_topn > 0) ? $rss_topn : (($opt_topn > 7) ? 7 : $opt_topn);
1008
1009    my @items;
1010
1011    foreach my $ymd (sort {$b cmp $a} keys %{$cl->{all}}) {
1012        $ctr--;
1013        last if ($ctr < 0);
1014        my $e = $cl->{all}->{$ymd};
1015        foreach my $i (sort {$b <=> $a} keys %$e) {
1016            next if ($i !~ /^\d/);
1017
1018            my $permlink = $clog_url_pref.datestr2url($ymd."-".$i);
1019            my ($ym) = ($ymd =~ /^(\d{4}-\d\d)-\d\d/);
1020
1021            my $coen = $e->{$i}{c};
1022            $coen =~ s!<a href="(\d.+?)"!<a href="$clog_url_pref$1"!g;
1023            $coen =~ s!<img src="([^h].+?)"!<img src="$clog_url_pref$1"!g;
1024
1025            my $cont = $e->{$i}{c};
1026            $cont = html2xmlstr($cont);
1027            if ($cont =~ s/^(([\x00-\x7F]|[\x80-\xFF]{2}){300}).+$/$1/sm) {
1028                $cont =~ s/&[^;]*$//g; # &gt...$ ��ML�ѡ������顼
1029                $cont .= "...";
1030            }
1031
1032            my $item_dcdate = # ($dcdate =~ /^$ymd/) ? $dcdate :
1033                $ymd."T23:59:59+09:00";
1034
1035            push @items, {
1036                permlink => $permlink,
1037                itemheader => html2xmlstr($e->{$i}{h}),
1038                itemauthor => $e->{$i}{a},
1039                itemcontent => $cont,
1040                itemcontentencoded => $coen,
1041                item_dcdate => $item_dcdate
1042            };
1043        }
1044    }
1045    my $t = HTML::Template->new(scalarref => \$rss_template,
1046                                die_on_bad_params => 0, gloval_vars => 1);
1047    $t->param(items => \@items);
1048    $t->param(changelog_name => $changelog_name);
1049    $t->param(dcdate => $dcdate);
1050    $t->param(changelog_description => $changelog_description);
1051    $t->param(clog_url => $clog_url);
1052    $t->param(clog_url_pref => $clog_url_pref);
1053    $t->param(rss_file => $rss_filename); # 050821
1054    $t->param(generatoragent=>"http://chalow.org/?v=$version");
1055    my $ostr = $t->output();
1056    to_utf8_cl(\$ostr) if (not $utf8_mode);
1057    output_to_file("$outputdir/$rss_filename", \$ostr);
1058}
1059
1060
1061sub html2xmlstr {
1062    local ($_) = @_;
1063    s/&nbsp;/ /g;
1064    s|<img.+?alt="(.*?)".*?>|[$1]|gosm;
1065    s/[\t\n]//g;
1066    s/[\x00-\x1f]+/ /g;
1067    s/\s\s+/ /g;
1068    s|<[^<>]+?>||gosm;
1069    s/&lt;/</go;
1070    s/&/&amp;/go; s/>/&gt;/go; s/</&lt;/go; s/\"/&quot;/go; # "���Ĥ�����    return $_;
1071}
1072
1073
1074### JavaScript feed �ե�������Ϥ���ub write_latest_item_list_file {
1075
1076    ### �Ƕ�����  my @lines;
1077    my $date;
1078    my $ctr = $latest_titles_num;
1079    foreach my $ymd (sort {$b cmp $a} keys %{$cl->{all}}) {
1080        $ctr--;
1081        last if ($ctr < 0);
1082        my $e = $cl->{all}->{$ymd};
1083        foreach my $i (sort {$b <=> $a} keys %$e) {
1084            next if ($i !~ /^\d/);
1085            my ($ym) = ($ymd =~ /^(\d{4}-\d\d)-\d\d/);
1086            my $c = $e->{$i}{h};
1087            $c =~ s/[\t\n]//g;
1088            $c =~ s/\s\s+/ /g;
1089            $c =~ s/\s*$//;
1090            $c =~ s/<.+?>//g;
1091            $c =~ s/^\*\s+//;
1092#           $c =~ s/\'/&\#x27;/g;
1093
1094            if ($date ne $ymd) {
1095                push @lines, "<a href=\"".
1096                    $clog_url_pref.datestr2url("$ymd")."\">$ymd</a><br>";
1097                $date = $ymd;
1098            }
1099            push @lines, "- <a href=\"".
1100                $clog_url_pref.datestr2url("$ymd-$i")."\">$c</a><br>";
1101        }
1102    }
1103
1104    my $ostr = join("\n", map {s/\'/&\#x27;/g; "document.writeln('".$_."');"}
1105                    @lines);
1106    output_to_file("$outputdir/cl.js", \$ostr);
1107
1108    $latest_item_list = join("\n", @lines);
1109
1110}
1111
1112
1113sub write_category_list_file {
1114    ### ���ƥ����
1115#    return if ($output_cat_pages == 0 or $cat_page_cgi eq "");
1116#    return if ($output_cat_pages == 0);
1117
1118    my @lines = ();
1119    foreach my $cat (sort keys %{$cl->{CAT}}) {
1120        my $n = $cl->{CAT}->{$cat};
1121        my $url;
1122        if ($output_cat_pages) {
1123            $url = get_category_filename($cat);
1124            $url = $clog_url_pref.$url;
1125        } else {
1126            $url = $cat_page_cgi;
1127            $url =~ s/%%CAT%%/urlencode($cat)/ge;
1128            $url = $clog_url_pref.$url if ($url !~ /^http/);
1129        }
1130        push @lines, "- <a href=\"$url\">$cat</a> ($n)<br>";
1131    }
1132
1133    my $ostr = join("\n", map {s/\'/&\#x27;/g; "document.writeln('".$_."');"}
1134                 @lines);
1135
1136    $category_list = join("\n", @lines);
1137    if ($output_cat_pages == 1) {
1138        output_to_file("$outputdir/cl-cat.js", \$ostr);
1139    }
1140}
1141
1142
1143### ����ե�������Ϥ��� clsearch.cgi ��Υե�������
1144sub write_itemlist_file {
1145    my $ostr;
1146    foreach my $ymd (sort {$b cmp $a} keys %{$cl->{all}}) {
1147        my $e = $cl->{all}->{$ymd};
1148        foreach my $i (sort {$b <=> $a} keys %$e) {
1149            next if ($i !~ /^\d/);
1150            my ($ym) = ($ymd =~ /^(\d{4}-\d\d)-\d\d/);
1151            my $h = $e->{$i}{h}.
1152                ((defined $e->{$i}{"cat"}) ?
1153                 join('', map {"[$_]"} @{$e->{$i}{"cat"}}) : "");
1154            my $c = $h."\x01".$e->{$i}{c};
1155            $c =~ s|<img.+?alt="(.*?)".*?>|[$1]|gosm;
1156            $c =~ s/[\t\n]//g;
1157            $c =~ s/&nbsp;/ /g;
1158            $c =~ s/\s\s+/ /g;
1159            $c =~ s/<.+?>//g;
1160            $c =~ s/\x01/\t/;   # Ķ ad hoc����
1161            $ostr .= datestr2anchor("[$ymd-$i]")."\t$c\n";
1162        }
1163    }
1164
1165    if (-e "$outputdir/cl.itemlist" and $stop_date != 0) { # ��ʬ����
1166        open(F, "$outputdir/cl.itemlist") or die;
1167        my $flag = 0;
1168        while (<F>) {
1169            if ($flag == 0) {
1170                (/\[(\d+)-(\d+)-(\d+)-/);
1171                my $cdate = $1 * 10000 + $2 * 100 + $3;
1172                $flag = 1 if ($stop_date > $cdate);
1173            }
1174            $ostr .= $_ if ($flag);
1175        }
1176        close F;
1177        print "update ";
1178    }
1179
1180    output_to_file("$outputdir/cl.itemlist", \$ostr);
1181}
1182
1183
1184### ���ǻ��ȥ���
1185sub datestr2anchor {
1186    my ($d) = @_;
1187    if ($page_mode == 2) {      # �����ƥ�����   $d =~ s!\[(\d{4}-\d\d-\d\d(-\d+)?)\]!<a href="$1.html">[$1]</a>!g;
1188    } elsif ($day_page_mode or $page_mode == 1) { # ��⡼��       $d =~ s!\[((\d{4}-\d\d-\d\d)(-\d+)?)\]!<a href="$2.html#$1">[$1]</a>!g;
1189    } else {                    # ������        $d =~ s!\[((\d{4}-\d\d)-\d\d(-\d+)?)\]!<a href="$2.html#$1">[$1]</a>!g;
1190    }
1191    return $d;
1192}
1193
1194sub datestr2url {
1195    my ($d) = @_;
1196    if ($page_mode == 2) {      # �����ƥ�����   $d =~ s!(\d{4}-\d\d-\d\d(-\d+)?)!$1.html!;
1197    } elsif ($day_page_mode or $page_mode ==1) { # ��⡼��        unless ($d =~ s!((\d{4}-\d\d-\d\d)-\d+)!$2.html\#$1!) {
1198            $d =~ s!(\d{4}-\d\d-\d\d)!$1.html!;
1199        }
1200    } else {                    # ������        $d =~ s!((\d{4}-\d\d)-\d\d(-\d+)?)!$2.html#$1!;
1201    }
1202    return $d;
1203}
1204
1205
1206### ʸ��������������Ū������������������y $num_of_escaped_string;
1207my %escaped_string;
1208my $num_of_escaped_src;
1209my %escaped_src;
1210my $num_of_escaped_plugin;
1211my %escaped_plugin;
1212
1213sub escape_string {
1214    my ($strp) = @_;
1215
1216    ### HTML ����������- ʸ���Τޤ�    my $btag = '_HTML_START_\n'; # ���ϥޡ���
1217    my $atag = '_HTML_END_\n'; # ��λ�ޡ���
1218    $num_of_escaped_string = 0;
1219    $$strp =~ s!$btag(.*?)$atag!
1220        $escaped_string{++$num_of_escaped_string} = $1,
1221        sprintf("\x5\x13%d\x3", $num_of_escaped_string)!gsmxe;
1222    $$strp =~ s!\[(literal|sic|esc)\](.*?)\[/\1\]!
1223        $escaped_string{++$num_of_escaped_string} = $2,
1224        sprintf("\x5\x13%d\x3", $num_of_escaped_string)!gsmxe;
1225
1226    ### ����������������- "&" ��<" �ʤɤ���� pre �����   $num_of_escaped_src = 0;
1227    $$strp =~ s!\[src\](.*?)\[/src\]!
1228        $escaped_src{++$num_of_escaped_src} = $1,
1229        $escaped_src{$num_of_escaped_src} =~ s/&/&amp;/g,
1230        $escaped_src{$num_of_escaped_src} =~ s/</&lt;/g,
1231        $escaped_src{$num_of_escaped_src} =~ s/>/&gt;/g,
1232        sprintf("\x6\x13%d\x3", $num_of_escaped_src)!gsmxe;
1233
1234    ### �ץ饰���󥨥�������    $num_of_escaped_plugin = 0;
1235    $$strp =~ s!{{(.*?)}}!
1236        $escaped_plugin{++$num_of_escaped_plugin} = $1,
1237        sprintf("\x7\x13%d\x3", $num_of_escaped_plugin)!gsmxe;
1238}
1239
1240sub unescape_string {
1241    my ($strp) = @_;
1242
1243    ### �ץ饰���󥢥󥨥�������- �¹ԡ�
1244    $$strp =~ s|\x7\x13(\d+)\x3|eval($escaped_plugin{$1})|ge;
1245    ### ���������󥨥�������- pre ���    #$$strp =~ s|\x6\x13(\d+)\x3|<pre>$escaped_src{$1}</pre>|g;
1246    $$strp =~ s|\x6\x13(\d+)\x3|</p><pre>$escaped_src{$1}</pre><p>|g;
1247    ### HTML ���󥨥�������    $$strp =~ s|\x5\x13(\d+)\x3|$escaped_string{$1}|g;
1248}
1249
1250
1251### inside referrer ������
1252sub get_inside_ref {
1253    my ($id) = @_;
1254    if (defined $inside_ref{"$id"}) {
1255        return map {datestr2anchor("[".$_."]")}
1256        (sort {$b cmp $a} keys %{$inside_ref{"$id"}});
1257    }
1258    return ();
1259}
1260
1261
1262### ���ƥ��������Υե��������
1263sub get_category_filename {
1264    my ($cn) = @_;
1265    to_utf8_cl(\$cn) if (not $utf8_mode and $cn =~ /[\x80-\xff]/);
1266    $cn =~ s/([^0-9a-z_-])/unpack('H2', $1)/gei;
1267    $cn =~ tr/A-Z/a-z/;
1268    return "cat_$cn.html";
1269}
1270
1271
1272### �����������
1273sub make_entry_header_html {
1274    my ($eh, $ymd) = @_;
1275    if ($show_day_of_week == 1) { ### ���θ�������뤫?
1276        # ��(Mon, Tue, ...)��� "2000-10-19" --> "2000-10-19 Thu"
1277        $eh .= " ".get_day_of_week($ymd);
1278    }
1279    return qq(<a name="$ymd" href="@{[datestr2url($ymd)]}">$eh</a>);
1280}
1281
1282
1283### �����ƥ��å������
1284sub make_item_header_html {
1285    my ($ih, $ymdi) = @_;
1286    # ��������
1287    my $ihb = "";
1288    if ($item_header_style == 0 or $item_header_style == 1) {
1289        $ihb = $item_header_mark;
1290        if ($use_item_anchor == 1) {
1291            my $day_url = datestr2url($ymdi);
1292            $ihb = qq(<a name="$ymdi" href="$day_url">$ihb</a>);
1293        }
1294        $ihb .= " ";
1295    }
1296
1297    # �����ǰϤ�   $ih = qq($ihb<span class="clitemheader">$ih</span>);
1298    # ���������
1299    if ($item_header_style == 0 or $item_header_style == 2) {
1300        $ih .= ":";
1301    }
1302    return $ih;
1303}
1304
1305
1306### make category link(anchor) string for item header
1307sub make_cat_link_html {
1308    my ($catp) = @_;
1309    my $catstr;
1310    if (defined $catp) {
1311        if ($output_cat_pages) {
1312            $catstr =
1313                join("", map
1314                     {"[<a href=\"".get_category_filename($_)."\">$_</a>]"}
1315                     @$catp);
1316        } elsif ($cat_page_cgi eq "") {
1317            $catstr = join("", map {"[".$_."]"} @$catp);
1318        } else {
1319            $catstr =
1320                join("", map
1321                     {my $tmp = $cat_page_cgi;
1322                      $tmp =~ s/%%CAT%%/urlencode($_)/ge;
1323                      "[<a href=\"$tmp\">$_</a>]"}
1324                     @$catp);
1325        }
1326       
1327    }
1328    return $catstr;
1329}   
1330
1331
1332### ��ꤵ�줿�ե�����ʸ�����sub output_to_file {
1333    my ($fname, $contp) = @_;
1334    $$contp =~ s/<!-- ReplaceOnce -->/$replace_once/;
1335
1336    if ($update_by_size == 1 and -s $fname == length($$contp)) {
1337        return;
1338    }
1339
1340    if ($utf8_mode) {           # ad hoc 050821
1341        $$contp =~ s/;charset=EUC-JP">/;charset=UTF-8">/;
1342    }
1343
1344    print "output to \"$fname\"\n" if (!defined $quiet_mode);
1345    open(F, "> $fname") || die "$fname: $!\n";
1346    binmode(F);
1347    print F $$contp;
1348    close(F);
1349}
1350
1351### URL ENCODE
1352sub urlencode {
1353    local ($_) = @_;
1354    s/([^ \n\.\*\-_A-Z0-9])/sprintf("%%%02lX",unpack("C",$1))/gie;
1355    s/ /+/g;
1356    return $_;
1357}
1358
1359### modularized for i18n
1360# delete content of this func,
1361# if you use utf8 file and don't use Jcode.
1362sub to_utf8_cl {
1363    my ($sp) = @_;
1364    use Jcode;
1365    $$sp = Jcode->new($$sp)->utf8;
1366}
1367
Note: See TracBrowser for help on using the browser.