## -*- perl -*-
## ----------------------------------------------------------------------
## spec/html: SGML conversion specification for HTML output
## ----------------------------------------------------------------------
## Copyright (C) 1998 Ardo van Rangelrooij
## Copyright (C) 1996 Ian Jackson
##
## This is free software; see the GNU General Public Licence
## version 2 or later for copying conditions.  There is NO warranty.
## ----------------------------------------------------------------------

## ----------------------------------------------------------------------
use POSIX;
use URI::URL;

## ----------------------------------------------------------------------
$format = '.html';

## ----------------------------------------------------------------------
## language definition
( $lang = POSIX::setlocale( LANG ) ) =~ s/_.*//;
if ( -r $ENV{ 'DEBIANDOCSGMLSPEC' } . '/i18n/' . $lang . $format )
{
    do $ENV{ 'DEBIANDOCSGMLSPEC' } . '/i18n/' . $lang . $format;
}
else
{
    %lang = (
	     'abstract' => 'Abstract',
	     'copyright' => 'Copyright Notice',
	     'contents' => 'Contents',
	     'chapter' => 'Chapter',
	     'appendix' => 'Appendix',
	     'footnotes' => 'Footnotes',
	     'next' => 'next',
	     'back' => 'back',
	     );
}

## ----------------------------------------------------------------------
## 
%htmlsani= (
	    '<' => 'lt',
	    '>' => 'gt',
	    '&' => 'amp',
	    '"' => 'quot'
	    );

## ----------------------------------------------------------------------
## base definition
$basename = @ARGV ? $ARGV[0] : ".";
if ( $basename =~ s,/+$,, )
{
    $rootfile = 'index';
    $prefix = '';
    $writesubdir = "$basename/";
    -d "$writesubdir" || mkdir( "$basename", 0777 ) ||
	die "cannot make subdir \`$basename': $!\n";
}
else
{
    $rootfile = '';
    $prefix = "$basename-";
    $writesubdir = '';
}

## ----------------------------------------------------------------------
## global variables
$need_para = 1;
undef $chainchapt;
$toclevel = 0;

## ----------------------------------------------------------------------
## tag processing
## ----------------------------------------------------------------------

## ----------------------------------------------------------------------
sub start_chapt
{
    ( $element, $event ) = @_;
    _start_file( _a( 'SRID' ) );
    $chaptheadnum = _a( 'CHAPT' );
    $chapthname = _a( 'HNAME' );
}
sub end_chapt
{
    _finish_file();
}

## ----------------------------------------------------------------------
sub start_appendix
{
    ( $element, $event ) = @_;
    _start_file( _a( 'SRID' ) );
    $chaptheadnum = _a( 'CHAPT' );
    $chapthname = _a( 'HNAME' );
}
sub end_appendix
{
    _finish_file();
}

## ----------------------------------------------------------------------
sub start_heading
{
    push_output( 'string' );
}
sub end_heading
{
    my $heading = pop_output;
    $heading =~ s/^\s+//;
    $heading =~ s/\s+$//;
    $heading =~ s/\s+/ /g;
    _output_heading( $heading );
}

## ----------------------------------------------------------------------
sub start_footnotebody
{
    ( $element, $event ) = @_;
    push( @elements, $element );
    push_output( 'string' );
    $indentlevel++;
}
sub end_footnotebody
{
    $indentlevel--;
    my $footnotebody = pop_output;
    $footnotebody =~ s/^\s+//;
    $footnotebody =~ s/\s+$//;
    $element = pop( @elements );
    _output_footnotebody( $footnotebody ) if length( $footnotebody );
}

## ----------------------------------------------------------------------
sub start_list
{
    _start_list( 'ul', 'li', @_ );
}
sub end_list
{
    _end_list();
}

## ----------------------------------------------------------------------
sub start_enumlist
{
    _start_list( 'ol', 'li', @_ );
}
sub end_enumlist
{
    _end_list();
}

## ----------------------------------------------------------------------
sub start_taglist
{
    _start_list( 'dl', 'dd', @_ );
}
sub end_taglist
{
    _end_list();
}

## ----------------------------------------------------------------------
sub start_item
{
    output( '<p>' ) if ! $lcompact && ! $tagged;
    $tagged = 0;
    output( "<$itemtag>" );
    $need_para = 0;
}
sub end_item
{
    $need_para = 1;
}

## ----------------------------------------------------------------------
## output definitions
## ----------------------------------------------------------------------

## ----------------------------------------------------------------------
sub _output_start_book
{
}
sub _output_end_book
{
}

## ----------------------------------------------------------------------
sub _output_titlepag
{
    _start_file( '' );
    _html_head( $title );
    output( "<hr>\n" );
    output( "\n" );
    if ( length( $abstract ) )
    {
	output( '  ' );
	output( "[" );
	_href_open( '', 'abstract' );
	output( $lang{ 'abstract' } );
	output( "</a>]\n" );
    }
    if ( length( $copyright ) )
    {
	output( '  ' );
	output( "[" );
	_href_open( '', 'copyright' );
	output( $lang{ 'copyright' } );
	output( "</a>]\n" );
    }
    output( '  ' );
    output( "[" );
    _href_open( '', 'contents' );
    output( $lang{ 'contents' } );
    output( "</a>]\n" );
    output( "\n" );
    output( "<hr>\n" );
    output( "\n" );
    output( "<h1>" );
    output( _squash_markup( $title ) );
    output( "</h1>\n" );
    output( "\n" );
    if ( length( $abstract )  || length( $copyright ) )
    {
	output( "<hr>\n" );
	output( "\n" );
    }
    if ( length( $abstract ) )
    {
	output( "<h2>" );
	output( "<a name=\"abstract\">" );
	output( $lang{ 'abstract' } );
	output( "</a>" );
	output( "</h2>\n" );
	output( "\n" );
	output( "$abstract\n" );
	output( "\n" );
    }
    if ( length( $copyright ) )
    {
	output( "<h2>" );
	output( "<a name=\"copyright\">" );
	output( $lang{ 'copyright' } );
	output( "</a>" );
	output( "</h2>\n" );
	output( "\n" );
	output( "$copyright\n" );
	output( "\n" );
    }
    output( "<hr>\n" );
    output( "\n" );
}

## ----------------------------------------------------------------------
sub _output_copyrightsummaries
{
    my ( @copyrightsummaries ) = @_;
    output( "<p>\n" );
    output( join( "<br>\n", @copyrightsummaries ), "\n" );
    output( "</p>\n" );
    output( "\n" );
}

## ----------------------------------------------------------------------
sub _output_toc
{
    my ( $toc ) = @_;
    output( "<h2>" );
    output( "<a name=\"contents\">" );
    output( $lang{ 'contents' } );
    output( "</a>" );
    output( "</h2>\n" );
    output( "\n" );
    output( "<ul>\n" );
    output( $toc );
    output( "</ul>\n" x ( $toclevel + 1 ) );
    output( "\n" );
    _finish_file();
}

## ----------------------------------------------------------------------
sub _output_tocentry
{
    my ( $tocentry ) = @_;
    my $level = _num_level( _a( 'LEVEL' ) );
    my $string = _a( 'CHAPT' ) . _a( 'SECT' );
    if ( $level > $tocdetail )
    {
        push_output( 'nul' );
	$tocignore++;
    }
    else
    {
        if ( $toclevel > $level )
	{
	    output( "</ul>\n" x ( $toclevel - $level ) );
	}
        elsif ( $toclevel < $level )
	{
	    output( "<ul>\n" x ( $level - $toclevel ) );
	}
        output( '<li>' );
        if ( ! $level )
	{
            $chaptsrid = _a( 'SRID' );
            if ( length( $chainchapt ) )
	    {
                $fchainsrid{$chainchapt} = $chaptsrid;
                $bchainsrid{$chaptsrid} = $chainchapt;
            }
            $chainchapt = $chaptsrid;
            _href_open( $chaptsrid );
            output( $string . ' ' );
        }
	else
	{
            _href_open( $chaptsrid, _a( 'SRID' ) );
            output( $string );
            output( '</a> ' );
        }
        $toclevel = $level;
    }
    output( $tocentry );
    if ( $tocignore )
    {
        pop_output;
	$tocignore--;
    }
    elsif ( $toclevel )
    {
        output( "\n" );
    }
    else
    {
        output( "</a>\n" );
    }
}

## ----------------------------------------------------------------------
sub _output_heading
{
    my ( $heading ) = @_;
    if ( defined( $chaptheadnum ) )
    {
	my $chaptname = ( $chaptheadnum =~ m/^[A-Z]$/
			  ? $lang{ 'appendix' }
			  : $lang{ 'chapter' } );
        _html_head( $title . ' - ' . _squash_markup( $heading ) );
	output( "<hr>\n" );
	output( "\n" );
	if ( defined( $bchainsrid{ $cfilesrid } ) )
	{
	    output( "[" );
	    _href_open( $bchainsrid{ $cfilesrid }, '' );
	    output( $lang{ 'back' } );
	    output( "</a>]\n" );
	}
	if ( length( $abstract ) )
	{
	    output( ' ' );
	    output( "[" );
	    _href_open( '', 'abstract' );
	    output( $lang{ 'abstract' } );
	    output( "</a>]\n" );
	}
	if ( length( $copyright ) )
	{
	    output( ' ' );
	    output( "[" );
	    _href_open( '', 'copyright' );
	    output( $lang{ 'copyright' } );
	    output( "</a>]\n" );
	}
	output( ' ' );
	output( "[" );
	_href_open( '', 'contents' );
	output( $lang{ 'contents' } );
	output( "</a>]\n" );
	if ( defined( $fchainsrid{ $cfilesrid } ) )
	{
	    output( ' ' );
	    output( "[" );
	    _href_open( $fchainsrid{ $cfilesrid }, '' );
	    output( $lang{ 'next' } );
	    output( "</a>]\n" );
	}
	output( "\n" );
	output( "<hr>\n" );
	output( "\n" );
        output( "<h1>\n" );
	output( _squash_markup( $title
				. ' - ' . $chaptname
				. ' ' . $chaptheadnum )
		. "<br>\n" );
	output( _squash_markup( $heading ) . "\n" );
	output( "</h1>\n" );
	output( "\n" );
	output( "<hr>\n" );
	output( "\n" );
	$need_hr = 0;
    }
    else
    {
	output( $heading );
        output( "$headclose\n" );
    }
}

## ----------------------------------------------------------------------
sub _output_p
{
    my ( $paragraph ) = @_;
    output( "<p>\n" ) if $need_para;
    output( "$paragraph\n" );
    output( "</p>\n" ) if $need_para;
    output( "\n" );
    $need_hr = 1;
}

## ----------------------------------------------------------------------
sub _output_example
{
    my ( $example ) = @_;
    output( "<pre>\n" );
    output( "$example\n" );
    output( "</pre>\n" );
}

## ----------------------------------------------------------------------
sub _output_footnotes
{
    my ( $footnotes ) = @_;
    _start_file( 'footnotes' );
    my $subdoctitle = $title . " - " . $lang{ 'footnotes' };
    _html_head( $subdoctitle );
    output( "<hr>\n" );
    output( "\n" );
    if ( length( $abstract ) )
    {
	output( '  ' );
	output( "[" );
	_href_open( '', 'abstract' );
	output( $lang{ 'abstract' } );
	output( "</a>]\n" );
    }
    if ( length( $copyright ) )
    {
	output( '  ' );
	output( "[" );
	_href_open( '', 'copyright' );
	output( $lang{ 'copyright' } );
	output( "</a>]\n" );
    }
    output( '  ' );
    output( "[" );
    _href_open( '', 'contents' );
    output( $lang{ 'contents' } );
    output( "</a>]\n" );
    output( "\n" );
    output( "<hr>\n" );
    output( "\n" );
    output( "<h1>" );
    output( _squash_markup( $subdoctitle ) );
    output( "</h1>\n" );
    output( "\n" );
    output( "<hr>\n" );
    output( "\n" );
    output( $footnotes );
    _finish_file();
}

## ----------------------------------------------------------------------
sub _output_footnote
{
}

## ----------------------------------------------------------------------
sub _output_footnotebody
{
    my ( $footnotebody ) = @_;
    my $footnotenum = _a( 'NUMBER' );
    output( "<h2>" );
    _href_open( _a( 'CSRID' ), "fr$footnotenum",
		'name="' . $footnotenum . '"' );
    output( $footnotenum );
    output( "</a>\n" );
    output( "</h2>\n" );
    output( $footnotebody );
}

## ----------------------------------------------------------------------
sub _output_footnoteref
{
    my ( $footnoteref ) = @_;
    _href_open( 'footnotes', $footnoteref, 'name="fr' . $footnoteref . '"' );
    output( "[$footnoteref]" );
    output( "</a>" );
}

## ----------------------------------------------------------------------
sub _output_tag
{
    my ( $tag ) = @_;
    output( '<p>' ) if ! $lcompact;
    $tagged = 1 if ! $lcompact;
    output( '<dt>' );
    output( $tag );
}

## ----------------------------------------------------------------------
sub _output_em
{
    my ( $em ) = @_;
    output( "<em>" );
    output( $em );
    output( '</em>' );
}

## ----------------------------------------------------------------------
sub _output_strong
{
    my ( $strong ) = @_;
    output( "<strong>" );
    output( $strong );
    output( '</strong>' );
}

## ----------------------------------------------------------------------
sub _output_var
{
    my ( $var ) = @_;
    output( '<var>' );
    output( $var );
    output( '</var>' );
}

## ----------------------------------------------------------------------
sub _output_package
{
    my ( $package ) = @_;
    output( "<code>" );
    output( $package );
    output( '</code>' );
}

## ----------------------------------------------------------------------
sub _output_prgn
{
    my ( $prgn ) = @_;
    output( "<code>" );
    output( $prgn );
    output( '</code>' );
}

## ----------------------------------------------------------------------
sub _output_file
{
    my ( $file ) = @_;
    output( "<code>" );
    output( $file );
    output( '</code>' );
}

## ----------------------------------------------------------------------
sub _output_tt
{
    my ( $tt ) = @_;
    output( "<samp>" );
    output( $tt );
    output( '</samp>' );
}

## ----------------------------------------------------------------------
sub _output_qref
{
    my ( $qref ) = @_;
    if ( _a( 'LEVEL' ) eq 'CHAPT' )
    {
	_href_open( _a( 'SRID' ), '' );
    }
    else
    {
	_href_open( _a( 'CSRID' ), _a( 'SRID' ) );
    }
    output( $qref );
    output( '</a>' );
}

## ----------------------------------------------------------------------
sub _output_ref
{
    my ( $ref ) = @_;
    my $refname = _a( 'HNAME' );
    my $level = _a( 'LEVEL' );
    if ( $level eq 'CHAPT' )
    {
	_href_open( _a( 'SRID' ), '' );
    }
    else
    {
	_href_open( _a( 'CSRID' ), _a( 'SRID' ) );
    }
    output( $ref );
    output( ", " );
    output( $refname );
    output( '</a>' );
}

## ----------------------------------------------------------------------
sub _output_manref
{
    my ( $name, $section ) = @_;
    output( '<code>' );
    output( $name . '(' . $section . ')' );
    output( '</code>' );
}

## ----------------------------------------------------------------------
sub _output_email
{
    my ( $email ) = @_;
    output( " " ) if $in_author;
    output( '<a href="' );
    output( url( "mailto:" . $email )->as_string );
    output( '">' );
    output( _sani_html( $email ) );
    output( '</a>' );
}

## ----------------------------------------------------------------------
sub _output_ftpsite
{
    my ( $ftpsite ) = @_;
    output( '<code>' );
    output( _sani_html( $ftpsite ) );
    output( '</code>' );
}

## ----------------------------------------------------------------------
sub _output_ftppath
{
    my ( $ftpsite, $ftppath ) = @_;
    output( '<a href="' );
    output( url( "ftp://" . $ftpsite . $ftppath )->as_string );
    output( '">' );
    output( '<code>' );
    output(  _sani_html( $ftppath ) );
    output( '</code>' );
    output( '</a>' );
}

## ----------------------------------------------------------------------
sub _output_httpsite
{
    my ( $httpsite ) = @_;
    output( '<code>' );
    output( _sani_html( $httpsite ) );
    output( '</code>' );
}

## ----------------------------------------------------------------------
sub _output_httppath
{
    my ( $httpsite, $httppath ) = @_;
    output( '<a href="' );
    output( url( "http://" . $httpsite . $httppath )->as_string );
    output( '">' );
    output( '<code>' );
    output(  _sani_html( $httppath ) );
    output( '</code>' );
    output( '</a>' );
}

## ----------------------------------------------------------------------
sub _output_url
{
    my ( $id, $name ) = @_;
    $name = $id if $name eq "";
    output( '<a href="' );
    output( url( $id )->as_string );
    output( '">' );
    output( _sani_html( $name ) );
    output( '</a>' );
}

## ----------------------------------------------------------------------
sub _odata
{
    ( $data, $event ) = @_;
    output( _sani_html( $data ) );
}

## ----------------------------------------------------------------------
## helper definitions
## ----------------------------------------------------------------------

## ----------------------------------------------------------------------
sub _html_head
{
    my ( $pagetitle ) = @_;
    output( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n" );
    output( "\n" );
    output( "<html>\n" );
    output( "\n" );
    output( "<head>\n" );
    output( "\n" );
    output( "<title>" );
    output( _squash_markup( $pagetitle ) );
    output( "</title>\n" );
    output( "\n" );
    output( "</head>\n" );
    output( "\n" );
    output( "<body>\n" );
    output( "\n" );
}

## ----------------------------------------------------------------------
sub _start_file
{
    $cfilesrid = $_[0];
    $currentfile = length( $cfilesrid ) ? "$prefix$cfilesrid" : $rootfile;
    $currentfile .= ".html";
    push_output( 'file', "$writesubdir$currentfile" );
}
sub _finish_file
{
    output( "<hr>\n" );
    output( "\n" );
    if ( defined( $bchainsrid{$cfilesrid} ) )
    {
	output( "[" );
	_href_open( $bchainsrid{$cfilesrid}, '' );
	output( $lang{ 'back' } );
	output( "</a>]\n" );
    }
    if ( length( $abstract ) )
    {
        output( ' ' );
	output( "[" );
	_href_open( '', 'abstract' );
	output( $lang{ 'abstract' } );
	output( "</a>]\n" );
    }
    if ( length( $copyright ) )
    {
        output( ' ' );
	output( "[" );
	_href_open( '', 'copyright' );
	output( $lang{ 'copyright' } );
    	output( "</a>]\n" );
}
    output( ' ' );
    output( "[" );
    _href_open( '', 'contents' );
    output( $lang{ 'contents' } );
    output( "</a>]\n" );
    if ( defined( $fchainsrid{$cfilesrid} ) )
    {
        output( ' ' );
	output( "[" );
	_href_open( $fchainsrid{$cfilesrid}, '' );
	output( $lang{ 'next' } );
	output( "</a>]\n" );
    }
    output( "\n" );
    output( "<hr>\n" );
    output( "\n" );
    output( "$title<br>\n" );
    output( "\n" );
    output( "<address>\n" );
    output( "$version<br>\n" ) if length( $version );
    output( join( "<br>\n", @authors ), "\n" );
    output( "</address>\n" );
    output( "\n" );
    output( "</body>\n" );
    output( "\n" );
    output( "</html>\n" );
    output( "\n" );
    pop_output;
    $cfilesrid = $chaptsrid;
    undef $ftpsite;
    undef $httpsite;
}

## ----------------------------------------------------------------------
sub _sect
{
    ( my $hlevel, $element, $event ) = @_;
    if ( $need_hr )
    {
	output( "<hr>\n" );
	output( "\n" );
    }
    else
    {
	$need_hr = 1;
    }
    $hlevel += 2;
    output( "<h$hlevel>\n" );
    output( "<a name=\"" . _a( 'SRID' ) . "\">" );
    output( _a( 'CHAPT' ) . _a( 'SECT' ) . ' ' );
    $headclose = "</a>\n</h$hlevel>\n";
    undef $chaptheadnum;
}

## ----------------------------------------------------------------------
sub _start_list
{
    push( @listtag, $listtag );
    push( @itemtag, $itemtag );
    push( @lcompact, $lcompact );
    ( $listtag, $itemtag, $element, $event ) = @_;
    $lcompact = $element->attribute( 'COMPACT' )->type eq 'TOKEN';
    output( "<$listtag" );
    output( " compact" ) if $lcompact;
    output( ">\n" );
}
sub _end_list
{
    output( "</$listtag>\n" );
    $listtag = pop( @listtag );
    $itemtag = pop( @itemtag );
}

## ----------------------------------------------------------------------
sub _href_open
{
    output( '<a href="' );
    my $rfn = length( $_[0] ) ? "$prefix$_[0]" : $rootfile;
    $rfn .= ".html";
    output( $rfn ) if $rfn ne $currentfile;
    output( '#' . $_[1] ) if length( $_[1] );
    output( '"' );
    output( " $_[2]" ) if length( $_[2] );
    output( '>' );
}

## ----------------------------------------------------------------------
sub _squash_markup
{
    my ( $in ) = @_;
    $in =~ s/\<[^<>]*\>//g;
    $in;
}

## ----------------------------------------------------------------------
sub _sani_html
{
    my ( $in ) = @_;
    my $out = '';
    while ( $in =~ m/[<>&\"]/ )
    {
        $out .= $` . '&' . $htmlsani{$&} . ';';
        $in = $';
    }
    $out .= $in;
    $out;
}

## ----------------------------------------------------------------------
## SGML definitions
## ----------------------------------------------------------------------

use DebianDoc_SGML;

## ----------------------------------------------------------------------
