## -*- perl -*-
## ----------------------------------------------------------------------
## spec/lout: SGML conversion specification for Lout 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;

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

## ----------------------------------------------------------------------
## language definition
%languages = (
	      'da' => 'Danish',
	      'de' => 'German',
	      'es' => 'Spanish',
	      'fr' => 'French',
	      'it' => 'English',
	      'nl' => 'Dutch'
	      );
( $lang = POSIX::setlocale( LANG ) ) =~ s/_.*//;
if ( -r $ENV{ 'DEBIANDOCSGMLSPEC' } . '/i18n/' . $lang . $format )
{
    $language = $languages{ $lang };
    do $ENV{ 'DEBIANDOCSGMLSPEC' } . '/i18n/' . $lang . $format;
}
else
{
    $language = 'English';
    %lang = (
	     'abstract' => 'Abstract',
	     'copyright notice' => 'Copyright Notice',
	     'contents' => 'Contents',
	     );
}

## ----------------------------------------------------------------------
## paper size definition
my @paper = split( /\s/, `2>/dev/null paperconf -Ns` );
if ( $#paper >= 0 )
{
    $pagespec = "\@PageType { $paper[0] }";
    if ( $#paper > 1 )
    {
	$pagespec = "$pagespec \@PageWidth { $paper[1]p } \@PageHeight { $paper[2]p }";
    }
}

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

## ----------------------------------------------------------------------
sub start_chapt
{
    _sect( -1, @_ );
}
sub end_chapt
{
    $stat = '';
}

## ----------------------------------------------------------------------
sub start_appendix
{
    _sect( -2, @_ );
}
sub end_appendix
{
    $stat = '';
}

## ----------------------------------------------------------------------
sub start_heading
{
    _start_heading( _a( 'SRID' ), _a( 'CHAPT' )._a( 'SECT' ) );
}
sub end_heading
{
    _end_heading();
}

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

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

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

## ----------------------------------------------------------------------
sub start_item
{
    if ( $ltype ne 'Tagged' )
    {
        output( "\@ListItem {\n" );
    }
    else
    {
        output( $incompact 
		? "//1.0vx\n{|2f {\n" 
		: "//1.0vx\n\@RawIndentedDisplay {\n" );
    }
    $stat = 'p';
}
sub end_item
{
    if ( $ltype ne 'Tagged' )
    {
        output( "\n}\n" );
    }
    else
    {
        output( $incompact ? "\n}}\n" : "\n}\n" );
        $lhadtags = 2;
    }
}

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

## ----------------------------------------------------------------------
sub _output_start_book
{
}
sub _output_end_book
{
    output( "\n\@End \@Text\n" );
}

## ----------------------------------------------------------------------
sub _output_titlepag
{
    output( "\@SysInclude{ fontdefs }\n" );
    output( "\@SysInclude{ langdefs }\n" );
    output( "\@SysInclude{ dl }\n" );
    output( "\@SysInclude{ docf }\n" );
    output( "\@Use { \@DocumentLayout\n" );
    output( "	$pagespec\n" );
    output( "	\@ParaGap { 1.70vx }\n" );
    output( "	\@InitialBreak { 1.0fx ragged hyphen }\n" );
    output( "	\@InitialLanguage { $language }\n" );
    output( "	\@PageHeaders { Titles }\n" );
    output( "	\@OptimizePages { Yes }\n" );
    output( "	\@RunningEvenTop { \@B { \@PageNum } }\n" );
    output( "	\@RunningOddTop { \@Right { \@B { \@PageNum } } }\n" );
    output( "	\@RunningEvenFoot { $version \@Right { $title } }\n" );
    output( "	\@RunningOddFoot { $title \@Right { $version } }\n" );
    output( "	\@RunningStartEvenTop { \@Null }\n" );
    output( "	\@RunningStartOddTop { \@Null }\n" );
    output( "	\@RunningStartEvenFoot { $version \@Right { $title } }\n" );
    output( "	\@RunningStartOddFoot { $title \@Right { $version } }\n" );
    output( "}\n" );
    output( "\@Use { \@OrdinaryLayout }\n" );
    output( "\@Doc \@Text \@Begin\n" );
    output( "\@CenteredDisplay {clines 1.3v} \@Break {\n" );
    output( "+5p \@Font Bold \@Font { $title }\n" );
    grep( output( "-2p \@Font { $_ }\n" ), @authors );
    output( "$version\n" ) if length( $version );
    output( "}\n" );
    $headinglevel = 0;
    if ( length( $abstract ) )
    {
        _start_heading( '', _zero_num() );
	_odata( $lang{ 'abstract' } );
	_end_heading();
	output( "//1vx\n" );
        output( "$abstract\n" );
    }
    if ( length( $copyright ) )
    {
        _start_heading( '', _zero_num() );
	_odata( $lang{ 'copyright notice' } );
	_end_heading();
	output( "//1vx\n" );
        output( "$copyright\n" );
    }
}

## ----------------------------------------------------------------------
sub _output_copyrightsummaries
{
    my ( @copyrightsummaries ) = @_;
    output( "lines \@Break{\n" );
    output( join( "\n", @copyrightsummaries ), "\n" );
    output( "}\n" );
}

## ----------------------------------------------------------------------
sub _output_toc
{
    my ( $toc ) = @_;
    _start_heading( '', _zero_num() );
    _odata( $lang{ 'contents' } );
    _end_heading();
    output( "//1vx\n" );
    output( "$toc\n" );
}

## ----------------------------------------------------------------------
sub _output_tocentry
{
    my ( $tocentry ) = @_;
    $level = _num_level( _a( 'LEVEL' ) );
    return if $level > $tocdetail;
    $tocsrid = _a( 'SRID' );
    $number = _a( 'CHAPT' ) . _a( 'SECT' );
    if ( $level <= -1 )
    {
        output( "//0.3vx Bold \@Font " );
        $iiendheight = '1.00';
    }
    else
    {
        $iiendheight = '0.95';
    }
    output( "\@HAdjust { \@HContract { { $number. } |5fx {" );
    output( $tocentry );
    output( "} } |2f \@PageOf { $tocsrid } } //${iiendheight}vx\n" );
}

## ----------------------------------------------------------------------
sub _output_p
{
    my ( $paragraph ) = @_;
    output( "\@LP\n" ) unless $stat =~ m/p/;
    output( "$paragraph\n" );
    output( "\n" );
}

## ----------------------------------------------------------------------
sub _output_example
{
    my ( $example ) = @_;
    output( "\n" );
    _end_line();
    output( "{\@RawIndentedDisplay lines \@Break"
	    . " { {0.7 1.0} \@Scale {Courier Bold} \@Font {\n" );
    output( "$example\n" );
    output( "}}} //0.2fe\n" );
}

## ----------------------------------------------------------------------
sub _output_footnotes
{
}

## ----------------------------------------------------------------------
sub _output_footnote
{
    my ( $footnote ) = @_;
    if ( $stat =~ /f$/ )
    {
	output( '{@AnotherFootNote{ ' );
    }
    else
    {
	output( '{@FootNote{ ' );
    }
    output( $footnote );
    output( '}}' );
}

## ----------------------------------------------------------------------
sub _output_footnotebody
{
}

## ----------------------------------------------------------------------
sub _output_footnoteref
{
}

## ----------------------------------------------------------------------
sub _output_tag
{
    my ( $tag ) = @_;
    if ( ( ! $incompact ) && ( $lhadtags == 2 ) )
    {
	output( "//0fe //1.2fx\n" );
    }
    elsif ( $lhadtags )
    {
	output( "//1.0vx\n" );
    }
    output( "{|0.5f {" );
    output( $tag );
    output( "}}\n" );
    $lhadtags = 1;
}

## ----------------------------------------------------------------------
sub _output_em
{
    my ( $em ) = @_;
    _start_italic();
    output( "$em" );
    _end_italic();
}

## ----------------------------------------------------------------------
sub _output_strong
{
    my ( $strong ) = @_;
    _start_bold();
    output( "$strong" );
    _end_bold();
}

## ----------------------------------------------------------------------
sub _output_var
{
    my ( $var ) = @_;
    _start_italic();
    output( "$var" );
    _end_italic();
}

## ----------------------------------------------------------------------
sub _output_package
{
    my ( $package ) = @_;
    _start_courier();
    output( "$package" );
    _end_courier();
}

## ----------------------------------------------------------------------
sub _output_prgn
{
    my ( $prgn ) = @_;
    _start_courier();
    output( "$prgn" );
    _end_courier();
}

## ----------------------------------------------------------------------
sub _output_file
{
    my ( $file ) = @_;
    _start_courier();
    output( "$file" );
    _end_courier();
}

## ----------------------------------------------------------------------
sub _output_tt
{
    my ( $tt ) = @_;
    _start_courier();
    output( "$tt" );
    _end_courier();
}

## ----------------------------------------------------------------------
sub _output_qref
{
    my ( $qref ) = @_;
    output( $qref );
}

## ----------------------------------------------------------------------
sub _output_ref
{
    my ( $ref ) = @_;
    my $refname = _a( 'SRID' );
    _odata( '`' );
    output( $ref );
    _odata( "', " );
    output( "page \@PageOf{$refname}" );
}

## ----------------------------------------------------------------------
sub _output_manref
{
    my ( $name, $section ) = @_;
    _start_courier();
    _odata( $name . '(' . $section . ')' );
    _end_courier();
}

## ----------------------------------------------------------------------
sub _output_email
{
    my ( $email ) = @_;
    output( " " ) if ( $in_author );
    _start_courier();
    _odata( '<' );
    output( $email );
    _odata( '>' );
    _end_courier();
}

## ----------------------------------------------------------------------
sub _output_ftpsite
{
    my ( $ftpsite ) = @_;
    _start_courier();
    output( $ftpsite );
    _end_courier();
}

## ----------------------------------------------------------------------
sub _output_ftppath
{
    my ( $ftpsite, $ftppath ) = @_;
    _start_courier();
    output( $ftppath );
    _end_courier();
}

## ----------------------------------------------------------------------
sub _output_httpsite
{
    my ( $httpsite ) = @_;
    _start_courier();
    output( $httpsite );
    _end_courier();
}

## ----------------------------------------------------------------------
sub _output_httppath
{
    my ( $httpsite, $httppath ) = @_;
    _start_courier();
    output( $httppath );
    _end_courier();
}

## ----------------------------------------------------------------------
sub _output_url
{
    my ( $id, $name ) = @_;
    _odata( $name ) if $name ne "";
    output( " (" ) if $name ne "";
    _start_courier();
    _odata( $id );
    _end_courier();
    output( ")" ) if $name ne "";
}

## ----------------------------------------------------------------------
sub _odata
{
    ( $data, $event ) = @_;
    $stat =~ s/f$//;
    if ( m/\S/ )
    {
	$stat =~ s/p/t/;
    }
    $_ = $data;
    if ( $stat =~ m/x/ )
    {
        s,\n, //1vx\n,g;
        output( _sani( $_, 1 ) );
    }
    else
    {
        s/\s+/ /g;
        output( _sani( $_, ( $stat =~ m/c[^R]*$/ ) ) );
    }
}

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

## ----------------------------------------------------------------------
sub _sect
{
    ( $headinglevel, $element, $event ) = @_;
}

## ----------------------------------------------------------------------
sub _start_heading
{
    my ( $pagemark, $number ) = @_;
    output( "\@LP\n" ) unless $stat =~ m/p/;
    output( $headinglevel < 0 ? '@NP' : '@CNP' );
    output( "\n" );
    if ( $headinglevel <= 0 )
    {
        output( "{\n"
		. "  newpath   0  ysize 0.3 ft sub  moveto\n"
		. "            xsize  0  rlineto\n"
		. "            0  "
		. ( $headinglevel < 0 ? '0.2' : '0.1' )
		. " ft  rlineto\n"
		. "            xsize neg  0  rlineto\n"
		. "  closepath fill\n"
		. "} \@Graphic { //1.6f \@HAdjust { \@HContract {" );
        $hend= "} |0f }} //0.0fe\n";
    }
    else
    {
        $hend= "//0.2fe\n";
    }
    output( '@Heading +' . ( 4 - $headinglevel )
	    . "p \@Font { 1.2vx \@Break {" );
    output( " {\@PageMark $pagemark}" ) if length( $pagemark );
    output( "\n$number.|0.5fe{ " );
    $stat = 'h';
}
sub _end_heading
{
    output( "}}}$hend\n" );
    $stat = '';
}

## ----------------------------------------------------------------------
sub _start_list
{
    $stat =~ s/f$//;
    push( @ltypes, $ltype );
    ( $ltype, $element, $event ) = @_;
    $incompact++ if ( $incompact 
		     || $element->attribute( 'COMPACT' )->type eq 'TOKEN' );
    if ( $ltype eq 'Enum' )
    {
        $ltype= ( ( $enumlistnest++ ) & 1 ) ? 'Roman' : 'Numbered';
    }
    if ( $incompact )
    {
	_end_line();
    }
    elsif ( $stat =~ m/t/ )
    {
	output( "\@LP\n" );
    }
    if ( $ltype ne 'Tagged' )
    {
        output( "{\@Raw${ltype}List\n" );
        output( "  gap { 1.0vx }\n" ) if $incompact;
    }
    push( @stats, $stat );
    push( @lhadtags, $lhadtags );
    $lhadtags = 0;
}
sub _end_list
{
    if ( $ltype ne 'Tagged' )
    {
        output( "\@RawEndList}//0ve\n" );
        $enumlistnest-- if $ltype ne 'Bullet';
    }
    else
    {
        output( $incompact ? "//0.2fe" : "//0fe\n" );
    }
    $stat = pop( @stats );
    $lhadtags = pop( @lhadtags );
    if ( $incompact )
    {
        $stat =~ s/^/l/;
    }
    else
    {
        $stat = 'P';
    }
    $ltype = pop( @ltypes );
    $incompact-- if $incompact;
}

## ----------------------------------------------------------------------
sub _start_courier
{
    _rescale();
    output( "{{0.7 1.0} \@Scale {Courier Bold} \@Font {" );
    $stat .= 'c';
}
sub _end_courier
{
    $stat =~ s/.$//;
    output( "}}" );
    _unrescale();
}

## ----------------------------------------------------------------------
sub _start_italic
{
    _rescale();
    $stat .= 'i';
    output( "{{Times Slope} \@Font {" );
}
sub _end_italic
{
    output( "}}" );
    $stat =~ s/.$//;
    _unrescale();
}

## ----------------------------------------------------------------------
sub _start_bold
{
    _rescale();
    $stat .= 'b';
    output( "{{Bold} \@Font {" );
}
sub _end_bold
{
    output( "}}" );
    $stat =~ s/.$//;
    _unrescale();
}

## ----------------------------------------------------------------------
sub _rescale
{
    $stat =~ s/f$//;
    return unless $stat =~ m/[cx][^R]*$/;
    output( "{{1.4285714285 1.0} \@Scale {" );
    $stat .= 'R';
}
sub _unrescale
{
    return unless $stat =~ s/R$//;
    output( "}}" );
}

## ----------------------------------------------------------------------
sub _start_line
{
    output( "\@LP\n" ) if $stat =~ s/P/t/;
}
sub _end_line
{
    _start_line();
    output( "//1.0vx\n" ) unless $stat =~ s/p/t/;
}

## ----------------------------------------------------------------------
sub _sani
{
    my ( $in, $hyphens ) = @_;
    my $out;
    $in = ' ' . $in . ' ';
    $out = '';
    while ( $in =~ m/(\s)(\S*[\-\@\/|\\\"\^\&\{\}\#\~]\S*)(\s)/ )
    {
        $out .= $` . $1;
        $in = $3 . $';
        $_ = $2;
        s/[\\\"]/\\$&/g;
        s/-/"--"/g if $hyphens;
        $out .= '"' . $_ . '"';
    }
    $out .= $in;
    $out =~ s/^ //;
    $out =~ s/ $//;
    $out;
}

## ----------------------------------------------------------------------
sub _zero_num
{
    '0.' . ++$c_zero_num;
}

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

use DebianDoc_SGML;

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