Annotation of htdocs/list2html.pl, Revision 1.97
1.1 abs 1: #!/usr/bin/env perl
2: #
1.97 ! kano 3: # $NetBSD: list2html.pl,v 1.96 2004/10/30 22:33:23 jschauma Exp $
1.3 abs 4: # Process *.list files into indexed *.html files. (abs)
1.1 abs 5: # Looks for these compulsary tags:
6: # <LIST> Include generated list of entries here.
1.28 abs 7: # <SECTION>Text Introduces new section
1.39 abs 8: # </LIST> Mark end of all special entries
1.1 abs 9: #
1.3 abs 10: # Plus these optional tags: (You will probably want to use <DATE> or <ENTRY>)
1.2 abs 11: # <DATE>tag date Text Change entry, expanded to title & added to list
12: # <ENTRY>tag Text New entry, expanded to title and added to list
1.58 dent 13: # <LISTLINK>url Text Link added to list, removed from main text
14: # <ENTRYLINK>url Text Link added to list and main text
1.1 abs 15: # <HEADING>Text Standard heading at top of document
1.51 dent 16: # <DEVHEADING>Text Standard heading at top of developer docs
1.11 abs 17: # <TROW>Text: Text Table row, with two text fields
1.39 abs 18: # NOTE: <TROW> will automatically continue
19: # until a link containing </table>
20: # <HOMELINK> Add flag link to NetBSD home page
21: # <DOCLINK> Add flag links to NetBSD home page & docs top
1.40 abs 22: # <DEVLINK> Add flag links to NetBSD home page & developers
1.47 dent 23: # <PORTLINK> Add flag links to NetBSD home page & ports top
1.48 dent 24: # <GALLINK> Add flag links to NetBSD home page & gallery
1.1 abs 25: # Continuation lines are understood (useful for the special tags)
1.6 abs 26: #
27: # Additional links:
1.34 abs 28: # ([\w.+]+)\((\d)\) -> manpages eg: ls(1)
29: # <([-\w.]+@[-\w.]+)> -> email address eg: <user@host>
30: # <PKGSRC>category/name -> link to pkgsrc README.html
1.36 abs 31: # <CURRENTSRC>path -> link to source file/dir in -current
1.38 abs 32: # <URL>[^\s<]+[^<\s.] -> Insert link to URL
1.61 itojun 33: # <RFC>RFC[0-9]+ -> link to RFC (www.normos.org)
1.36 abs 34: #
1.71 dent 35: # ([a-zA-Z_][-\w.+]*[\w+])\((\d)(|\.(\w+))(|\+(\W+))\)
36: # -> man pages: Default collection is NetBSD-current.
37: # Available collections are "1.3.3",
1.74 dent 38: # "1.4.3", "1.5", "1.5.1", "current"
1.71 dent 39: #
40: # Usage examples: ls(1), ls(1.i386)
41: # ls(1+1.4.3), ls(1.i386+1.4.3)
42: #
1.36 abs 43: # NOTE: Update htdocs/developers/htdocs.list when adding features.
1.9 abs 44: #
1.35 abs 45: # (c) 1999, 2000 DKBrownlee. All rights reserved. This file may be used to
46: # update the information on the NetBSD website. If you want to use it
47: # for any other purpose, ask me first.. abs@mono.org
1.9 abs 48: #
1.1 abs 49:
50: use strict;
1.92 grant 51: use File::Basename;
1.21 abs 52: use Getopt::Std;
1.67 dent 53: use Text::Wrap;
54: $Text::Wrap::columns = 45;
1.42 abs 55: $^W = 1;
1.79 abs 56: umask 022;
1.43 abs 57: my($verbose, %extras, $months_previous, $list_date_links);
1.42 abs 58: my($version, %opt, %pkgname);
1.90 jschauma 59: my(%months) = ('Jan' => 1, 'Feb' => 2, 'Mar' => 3,
60: 'Apr' => 4, 'May' => 5, 'Jun' => 6,
61: 'Jul' => 7, 'Aug' => 8, 'Sep' => 9,
62: 'Oct' => 10, 'Nov' => 11, 'Dec' => 12 );
63:
1.31 abs 64:
65: # List of pkgsrc names to 'human preferred' forms
66: %pkgname = qw(kde KDE gimp GIMP gnome GNOME xsane XSane);
1.1 abs 67:
1.75 hubertf 68: $months_previous = 13; # Previous months to display for DATE entries
1.68 dent 69: $list_date_links = 8; # List the first N date entries on stdout
1.8 abs 70:
1.97 ! kano 71: $version = '$Revision: 1.96 $';
1.42 abs 72: $version =~ /([\d.]+)/ && ($version = $1);
1.5 abs 73:
1.93 grant 74: if (!&getopts('a:c:dm:qhV', \%opt) || $opt{'h'} || ( !$opt{'V'} && @ARGV != 2) )
1.5 abs 75: {
76: print "list2html.pl [opts] infile outfile
77: [opts] -a xxx Define 'arch=xxx' when linking to manpages
1.66 kim 78: -c xxx Define 'collection=xxx' when linking to manpages
1.80 grant 79: -d Supress listing of first N date entries on stdout
1.8 abs 80: -m xxx Set months to display for <DATE> (default $months_previous)
1.93 grant 81: -q Suppress all output except errors
1.5 abs 82: -h This help.
1.21 abs 83: -V Display version and exit ($version - David Brownlee/abs)
1.5 abs 84:
1.25 abs 85: list2html.pl processes .list files into .html, parsing various special tags.
1.5 abs 86: .list files are intended to reduce the effort required to maintain files such
87: as FAQs, and change logs. More details given at the start of list2html.pl.
88: ";
89: exit;
90: }
1.21 abs 91: if ($opt{'V'})
92: { print "$version\n"; exit; }
1.5 abs 93:
1.21 abs 94: if ($opt{'m'})
1.42 abs 95: { $months_previous = $opt{'m'}; }
96: $months_previous = &get_minmonth($months_previous);
1.1 abs 97:
1.93 grant 98: $verbose = 1;
99: if ($opt{'q'})
100: { $verbose = 0; }
101:
1.42 abs 102: %extras = (
1.39 abs 103:
1.60 dent 104: '<HEADING>\s*(.*)',
105: '<table><tr><td>
1.76 jschauma 106: <a href="$HOME/Misc/disclaimer.html#bsd-daemon"><img
1.60 dent 107: align="middle" src="$HOME/images/BSD-daemon.jpg" border="0"
108: width=146 height=129 alt="BSD daemon"></a>
109: </td><td align=center>
110: <h1>NetBSD Documentation:</h1>
111: <h1>$SUB1</h1>
112: </td></tr></table>
113: <p>'
114: ,
115:
116: '<DEVHEADING>\s*(.*)',
117: '<table><tr><td>
1.76 jschauma 118: <a href="$HOME/Misc/disclaimer.html#bsd-daemon"><img
1.60 dent 119: align="middle" src="$HOME/images/BSD-daemon.jpg" border="0"
120: width=146 height=129 alt="BSD daemon"></a>
121: </td><td align=center>
122: <h1>NetBSD Developer Documentation:</h1>
123: <h1>$SUB1</h1>
1.51 dent 124: </td></tr></table>
1.60 dent 125: <p>'
126: ,
1.51 dent 127:
1.60 dent 128: '<HOMELINK>',
1.96 jschauma 129: '<table border="0" summary="Footer navigation"><tr>
130: <td class="foothome"><span class="foothome"><a href="$HOME/"><img src="$HOME/images/NetBSD-flag.png" alt="" border="0" width="90" height="90"></a></span></td>
131: <td class="foothome">
132: <span class="foothome"><a href="$HOME/">Home page</a></span><br>
133: </td>
134: </tr></table>'
1.60 dent 135: ,
1.39 abs 136:
1.60 dent 137: '<DEVLINK>',
138: '<table width="100%"><tr><td>
1.96 jschauma 139: <table border="0" summary="Footer navigation"><tr>
140: <td class="foothome"><span class="foothome"><a href="$HOME/"><img src="$HOME/images/NetBSD-flag.png" alt="" border="0" width="90" height="90"></a></span></td>
141: <td class="foothome">
142: <span class="foothome"><a href="$HOME/">Home page</a></span><br>
143: </td>
144: </tr></table>
1.40 abs 145: </td><td>
1.96 jschauma 146: <table border="0" summary="Footer navigation"><tr>
147: <td class="foothome"><span class="foothome"><a href="$DEVELOPERS"><img src="$HOME/images/NetBSD-flag.png" alt="" border="0" width="90" height="90"></a></span></td>
148: <td class="foothome">
149: <span class="foothome"><a href="$DEVELOPERS">Developer Documentation</a></span><br>
150: </td>
151: </tr></table>
152:
1.60 dent 153: </td></tr></table>'
154: ,
1.40 abs 155:
1.60 dent 156: '<DOCLINK>',
157: '<table width="100%"><tr><td>
1.96 jschauma 158: <table border="0" summary="Footer navigation"><tr>
159: <td class="foothome"><span class="foothome"><a href="$HOME/"><img src="$HOME/images/NetBSD-flag.png" alt="" border="0" width="90" height="90"></a></span></td>
160: <td class="foothome">
161: <span class="foothome"><a href="$HOME/">Home page</a></span><br>
162: </td>
163: </tr></table>
1.39 abs 164: </td><td>
1.96 jschauma 165: <table border="0" summary="Footer navigation"><tr>
166: <td class="foothome"><span class="foothome"><a href="$DOCS"><img src="$HOME/images/NetBSD-flag.png" alt="" border="0" width="90" height="90"></a></span></td>
167: <td class="foothome">
168: <span class="foothome"><a href="$DOCS">Documentation top level</a></span><br>
169: </td>
170: </tr></table>
171:
1.60 dent 172: </td></tr></table>'
173: ,
1.47 dent 174:
1.60 dent 175: '<PORTLINK>',
176: '<table width="100%"><tr><td>
1.96 jschauma 177: <table border="0" summary="Footer navigation"><tr>
178: <td class="foothome"><span class="foothome"><a href="$HOME/"><img src="$HOME/images/NetBSD-flag.png" alt="" border="0" width="90" height="90"></a></span></td>
179: <td class="foothome">
180: <span class="foothome"><a href="$HOME/">Home page</a></span><br>
181: </td>
182: </tr></table>
1.47 dent 183: </td><td>
1.96 jschauma 184: <table border="0" summary="Footer navigation"><tr>
185: <td class="foothome"><span class="foothome"><a href="$PORTS"><img src="$HOME/images/NetBSD-flag.png" alt="" border="0" width="90" height="90"></a></span></td>
186: <td class="foothome">
187: <span class="foothome"><a href="$PORTS">Supported Architectures</a></span><br>
188: </td>
189: </tr></table>
190:
1.60 dent 191: </td></tr></table>'
192: ,
1.48 dent 193:
1.60 dent 194: '<GALLINK>',
195: '<table width="100%"><tr><td>
1.96 jschauma 196: <table border="0" summary="Footer navigation"><tr>
197: <td class="foothome"><span class="foothome"><a href="$HOME/"><img src="$HOME/images/NetBSD-flag.png" alt="" border="0" width="90" height="90"></a></span></td>
198: <td class="foothome">
199: <span class="foothome"><a href="$HOME/">Home page</a></span><br>
200: </td>
201: </tr></table>
1.48 dent 202: </td><td>
1.96 jschauma 203: <table border="0" summary="Footer navigation"><tr>
204: <td class="foothome"><span class="foothome"><a href="$GALLERY"><img src="$HOME/images/NetBSD-flag.png" alt="" border="0" width="90" height="90"></a></span></td>
205: <td class="foothome">
206: <span class="foothome"><a href="$GALLERY">Gallery Page</a></span><br>
207: </td>
208: </tr></table>
209:
1.60 dent 210: </td></tr></table>'
1.39 abs 211:
1.1 abs 212: );
213:
214: # XXX Should DTRT with faqs not under Documentation
215:
1.42 abs 216: &makelist(@ARGV, &extras_generate(%extras));
1.1 abs 217: exit;
218:
1.5 abs 219: sub check_date
220: {
1.42 abs 221: my($date) = @_;
222: my($month, $when);
1.5 abs 223: if ($date !~ /(\S+)\s*(\d+)/)
224: { &fail("Unable to parse date '$date'"); }
1.42 abs 225: if (!defined($month = $months{$1}))
1.5 abs 226: {
227: &warn("Unable to parse month '$1'");
1.42 abs 228: $month = 12;
1.5 abs 229: }
1.42 abs 230: $when = sprintf("%04d%02d", $2, $month);
1.5 abs 231: ( $when>$months_previous );
232: }
233:
1.24 abs 234: sub extract_tags
235: {
1.42 abs 236: my($file, @tags) = @_;
237: my($tag, %map);
1.24 abs 238:
1.42 abs 239: if (!open(FILE, $file))
1.28 abs 240: { return; }
1.24 abs 241: while (<FILE>)
242: {
243: foreach $tag (@tags)
244: {
245: if ( /($tag)/ )
1.42 abs 246: { $map{$tag} = $1; }
1.24 abs 247: }
248: }
249: close(FILE);
250: %map;
251: }
252:
1.5 abs 253: sub extras_generate
254: {
1.42 abs 255: my(%extras) = @_;
1.48 dent 256: my($pathtodoc, $pathtodev, $pathtoports, $pathtogal, $str, $home);
1.5 abs 257:
1.92 grant 258: $home = $0;
1.95 grant 259: # extract the relative pathname from our name, no trailing / or
260: # language
1.92 grant 261: if ($home =~ m#^/#) {
262: $home = dirname($home);
1.94 grant 263: if ($home =~ m#.*?/(\.\.?/?.*)$#) {
264: ($home = $1) =~ s#/$##;
1.95 grant 265: $home =~ s#/../[a-z]{2}##;
1.92 grant 266: }
267: } else {
268: if ($home !~ m#(.*)/[^/]+.pl#) {
269: &fail("Unable to extract path from '$0'");
270: }
271: $home = $1;
272: }
273:
1.46 dent 274: $pathtodoc = "$home/Documentation/";
275: $pathtodev = "$home/developers/";
1.47 dent 276: $pathtoports = "$home/Ports/";
1.48 dent 277: $pathtogal = "$home/gallery/";
1.5 abs 278: foreach $str ( keys %extras )
279: {
1.39 abs 280: $extras{$str} =~ s#\$HOME#$home#g;
1.40 abs 281: $extras{$str} =~ s#\$DEVELOPERS#$pathtodev#g;
1.56 dent 282: $extras{$str} =~ s#\$DOCS#$pathtodoc#g;
1.47 dent 283: $extras{$str} =~ s#\$PORTS#$pathtoports#g;
1.48 dent 284: $extras{$str} =~ s#\$GALLERY#$pathtogal#g;
1.5 abs 285: }
286: (%extras);
287: }
288:
289: sub extras_process
290: {
1.42 abs 291: my($data, %extras) = @_;
1.39 abs 292: my($key, $sub1, $sub2, $value);
1.5 abs 293:
294: foreach $key ( keys %extras )
295: {
1.42 abs 296: $value = $extras{$key};
1.28 abs 297: if ($data =~ /$key/)
1.5 abs 298: {
1.39 abs 299: ($sub1, $sub2) = ($1, $2);
300: if (defined($sub1))
1.42 abs 301: { $value =~ s#\$SUB1#$sub1#g; }
1.39 abs 302: if (defined($sub2))
1.42 abs 303: { $value =~ s#\$SUB2#$sub2#g; }
304: $data =~ s/$key.*/$value/;
1.5 abs 305: }
306: }
307: $data;
308: }
309:
310: sub fail
311: {
1.42 abs 312: print STDERR "ABORTING: ", @_, "\n";
1.5 abs 313: exit 3
314: }
315:
1.8 abs 316: sub get_minmonth
317: {
1.42 abs 318: my($monthsback) = @_;
319: my($year, $month);
1.8 abs 320:
1.42 abs 321: ($month, $year) = (localtime(time))[4, 5];
1.8 abs 322:
323: ++$month;
1.42 abs 324: $month -= $monthsback;
1.28 abs 325: while ($month<1)
1.8 abs 326: {
1.42 abs 327: $month += 12;
1.8 abs 328: --$year;
329: }
1.42 abs 330: sprintf("%04d%02d", $year+1900, $month);
1.8 abs 331: }
332:
1.17 abs 333: # Collect $list containing forward links as we go. In general each entry will
334: # generate something in $list and some expanded data in the main $data.
335: #
1.3 abs 336: sub makelist
1.1 abs 337: {
1.42 abs 338: my($infile, $outfile, %extras) = @_;
339: my($data, $section, $href, $header, $list, $pre, %tags, $date_month);
1.43 abs 340: my($date_num, $date_num_used, $entry_num, $ignore, @date_links);
341: my($in_entry, $in_section, $endlist);
1.18 abs 342: my($title_font) = "<font face=\"helvetica, arial, sans-serif\">";
343: my($end_title_font) = "</font>";
1.42 abs 344: my(%rcsmap) = &extract_tags($outfile, '\$NetBSD.*\$');
1.39 abs 345: my($rcstag, $in_trow);
1.1 abs 346:
1.42 abs 347: $list = '';
1.1 abs 348:
1.42 abs 349: $data = $date_month = '';
350: $entry_num = $date_num = $date_num_used = 0;
351: open(FILE, $infile) || die("Unable to open '$infile': $!");
1.1 abs 352: foreach( <FILE> )
353: {
1.24 abs 354: foreach $rcstag (%rcsmap)
355: { s/$rcstag/$rcsmap{$rcstag}/; }
1.28 abs 356: if (defined($pre)) # Handle continuation lines
1.42 abs 357: { $_ = $pre.$_; $pre = undef; }
1.2 abs 358:
1.42 abs 359: if (substr($_, -2) eq "\\\n") # Handle continuation lines
1.1 abs 360: {
361: s/\\\n$//;
1.42 abs 362: $pre = $_;
1.1 abs 363: next;
364: }
365:
1.28 abs 366: if (m#^<DATE>\s*(.+\S)#) # Changes
1.1 abs 367: {
1.90 jschauma 368: my($year, $month, $date, $link, $linkwrapped);
1.1 abs 369:
1.2 abs 370: if ($in_entry)
371: {
1.53 dent 372: $data .= "</dd></dl>\n";
1.42 abs 373: $in_entry = undef;
1.2 abs 374: }
1.42 abs 375: $ignore = undef;
1.1 abs 376: ++$date_num;
1.42 abs 377: $header = $1;
1.28 abs 378: if ($header !~ /^([-a-z0-9_.+]+)\s+(\d+) (\S+) (\d+) - (\S.*)/)
1.1 abs 379: { &fail("'$header' not in expected 'date - event' format"); }
1.42 abs 380: $href = $1;
1.90 jschauma 381: $month = $months{"$3"};
382: $date = sprintf("%d-%02d-%02d", $4, $month, $2);
1.42 abs 383: $header = "$5 ($2 $3)";
384: $month = "$3 $4";
385: $link = $5;
1.28 abs 386: if (defined($tags{$href}))
1.1 abs 387: { &fail("Duplicate name tag '$href'"); }
1.42 abs 388: $tags{$href} = 1;
1.1 abs 389: if (!&check_date($month))
1.42 abs 390: { $ignore = 1; }
1.1 abs 391: else
392: {
1.42 abs 393: $_ = '';
1.1 abs 394: ++$date_num_used;
1.28 abs 395: if ($month ne $date_month)
1.1 abs 396: {
1.28 abs 397: if ($date_month ne '')
1.53 dent 398: { $list .= "</ul>\n"; }
399: $list .= "<h3>$month</h3>\n<ul>\n";
1.42 abs 400: $_ .= "<hr><h2>$month</h2><hr>\n";
401: $date_month = $month;
1.1 abs 402: }
403:
1.54 dent 404: $_.= "<p><h3>\n$title_font".
1.88 jschauma 405: "<a name=\"$href\"></a>$header$end_title_font\n".
1.53 dent 406: "<font size=\"-1\">".
407: "(<a href=\"#top\">top</a>)</font>\n".
408: "</h3><dl><dt><dd>\n";
1.90 jschauma 409: $list .= "<li>$title_font\n<!-- $date --><a href=\"#$href\">$link</a>".
1.53 dent 410: "$end_title_font</li>\n";
1.43 abs 411: if (@date_links < $list_date_links)
412: {
1.67 dent 413:
414: $linkwrapped = wrap("", " ", $link);
415:
1.63 dent 416: push(@date_links, "<li><font face=\"helvetica, arial\" size=\"-1\">\n".
1.67 dent 417: " <a href=\"Changes/#$href\">$linkwrapped</a>\n".
1.63 dent 418: "</font></li>\n");
1.43 abs 419: }
1.42 abs 420: $in_entry = 1;
1.1 abs 421: }
422: }
1.2 abs 423:
1.39 abs 424: if (m#^<ENTRY>\s*(.+\S)#)
1.1 abs 425: {
1.29 abs 426: if (! $in_section )
1.53 dent 427: { $list .= "<ul>\n"; } # Start title list
1.28 abs 428:
1.2 abs 429: if ($in_entry)
430: {
1.53 dent 431: $data .= "</dd></dl>\n";
1.42 abs 432: $in_entry = undef;
1.2 abs 433: }
1.25 abs 434:
1.42 abs 435: $ignore = undef;
1.1 abs 436: ++$entry_num;
1.42 abs 437: $_ = $1;
1.91 jschauma 438: if (! /^([-a-zA-Z0-9_.+,]+)\s+(.*)/)
439: { &fail("Invalid <ENTRY> ($_), not ([-a-zA-Z0-9_.+,]+)\s+(.*)"); }
1.42 abs 440: $href = $1;
441: $header = $2;
1.28 abs 442: if (defined($tags{$href}))
1.2 abs 443: { &fail("Duplicate name tag '$href'"); }
1.42 abs 444: $tags{$href} = 1;
1.1 abs 445:
1.53 dent 446: $_ = "<p><h3>\n$title_font".
447: "<a name=\"$href\">$header</a>$end_title_font\n".
448: "<font size=\"-1\">".
449: "(<a href=\"#top\">top</a>)</font>\n".
450: "</h3><dl><dt><dd>\n";
451: $list .= "<li>$title_font\n<a href=\"#$href\">$header</a>".
452: "$end_title_font</li>\n";
1.29 abs 453: $in_entry = $in_section = 1;
1.1 abs 454: &verbose("\t$href\n");
455: }
1.2 abs 456:
1.58 dent 457: if (m#^<LISTLINK>\s*(.+\S)#)
1.1 abs 458: {
1.29 abs 459: if ( ! $in_section )
1.53 dent 460: { $list .= "<ul>\n"; } # Start title list
1.29 abs 461:
1.42 abs 462: $ignore = undef;
1.1 abs 463: ++$entry_num;
1.42 abs 464: $_ = $1;
1.28 abs 465: if (! m#^(\S+)\s+(.*)#)
1.58 dent 466: { &fail("Invalid <LISTLINK> ($_), not (\S+)\s+(.*)"); }
1.42 abs 467: $href = $1;
468: $header = $2;
1.2 abs 469: $_ = '';
1.58 dent 470: $list .= "<li>$title_font\n<a href=\"$href\">$header</a>".
1.53 dent 471: "$end_title_font</li>\n";
1.29 abs 472: $in_section = 1;
1.1 abs 473: &verbose("\t$href\n");
474: }
1.58 dent 475:
476: if (m#^<ENTRYLINK>\s*(.+\S)#)
477: {
478: if ( ! $in_section )
479: { $list .= "<ul>\n"; } # Start title list
480:
481: if ($in_entry)
482: {
483: $data .= "</dd></dl>\n";
484: $in_entry = undef;
485: }
486:
487: $ignore = undef;
488: ++$entry_num;
489: $_ = $1;
490: if (! m#^(\S+)\s+(.*)#)
491: { &fail("Invalid <ENTRYLINK> ($_), not (\S+)\s+(.*)"); }
492: $href = $1;
493: $header = $2;
494: $_ = "<p><h3>\n$title_font".
495: "<a href=\"$href\">$header</a>$end_title_font\n".
496: "<font size=\"-1\">".
497: "(<a href=\"#top\">top</a>)</font>\n".
498: "</h3><dl><dt><dd>\n";
499: $list .= "<li>$title_font\n<a href=\"$href\">$header</a>".
500: "$end_title_font</li>\n";
501: $in_entry = $in_section = 1;
502: &verbose("\t$href\n");
503: }
1.2 abs 504:
1.39 abs 505: if (m#^<SECTION>\s*(.+\S)#)
1.1 abs 506: {
1.2 abs 507: if ($in_entry)
508: {
1.53 dent 509: $data .= "</dd></dl>\n";
1.42 abs 510: $in_entry = undef;
1.2 abs 511: }
1.7 abs 512: else # In case no entries
513: { $data =~ s#<hr>\n<h2>.*</h2><hr>\n*$##; }
1.42 abs 514: $ignore = undef;
1.28 abs 515: if (defined($section))
1.16 abs 516: {
1.53 dent 517: $list .= "</ul>\n";
1.42 abs 518: $section = $1;
519: $list .= "<h2>$section</h2>\n";
1.53 dent 520: $list .= "<ul>\n"; # Start title list
1.16 abs 521: }
522: else
1.17 abs 523: { # If we have never seen <SECTION> remember top link!
1.42 abs 524: $section = $1;
525: $list .= "<h2><a name=\"top\">$section</a></h2>\n".
1.53 dent 526: "<ul>\n";
1.16 abs 527: }
1.42 abs 528: $_ = "<hr>\n<h2>$section</h2><hr>";
1.29 abs 529: $in_section = 1;
1.1 abs 530: &verbose(" $section\n");
1.11 abs 531: }
1.39 abs 532:
533: if (m#^<TROW>\s*(.*)#)
1.11 abs 534: {
1.42 abs 535: $_ = $1;
1.28 abs 536: if (! m#^([^:]+:)\s+(.*)#)
1.11 abs 537: { &fail("<TROW> should match ([^:]+:)\s+(.*)"); }
1.42 abs 538: $ignore = undef;
1.77 darcy 539: $_ = "<tr><th valign=top align=right>$1</th>\n <td valign=top>$2</td></tr>\n";
1.39 abs 540: $in_trow = 1;
541: }
542: elsif ($in_trow)
543: {
544: if (m#</table>#i)
545: { $in_trow = 0; }
546: else
547: { # Append to last <TROW>
548: substr($data, -11, 0) = ' '.&sub_external_links($_);
549: $_ = '';
550: }
1.1 abs 551: }
1.2 abs 552:
1.39 abs 553: if (m#^</LIST>#)
1.1 abs 554: {
1.2 abs 555: if ($in_entry)
556: {
1.53 dent 557: $data .= "</dd></dl>\n";
1.42 abs 558: $in_entry = undef;
1.2 abs 559: }
560: if ($endlist)
1.39 abs 561: { &fail("Duplicate </LIST>"); }
1.42 abs 562: $endlist = 1;
563: $ignore = undef;
564: $_ = "<hr>\n";
1.1 abs 565: }
1.2 abs 566:
1.28 abs 567: if (! $ignore)
1.42 abs 568: { $data .= &sub_external_links($_); }
1.1 abs 569: }
570:
571: close(FILE);
1.53 dent 572: $list .= "</ul>\n";
1.97 ! kano 573: $list =~ s#<ul>\n</ul>\n##g;
1.72 dent 574: if (!$endlist)
1.73 dent 575: { &warn("Unable to locate </LIST> tag, check header to see if this is desired\n"); }
1.72 dent 576: if ($data !~ s/<LIST>/$list/)
1.73 dent 577: { &warn("Unable to locate <LIST> tag, check header to see if this is desired\n"); }
1.42 abs 578: $_ = "\n\n<!-- DO NOT EDIT THIS FILE. EDIT '$infile' AND RUN 'make' -->\n";
1.7 abs 579: if ($data !~ s/(<head[^>]*>)/$1$_/i)
580: { &fail("Unable to locate <head> tag"); }
581:
1.42 abs 582: open(FILE, ">$outfile") || die("Unable to write '$outfile': $!");
583: print FILE &extras_process($data, %extras);
1.1 abs 584: close(FILE);
1.93 grant 585: if ($date_num) {
586: if ($verbose) {
587: print "$date_num date entr", ($date_num == 1)?'y':'ies';
588: if ($date_num_used != $date_num)
589: { print " ($date_num_used used)"; }
590: print ".\n";
591: if (@date_links && !$opt{'d'}) {
592: print "First $list_date_links date links (for main index.html):\n",
593: @date_links;
1.43 abs 594: }
1.1 abs 595: }
1.93 grant 596: }
597: if ($entry_num && $verbose)
1.42 abs 598: { print "$entry_num entr", ($entry_num == 1)?'y':'ies', ".\n"; }
1.1 abs 599: }
600:
1.5 abs 601: sub sub_external_links
1.1 abs 602: {
1.42 abs 603: my($text) = @_;
1.1 abs 604:
1.44 abs 605: # Man page references. As of 1.4 matches every page except '[' and 'w'.
606: #
1.65 dent 607: $_ = $text; # Output text include match string, so handle in sections
1.44 abs 608: $text = '';
1.69 dent 609:
610: while ( m#([a-zA-Z_][-\w.+]*[\w+])\((\d)(|\.(\w+))(|\+(\W+))\)# )
1.44 abs 611: {
1.69 dent 612: my($page, $section, $arch, $collection) = ($1, $2, $4, $6);
1.66 kim 613: my($link);
1.44 abs 614:
1.87 keihan 615: $link = 'http://man.NetBSD.org/man/';
1.1 abs 616:
1.64 dent 617: $link .= "$page+$section";
1.65 dent 618:
619: if (defined($arch))
620: { $link .= ".$arch"; }
621: elsif ($opt{'a'})
622: { $link .= ".$opt{'a'}"; }
1.66 kim 623:
624: if (defined($collection))
1.71 dent 625: { $link .= "+NetBSD-$collection"; }
1.66 kim 626: elsif ($opt{'c'})
627: { $link .= "+$opt{'c'}"; }
1.69 dent 628: else
629: { $link .= "+NetBSD-current"; }
1.44 abs 630:
631: $text .= $` . "<a href=\"$link\">$page($section)</a>";
632: $_ = $';
633: }
634: $text .= $_;
1.34 abs 635:
636: # Expand <CURRENTSRC>path
637: #
1.61 itojun 638: while ($text =~ m#<CURRENTSRC>([^\s<>]+\w)#)
1.35 abs 639: {
640: my($path);
641:
642: $path = $1;
1.36 abs 643: $path =~ s#^/##;
1.37 abs 644: $path =~ s#^usr/##;
1.86 grant 645: $path =~ s#^src/##;
646: if ($path =~ m#^(sys|share|gnu)src#) {
647: my($module) = $1;
648: $path =~ s#^${module}src##;
649: $path = "src/".$module.$path;
650: }
651: elsif ($path !~ m#^(pkgsrc|xsrc|othersrc)#) {
652: $path = "src/$path";
1.85 grant 653: }
1.87 keihan 654: $text =~ s#<CURRENTSRC>([^\s<>]+\w)#<a href="http://cvsweb.NetBSD.org/bsdweb.cgi/$path?rev=HEAD&content-type=text/x-cvsweb-markup">$1</a>#;
1.35 abs 655: }
1.38 abs 656:
657: # Expand <URL>[^\s<]+[^<\s.]
658: $text =~ s#<URL>([^\s<]+[^<\s.])#<a href="$1">$1</a>#g;
1.25 abs 659:
1.27 soren 660: # Expand <PKGSRC>category/name entries
1.25 abs 661: #
1.89 dent 662: while ($text =~ m#<PKGSRC>(([-\w.]+/|)([^\s<>]+\w))#)
1.31 abs 663: {
664: my($n) = $3;
665: if (defined($pkgname{$n}))
666: { $n = $pkgname{$n}; }
1.89 dent 667: $text =~ s#<PKGSRC>(([-\w.]+/|)([^\s<>]+\w))#<a href="ftp://ftp.NetBSD.org/pub/NetBSD/packages/pkgsrc/$1/README.html">$n</a>#;
1.61 itojun 668: }
669:
670: # Expand <RFC>RFCxxxx entries
671: #
672: while ($text =~ m#<RFC>([^\s<>]+\w)#)
673: {
674: my($o, $n);
675: $o = $n = $1;
676: $n =~ s#^rfc##i;
677: if ($n =~ /^\d+$/)
678: {
679: $text =~ s#<RFC>$o#<a href="http://www.normos.org/ietf/rfc/rfc$n.txt">$o</a>#;
680: }
681: else
682: {
683: $text =~ s#<RFC>$o#$o#;
684: }
1.31 abs 685: }
1.25 abs 686:
1.10 abs 687: # Expand <user@host> email addresses
688: #
1.13 abs 689: $text =~ s#<([-\w.]+@[-\w.]+)>#<a href="mailto:$1"><$1></a>#g;
1.25 abs 690:
1.5 abs 691: $text;
1.1 abs 692: }
693:
694: sub verbose
695: { $verbose && print @_; }
1.8 abs 696:
697: sub warn
1.93 grant 698: { $verbose && print "WARNING: ", @_; }
CVSweb <webmaster@jp.NetBSD.org>