1 # GotMArc was written by Omar Polo <op@openbsd.org> and is placed in
2 # the public domain. The author hereby disclaims copyright to this
12 our @ISA = qw(Exporter);
13 our @EXPORT_OK = qw(san urlencode parse initpage endpage index_header
14 thread_header threntry thrslice thrnav);
26 unless (defined($str)) {
27 my ($pkg, $file, $line) = caller 1;
28 die "bad $pkg / $file:$line";
30 $str =~ s/([^-_~.A-Za-z0-9])/sprintf("%%%2X", ord($1))/ge;
43 my ($indent, $fname, $date, $from, $subj) = $line =~ m{
44 ^([^-]*)- # the indent level
46 (\d{4}-\d\d-\d\d[ ]\d\d:\d\d) # date
49 }x or die "can't parse: $line";
51 my $level = length($indent);
52 $level = 10 if $indent =~ m/\.\.\d+\.\./;
57 my ($time, $id) = split /\./, basename($fname);
58 my $mid = "$time.$id";
60 return {level => $level, fname => $fname,
61 mid => $mid, date => $date, from => $from, subj => $subj};
67 open my $fh, "<", $path or die "can't open $path: $!";
71 my $small_logo = readall "logo-small.html";
72 my $hdr = readall "head.html";
73 my $foot = readall "foot.html";
74 my $idxhdr = readall "index-header.html";
77 my ($fh, $title) = @_;
78 say $fh $hdr =~ s/TITLE/$title/r;
87 my ($fh, $page, $subtitle) = @_;
88 my $html = $idxhdr =~ s/PAGE/$page/r;
89 $html =~ s/SUBTITLE/$subtitle/;
94 my ($fh, $e, $mail, $p, $n) = @_;
98 my $enctid = urlencode $mail->{tid} if defined $mail;
99 my $encmid = urlencode $mail->{mid} if defined $mail;
101 print $fh "<header class='mail-header'>\n";
104 print $fh $small_logo;
105 print $fh "<a href='/'>Index</a>";
106 print $fh " | <a href='/thread/$enctid.html#$encmid'>Thread</a>"
108 print $fh " | <a href='/search'>Search</a>";
112 foreach my $entry (@entries) {
113 my ($k, $v) = split /: /, $entry, 2;
115 say $fh "<dt>$k:</dt><dd>$v</dd>";
119 say $fh "<p>Download raw <a href='/text/$encmid.txt'>body</a>.</p>"
122 if (defined($p) and defined($n)) {
124 say $fh "<summary>Thread</summary>";
125 thrslice($fh, $mail, $p, $n);
126 say $fh "</details>";
127 thrnav($fh, $p, $n, $mail->{mid}, $mail->{tid});
130 say $fh "</header>\n";
134 my ($fh, $type, $base, $last_level, $mail, $cur) = @_;
135 my $level = $mail->{level} - $base;
137 say $fh "</ul></li>" x ($last_level - $level) if $last_level > $level;
138 say $fh "<li><ul>" if $last_level < $level;
140 my $encmid = urlencode $mail->{mid};
142 print $fh "<li id='$encmid' class='mail'>";
143 print $fh "<p class='mail-meta'>";
144 print $fh "<time>$mail->{date}</time> ";
145 print $fh "<span class='from'>$mail->{from}</span>";
146 print $fh "<span class='colon'>:</span>";
148 print $fh "<p class='subject'>";
150 my $subj = $mail->{subj};
151 if (!defined($cur) || $mail->{mid} ne $cur->{mid}) {
152 print $fh "<a href='/$type/$encmid.html'>$subj</a>";
154 print $fh "<span>$subj</span>";
167 $l = $_->{level} if $_->{level} < $l;
173 my ($fh, $mail, $p, $n) = @_;
176 my @thread = (@prev, $mail, @next);
177 return unless @thread;
178 my $base = min_level @thread;
180 print $fh "<div class='thread'>";
181 print $fh "<ul class='mails'>";
182 $level = threntry $fh, "mail", $base, $level, $_, $mail for @thread;
183 print $fh "</ul></li>" x $level;
184 print $fh "</ul></div>";
188 my ($fh, $p, $n) = @_;
192 return if !@prev && !@next;
196 my $mail = $prev[-1];
197 my $encmid = $mail->{mid};
198 say $fh "<a href='/mail/$encmid.html'>Previous in thread</a>";
200 say $fh "<span>Previous in thread</span>";
205 my $encmid = $mail->{mid};
206 say $fh "<a href='/mail/$encmid.html'>Next in thread</a>";
208 say $fh "<span>Next in thread</span>";