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