[BACK]Return to list2html.pl CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / htdocs

Annotation of htdocs/list2html.pl, Revision 1.27

1.1       abs         1: #!/usr/bin/env perl
                      2: #
1.27    ! soren       3: # $Id: list2html.pl,v 1.26 1999/10/28 23:31:17 abs 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.3       abs         7: #      <SECTION>Text           Introduces new section, before DATE or ENTRY
1.1       abs         8: #      <ENDLIST>               Optional tag for end of all special entries
                      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
                     13: #      <ENTRYLINK>url Text     Link added to list, removed from main text
1.1       abs        14: #      <HEADING>Text           Standard heading at top of document
                     15: #      <BASELINKS>             Standard links at base of document
1.11      abs        16: #      <TROW>Text: Text        Table row, with two text fields
1.1       abs        17: #
                     18: # Continuation lines are understood (useful for the special tags)
1.6       abs        19: #
                     20: # Additional links:
                     21: #      ([\w.+]+)\((\d)\) -> manpages           eg: ls(1)
                     22: #      <([-\w.]+@[-\w.]+)> -> email address    eg: <user@host>
1.25      abs        23: #      <PKGSRC>category/name -> link to pkgsrc README.html
1.9       abs        24: #
1.14      abs        25: # (c) 1999 DKBrownlee. All rights reserved. This file may be used to update
                     26: # the information on the NetBSD website. If you want to use it for any other
                     27: # purpose, ask me first.. abs@mono.org
1.9       abs        28: #
1.1       abs        29:
                     30: use strict;
1.21      abs        31: use Getopt::Std;
1.1       abs        32: $^W=1;
                     33: my($verbose,%extras,$months_previous);
1.21      abs        34: my($version,%opt);
1.1       abs        35:
1.8       abs        36: $months_previous=9;    # previous months to display for DATE entries
                     37:
1.27    ! soren      38: $version='$Revision: 1.26 $';
1.21      abs        39: $version =~ /([\d.]+)/ && ($version=$1);
                     40:
                     41: if (!&getopts('a:m:hV',\%opt) || $opt{'h'} || ( !$opt{'V'} && @ARGV != 2) )
1.5       abs        42:
                     43:     {
                     44:     print "list2html.pl [opts] infile outfile
                     45: [opts] -a xxx  Define 'arch=xxx' when linking to manpages
1.8       abs        46:        -m xxx  Set months to display for <DATE> (default $months_previous)
1.5       abs        47:        -h      This help.
1.21      abs        48:        -V      Display version and exit ($version - David Brownlee/abs)
1.5       abs        49:
1.25      abs        50: list2html.pl processes .list files into .html, parsing various special tags.
1.5       abs        51: .list files are intended to reduce the effort required to maintain files such
                     52: as FAQs, and change logs. More details given at the start of list2html.pl.
                     53: ";
                     54:     exit;
                     55:     }
1.21      abs        56: if ($opt{'V'})
                     57:     { print "$version\n"; exit; }
1.5       abs        58:
1.1       abs        59: $verbose=1;
1.21      abs        60: if ($opt{'m'})
                     61:     { $months_previous=$opt{'m'}; }
1.8       abs        62: $months_previous=&get_minmonth($months_previous);
1.1       abs        63:
                     64: %extras=(
                     65:        '<HEADING>\s*(.*)','
                     66: <table><tr><td>
                     67: <a href="$HOME/Misc/daemon-copy.html">
1.22      itojun     68: <img align="center" src="$HOME/images/BSD-demon.jpg" border=0
1.19      abs        69: width=146 height=129 alt="BSD demon"></a>
1.1       abs        70: </td><td align=center>
                     71: <h1>NetBSD Documentation:</h1>
                     72: <h1>$TITLE</h1>
                     73: </td></tr></table>
                     74: <p>
                     75: ',     '<BASELINKS>','
                     76: <table width="100%"><tr>
                     77:   <td>
                     78:     <table><tr>
                     79:       <td>
                     80:        <a href="$HOME/index.html">
1.22      itojun     81:         <img src="$HOME/images/NetBSD-banner.jpg" width=91 height=42
1.23      darcy      82:            border="0" alt="NetBSD&nbsp;Home"></a>
1.1       abs        83:       </td><td>
                     84:        <a href="$HOME/index.html">Home Page</a>
                     85:       </td>
                     86:     </tr></table>
                     87:   </td><td>
                     88:     <table><tr>
                     89:       <td>
                     90:        <a href="$DOCUMENTATION/index.html"> <img
1.22      itojun     91:            src="$HOME/images/NetBSD-banner.jpg" width=91 height=42
1.23      darcy      92:            alt="NetBSD&nbsp;Documentation"
                     93:         border="0"></a>
1.1       abs        94:       </td><td>
                     95:        <a href="$DOCUMENTATION/index.html">Documentation top level</a>
                     96:       </td>
                     97:     </tr></table>
                     98:   </td>
                     99: </tr></table>
                    100: '
                    101: );
                    102:
                    103: # XXX Should DTRT with faqs not under Documentation
                    104:
1.3       abs       105: &makelist(@ARGV,&extras_generate(%extras));
1.1       abs       106: exit;
                    107:
1.5       abs       108: sub check_date
                    109:     {
                    110:     my($date)=@_;
                    111:     my($month,$when);
                    112:     my(%months)=('Jan' => 1,   'Feb' => 2,     'Mar' => 3,
                    113:                 'Apr' => 4,    'May' => 5,     'Jun' => 6,
                    114:                 'Jul' => 7,    'Aug' => 8,     'Sep' => 9,
                    115:                 'Oct' => 10,   'Nov' => 11,    'Dec' => 12 );
                    116:
                    117:     if ($date !~ /(\S+)\s*(\d+)/)
                    118:        { &fail("Unable to parse date '$date'"); }
                    119:     if (!defined($month=$months{$1}))
                    120:        {
                    121:        &warn("Unable to parse month '$1'");
                    122:        $month=12;
                    123:        }
                    124:     $when=sprintf("%04d%02d",$2,$month);
                    125:     ( $when>$months_previous );
                    126:     }
                    127:
1.24      abs       128: sub extract_tags
                    129:     {
                    130:     my($file,@tags)=@_;
                    131:     my($tag,%map);
                    132:
                    133:     if (!open(FILE,$file))
                    134:        { return(undef); }
                    135:     while (<FILE>)
                    136:        {
                    137:        foreach $tag (@tags)
                    138:            {
                    139:            if ( /($tag)/ )
                    140:                { $map{$tag}=$1; }
                    141:            }
                    142:        }
                    143:     close(FILE);
                    144:     %map;
                    145:     }
                    146:
1.5       abs       147: sub extras_generate
                    148:     {
                    149:     my(%extras)=@_;
                    150:     my($pathtodoc,$str);
                    151:
                    152:     if( $0 !~ m#(.*)/[^/]+.pl# )
                    153:        { &fail("Unable to extract path from '$0'"); }
                    154:     $pathtodoc="$1/Documentation";
                    155:     foreach $str ( keys %extras )
                    156:        {
                    157:        $extras{$str} =~ s#\$HOME#$pathtodoc/..#g;
                    158:        $extras{$str} =~ s#\$DOCUMENTATION#$pathtodoc#g;
                    159:        }
                    160:     (%extras);
                    161:     }
                    162:
                    163: sub extras_process
                    164:     {
                    165:     my($data,%extras)=@_;
                    166:     my($key,$title,$value);
                    167:
                    168:     foreach $key ( keys %extras )
                    169:        {
                    170:        $value=$extras{$key};
                    171:        if( $data =~ /$key/ )
                    172:            {
                    173:            if( defined($1) )
                    174:                {
                    175:                $title=$1;
                    176:                $value=~s#\$TITLE#$title#g;
                    177:                }
                    178:            $data=~s/$key.*/$value/;
                    179:            }
                    180:        }
                    181:     $data;
                    182:     }
                    183:
                    184: sub fail
                    185:     {
                    186:     print STDERR "ABORTING: ",@_,"\n";
                    187:     exit 3
                    188:     }
                    189:
1.8       abs       190: sub get_minmonth
                    191:     {
                    192:     my($monthsback)=@_;
                    193:     my($year,$month);
                    194:
                    195:     ($month,$year)=(localtime(time))[4,5];
                    196:
                    197:     ++$month;
                    198:     $month-=$monthsback;
                    199:     while( $month<1 )
                    200:        {
                    201:        $month+=12;
                    202:        --$year;
                    203:        }
                    204:     sprintf("%04d%02d",$year+1900,$month);
                    205:     }
                    206:
1.17      abs       207: # Collect $list containing forward links as we go. In general each entry will
                    208: # generate something in $list and some expanded data in the main $data.
                    209: #
1.3       abs       210: sub makelist
1.1       abs       211:     {
                    212:     my($infile,$outfile,%extras)=@_;
                    213:     my($data,$section,$href,$header,$list,$pre,%tags,$date_month);
1.2       abs       214:     my($date_num,$date_num_used,$entry_num,$ignore,$in_entry,$endlist);
1.18      abs       215:     my($title_font) = "<font face=\"helvetica, arial, sans-serif\">";
                    216:     my($end_title_font) = "</font>";
1.24      abs       217:     my(%rcsmap)=&extract_tags($outfile,'\$NetBSD.*\$');
                    218:     my($rcstag);
1.1       abs       219:
1.7       abs       220:     $list='';
1.1       abs       221:
                    222:     $data=$date_month='';
                    223:     $entry_num=$date_num=$date_num_used=0;
                    224:     open(FILE,$infile) || die("Unable to open '$infile': $!");
                    225:     foreach( <FILE> )
                    226:        {
1.24      abs       227:        foreach $rcstag (%rcsmap)
                    228:            { s/$rcstag/$rcsmap{$rcstag}/; }
1.16      abs       229:        if( defined($pre) )             # Handle continuation lines
1.1       abs       230:            { $_=$pre.$_; $pre=undef; }
1.2       abs       231:
1.16      abs       232:        if( substr($_,-2) eq "\\\n" )   # Handle continuation lines
1.1       abs       233:            {
                    234:            s/\\\n$//;
                    235:            $pre=$_;
                    236:            next;
                    237:            }
                    238:
                    239:        if( m#^<DATE>\s*(.+\S)# )       # Changes
                    240:            {
                    241:            my($year,$month,$link);
                    242:
1.2       abs       243:            if ($in_entry)
                    244:                {
                    245:                $data.="</dd></dl></p>\n";
                    246:                $in_entry=undef;
                    247:                }
1.1       abs       248:            $ignore=undef;
                    249:            ++$date_num;
                    250:            $header=$1;
1.2       abs       251:            if( $header !~ /^([-a-z0-9_.+]+)\s+(\d+) (\S+) (\d+) - (\S.*)/ )
1.1       abs       252:                { &fail("'$header' not in expected 'date - event' format"); }
                    253:            $href=$1;
1.2       abs       254:            $header="$5 ($2 $3)";
                    255:            $month="$3 $4";
                    256:            $link=$5;
1.1       abs       257:            if( defined($tags{$href}) )
                    258:                { &fail("Duplicate name tag '$href'"); }
                    259:            $tags{$href}=1;
                    260:            if (!&check_date($month))
                    261:                { $ignore=1; }
                    262:            else
                    263:                {
1.2       abs       264:                $_='';
1.1       abs       265:                ++$date_num_used;
                    266:                if( $month ne $date_month )
                    267:                    {
                    268:                    if( $date_month ne '' )
1.18      abs       269:                        { $list.="</ul>$end_title_font\n"; }
                    270:                    $list.="<h3>$month</h3>\n$title_font<ul>\n";
1.2       abs       271:                    $_.="<hr><h2>$month</h2><hr>\n";
1.1       abs       272:                    $date_month=$month;
                    273:                    }
                    274:
1.18      abs       275:                $_.= "<p><dl><dt>\n$title_font".
1.2       abs       276:                        "<h3><a name=\"$href\">$header</a> <font size=\"-1\">".
1.18      abs       277:                        "(<a href=\"#top\">top</a>)</font></h3>\n".
                    278:                        "$end_title_font\n</dt><dd>";
1.1       abs       279:                $list.="<li><a href=\"#$href\">$link</a></li>\n";
1.7       abs       280:                $in_entry=1;
1.1       abs       281:                }
                    282:            }
1.2       abs       283:
                    284:        elsif( m#^<ENTRY>\s*(.+\S)# )
1.1       abs       285:            {
1.2       abs       286:            if ($in_entry)
                    287:                {
                    288:                $data.="</dd></dl></p>\n";
                    289:                $in_entry=undef;
                    290:                }
1.25      abs       291:
1.1       abs       292:            $ignore=undef;
                    293:            ++$entry_num;
                    294:            if( !defined($section) )
1.2       abs       295:                { &fail("<ENTRY> before <SECTION> tag"); }
1.1       abs       296:            $_=$1;
1.20      abs       297:            if( ! /^([-a-z0-9_.+,]+)\s+(.*)/ )
                    298:                { &fail("Invalid <ENTRY> ($_), not ([-a-z0-9_.+,]+)\s+(.*)"); }
1.1       abs       299:            $href=$1;
                    300:            $header=$2;
1.2       abs       301:            if( defined($tags{$href}) )
                    302:                { &fail("Duplicate name tag '$href'"); }
                    303:            $tags{$href}=1;
1.1       abs       304:
1.15      abs       305:            $_ = "<p><dl><dt>\n$title_font".
1.2       abs       306:                    "<h3><a name=\"$href\">$header</a>\n<font size=\"-1\">".
1.15      abs       307:                    "(<a href=\"#top\">top</a>)</font></h3>$end_title_font\n".
                    308:                    "</dt><dd>\n";
                    309:            $list.="<li><a href=\"#$href\">".
1.18      abs       310:                    "$header".
1.15      abs       311:                    "</a></li>\n";
1.2       abs       312:            $in_entry=1;
1.1       abs       313:            &verbose("\t$href\n");
                    314:            }
1.2       abs       315:
                    316:        elsif( m#^<ENTRYLINK>\s*(.+\S)# )
1.1       abs       317:            {
                    318:            $ignore=undef;
                    319:            ++$entry_num;
                    320:            if( !defined($section) )
1.2       abs       321:                { &fail("<ENTRYLINK> before <SECTION> tag"); }
1.1       abs       322:            $_=$1;
1.2       abs       323:            if( ! m#^(\S+)\s+(.*)# )
                    324:                { &fail("Invalid <ENTRYLINK> ($_), not (\S+)\s+(.*)"); }
1.1       abs       325:            $href=$1;
                    326:            $header=$2;
1.2       abs       327:            $_ = '';
                    328:            $list.="<li><a href=\"$href\">$header</a></li>\n";
1.1       abs       329:            &verbose("\t$href\n");
                    330:            }
1.2       abs       331:
1.1       abs       332:        elsif( m#^<SECTION>\s*(.+\S)# )
                    333:            {
1.2       abs       334:            if ($in_entry)
                    335:                {
                    336:                $data.="</dd></dl></p>\n";
                    337:                $in_entry=undef;
                    338:                }
1.7       abs       339:            else # In case no entries
                    340:                { $data =~ s#<hr>\n<h2>.*</h2><hr>\n*$##; }
1.1       abs       341:            $ignore=undef;
                    342:            if( defined($section) )
1.16      abs       343:                {
1.18      abs       344:                $list.="</ul>$end_title_font\n";
1.16      abs       345:                $section=$1;
1.18      abs       346:                $list.="<h2>$section</h2>\n$title_font<ul>\n";
1.16      abs       347:                }
                    348:            else
1.17      abs       349:                {       # If we have never seen <SECTION> remember top link!
1.16      abs       350:                $section=$1;
1.18      abs       351:                $list.="<h2><a name=\"top\">$section</a></h2>\n".
                    352:                        "$title_font<ul>\n";
1.16      abs       353:                }
1.2       abs       354:            $_="<hr>\n<h2>$section</h2><hr>";
1.1       abs       355:            &verbose("    $section\n");
1.11      abs       356:            }
                    357:        elsif( m#^<TROW>\s*(.*)# )
                    358:            {
                    359:            $_=$1;
                    360:            if( ! m#^([^:]+:)\s+(.*)# )
                    361:                { &fail("<TROW> should match ([^:]+:)\s+(.*)"); }
                    362:            $ignore=undef;
1.12      abs       363:            $_ = "<tr><th valign=top align=right>$1</th>\n    <td>$2</td></tr>";
1.1       abs       364:            }
1.2       abs       365:
1.1       abs       366:        elsif( m#^<ENDLIST># )
                    367:            {
1.2       abs       368:            if ($in_entry)
                    369:                {
                    370:                $data.="</dd></dl></p>\n";
                    371:                $in_entry=undef;
                    372:                }
                    373:            if ($endlist)
                    374:                { &fail("Duplicate <ENDLIST>"); }
                    375:            $endlist=1;
1.1       abs       376:            $ignore=undef;
1.3       abs       377:            $_="<hr>\n";
1.1       abs       378:            }
1.2       abs       379:
1.4       abs       380:        # Foul hack to avoid incorrect installboot(8) references
                    381:        # May fail valid links also. Only until i386 vs alpha manpage resolved.
1.5       abs       382:        if( ! $ignore )
                    383:            { $data.=&sub_external_links($_); }
1.1       abs       384:        }
                    385:
                    386:     close(FILE);
1.18      abs       387:     $list.="</ul>$end_title_font\n";
1.2       abs       388:     if (!$endlist)
                    389:        { &fail("Missing <ENDLIST> tag"); }
                    390:     if ($data !~ s/<LIST>/$list/)
1.1       abs       391:        { &fail("Unable to locate <LIST> tag"); }
1.7       abs       392:     $_="\n\n<!-- DO NOT EDIT THIS FILE. EDIT '$infile' AND RUN 'make' -->\n";
                    393:     if ($data !~ s/(<head[^>]*>)/$1$_/i)
                    394:        { &fail("Unable to locate <head> tag"); }
                    395:
1.1       abs       396:     open(FILE,">$outfile") || die("Unable to write '$outfile': $!");
                    397:     print FILE &extras_process($data,%extras);
                    398:     close(FILE);
                    399:     if( $date_num )
                    400:        {
                    401:        print "$date_num date entr",($date_num==1)?'y':'ies';
                    402:        if ($date_num_used != $date_num)
                    403:            { print " ($date_num_used used)"; }
                    404:        print ".\n";
                    405:        }
                    406:     if( $entry_num )
                    407:        { print "$entry_num entr",($entry_num==1)?'y':'ies',".\n"; }
                    408:     }
                    409:
1.5       abs       410: sub sub_external_links
1.1       abs       411:     {
1.5       abs       412:     my($text)=@_;
                    413:     my($link);
1.1       abs       414:
1.5       abs       415:     $link='http://www.flame.org/cgi-bin/uncgi/hman?';
1.1       abs       416:
1.21      abs       417:     if ($opt{'a'})
                    418:        { $link.="arch=$opt{'a'}&amp;"; }
1.10      abs       419:
                    420:     # Man page references. As of 1.4 matches every page except '[' and 'w'.
                    421:     #
1.5       abs       422:     $text =~
1.10      abs       423:        s#([a-zA-Z_][-\w.+]*[\w+])\((\d)\)#<a href="${link}page=$1&amp;sect=$2">$1($2)</a>#g;
1.25      abs       424:
1.27    ! soren     425:     # Expand <PKGSRC>category/name entries
1.25      abs       426:     #
1.26      abs       427:     $text =~ s#<PKGSRC>((\w+/|)([^\s<>]+\w))#<a href="ftp://ftp.netbsd.org/pub/NetBSD/packages/pkgsrc/$1/README.html">$3</a>#g;
1.25      abs       428:
1.10      abs       429:     # Expand <user@host> email addresses
                    430:     #
1.13      abs       431:     $text =~ s#<([-\w.]+@[-\w.]+)>#<a href="mailto:$1">&lt;$1&gt;</a>#g;
1.25      abs       432:
1.5       abs       433:     $text;
1.1       abs       434:     }
                    435:
                    436: sub verbose
                    437:     { $verbose && print @_; }
1.8       abs       438:
                    439: sub warn
                    440:     { print "WARNING: ",@_; }

CVSweb <webmaster@jp.NetBSD.org>