use strict;

# ==============================================================================
# latex output
sub ET3
{
    my ($node, $et) = @_;
    $_ = $node->{'path'};

# sections and floats ------------------------------------------------------
    m</div_sect0/$> && do {
        print "\\begin\{nextchtoc\}\n";
        $node->Proc( \&ET3_chtoc );
        print "\\end\{nextchtoc\}\n";
        return $node->Proc( $et );
    };

    m</div_(sect[0123])/$> && 
        return $node->Proc( $et );

#    m</div_(sect[0123])/(h[234]|p|[uod]l|div_programlisting)/$> && 
#        return $node;


    m</div_example/$> && do {
        print "\n\n\\begin\{example\}\n";
        print( ( $node->{'root'}{'style'}{ $node->{'attr'}{'name'} } 
              or '' ) . "\n" );
        $node->Proc( $et );
        print "\\end\{example\}\n";
        return $node;
    };

    m</div_table/$> && do {
        my $env = ( $node->{'root'}{'style'}{ 
            "div_table" . $node->{'attr'}{'name'} } or 'table' );

        print "\n\n\\begin\{$env\}\[ht!\]\n";
        $node->Proc( $et );
        print "\\end\{$env\}\n";
        return $node;
    };

    m</div_figure/$> && do {
        print "\n\n\\begin\{figure\}\[ht!\]\n";
        push @{$node->{'content'}}, shift @{$node->{'content'}};
        $node->Proc( $et );
        print "\\end\{figure\}\n";
        return $node;
    };

# captions -----------------------------------------------------------------
    m</div_sect0/h1/$> && print "\n\n\\chapter";
    m</div_sect([123])/h[234]/$> && print "\n\n\\", "sub" x ($1-1), "section";
    m</div_(table|figure|example)/h4/$> && print "\\caption";

    m</h[1234]/$> && do {
        print "\{";
        $node->Proc( $et );
        print "\}\n", Label( $node );
        return $node;
    };

# content of figure --------------------------------------------------------
    m</div_figure/img/$> && do {
        my $img = $node->{'attr'}{'src'}|| die;
        $img =~ s/\.gif$//;
        print "\\centerline\{\\includegraphics[width=\\columnwidth]\{$img\}\}\n";
        return $node;
    };

#tables --------------------------------------------------------------------
    m</table/$> && do {
        print "\\begin{mmtabular}[" .
            ( $node->{'root'}{'style'}{ $node->{'parent'}{'attr'}{'name'} } 
              or '' ) . "]\n";

        $node->Proc( $et, 'path' => 'COL/', 'column' => [] );        
        foreach my $col (@{$node->{'column'}})
        {
            print "\\column{";
            $col->Proc( $et );
            print "}\n";
        }

        $node->Proc( $et, 'path' => '/table/' );        
        print "\\end{mmtabular}\n";
        return $node;
    };

    m<^COL/tr([hd])/$> && return $node->Proc( $et, 'col' => 0 );

    m<^COL/tr([hd])/t[dh]/$> && do {
        if( !defined( $node->{'parent'}{'parent'}{'column'}[
                               $node->{'parent'}{'col'} ] ) )
        {
            $node->{'parent'}{'parent'}{'column'}[ $node->{'parent'}{'col'} ] = 
                new ML::Tree( 'COL', {} );
        }

        $node->{'tag'} = "t$1";
        $node->{'parent'}{'col'} ++;
        $node->{'parent'}{'parent'}{'column'}[ 
                              $node->{'parent'}{'col'} - 1 ]->Add( $node );
        return $node;
    };

    m<^COL/t([dh])/$> && do {
        if( $node->{'attr'}{'colspan'} )  {print "\\cr"; return $node;}
        print "\\c$1\{";
        $node->Proc( $et );        
        print "}\\cr ";
        return $node;
    };

    m<^COL/t[dh]/p/$> && do { print "\\tpar "; return $node; };

    m</table/tr([hd])/$> && do {
        print "\\tr$1\{";
        $node->Proc( $et );
        print "}\n";
        return $node;
    };

    m</table/tr[hd]/t[dh]/$> && do {
        my $algn = $node->{'attr'}{'align'} ?
            $node->{'attr'}{'align'} eq 'center' ? 'c' :
                $node->{'attr'}{'align'} eq 'right' ? 'r' : 'l' : 'l';
        if( $node->{'attr'}{'colspan'} )
        {
            for( my $i = $node->{'attr'}{'colspan'}; $i > 1; -- $i )
            {    print "\\sp"; }
        }
        print "\\td$algn\{";
        $node->{'tx'} = 0;
        $node->Proc( $et );
        print "}";
        return $node;
    };

    m</t[dh]/TEXT_S> && !$node->{'parent'}{'tx'} && return $node;

    m</t[dh]/TEXT> && ($node->{'parent'}{'tx'} = 1);

    m</t[dh]/p/$> && do {
        print "\\tabpar{";
        $node->Proc( $et );
        print "}";
        return $node;
    };

# footnotes ----------------------------------------------------------------
    m</a_footnote/$> && do {
        print "\\footnote\{";
        $node->Proc( $et );
        print "\}";
        return $node;
    };

# lists --------------------------------------------------------------------
    m</ul/$> and $node->{'tx'} = 'itemize';
    m</ol/$> and $node->{'tx'} = 'enumerate';
    m</dl/$> and $node->{'tx'} = 'description';

    m</([uod])l/$> && do {
        print "\\begin\{$node->{'tx'}\}\n";
        $node->Proc( $et );
        print "\n\\end\{$node->{'tx'}\}\n";
        return $node;
    };

    m</li/$> && do { print "\n\\item ";  return $node->Proc( $et ); };
    m</dt/$> && do { print "\n\\item[";  return $node->Proc( $et ); };
    m</dt/br/$> && return $node;
    
    m</dd/$> && do { print "] ";  return $node->Proc( $et ); };

# references to floats and chapters ------------------------------------------
    m</a_fig/$> && print "Figure~\\ref\{$node->{'attr'}{'label'}\}";
    m</a_ex/$> && print "Example~\\ref\{$node->{'attr'}{'label'}\}";
    m</a_tab/$> && print "Table~\\ref\{$node->{'attr'}{'label'}\}";
    m</a_ch/$> && print "Chapter~\\ref\{$node->{'attr'}{'label'}\}";
#    m</ref_app/$> && print "Appendix~\\ref\{$node->{'attr'}{'label'}\}";
    m</a_app/$> && do {
        $node->{'attr'}{'label'} =~ /(\w)$/;
        print "Appendix~", uc($1);
    };
    m</a_ref/$> && do {
        $node->{'attr'}{'label'} =~ /(\w)$/;
        print "[$1]";
    };


    m</a_(fig|ex|tab|ch|app|ref)/$> &&  return $node;

# programlisting -----------------------------------------------------------
    m</div_(example|sect[0123])/div_programlisting/$> && do {
        print "\n\n\\begin\{code\}\n";
        $node->Proc( $et );
        print "\\end\{code\}\n";
        return $node;
    };

    m</t[dh]/div_programlisting/$> && do {
        print "\\vtop{";
#        $main::rows = 1;
        print "\\begin\{code\}";
        $node->Proc( $et );
        print "\\end\{code\}";
        print "}";
        return $node;
    };


    m</(dd|li)/div_programlisting/$> && do {
        print "\\begin\{code\}";
        $node->Proc( $et );
        print "\\end\{code\}";
        return $node;
    };



    
# other --------------------------------------------------------------------
    m</br/> && do { print "\\\\"; return $node; };

    m</(tt|i|b)/$> && do { 
        print "\\text" . { 'tt' => 'tt', 'i' => 'it', 'b' => 'bf' }->{$1} .
            "\{";
        $node->Proc( $et ); 
        print "\}";
        return $node;
    };

    m</p/$> && do { $node->Proc( $et ); print "\\par"; return $node; };

    m</div_programlisting(/\w+)*/TEXT(_S)?/$> && do { 
        CodeText( $node ); 
        return $node;
    };

    m</tt(/w+)*/TEXT(_S)?/$> && do { TText( $node ); return $node };
    m</i(/w+)*/TEXT(_S)?/$> && do { IText( $node ); return $node };

    m</TEXT(_S)?/$> && do { Text( $node ); return $node };

    die $node->Tx( "%f unhandled %p\n " );
}

sub ET3_chtoc
{
    my ($node, $et) = @_;
    $_ = $node->{'path'};

    m</div_sect1/h2/$> && do {
        print "\\chtocitem\{";
        $node->Proc( \&ET3 );
        print "\}\n";
        return $node;
    };

    m</div_sect1/$> &&  return $node->Proc( $et );
    return $node;
}

sub Label
{
    my $node = shift;
    my $tx = "\\label\{$node->{'attr'}{'name'}\}";
    if( $node->{'attr'}{'orignum'} )
    {
        $tx .= "  % $node->{'attr'}{'orignum'}";
    }

    return $tx . "\n";
}

sub TText
{
    my $Tx = $_[0]->{'content'};

    Diag( $_[0]->Tx( "%f warning: end of sentence in [it]t in %p", 'w' ) )
        if( $Tx =~ /\w\.\s/ );

    $Tx = SpecChars( $Tx );
    $Tx =~ s/(\S)\.(\S)/$1\\\.$2/g;
    $Tx =~ s/\"/\\\"/g;

    print $Tx;
}

sub IText
{
    my $Tx = $_[0]->{'content'};

    Diag( $_[0]->Tx( "%f warning: end of sentence in [it]t in %p", 'w' ) )
        if( $Tx =~ /\w\.\s/ );

    $Tx = SpecChars( $Tx );
    $Tx =~ s/(\S)\.(\S)/$1\\\.$2/g;

    $Tx =~ s/</\\</g;
    $Tx =~ s/>/\\>/g;
    $Tx =~ s/\"/\\\"/g;
    print $Tx;
}

sub Text
{
    my $Tx = $_[0]->{'content'};

    Diag( $_[0]->Tx( "%f warning: end of sentence without space in %p", 'w' ) )
        if( $Tx =~ /\S\.\S/ );
    $Tx = SpecChars( $Tx );
    $Tx =~ s/</\\</g;
    $Tx =~ s/>/\\>/g;
    print $Tx;
}


sub SpecChars
{
    my $Tx = shift;
    $Tx =~ s/\\/\\bslsh /g;
    $Tx =~ s/\&lt;/</g;
    $Tx =~ s/\&gt;/>/g;
    $Tx =~ s/\&quot;/\"/g;
    $Tx =~ s/\&apos;/\'/g;
    $Tx =~ s/\&nbsp;/~/g;
    $Tx =~ s/\&copy;/\\cp /g;
    $Tx =~ s/\&amp;/\\&/g;
    $Tx =~ s/\$/\\\$/g;
    $Tx =~ s/\{/\\\{/g;
    $Tx =~ s/\}/\\\}/g;
    $Tx =~ s/_/\\_/g;
    $Tx =~ s/%/\\%/g;
    $Tx =~ s/\#/\\\#/g;
    $Tx =~ s/\|/\\\|/g;
    $Tx =~ s/\^/\\\^/g;
    $Tx =~ s/([^-])--([^-])/$1\\=$2/g;
    $Tx =~ s/\\bslsh /{\\bslsh}/g;
    $Tx =~ s/\\cp /{\\copyright}/g;
    return $Tx;
}

sub CodeText
{
    my $Tx = $_[0]->{'content'};

    $Tx =~ s/\\/\\bslsh /g;
    $Tx =~ s/\&lt;/</g;
    $Tx =~ s/\&gt;/>/g;
    $Tx =~ s/\&quot;/\"/g;
    $Tx =~ s/\&apos;/\'/g;
    $Tx =~ s/\&nbsp;/ /g;
    $Tx =~ s/\&copy;/\\cp /g;
    $Tx =~ s/\&amp;/\\&/g;
    $Tx =~ s/%/\\%/g;
    $Tx =~ s/\#/\\\#/g;
    $Tx =~ s/\$/\\\$/g;
    $Tx =~ s/\{/\\\{/g;
    $Tx =~ s/\}/\\\}/g;
    $Tx =~ s/\./\\\./g;
    $Tx =~ s/\,/\\\,/g;
    $Tx =~ s/-/\\-/g;
    $Tx =~ s/\//\\\//g;
    $Tx =~ s/\\bslsh /{\\bslsh}/g;
    $Tx =~ s/\\cp /{\\copyright}/g;
    $Tx =~ s/~/\\vlnovka\\/g;
    $Tx =~ s/ /~/g;
    $Tx =~ s/\\vlnovka\\/\\~/g;
    $Tx =~ s/_/\\_/g;
    $Tx =~ s/\^/\\\^/g;
    $Tx =~ s/\|/\\\|/g;
    $Tx =~ s/(\S)\s*$/$1/;
    if( $main::rows )
    {
        $Tx =~ s/\n/\}\n\\row\{/g;
    }
    else
    {
        $Tx =~ s/\n/\\\\\n/g;
    }
    print $Tx;
}


1;



