Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | ##---------------------------------------------------------------------------## |
2 | ## File: | |
3 | ## $Id: mhrcvars.pl,v 2.21 2002/07/27 05:13:13 ehood Exp $ | |
4 | ## Author: | |
5 | ## Earl Hood mhonarc@mhonarc.org | |
6 | ## Description: | |
7 | ## Defines routine for expanding resource variables. | |
8 | ##---------------------------------------------------------------------------## | |
9 | ## MHonArc -- Internet mail-to-HTML converter | |
10 | ## Copyright (C) 1996-2001 Earl Hood, mhonarc@mhonarc.org | |
11 | ## | |
12 | ## This program is free software; you can redistribute it and/or modify | |
13 | ## it under the terms of the GNU General Public License as published by | |
14 | ## the Free Software Foundation; either version 2 of the License, or | |
15 | ## (at your option) any later version. | |
16 | ## | |
17 | ## This program is distributed in the hope that it will be useful, | |
18 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | ## GNU General Public License for more details. | |
21 | ## | |
22 | ## You should have received a copy of the GNU General Public License | |
23 | ## along with this program; if not, write to the Free Software | |
24 | ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
25 | ## 02111-1307, USA | |
26 | ##---------------------------------------------------------------------------## | |
27 | ||
28 | package mhonarc; | |
29 | ||
30 | ## Mapping of old resource variables to current versions. | |
31 | my %old2new = ( | |
32 | 'FIRSTPG' => [ 'PG', 'FIRST' ], | |
33 | 'LASTPG' => [ 'PG', 'LAST' ], | |
34 | 'NEXTBUTTON' => [ 'BUTTON', 'NEXT' ], | |
35 | 'NEXTFROM' => [ 'FROM', 'NEXT' ], | |
36 | 'NEXTFROMADDR' => [ 'FROMADDR', 'NEXT' ], | |
37 | 'NEXTFROMNAME' => [ 'FROMNAME', 'NEXT' ], | |
38 | 'NEXTLINK' => [ 'LINK', 'NEXT' ], | |
39 | 'NEXTMSG' => [ 'MSG', 'NEXT' ], | |
40 | 'NEXTMSGNUM' => [ 'MSGNUM', 'NEXT' ], | |
41 | 'NEXTPG' => [ 'PG', 'NEXT' ], | |
42 | 'NEXTPGLINK' => [ 'PGLINK', 'NEXT' ], | |
43 | 'NEXTSUBJECT' => [ 'SUBJECT', 'NEXT' ], | |
44 | 'PREVBUTTON' => [ 'BUTTON', 'PREV' ], | |
45 | 'PREVFROM' => [ 'FROM', 'PREV' ], | |
46 | 'PREVFROMADDR' => [ 'FROMADDR', 'PREV' ], | |
47 | 'PREVFROMNAME' => [ 'FROMNAME', 'PREV' ], | |
48 | 'PREVLINK' => [ 'LINK', 'PREV' ], | |
49 | 'PREVMSG' => [ 'MSG', 'PREV' ], | |
50 | 'PREVMSGNUM' => [ 'MSGNUM', 'PREV' ], | |
51 | 'PREVPGLINK' => [ 'PGLINK', 'PREV' ], | |
52 | 'PREVPG' => [ 'PG', 'PREV' ], | |
53 | 'PREVSUBJECT' => [ 'SUBJECT', 'PREV' ], | |
54 | 'TFIRSTPG' => [ 'PG', 'TFIRST' ], | |
55 | 'TLASTPG' => [ 'PG', 'TLAST' ], | |
56 | 'TNEXTBUTTON' => [ 'BUTTON', 'TNEXT' ], | |
57 | 'TNEXTFROM' => [ 'FROM', 'TNEXT' ], | |
58 | 'TNEXTFROMADDR' => [ 'FROMADDR', 'TNEXT' ], | |
59 | 'TNEXTFROMNAME' => [ 'FROMNAME', 'TNEXT' ], | |
60 | 'TNEXTLINK' => [ 'LINK', 'TNEXT' ], | |
61 | 'TNEXTMSG' => [ 'MSG', 'TNEXT' ], | |
62 | 'TNEXTMSGNUM' => [ 'MSGNUM', 'TNEXT' ], | |
63 | 'TNEXTPGLINK' => [ 'PGLINK', 'TNEXT' ], | |
64 | 'TNEXTPG' => [ 'PG', 'TNEXT' ], | |
65 | 'TNEXTSUBJECT' => [ 'SUBJECT', 'TNEXT' ], | |
66 | 'TPREVBUTTON' => [ 'BUTTON', 'TPREV' ], | |
67 | 'TPREVFROM' => [ 'FROM', 'TPREV' ], | |
68 | 'TPREVFROMADDR' => [ 'FROMADDR', 'TPREV' ], | |
69 | 'TPREVFROMNAME' => [ 'FROMNAME', 'TPREV' ], | |
70 | 'TPREVLINK' => [ 'LINK', 'TPREV' ], | |
71 | 'TPREVMSG' => [ 'MSG', 'TPREV' ], | |
72 | 'TPREVMSGNUM' => [ 'MSGNUM', 'TPREV' ], | |
73 | 'TPREVPGLINK' => [ 'PGLINK', 'TPREV' ], | |
74 | 'TPREVPG' => [ 'PG', 'TPREV' ], | |
75 | 'TPREVSUBJECT' => [ 'SUBJECT', 'TPREV' ], | |
76 | ); | |
77 | ||
78 | ##--------------------------------------------------------------------------- | |
79 | ## replace_li_var() is used to substitute vars to current | |
80 | ## values. This routine relies on some variables being set by the | |
81 | ## calling routine or as globals. | |
82 | ## | |
83 | sub replace_li_var { | |
84 | my($val, $index) = ($_[0], $_[1]); | |
85 | my($var,$len,$canclip,$raw,$isurl,$tmp,$ret) = ('',0,0,0,0,'',''); | |
86 | my($jstr) = (0); | |
87 | my($expand) = (0); | |
88 | my($n) = (0); | |
89 | my($lref, $key, $pos); | |
90 | my($arg, $opt) = ("", ""); | |
91 | ||
92 | ## Get variable argument string | |
93 | if ($val =~ s/\(([^()]*)\)//) { | |
94 | $arg = $1; | |
95 | } | |
96 | ||
97 | ## Get length specifier (if defined) | |
98 | ($var, $len) = split(/:/, $val, 2); | |
99 | $len = -1 unless defined $len; | |
100 | ||
101 | ## Check for old resource variables and map to new | |
102 | ($var, $arg) = @{$old2new{$var}} if defined($old2new{$var}); | |
103 | ||
104 | ## Check if variable in a URL string | |
105 | $isurl = 1 if ($len =~ s/u//ig); | |
106 | ## Check if variable in a JavaScript string | |
107 | $jstr = 1 if ($len =~ s/j//ig); | |
108 | ||
109 | ## Do variable replacement | |
110 | REPLACESW: { | |
111 | ## Invoke callback if defined | |
112 | if (defined($CBRcVarExpand) && defined(&$CBRcVarExpand)) { | |
113 | ($tmp, $expand, $canclip) = &$CBRcVarExpand($index, $var, $arg); | |
114 | last REPLACESW if defined($tmp); | |
115 | } | |
116 | ||
117 | ## -------------------------------------- ## | |
118 | ## Message information resource variables ## | |
119 | ## -------------------------------------- ## | |
120 | if ($var eq 'DATE') { ## Message "Date:" | |
121 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
122 | $tmp = defined($key) ? $Date{$key} : ""; | |
123 | last REPLACESW; | |
124 | } | |
125 | if ($var eq 'DDMMYY' || $var eq 'DDMMYYYY' || | |
126 | $var eq 'MMDDYY' || $var eq 'MMDDYYYY' || | |
127 | $var eq 'YYMMDD' || $var eq 'YYYYMMDD') { | |
128 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
129 | $tmp = defined($key) ? | |
130 | &time2mmddyy((split(/$X/o, $key))[0], lc $var) : | |
131 | ""; | |
132 | last REPLACESW; | |
133 | } | |
134 | my($cnd1, $cnd2, $cnd3) = (0,0,0); | |
135 | if (($cnd1 = ($var eq 'FROM')) || ## Message "From:" | |
136 | ($cnd2 = ($var eq 'FROMADDR')) || ## Message from mail address | |
137 | ($cnd3 = ($var eq 'FROMNAME'))) { ## Message from name | |
138 | my $esub = $cnd1 ? sub { $_[0]; } : | |
139 | $cnd2 ? \&extract_email_address : | |
140 | \&extract_email_name; | |
141 | $canclip = 1; $raw = 1; | |
142 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
143 | $tmp = defined($key) ? &$esub($From{$key}) : "(nil)"; | |
144 | last REPLACESW; | |
145 | } | |
146 | if ( ($cnd1 = ($var eq 'FROMADDRNAME')) || | |
147 | ($cnd2 = ($var eq 'FROMADDRDOMAIN')) ) { | |
148 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
149 | if (!defined($key)) { | |
150 | $tmp = ""; | |
151 | last REPLACESW; | |
152 | } | |
153 | my @a = split(/@/, extract_email_address($From{$key}), 2); | |
154 | if ($cnd1) { | |
155 | $tmp = $a[0]; | |
156 | last REPLACESW; | |
157 | } | |
158 | $tmp = defined($a[1]) ? $a[1] : ""; | |
159 | last REPLACESW; | |
160 | } | |
161 | if ($var eq 'ICON') { ## Message icon | |
162 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
163 | if (!defined($key)) { | |
164 | $tmp = ""; | |
165 | last REPLACESW; | |
166 | } | |
167 | my($iconurl, $iw, $ih) = mhonarc::get_icon_url($ContentType{$key}); | |
168 | my $alttext = $iconurl ? $ContentType{$key} : 'unknown'; | |
169 | $tmp = qq|<img src="$iconurl" border="0" alt="[$alttext]"|; | |
170 | $tmp .= ' width="' . $iw . '"' if $iw; | |
171 | $tmp .= ' height="' . $ih . '"' if $ih; | |
172 | $tmp .= '>'; | |
173 | last REPLACESW; | |
174 | } | |
175 | if ($var eq 'ICONURL') { ## URL to message icon | |
176 | $isurl = 0; | |
177 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
178 | my($iconurl, $iw, $ih) = mhonarc::get_icon_url($ContentType{$key}); | |
179 | $tmp = $iconurl if defined($iconurl); | |
180 | last REPLACESW; | |
181 | } | |
182 | if ($var eq 'MSG') { ## Filename of message page | |
183 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
184 | $tmp = defined($key) ? &msgnum_filename($IndexNum{$key}) : ""; | |
185 | last REPLACESW; | |
186 | } | |
187 | if ($var eq 'MSGGMTDATE') { ## Message GMT date | |
188 | ($lref, $key, $pos, $opt) = compute_msg_pos($index, $var, $arg); | |
189 | $tmp = &time2str($opt || $MsgGMTDateFmt, | |
190 | &get_time_from_index($key), 0); | |
191 | last REPLACESW; | |
192 | } | |
193 | if ($var eq 'MSGID') { ## Message-ID | |
194 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
195 | $tmp = defined($key) ? $Index2MsgId{$key} : ""; | |
196 | last REPLACESW; | |
197 | } | |
198 | if ($var eq 'MSGLOCALDATE') { ## Message local date | |
199 | ($lref, $key, $pos, $opt) = compute_msg_pos($index, $var, $arg); | |
200 | $tmp = &time2str($opt || $MsgLocalDateFmt, | |
201 | &get_time_from_index($key), 1); | |
202 | last REPLACESW; | |
203 | } | |
204 | if ($var eq 'MSGNUM') { ## Message number | |
205 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
206 | $tmp = defined($key) ? &fmt_msgnum($IndexNum{$key}) : ""; | |
207 | last REPLACESW; | |
208 | } | |
209 | if ($var eq 'MSGTORDNUM') { ## Message ordinal num in cur thread | |
210 | # Some form of optimization should be done here since | |
211 | # computation can degrade to n^2 (where n is size of thread) | |
212 | # if variable is referenced for each message on thread index | |
213 | # page. | |
214 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg, 1); | |
215 | $tmp = 1; | |
216 | my $level = $ThreadLevel{$key}; | |
217 | for (--$pos ; ($level > 0) && ($pos >= 0); --$pos, ++$tmp ) { | |
218 | $level = $ThreadLevel{$TListOrder[$pos]}; | |
219 | } | |
220 | last REPLACESW; | |
221 | } | |
222 | if ($var eq 'NOTE') { ## Annotation template markup | |
223 | $expand = 1; | |
224 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
225 | $tmp = note_exists($key) ? $NOTE : $NOTEIA; | |
226 | last REPLACESW; | |
227 | } | |
228 | if ($var eq 'NOTEICON') { ## Annotation ICON (HTML markup) | |
229 | $expand = 1; | |
230 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
231 | $tmp = note_exists($key) ? $NOTEICON : $NOTEICONIA; | |
232 | last REPLACESW; | |
233 | } | |
234 | if ($var eq 'NOTETEXT') { ## Annotation text | |
235 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
236 | $tmp = get_note($key); | |
237 | last REPLACESW; | |
238 | } | |
239 | if ($var eq 'NUMFOLUP') { ## Number of explicit follow-ups | |
240 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
241 | $tmp = defined($key) ? $FolCnt{$key} : ""; | |
242 | last REPLACESW; | |
243 | } | |
244 | if ($var eq 'ORDNUM') { ## Sort order number of message | |
245 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
246 | $tmp = defined($key) ? $pos+1 : -1; | |
247 | last REPLACESW; | |
248 | } | |
249 | if ($var eq 'SUBJECT') { ## Message subject | |
250 | $canclip = 1; $raw = 1; $isurl = 0; | |
251 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
252 | if (defined($key)) { | |
253 | $tmp = $Subject{$key}; | |
254 | $tmp = $NoSubjectTxt if $tmp eq ""; | |
255 | } else { | |
256 | $tmp = ""; | |
257 | } | |
258 | last REPLACESW; | |
259 | } | |
260 | if ($var eq 'SUBJECTNA') { ## Message subject (not linked) | |
261 | $canclip = 1; $raw = 1; | |
262 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
263 | if (defined($key)) { | |
264 | $tmp = $Subject{$key}; | |
265 | $tmp = $NoSubjectTxt if $tmp eq ""; | |
266 | } else { | |
267 | $tmp = ""; | |
268 | } | |
269 | last REPLACESW; | |
270 | } | |
271 | if ($var eq 'TLEVEL') { ## Thread level | |
272 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
273 | $tmp = $ThreadLevel{$key}; | |
274 | last REPLACESW; | |
275 | } | |
276 | ||
277 | ## ------------------------------------- ## | |
278 | ## Message navigation resource variables ## | |
279 | ## ------------------------------------- ## | |
280 | if ($var eq 'BUTTON') { | |
281 | $expand = 1; | |
282 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
283 | SW: { | |
284 | if ($arg eq 'NEXT') { | |
285 | $tmp = defined($key) ? $NEXTBUTTON : $NEXTBUTTONIA; | |
286 | last SW; } | |
287 | if ($arg eq 'PREV') { | |
288 | $tmp = defined($key) ? $PREVBUTTON : $PREVBUTTONIA; | |
289 | last SW; } | |
290 | if ($arg eq 'TNEXT') { | |
291 | $tmp = defined($key) ? $TNEXTBUTTON : $TNEXTBUTTONIA; | |
292 | last SW; } | |
293 | if ($arg eq 'TPREV') { | |
294 | $tmp = defined($key) ? $TPREVBUTTON : $TPREVBUTTONIA; | |
295 | last SW; } | |
296 | if ($arg eq 'TNEXTIN') { | |
297 | $tmp = defined($key) ? $TNEXTINBUTTON : $TNEXTINBUTTONIA; | |
298 | last SW; } | |
299 | if ($arg eq 'TPREVIN') { | |
300 | $tmp = defined($key) ? $TPREVINBUTTON : $TPREVINBUTTONIA; | |
301 | last SW; } | |
302 | if ($arg eq 'TNEXTTOP') { | |
303 | $tmp = defined($key) ? $TNEXTTOPBUTTON : $TNEXTTOPBUTTONIA; | |
304 | last SW; } | |
305 | if ($arg eq 'TPREVTOP') { | |
306 | $tmp = defined($key) ? $TPREVTOPBUTTON : $TPREVTOPBUTTONIA; | |
307 | last SW; } | |
308 | } | |
309 | last REPLACESW; | |
310 | } | |
311 | if ($var eq 'LINK') { | |
312 | $expand = 1; | |
313 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
314 | SW: { | |
315 | if ($arg eq 'NEXT') { | |
316 | $tmp = defined($key) ? $NEXTLINK : $NEXTLINKIA; | |
317 | last SW; } | |
318 | if ($arg eq 'PREV') { | |
319 | $tmp = defined($key) ? $PREVLINK : $PREVLINKIA; | |
320 | last SW; } | |
321 | if ($arg eq 'TNEXT') { | |
322 | $tmp = defined($key) ? $TNEXTLINK : $TNEXTLINKIA; | |
323 | last SW; } | |
324 | if ($arg eq 'TPREV') { | |
325 | $tmp = defined($key) ? $TPREVLINK : $TPREVLINKIA; | |
326 | last SW; } | |
327 | if ($arg eq 'TNEXTIN') { | |
328 | $tmp = defined($key) ? $TNEXTINLINK : $TNEXTINLINKIA; | |
329 | last SW; } | |
330 | if ($arg eq 'TPREVIN') { | |
331 | $tmp = defined($key) ? $TPREVINLINK : $TPREVINLINKIA; | |
332 | last SW; } | |
333 | if ($arg eq 'TNEXTTOP') { | |
334 | $tmp = defined($key) ? $TNEXTTOPLINK : $TNEXTTOPLINKIA; | |
335 | last SW; } | |
336 | if ($arg eq 'TPREVTOP') { | |
337 | $tmp = defined($key) ? $TPREVTOPLINK : $TPREVTOPLINKIA; | |
338 | last SW; } | |
339 | } | |
340 | last REPLACESW; | |
341 | } | |
342 | ||
343 | if ($var eq 'TSLICE') { | |
344 | my($bcnt, $acnt, $inclusive); | |
345 | if ($arg) { | |
346 | ($bcnt, $acnt, $inclusive) = split(/[;:]/, $arg); | |
347 | $bcnt = $TSliceNBefore if (!defined($bcnt) || $bcnt !~ /^\d+$/); | |
348 | $acnt = $TSliceNAfter if (!defined($acnt) || $acnt !~ /^\d+$/); | |
349 | $inclusive = $TSliceInclusive if (!defined($inclusive)); | |
350 | } else { | |
351 | $bcnt = $TSliceNBefore; | |
352 | $acnt = $TSliceNAfter; | |
353 | $inclusive = $TSliceInclusive; | |
354 | } | |
355 | $tmp = &make_thread_slice($index, $bcnt, $acnt, $inclusive) | |
356 | if ($bcnt != 0 || $acnt != 0); | |
357 | last REPLACESW; | |
358 | } | |
359 | ||
360 | ## -------------------------------- ## | |
361 | ## Index related resource variables ## | |
362 | ## -------------------------------- ## | |
363 | if ($var eq 'A_ATTR') { ## Anchor attrs to link to message | |
364 | $isurl = 0; | |
365 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
366 | if (!defined($key)) { $tmp = ""; last REPLACESW; } | |
367 | $tmp = qq/name="/ . &fmt_msgnum($IndexNum{$key}) . | |
368 | qq/" href="/ . | |
369 | &msgnum_filename($IndexNum{$key}) . | |
370 | qq/"/; | |
371 | last REPLACESW; | |
372 | } | |
373 | if ($var eq 'A_NAME') { ## Anchor name for message position | |
374 | $isurl = 0; | |
375 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
376 | if (!defined($key)) { $tmp = ""; last REPLACESW; } | |
377 | $tmp = qq/name="/ . &fmt_msgnum($IndexNum{$key}) . qq/"/; | |
378 | last REPLACESW; | |
379 | } | |
380 | if ($var eq 'A_HREF') { ## Anchor href to link to message | |
381 | $isurl = 0; | |
382 | ($lref, $key, $pos) = compute_msg_pos($index, $var, $arg); | |
383 | if (!defined($key)) { $tmp = ""; last REPLACESW; } | |
384 | $tmp = qq/href="/ . &msgnum_filename($IndexNum{$key}) . qq/"/; | |
385 | last REPLACESW; | |
386 | } | |
387 | if ($var eq 'IDXFNAME') { ## Filename of index page | |
388 | if ($MULTIIDX && ($n = int($Index2MLoc{$index}/$IDXSIZE)+1) > 1) { | |
389 | $tmp = sprintf("%s%d.$HtmlExt", | |
390 | $IDXPREFIX, $index ne '' ? $n : 1); | |
391 | } else { | |
392 | $tmp = $IDXNAME; | |
393 | } | |
394 | $tmp .= ".gz" if $GzipLinks; | |
395 | last REPLACESW; | |
396 | } | |
397 | if ($var eq 'IDXLABEL') { ## Label for main index | |
398 | $tmp = $IDXLABEL; | |
399 | last REPLACESW; | |
400 | } | |
401 | if ($var eq 'IDXSIZE') { ## Index page size | |
402 | $tmp = $IDXSIZE; | |
403 | last REPLACESW; | |
404 | } | |
405 | if ($var eq 'IDXTITLE') { ## Main index title | |
406 | $canclip = 1; $expand = 1; | |
407 | $tmp = $TITLE; | |
408 | last REPLACESW; | |
409 | } | |
410 | if ($var eq 'NUMOFIDXMSG') { ## Number of items on the index page | |
411 | $tmp = $PageSize; | |
412 | last REPLACESW; | |
413 | } | |
414 | if ($var eq 'NUMOFMSG') { ## Total number of messages | |
415 | $tmp = $NumOfMsgs; | |
416 | last REPLACESW; | |
417 | } | |
418 | if ($var eq 'SORTTYPE') { ## Sort type of index | |
419 | SORTTYPE: { | |
420 | if ($NOSORT) { $tmp = 'Number'; last SORTTYPE; } | |
421 | if ($AUTHSORT) { $tmp = 'Author'; last SORTTYPE; } | |
422 | if ($SUBSORT) { $tmp = 'Subject'; last SORTTYPE; } | |
423 | $tmp = 'Date'; | |
424 | last SORTTYPE; | |
425 | } | |
426 | last REPLACESW; | |
427 | } | |
428 | if ($var eq 'TIDXFNAME') { | |
429 | if ($MULTIIDX && ($n = int($Index2TLoc{$index}/$IDXSIZE)+1) > 1) { | |
430 | $tmp = sprintf("%s%d.$HtmlExt", | |
431 | $TIDXPREFIX, $index ne '' ? $n : 1); | |
432 | } else { | |
433 | $tmp = $TIDXNAME; | |
434 | } | |
435 | $tmp .= ".gz" if $GzipLinks; | |
436 | last REPLACESW; | |
437 | } | |
438 | if ($var eq 'TIDXLABEL') { | |
439 | $tmp = $TIDXLABEL; | |
440 | last REPLACESW; | |
441 | } | |
442 | if ($var eq 'TIDXTITLE') { | |
443 | $canclip = 1; $expand = 1; | |
444 | $tmp = $TTITLE; | |
445 | last REPLACESW; | |
446 | } | |
447 | if ($var eq 'TSORTTYPE') { | |
448 | TSORTTYPE: { | |
449 | if ($TNOSORT) { $tmp = 'Number'; last TSORTTYPE; } | |
450 | if ($TSUBSORT) { $tmp = 'Subject'; last TSORTTYPE; } | |
451 | $tmp = 'Date'; | |
452 | last TSORTTYPE; | |
453 | } | |
454 | last REPLACESW; | |
455 | } | |
456 | ||
457 | if ($var eq 'PGLINK') { | |
458 | $expand = 1; | |
459 | SW: { | |
460 | if ($arg eq 'NEXT') { | |
461 | $tmp = $PageNum < $NumOfPages ? | |
462 | $NEXTPGLINK : $NEXTPGLINKIA; | |
463 | last SW; } | |
464 | if ($arg eq 'PREV') { | |
465 | $tmp = $PageNum > 1 ? $PREVPGLINK : $PREVPGLINKIA; | |
466 | last SW; } | |
467 | if ($arg eq 'TNEXT') { | |
468 | $tmp = $PageNum < $NumOfPages ? | |
469 | $TNEXTPGLINK : $TNEXTPGLINKIA; | |
470 | last SW; } | |
471 | if ($arg eq 'TPREV') { | |
472 | $tmp = $PageNum > 1 ? $TPREVPGLINK : $TPREVPGLINKIA; | |
473 | last SW; } | |
474 | if ($arg eq 'FIRST') { | |
475 | $tmp = $FIRSTPGLINK; | |
476 | last SW; } | |
477 | if ($arg eq 'LAST') { | |
478 | $tmp = $LASTPGLINK; | |
479 | last SW; } | |
480 | if ($arg eq 'TFIRST') { | |
481 | $tmp = $TFIRSTPGLINK; | |
482 | last SW; } | |
483 | if ($arg eq 'TLAST') { | |
484 | $tmp = $TLASTPGLINK; | |
485 | last SW; } | |
486 | } | |
487 | last REPLACESW; | |
488 | } | |
489 | if ($var eq 'PGLINKLIST') { | |
490 | my $num = $PageNum; | |
491 | my $t = $arg =~ s/T//gi; | |
492 | my($before, $after) = split(/;/, $arg); | |
493 | my $prefix = $t ? $TIDXPREFIX : $IDXPREFIX; | |
494 | my $suffix = $HtmlExt; | |
495 | $suffix .= '.gz' if $GzipLinks; | |
496 | if ($before ne "") { | |
497 | $before = $num - abs($before); | |
498 | $before = 1 unless $before > 1; | |
499 | } else { | |
500 | $before = 1; | |
501 | } | |
502 | if ($after ne "") { | |
503 | $after = $num + abs($after); | |
504 | $after = $NumOfPages unless $after < $NumOfPages; | |
505 | } else { | |
506 | $after = $NumOfPages; | |
507 | } | |
508 | $tmp = ""; | |
509 | for ($i=$before; $i < $num; ++$i) { | |
510 | if ($i == 1) { | |
511 | $tmp .= sprintf('<a href="%s%s">%d</a> | ', | |
512 | ($t ? $TIDXNAME : $IDXNAME), | |
513 | ($GzipLinks ? '.gz' : ""), $i); | |
514 | next; | |
515 | } | |
516 | $tmp .= sprintf('<a href="%s%d.%s">%d</a> | ', | |
517 | $prefix, $i, $suffix, $i); | |
518 | } | |
519 | $tmp .= $num; | |
520 | for ($i=$num+1; $i <= $after; ++$i) { | |
521 | $tmp .= sprintf(' | <a href="%s%d.%s">%d</a>', | |
522 | $prefix, $i, $suffix, $i); | |
523 | } | |
524 | last REPLACESW; | |
525 | } | |
526 | ||
527 | if ($var eq 'PAGENUM') { | |
528 | $tmp = $PageNum; | |
529 | last REPLACESW; | |
530 | } | |
531 | if ($var eq 'NUMOFPAGES') { | |
532 | $tmp = $NumOfPages; | |
533 | last REPLACESW; | |
534 | } | |
535 | ||
536 | if ($var eq 'PG') { | |
537 | my $num = $PageNum; | |
538 | my $t = ($arg =~ s/^T//); | |
539 | my $prefix = $t ? $TIDXPREFIX : $IDXPREFIX; | |
540 | SW: { | |
541 | if ($arg eq 'NEXT') { $num = $PageNum+1; last SW; } | |
542 | if ($arg eq 'PREV') { $num = $PageNum-1; last SW; } | |
543 | if ($arg eq 'FIRST') { $num = 0; last SW; } | |
544 | if ($arg eq 'LAST') { $num = $NumOfPages; last SW; } | |
545 | if ($arg =~ /^-?\d+$/) { $num = $PageNum+$arg; last SW; } | |
546 | } | |
547 | if ($num < 2) { | |
548 | $tmp = $t ? $TIDXNAME : $IDXNAME; | |
549 | } else { | |
550 | $num = $NumOfPages if $num > $NumOfPages; | |
551 | $tmp = sprintf("%s%d.$HtmlExt", $prefix, $num); | |
552 | } | |
553 | $tmp .= ".gz" if $GzipLinks; | |
554 | last REPLACESW; | |
555 | } | |
556 | ||
557 | ## -------------------------------- ## | |
558 | ## Miscellaneous resource variables ## | |
559 | ## -------------------------------- ## | |
560 | if ($var eq 'DOCURL') { | |
561 | $isurl = 0; | |
562 | $tmp = $DOCURL; | |
563 | last REPLACESW; | |
564 | } | |
565 | if ($var eq 'ENV') { | |
566 | $tmp = htmlize($ENV{$arg}); | |
567 | last REPLACESW; | |
568 | } | |
569 | if ($var eq 'GMTDATE') { | |
570 | $tmp = &time2str($arg || $GMTDateFmt, time, 0); | |
571 | last REPLACESW; | |
572 | } | |
573 | if ($var eq 'HTMLEXT') { | |
574 | $tmp = $HtmlExt; | |
575 | last REPLACESW; | |
576 | } | |
577 | if ($var eq 'IDXPREFIX') { | |
578 | $tmp = $IDXPREFIX; | |
579 | last REPLACESW; | |
580 | } | |
581 | if ($var eq 'LOCALDATE') { | |
582 | $tmp = &time2str($arg || $LocalDateFmt, time, 1); | |
583 | last REPLACESW; | |
584 | } | |
585 | if ($var eq 'MSGPREFIX') { | |
586 | $tmp = $MsgPrefix; | |
587 | last REPLACESW; | |
588 | } | |
589 | if ($var eq 'OUTDIR') { | |
590 | $tmp = $OUTDIR; | |
591 | last REPLACESW; | |
592 | } | |
593 | if ($var eq 'PROG') { | |
594 | $tmp = $PROG; | |
595 | last REPLACESW; | |
596 | } | |
597 | if ($var eq 'TIDXPREFIX') { | |
598 | $tmp = $TIDXPREFIX; | |
599 | last REPLACESW; | |
600 | } | |
601 | if ($var eq 'VERSION') { | |
602 | $tmp = $VERSION; | |
603 | last REPLACESW; | |
604 | } | |
605 | if ($var eq '') { | |
606 | $tmp = '$'; | |
607 | last REPLACESW; | |
608 | } | |
609 | ||
610 | ## --------------------------- ## | |
611 | ## User defined variable check ## | |
612 | ## --------------------------- ## | |
613 | if (defined($CustomRcVars{$var})) { | |
614 | $expand = 1; | |
615 | $tmp = $CustomRcVars{$var}; | |
616 | last REPLACESW; | |
617 | } | |
618 | ||
619 | warn qq/Warning: Unrecognized variable: "$val"\n/; | |
620 | return "\$$val\$"; | |
621 | } | |
622 | ||
623 | ## Check if string needs to be expanded again | |
624 | if ($expand) { | |
625 | $tmp =~ s/$VarExp/&replace_li_var($1,$index)/geo; | |
626 | } | |
627 | ||
628 | ## Check if URL text specifier is set | |
629 | if ($isurl) { | |
630 | $ret = &urlize($tmp); | |
631 | ||
632 | } else { | |
633 | if ($raw) { | |
634 | $ret = &$MHeadCnvFunc($tmp); | |
635 | } else { | |
636 | $ret = $tmp; | |
637 | } | |
638 | ||
639 | # Check for clipping | |
640 | if ($len > 0 && $canclip && (length($ret) > 0)) { | |
641 | $ret = &$TextClipFunc($ret, $len, 1); | |
642 | } | |
643 | ||
644 | # Check if JavaScript string | |
645 | if ($jstr) { | |
646 | $ret =~ s/\\/\\\\/g; # escape backslashes | |
647 | $ret =~ s/(["'])/\\$1/g; # escape quotes | |
648 | $ret =~ s/\n/\\n/g; # escape newlines | |
649 | $ret =~ s/\r/\\r/g; # escape returns | |
650 | } | |
651 | } | |
652 | ||
653 | ## Check for subject link | |
654 | $ret = qq|<a name="| . | |
655 | &fmt_msgnum($IndexNum{$index}) . | |
656 | qq|" href="| . | |
657 | &msgnum_filename($IndexNum{$index}) . | |
658 | qq|">$ret</a>| | |
659 | if $var eq 'SUBJECT' && $arg eq ""; | |
660 | ||
661 | $ret; | |
662 | } | |
663 | ||
664 | ##---------------------------------------------------------------------------## | |
665 | ## compute_msg_pos(): Get message location data. | |
666 | ## Return: | |
667 | ## ($aref, : Reference to message listing array. | |
668 | ## $key, : Message index key | |
669 | ## $pos, : Integer offset location in $aref | |
670 | ## $opt) : Left-over option string | |
671 | ## $key will be undefined and $post will be set to -1 if message | |
672 | ## position cannot be computed or is out-of-bounds. | |
673 | ## | |
674 | sub compute_msg_pos { | |
675 | my($idx, $var, $arg, $usethread) = @_; | |
676 | my($ofs, $pos, $aref, $href, $key); | |
677 | my $opt = undef; | |
678 | my $flip = 0; | |
679 | my $orgarg = $arg; | |
680 | ||
681 | ## Determine what list type | |
682 | if (($arg =~ s/^T//) || $usethread) { | |
683 | $aref = \@TListOrder; | |
684 | $href = \%Index2TLoc; | |
685 | $usethread = 1; | |
686 | } else { | |
687 | $aref = \@MListOrder; | |
688 | $href = \%Index2MLoc; | |
689 | $flip = $REVSORT; | |
690 | } | |
691 | ||
692 | ## Extract out optional data | |
693 | ($arg, $opt) = split(/;/, $arg, 2); | |
694 | ||
695 | SW: { | |
696 | if ($usethread && $TREVERSE) { | |
697 | # when threads are listed in reverse, we preserve the | |
698 | # sematics of "next/prev thread" | |
699 | if ($arg eq 'NEXTTOP') { | |
700 | $arg = 'PREVTOP'; | |
701 | } elsif ($arg eq 'PREVTOP') { | |
702 | $arg = 'NEXTTOP'; | |
703 | } | |
704 | } | |
705 | ||
706 | $ofs = 0, last SW | |
707 | if (!defined($arg)) || ($arg eq '') || ($arg eq 'CUR'); | |
708 | $ofs = ($flip ? -$arg : $arg), last SW | |
709 | if $arg =~ /^-?\d+$/; | |
710 | ||
711 | if ($arg eq 'NEXT') { # next message | |
712 | if (!$usethread || !$TREVERSE) { | |
713 | $ofs = ($flip ? -1 : 1); | |
714 | last SW; | |
715 | } | |
716 | # get here, it is thread and reverse | |
717 | undef $ofs; | |
718 | $pos = $href->{$idx}; | |
719 | if (($pos < $#$aref) && ($ThreadLevel{$aref->[$pos+1]} > 0)) { | |
720 | ++$pos; | |
721 | last SW; | |
722 | } | |
723 | # get here, must goto physical previous top | |
724 | # note no `last SW' statement | |
725 | $arg = 'PREVTOP'; | |
726 | } | |
727 | if ($arg eq 'PREV') { # prev message | |
728 | if (!$usethread || !$TREVERSE) { | |
729 | $ofs = ($flip ? 1 : -1); | |
730 | last SW; | |
731 | } | |
732 | # get here, it is thread and reverse | |
733 | undef $ofs; | |
734 | if ($ThreadLevel{$idx} > 0) { | |
735 | $pos = $href->{$idx}; | |
736 | if (($pos > 0) && ($ThreadLevel{$aref->[$pos-1]} >= 0)) { | |
737 | --$pos; | |
738 | last SW; | |
739 | } | |
740 | } | |
741 | # get here, must goto physical next top | |
742 | # note no `last SW' statement | |
743 | $arg = 'NEXTTOP'; | |
744 | } | |
745 | if ($arg eq 'FIRST') { | |
746 | $pos = $flip ? $#$aref : 0; | |
747 | undef $ofs; | |
748 | last SW; | |
749 | } | |
750 | if ($arg eq 'LAST') { | |
751 | $pos = $flip ? 0 : $#$aref; | |
752 | undef $ofs; | |
753 | last SW; | |
754 | } | |
755 | ||
756 | # if not thread variable, no more checking | |
757 | if (!$usethread) { | |
758 | warn qq/Warning: $var: Invalid variable argument: "$orgarg"\n/; | |
759 | $ofs = 0; | |
760 | last SW; | |
761 | } | |
762 | ||
763 | if ($arg eq 'NEXTIN') { # next message within a thread | |
764 | $pos = $href->{$idx} + 1; | |
765 | if ($pos > $#$aref || $ThreadLevel{$aref->[$pos]} <= 0) { | |
766 | $pos = -1; | |
767 | } | |
768 | undef $ofs; | |
769 | last SW; | |
770 | } | |
771 | if ($arg eq 'PREVIN') { # previous message within a thread | |
772 | undef $ofs; | |
773 | $pos = $href->{$idx}; | |
774 | if ($ThreadLevel{$aref->[$pos]} <= 0) { | |
775 | $pos = -1; | |
776 | last SW; | |
777 | } | |
778 | --$pos; | |
779 | $pos = -1 if ($pos < 0); | |
780 | last SW; | |
781 | } | |
782 | if ($arg eq 'PARENT') { # parent message in thread | |
783 | undef $ofs; | |
784 | my $level = $ThreadLevel{$idx}; | |
785 | $pos = $Index2TLoc{$idx}; | |
786 | last SW if ($level <= 0); | |
787 | for (--$pos; $pos >= 0; --$pos) { | |
788 | last if $ThreadLevel{$aref->[$pos]} < $level; | |
789 | } | |
790 | last SW; | |
791 | } | |
792 | if ($arg eq 'TOP') { | |
793 | undef $ofs; | |
794 | $pos = $Index2TLoc{$idx}; | |
795 | for (; $pos >= 0; --$pos) { | |
796 | last if $ThreadLevel{$aref->[$pos]} <= 0; | |
797 | } | |
798 | last SW; | |
799 | } | |
800 | if (($arg eq 'NEXTTOP') ){ # start of next thread | |
801 | undef $ofs; | |
802 | $pos = $Index2TLoc{$idx}; | |
803 | for (++$pos; $pos <= $#$aref; ++$pos) { | |
804 | last if $ThreadLevel{$aref->[$pos]} <= 0; | |
805 | } | |
806 | last SW; | |
807 | } | |
808 | if (($arg eq 'PREVTOP') ){ # start of previous thread | |
809 | undef $ofs; | |
810 | # Find current top first, then find previous top | |
811 | for ($pos = $Index2TLoc{$idx}; $pos >= 0; --$pos) { | |
812 | last if $ThreadLevel{$aref->[$pos]} <= 0; | |
813 | } | |
814 | if ($pos >= 0) { | |
815 | for (--$pos; $pos >= 0; --$pos) { | |
816 | last if $ThreadLevel{$aref->[$pos]} <= 0; | |
817 | } | |
818 | } | |
819 | last SW; | |
820 | } | |
821 | if ($arg eq 'END') { # last message of thread | |
822 | undef $ofs; | |
823 | $pos = $Index2TLoc{$idx}; | |
824 | for (; $pos < $#$aref; ++$pos) { | |
825 | last if $ThreadLevel{$aref->[$pos+1]} <= 0; | |
826 | } | |
827 | last SW; | |
828 | } | |
829 | ||
830 | warn qq/Warning: $var: Unrecognized variable argument: "$orgarg"\n/; | |
831 | $ofs = 0; | |
832 | } | |
833 | $pos = $href->{$idx} + $ofs if defined($ofs); | |
834 | if (($pos > $#$aref) || ($pos < 0)) { | |
835 | $pos = -1; | |
836 | $key = undef; | |
837 | } else { | |
838 | $key = $aref->[$pos]; | |
839 | } | |
840 | ||
841 | ($aref, $key, $pos, $opt); | |
842 | } | |
843 | ||
844 | ##---------------------------------------------------------------------------## | |
845 | 1; |