code:
# -*-perl-*-
#+##############################################################################
#
# html32.pm: output HTML 3.2
#
#    Copyright (C) 2003, 2004, 2007, 2009 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License,
# or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Originally written by Patrice Dumas.
#
#-##############################################################################

use strict;

set_default('COMPLEX_FORMAT_IN_TABLE', 1);

#html_default_load();
t2h_default_load_format('html');

set_default('DOCTYPE', '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN" "http://www.w3.org/TR/html32/loose.dtd">');

set_default('FRAMESET_DOCTYPE', get_conf('DOCTYPE'));

set_from_init_file('BODYTEXT', 'bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000"');
# this controls the pre style for menus
$MENU_PRE_STYLE = '';

$NO_BULLET_LIST_STYLE ='';

$MENU_SYMBOL = '*';

# This lines are inserted before and after the shortcontents
$BEFORE_OVERVIEW = "";
$AFTER_OVERVIEW = '';

# This lines are inserted before and after the contents
$BEFORE_TOC_LINES = "";
$AFTER_TOC_LINES = '';

# html version for latex2html
set_default('L2H_HTML_VERSION', '3.2');

# no css. NO_CSS also triggers no class if html_default_attribute_class
# is used, which is the case for all the dynamically output elements.
set_default('NO_CSS', 1);

# no accesskey in html 3.2
set_default('USE_ACCESSKEY', 0);

# Similar with what t2h_default_set_iso_symbols(0) does but without changing
# all the things command, only a selected list.
# USE_ISO is not needed since normal_text is redefined.
set_default('OPEN_QUOTE_SYMBOL', '`');
set_default('CLOSE_QUOTE_SYMBOL', "'");
t2h_remove_text_substitutions("'", 1, 0, 0, 1);
t2h_remove_text_substitutions('`', 1, 0, 0, 1);

foreach my $command ('euro', 'geq', 'leq',
   'bullet', 'equiv', 'expansion', 'point', 'result', 'arrow',
   'quotedblleft', 'quotedblright',
   'quoteleft', 'quoteright',
   'quotedblbase', 'quotesinglbase', 'guillemetleft', 'guillemetright',
   'guillemotleft', 'guillemotright', 'guilsinglleft', 'guilsinglright')
{
    $things_map{$command} = &$protect_text($default_things_map{$command});
    $pre_map{$command} = $things_map{$command};
}

$things_map{'oe'} = 'œ';
$things_map{'OE'} = 'Œ';
$things_map{'dots'} = '...';
$things_map{'enddots'} = '...';

$pre_map{'dots'} = '...';
$pre_map{'oe'} = $things_map{'oe'};
$pre_map{'OE'} = $things_map{'OE'};

$style_map{'sansserif'} = {};
$style_map{'r'} = {};
$style_map_pre{'r'} = {};
$style_map_pre{'sansserif'} = {};

$format_map{'multitable'} = 'table';

# formatting functions

$protect_text      = \&t2h_html32_protect_text;
$normal_text       = \&t2h_html32_normal_text;
#$acronym_like      = \&t2h_html32_acronym_like;
$acronym_like      = \&t2h_default_acronym_like;
$row               = \&t2h_html32_row;
$cell              = \&t2h_html32_cell;

# " is not in html 3.2
sub t2h_html32_protect_text($)
{
   my $text = shift;
   $text =~ s/&/&/g;
   $text =~ s/</</g;
   $text =~ s/>/>/g;
   $text =~ s/\"/"/g;
   return $text;
}

sub t2h_html32_normal_text($$$$$$$;$)
{
   my $text = shift;
   my $in_raw_text = shift;
   my $in_preformatted = shift;
   my $in_code = shift;
   my $in_math = shift;
   my $in_simple = shift;
   my $style_stack = shift;
   my $state = shift;

   $text = uc($text) if (in_cmd($style_stack, 'sc'));
   $text = &$protect_text($text) unless($in_raw_text);
   if (! $in_code and !$in_preformatted)
   {
       if ($in_raw_text) #FIXME really do that ? It is done by makeinfo
       {
           $text =~ s/``/"/g;
           $text =~ s/''/"/g;
       }
       else
       {
           $text =~ s/``/"/g;
           $text =~ s/''/"/g;
       }
       # FIXME really do that in raw text?
       $text =~ s/---/\x{1F}/g;
       $text =~ s/--/-/g;
       $text =~ s/\x{1F}/--/g;
   }
   return $text;
}

# no acronym, and no abbr in html 3.2
sub t2h_html32_acronym_like($$$$$$)
{
    my $command = shift;
    my $acronym_texi = shift;
    my $acronym_text = shift;
    my $with_explanation = shift;
    my $explanation_lines = shift;
    my $explanation_text = shift;
    my $explanation_simply_formatted = shift;

    if ($with_explanation)
    {
        return gdt('{acronym_like} ({explanation})', {'acronym_like' => $acronym_text, 'explanation' => $explanation_text},{'duplicate'=>1})
    }
    else
    {
        return $acronym_text;
    }
}

# row in multitable. no thead in html 3.2
sub t2h_html32_row($$)
{
    my $text = shift;
    my $macro = shift;

    if ($text =~ /\S/)
    {
         return '
' . $text . '
' . "\n";
    }
    return '';
}

# cell in multitable. in html 3.2 width is in pixel and not in percent in
# th or td.
sub t2h_html32_cell($$)
{
    my $text = shift;
    my $row_macro = shift;
    my $columnfractions = shift;
    my $prototype_row = shift;

    $text =~ s/^\s*//;
    $text =~ s/\s*$//;

    if ($row_macro eq 'headitem')
    {
        return "" . $text . '	';
    }
    return "" . $text . '	';
}


code:
# -*-perl-*-
######################################################################
# File: mediawiki.pm
#
# Override values for various customizable procedures are set in this file
# in such a way as to create text suitable for pasting into a MediaWiki.
#
# Load the file with command-line option: --init-file mediawiki.pm
#
# This file is in the public domain. Thus it may easily be used as an
# example for further customizations.
#
# Originally written by Derek Price in 2005.
# Modified in 2008 and 2009.
#
# $Id: mediawiki.pm,v 1.1 2011-04-09 00:10:45 pertusus Exp $

use strict;

#html_default_load();
t2h_default_load_format('html');

# remark: in my tests, there was no support for mathtt in texvc
# https://bugzilla.wikimedia.org/show_bug.cgi?id=21475
default_load_tex_math();

# inline css style
set_default('INLINE_CSS_STYLE', 1);

set_default('USE_SECTIONS', 1);
set_default('USE_NODES', undef);

# numbers are added automatically based on mediawiki markup
set_default('NUMBER_SECTIONS', 0);

# if this is set footnotes are on a separated page. Otherwise they are at
# the end of each file (if the document is split).
# At the end is better for the mediawiki output which is more per page
# oriented.
set_default('footnotestyle', 'end');

# extension
set_default('EXTENSION', undef);

# extension for nodes files when NODE_FILES is true
set_default('NODE_FILE_EXTENSION', '');

# no title page at the beginning
set_default('USE_TITLEPAGE_FOR_TITLE', 0);

# if set and SPLIT is set, then split index pages at the next letter
# after they have more than that many entries
set_default('SPLIT_INDEX', undef);

# Use preformatted menus.
set_default('SIMPLE_MENU', 1);

# no NODE_FILES. In fact the whole ref to external manual is broken.
# This may be revisited later.
set_default('NODE_FILES', 0);

$DEFAULT_RULE = "\n----\n";

my %mediawiki_table_commands;

# FIXME b, i could be ''' ''
# FIXME ''' and '' are stopped by end of lines!
my %style_map_mediawiki = (
  'emph',       {'inline_begin' => "''"},
  'email',      {'function' => \&mediawiki_default_email},
  'math',       {'function' => \&mediawiki_default_math},
  'url',      {'function' => \&mediawiki_default_uref},
  'uref',      {'function' => \&mediawiki_default_uref},
  'strong',     {'inline_begin' => "'''"}
);

foreach my $style_command (keys(%style_map_mediawiki))
{
    if ($style_map_mediawiki{$style_command}->{'inline_begin'})
    {
        foreach my $key ('inline_attribute', 'attribute')
        {
            delete $style_map_pre{$style_command}->{$key};
            delete $style_map{$style_command}->{$key};
        }
        $style_map_pre{$style_command}->{'inline_end'} = $style_map_mediawiki{$style_command}->{'inline_begin'};
        $style_map{$style_command}->{'inline_end'} = $style_map_mediawiki{$style_command}->{'inline_begin'};
    }
    foreach my $key (keys(%{$style_map_mediawiki{$style_command}}))
    {
        $style_map_pre{$style_command}->{$key} = $style_map_mediawiki{$style_command}->{$key};
        $style_map{$style_command}->{$key} = $style_map_mediawiki{$style_command}->{$key};
    }
}

# no samp/kbd in allowed html elements in the default case.
foreach my $style_command (keys(%style_map))
{
    if ($style_map{$style_command}->{'inline_attribute'})
    {
        $style_map{$style_command}->{'inline_attribute'} =~ s/^(samp|kbd)/code/;
    }
}

foreach my $style_command (keys(%style_map_pre))
{
    if ($style_map_pre{$style_command}->{'inline_attribute'})
    {
        $style_map_pre{$style_command}->{'inline_attribute'} =~ s/^(samp|kbd)/code/;
    }
}

$style_map{'indicateurl'} = {'begin' => '<<nowiki>', 'end' => '</nowiki>>'};
$style_map_pre{'indicateurl'} = {'begin' => '<<nowiki>', 'end' => '</nowiki>>'};

sub mediawiki_default_email($$)
{
    my $command = shift;
    my $args = shift;
    my $mail = shift @$args;
    my $text = shift @$args;
    $text = '' if (!defined($text));
    $mail = main::normalise_space($mail);
    $text = main::normalise_space($text);
    return $text if ($mail eq '');
    $text = ' ' . $text if ($text ne '');
    return "[mailto:$mail$text]";
}

sub mediawiki_default_uref($$)
{
    shift;
    my $args = shift;
    my $url = shift @$args;
    my $text = shift @$args;
    my $replacement = shift @$args;
    $url = main::normalise_space($url);
    $replacement = '' if (!defined($replacement));
    $replacement = main::normalise_space($replacement);
    $text = '' if (!defined($text));
    $text = main::normalise_space($text);
    $text = $replacement if ($replacement ne '');
    return $text if ($url eq '');
    return &$anchor('', $url, $text);
}

sub mediawiki_default_math($$)
{
    shift;
    my $args = shift;
    my $text = shift @$args;
    return "<math>$text</math>";
}

foreach my $format ('enumerate', 'table', 'vtable', 'ftable')
{
   $format_map{$format} = '';
}

my %processed_formats = ();
# there are no pre used in mediawiki, to have links working in
# complex formats, therefore the styles are copied in div that
# are used instead. This doesn't really improve the situation,
# though, since the div outside of a
 is not taken into account.
foreach my $complex_format (keys(%complex_format_map))
{
   my $class = $complex_format_map{$complex_format}->{'class'};
   $class = $complex_format if (!defined($class));

   # Avoid doing things twice if the class is associated with more than one
   # complex format
   next if($processed_formats{$class});

   if (defined($css_map{"pre.$class"}))
   {
      if (defined($css_map{"div.$class"}))
      {
           $css_map{"div.$class"} .= "; ";
      }
      else
      {
            $css_map{"div.$class"} = '';
      }
      $css_map{"div.$class"} .= $css_map{"pre.$class"};
   }
   $processed_formats{$class} = 1;
}

foreach my $format ('example', 'display', 'lisp', 'format')
{
   $complex_format_map{$format}->{'begin'} = html_default_attribute_class('div', $format).">\n";
   $complex_format_map{"small$format"}->{'begin'} = html_default_attribute_class('div', "small$format").">\n";
   $complex_format_map{$format}->{'end'} = '
'."\n";
   $complex_format_map{"small$format"}->{'end'} = '
'."\n";
}
foreach my $format ('menu', 'detailmenu', 'menu_comment')
{
   my $class = $complex_format_map{$format}->{'class'};
   $class = $format if (!defined($class));
   $complex_format_map{$format}->{'begin'} = html_default_attribute_class('div', $class).">\n";
   $complex_format_map{$format}->{'end'} = '
'."\n";
}

$texi_formats_map{'direntry'} = 0;

# no acronym nor abbr allowed in wikitext.
$acronym_like = \&t2h_default_acronym_like;

push @command_handler_setup, \&mediawiki_default_initialize_variables;

my %mediawiki_doc_nr_to_file; # File name cache based on file index.
my %mediawiki_target_to_name;
my %mediawiki_special_file_name;
sub mediawiki_default_initialize_variables()
{
    %mediawiki_doc_nr_to_file = (); # File name cache based on file index.
    %mediawiki_target_to_name = ();
    %mediawiki_special_file_name = ();
}

my @html_files_from_tex;
my $mediawiki_out_dir;
my $tex_extension;

push @command_handler_init, \&mediawiki_default_init_html_to_wiki;

sub mediawiki_default_init_html_to_wiki
{
  # This must be done here, because the latex2html handler is added
  # after command line scanning, so after the mediawiki.pm parsing
  push @command_handler_process, \&mediawiki_default_html_to_wiki;

  $command_handler{'math'}->{'init'} = undef;
  $command_handler{'math'}->{'expand'} = undef;
  $command_handler{'math'} = undef;
  $mediawiki_out_dir = "$Texi2HTML::THISDOC{'destination_directory'}";
  $mediawiki_out_dir = './' if (!defined($mediawiki_out_dir) or $mediawiki_out_dir =~ /^\s*$/);
  @html_files_from_tex = ();
  $tex_extension = undef;
  if ($Texi2HTML::THISDOC{'extensions'}->{'tex4ht'})
  {
    push @html_files_from_tex, "$Texi2HTML::THISDOC{'file_base_name'}_tex4ht_tex.html";
    $tex_extension = 'tex4ht';
  }
  elsif (get_conf('L2H'))
  {
    push @html_files_from_tex, "$Texi2HTML::THISDOC{'file_base_name'}_l2h.html";
    $tex_extension = 'l2h';
    # avoid use of the cache
    set_default('L2H_SKIP', 0);
  }
}

# could be in texi2html.pm...
sub mediawiki_default_readd_end_of_lines($$$$;$)
{
   my $from_file = shift;
   my $to_file = shift;
   my $tex_extension = shift;
   my $basename = shift;
   my $before_wiki = shift;
   # html2wiki removes end of lines, they are readded here
   unless (open (ORIG, $from_file))
   {
      print STDERR "open $from_file error: $!\n";
      return 0;
   }
   unless (open (FINAL, ">$to_file"))
   {
      print STDERR "open $to_file error: $!\n";
      return 0;
   }
   my $line;
   while ($line = <ORIG>)
   {
      if ($before_wiki)
      {
        $line =~ s/() *$/$1\n\n
intersticiae<\/p>\n/;
        $line = Texi2HTML::LaTeX2HTML::change_image_file_names($line) if ($tex_extension eq 'l2h');
      }
      else
      {
        $line =~ s/^()(.+)/$1\n$5/;
        $line =~ s/(.+)() *$/$1\n$2/;
      }
      print FINAL "$line";
   }
   close ORIG;
   close FINAL;
   return 1;
}

sub mediawiki_default_html_to_wiki
{
  foreach my $file (@html_files_from_tex)
  {
     if (-f $mediawiki_out_dir.$file)
     {
        my $html_file = $mediawiki_out_dir.$file;
        my $tmp_file = $mediawiki_out_dir.$file.".tmp";
        my $tmp_file2 = $mediawiki_out_dir.$file.".tmp2";
        my $tmp_file3 = $mediawiki_out_dir.$file.".tmp3";
        my $basename = $file;
        $basename =~ s/\.html$//;
        if (!rename ($html_file, $tmp_file))
        {
           print STDERR "rename $html_file $tmp_file error: $!\n";
           return;
        }
        #system ("cp $tmp_file $tmp_file.save");
        # Add a paragraph between the end and begin comments to force
        # html2wiki to leave them appart.
        return unless (mediawiki_default_readd_end_of_lines($tmp_file, $tmp_file3, $tex_extension, $basename, 1));
        if (!rename ($tmp_file3, $tmp_file))
        {
           print STDERR "rename $tmp_file3 $tmp_file error: $!\n";
           return;
        }
        #system ("cp $tmp_file $tmp_file3.save");
        my $cmd = "html2wiki --dialect MediaWiki --strip-tags '' $tmp_file > $tmp_file2";
        print STDERR "Launching(". Cwd::cwd() ."): $cmd\n" if (get_conf('VERBOSE'));
        if (system ($cmd))
        {
           main::document_warn ("mediawiki_tex command failed: $cmd");
           return;
        }
        # this ensures that there is one end of line before the
        # html comment, and after, even though html2wiki removed them
        return unless (mediawiki_default_readd_end_of_lines($tmp_file2, $html_file, $tex_extension, $basename));
        #system ("cp $html_file $html_file.save");
     }
     else
     { # FIXME error message?
     }
  }
}

$heading_text                 = \&mediawiki_heading_text;

sub mediawiki_heading_text($$$)
{
    my $command = shift;
    my $text = shift;
    my $level = shift;

    return '' if ($text !~ /\S/);
    $level = 1 if ($level == 0);
    return (("=" x $level) . "= $text =" . ("=" x $level) . "\n");
}

###################################################################
# Layout of standard header and footer
#

$print_page_head	      = \&mediawiki_default_print_page_head;
$print_page_foot	      = \&mediawiki_default_print_page_foot;

sub mediawiki_default_print_page_head($)
{
    my $fh = shift;
    print $fh "$AFTER_BODY_OPEN\n" if $AFTER_BODY_OPEN;
}

sub mediawiki_default_print_page_foot($)
{
    my $fh = shift;
    my $program_string = &$program_string();
    print $fh $program_string, "\n";
    print $fh $PRE_BODY_CLOSE, "\n" if $PRE_BODY_CLOSE;
}

# This function produces an anchor
#
# arguments:
# $name           :   anchor name
# $href           :   anchor href
# $text           :   text displayed
# extra_attribs   :   added to anchor attributes list

$anchor = \&mediawiki_anchor;

sub mediawiki_anchor($;$$$)
{
    my $name = shift;
    my $href = shift;
    my $text = shift;
    my $attributes = shift; # ignored
    $href = '' if !defined $href or $href !~ /\S/;
    $text = '' if !defined $text or $text !~ /\S/;
    return $text if $name eq '' and $href eq '';
    $name = "

" if $name ne '';
    if (defined($href) and $href ne '')
    {
        my $wiki_href;
        my ($file, $target);

        if ($href =~ /^([^#]*)\#(.+)$/)
        {
            $file = $1;
            $target = $2;

            if (defined($mediawiki_target_to_name{$target}))
            {
                if ($file eq '')
                {
                    $target = $mediawiki_target_to_name{$target}->[0]->[1]->{'simple_format'}
                      if ($mediawiki_target_to_name{$target}->[0]->[1]->{'simple_format'} ne '');
                    $wiki_href = '#' . $target;
                }
                else
                {
                    foreach my $element (@{$mediawiki_target_to_name{$target}})
                    {
                        if ($file eq $element->[0])
                        {
                             $target = $element->[1]->{'simple_format'} if ($element->[1]->{'simple_format'} ne '');
                             $wiki_href = $file . '#' . $target;
                        }
                    }
                }
            }

            # Element pages, or misc relative links.
            # mediawiki 1.15.1 doesn't like anchor only urls, they work as wiki_ref.
            if (!defined($wiki_href) and ($mediawiki_special_file_name{$file} or $file eq ''))
            {
                $wiki_href = $href;
            }
        }
        # Element page, no target
        elsif ($mediawiki_special_file_name{$href})
        {
            $file = $href;
            $wiki_href = $href;
        }
        if (defined($wiki_href))
        {
	    $text = "|$text" if $text;
            # FIXME trouble with http://meta.wikimedia.org/wiki/Help:Namespace#Generic_namespace_names
            # and with http://en.wikipedia.org/wiki/Wikipedia:Naming_conventions_(technical_restrictions)#Forbidden_characters

    	    $href = "[[$wiki_href$text]]";
        }
        else
        {
	    $text = " $text" if $text;
    	    $href = "[$href$text]";
        }
    }
    else
    {
    	$href = $text;
    }
#print STDERR "!!!$name!$href!$text!$attributes!\n";
    return "$name$href";
}

# it is not possible (at least not easy) to protect only 2 consecutive
# {, although it would be better.
foreach my $brace ('{', '}')
{
   $simple_map{$brace} = "<nowiki>$simple_map{$brace}</nowiki>";
   $simple_map_pre{$brace} = "<nowiki>$simple_map_pre{$brace}</nowiki>";
}

# remark: this nullifies the change of default_load_tex_math for normal_text.
# We assume that in @math the TeX characters have already been
# rightly protected and so don't protect once more. This is important
# for <, not to lead to <.
# remark: texvc doesn't accept " \&
$normal_text = \&mediawiki_default_normal_text;
sub mediawiki_default_normal_text($$$$$$$;$)
{
   my @initial_args = @_;
   my $text = shift;
   my $in_raw_text = shift; # remove_texi
   my $in_preformatted = shift;
   my $in_code = shift;
   my $in_math = shift;
   my $in_simple = shift;
   my $style_stack = shift;
   my $state = shift;

   if ($in_math)
   {
       $text = uc($text) if (in_cmd($style_stack, 'sc'));
       return $text;
   }
   $text = &html_default_normal_text (@initial_args);
   my $colon = '';
   foreach my $command (@$style_stack)
   {
      if ($mediawiki_table_commands{$command} or $def_map{$command})
      {
          $colon = '|( :)' ;
          last;
      }
      #print STDERR "$command\n";
   }
   # '' is changed to &ldsquo; so it doesn't needs to be protected in
   # normal text...
   if (!$in_raw_text and !$in_simple)
   {
        $text =~ s/(([\[\]]|[']{2,}|(\{\{)|(\}\})$colon)+)/<nowiki>$1<\/nowiki>/g;
   }
   return $text;
}

#$heading = \&mediawiki_default_heading;
sub mediawiki_default_heading($$$$$;$$)
{
    my $element = shift;
    my $command = shift;
    my $texi_line = shift;
    my $line = shift;
    my $in_preformatted = shift;
    my $one_section = shift;
    my $element_heading = shift;

    my $result = t2h_default_heading($element, $command, $texi_line, $line,
      $in_preformatted, $one_section, $element_heading);
    if ($result ne '')
    {
        if ($element->{'no_texi'} =~ /[\#<>\[\]|{}]/)
        {
            main::msg_warn("# < > [ ] | { } not allowed in title `$element->{'texi'}'",$element->{'line_nr'});
        }
    }
    return $result;
}
# This function formats a footnote reference and the footnote text associated
# with a given footnote.
# The footnote reference is the text appearing in the main document pointing
# to the footnote text.
#
# arguments:
# absolute number of the footnote (in the document)
# relative number of the footnote (in the page)
# identifier for the footnote
# identifier for the footnote reference in the main document
# main document file
# footnote text file
# array with the footnote text lines
# the state. See menu entry.
#
# returns:
# reference on an array containing the footnote text lines which should
#     have been updated
# the text for the reference pointing on the footnote text

# FIXME the <ref>... stuff is only available with the Cite extension.

$foot_line_and_ref = \&mediawiki_default_foot_line_and_ref;
$foot_section      = \&mediawiki_default_foot_section;

sub mediawiki_default_foot_line_and_ref($$$$$$$)
{
    my $number_in_doc = shift;
    my $number_in_page = shift;
    my $footnote_id = shift;
    my $place_id = shift;
    my $document_file = shift;
    my $footnote_file = shift;
    my $lines = shift;
    my $state = shift;

    my $result = '<ref>';
    foreach my $line (@$lines)
    {
       $result .= $line;
    }
    # The result shouldn't be empty, such that the call to print_Footnotes
    # and foot_section are not skipped
    return ([' '], $result . '</ref>');
}

# formats a group of footnotes.
#
# argument:
# array reference on the footnotes texts lines
#
# returns an array reference on the group of footnotes lines
# FIXME maybe do a header?
sub mediawiki_default_foot_section($)
{
    my $lines = shift;
    #unshift @$lines, "$DEFAULT_RULE\n" if $DEFAULT_RULE;
    #unshift @$lines, "==== " . gdt('Footnotes') . " ====\n";
    @$lines = ("<references/>\n\n");
    return $lines;
}

# FIXME maybe also a header here?
$print_Footnotes = \&mediawiki_default_print_Footnotes;
sub mediawiki_default_print_Footnotes
{
   my $fh = shift;
   my $new_file = shift;
   my $misc_page = shift;
   my $buttons = \@MISC_BUTTONS;

   &$print_misc_header($fh, $buttons, $new_file, $misc_page) if ($new_file);
   print $fh "<references/>\n\n";
   &$print_misc_footer($fh, $buttons, $new_file) if ($new_file);
}

$button_formatting	      = \&mediawiki_button_formatting;

sub mediawiki_button_formatting
{
   my $button = shift;
   my $vertical = shift;
   my ($active, $passive) = HTML_DEFAULT_button_formatting($button, $vertical);
   if (defined($active) and !ref($button))
   {
      $active =~ s/^\[/\|/;
      $active =~ s/\]$/\|/;
   }
   return ($active, $passive);
}

$element_file_name = \&mediawiki_element_file_name;

sub mediawiki_element_file_name
{
    my $element = shift;
    my $type = shift;
    my $docu_name = shift;
    my $file;
#print STDERR "!$element!$type!$docu_name!\n";

    if (!$element)
    {
	if ($type =~ /^toc$/)
	{
	    $file = $docu_name . ": Table of Contents";
	}
	elsif ($type =~ /^stoc$/)
	{
	    $file = $docu_name . ": Short Table of Contents";
	}
	elsif ($type =~ /^foot$/)
	{
	    $file = $docu_name . ": Footnotes";
	}
	elsif ($type =~ /^about$/)
	{
	    $file = $docu_name . ": About this Manual";
	}
	elsif ($type =~ /^doc$/)
	{
	    $file = $docu_name;
	}
    }
    else
    {
        my $name = main::substitute_line($element->{'texi'}, 'file name', {'remove_texi' => 1}, $element->{'line_nr'});
        if (exists $mediawiki_doc_nr_to_file{$element->{'doc_nr'}})
        {
	    $file = $mediawiki_doc_nr_to_file{$element->{'doc_nr'}};
	    $mediawiki_doc_nr_to_file{$element->{'doc_nr'}} = $file;
        }
        else
        {
	    $name =~ s,/,%47,g;
	    $name =~ s,\\,%92,g;
	    $file = "$docu_name" . (($type eq 'top') ? "" : ": " . $name);
	    $mediawiki_doc_nr_to_file{$element->{'doc_nr'}} = $file;
        }
        push @{$mediawiki_target_to_name{$element->{'target'}}}, [ $file, $element ];
        if ($name =~ /[\#<>\[\]|{}]/)
        {
            main::msg_warn("# < > [ ] | { } not allowed in title `$element->{'texi'}'",$element->{'line_nr'});
        }
    }
    $mediawiki_special_file_name{$file} = 1;
    return $file;
}

$node_file_name = \&mediawiki_default_node_file_name;
sub mediawiki_default_node_file_name($$)
{
    my $node = shift;
    my $type = shift;
    my $filename = T2H_DEFAULT_node_file_name($node, $type);
    my $command = 'node';
    $command = $node->{'tag'};
    my $name = main::substitute_line($node->{'texi'}, 'node name', {'remove_texi' => 1}, $node->{'line_nr'});
    if ($name =~ /[\#<>\[\]|{}]/)
    {
        main::msg_warn("# < > [ ] | { } not allowed in references, in \@$command `$node->{'texi'}'",$node->{'line_nr'});
    }

    return $filename;
}

# a preformatted region
# arguments:
# $text of the preformatted region
# $pre_style css style
# $class identifier for the preformatted region (example, menu-comment)
# The following is usefull if the preformatted is in an itemize.
# $leading_command is the leading formatting command (like @minus)
# $leading_command_formatted is the leading formatting command formatted
# $preformatted_number is a reference on the number of preformatteds appearing
#    in the format. The value should be increased if a preformatted is done
$preformatted      = \&mediawiki_default_preformatted;
sub mediawiki_default_preformatted($$$$$$$$$$)
{
    my $text = shift;
    my $pre_style = shift;
    my $class = shift;
    my $leading_command = shift;
    my $leading_command_formatted = shift;
    my $preformatted_number = shift;
    my $format = shift;
    my $item_nr = shift;
    my $enumerate_style = shift;
    my $number = shift;
    my $command_stack_at_end = shift;
    my $command_stack_at_begin = shift;

    return '' if ($text eq '');
    $leading_command_formatted = '' if (!defined($leading_command_formatted) or
          exists($special_list_commands{$format}->{$leading_command}));
    if (defined($preformatted_number) and defined($$preformatted_number))
    {
        $$preformatted_number++;
    }

    my $top_stack = '';
    $top_stack = $command_stack_at_begin->[-1] if (scalar (@$command_stack_at_begin));
    if ($top_stack eq 'multitable')
    {
       $text =~ s/^\s*//;
       $text =~ s/\s*$//;
    }

    $text =~ s/^/ /mg;
   # return html_default_attribute_class('div', $class).">\n$text
\n";
    return "$text";
    #return "
<nowiki>$text</nowiki>
";
}

sub mediawiki_default_remove_eol($)
{
   my $text = shift;
   chomp($text);
   my $res = '';
   foreach my $line (split /\n/, $text)
   {
      $res .= $line . " ";
   }
   $res =~ s/ $//;
   $res .= "\n";
   return $res;
}

my %mediawiki_default_indent_symbol = (
  'itemize' => '*',
  'enumerate' => '#'
);
foreach my $table ('table', 'ftable', 'vtable')
{
   $mediawiki_default_indent_symbol{$table} = ':';
   $mediawiki_table_commands{$table} = 1;
}
foreach my $definition_command (keys(%def_map))
{
   $mediawiki_default_indent_symbol{$definition_command} = ':';
}

sub mediawiki_default_indent_string($;$)
{
   my $commands = shift;
   my $remove_last = shift;

   $commands = $Texi2HTML::THISDOC{'command_stack'} if (!defined($commands));
   my $indent_string = '';
   foreach my $format (@$commands)
   {
      $indent_string .= $mediawiki_default_indent_symbol{$format}
         if defined($mediawiki_default_indent_symbol{$format});
   }
   $indent_string =~ s/.$// if ($remove_last);
   return $indent_string;
}

$paragraph      = \&mediawiki_default_paragraph;
sub mediawiki_default_paragraph($$$$$$$$$$$$)
{
    my $text = shift;
    my $align = shift;
    my $indent = shift;
    my $paragraph_command = shift;
    my $paragraph_command_formatted = shift;
    my $paragraph_number = shift;
    my $format = shift;
    my $item_nr = shift;
    my $enumerate_style = shift;
    my $number = shift;
    my $command_stack_at_end = shift;
    my $command_stack_at_begin = shift;
#print STDERR "format: $format\n" if (defined($format));
#print STDERR "paragraph @$command_stack_at_end; @$command_stack_at_begin\n";
#    $paragraph_command_formatted = '' if (!defined($paragraph_command_formatted) or
#          exists($special_list_commands{$format}->{$paragraph_command}));
    return '' if ($text =~ /^\s*$/);

    if (defined($paragraph_number) and defined($$paragraph_number))
    {
         $$paragraph_number++;
    }

    # remove leading spaces, they trigger a preformatted environment in wikitext
    $text =~ s/^\s*//mg;
    my $top_stack = '';
    $top_stack = $command_stack_at_begin->[-1] if (scalar (@$command_stack_at_begin));
    if ($top_stack eq 'multitable')
    {
       $html_default_multitable_stack[-1]->[1]++;
       return mediawiki_default_remove_eol($text);
    }

    if ($align)
    {
        $text = "
".$text.'
';
    }

    my $indent_string = mediawiki_default_indent_string($command_stack_at_begin);
    if ($indent_string)
    {
       $text = $indent_string . ' ' .mediawiki_default_remove_eol($text);
    }

    return $text;
}

$list_item = \&mediawiki_default_list_item;
sub mediawiki_default_list_item
{
   my $text = shift;
   return $text;
}

$def_item = \&mediawiki_default_def_item;
sub mediawiki_default_def_item($$$)
{
    my $text = shift;
    my $only_inter_item_commands = shift;
    my $command = shift;
    if ($text =~ /\S/)
    {
        if (! get_conf('DEF_TABLE'))
        {
            return $text;# unless $only_inter_item_commands;
            #return $text; # invalid without dd in ul
        }
        else
        {
            return '
' . $text . '
';
        }
    }
    return '';
}

$table_item = \&mediawiki_default_table_item;
sub mediawiki_default_table_item($$$$$$$)
{
    my $text = shift;
    my $index_label = shift;
    my $format = shift;
    my $command = shift;
#    my $formatted_command = shift;
    my $style_stack = shift;
#    my $text_formatted = shift;
#    my $text_formatted_leading_spaces = shift;
#    my $text_formatted_trailing_spaces = shift;
    my $item_cmd = shift;
    my $formatted_index_entry = shift;

#    if (defined($text_formatted) and !exists $special_list_commands{$format}->{$command})
#    {
#        $text = $text_formatted_leading_spaces . $text_formatted .$text_formatted_trailing_spaces;
#    }
#    $formatted_command = '' if (!defined($formatted_command) or
#          exists($special_list_commands{$format}->{$command}));
    if (html_teletyped_in_stack($style_stack))
    {
#       $text .= '</tt>';
#       $formatted_command = '<tt>' . $formatted_command;
        $text = '<tt>' . $text . '</tt>';
    }
    $text .= "\n" . $index_label  if (defined($index_label));
#    return '
' . $formatted_command . $text . '
' . "\n";
    return mediawiki_default_indent_string(undef,1) .";$text\n";
}

$table_line = \&mediawiki_default_table_line;
sub mediawiki_default_table_line($$$)
{
    my $text = shift;
    my $only_inter_item_commands = shift;
    my $before_items = shift;

    $only_inter_item_commands = '' if (!defined($only_inter_item_commands));

    if ($text =~ /\S/)
    {
        #return ";$text\n";# unless ($only_inter_item_commands);
        return $text;
        #return $text; # invalid without dd in ul
    }
    return '';
}

$def_line = \&mediawiki_default_def_line;
sub mediawiki_default_def_line($$$$$$$$$$$$$$$$)
{
   my $category_prepared = shift;
   my $name = shift;
   my $type = shift;
   my $arguments = shift;
   my $index_label = shift;
   my $arguments_array = shift;
   my $arguments_type_array = shift;
   my $unformatted_arguments_array = shift;
   my $command = shift;
   my $class_name = shift;
   my $category = shift;
   my $class = shift;
   my $style = shift;
   my $original_command = shift;

   $index_label = '' if (!defined($index_label));
   chomp($index_label);
   $category_prepared = '' if (!defined($category_prepared) or ($category_prepared =~ /^\s*$/));
   $name = '' if (!defined($name) or ($name =~ /^\s*$/));
   $type = '' if (!defined($type) or $type =~ /^\s*$/);
   if (!defined($arguments) or $arguments =~ /^\s*$/)
   {
       $arguments = '';
   }
   else
   {
       chomp ($arguments);
       $arguments = '' . $arguments . '';
   }
   my $type_name = '';
   $type_name = " $type" if ($type ne '');
   $type_name .= ' ' . $name . '' if ($name ne '');
   $type_name .= $arguments;
   if (! get_conf('DEF_TABLE'))
   {
       return mediawiki_default_indent_string(undef,1) .';'. $index_label. $category_prepared . '<nowiki>:</nowiki>' . $type_name . "\n";
   }
   else
   {
       return "
" . $type_name .
       "	" . $category_prepared . $index_label . "
\n";
   }
}

$def = \&mediawiki_default_def;
sub mediawiki_default_def($$)
{
    my $text = shift;
    my $command = shift;
    if ($text =~ /\S/)
    {
        if (! get_conf('DEF_TABLE'))
        {
            return $text;
        }
        else
        {
            return "
\n" . $text . "
\n";
        }
    }
    return '';

}

$table_list = \&mediawiki_default_table_list;

sub mediawiki_default_table_list($$$$$$$$$)
{
    my $format_command = shift;
    my $text = shift;
    my $command = shift;
    my $formatted_command = shift;
# enumerate
    my $item_nr = shift;
    my $enumerate_style = shift;
# itemize
    my $prepended = shift;
    my $prepended_formatted = shift;
# multitable
    my $columnfractions = shift;
    my $prototype_row = shift;
    my $prototype_lengths = shift;
    my $column_number = shift;

    if ($format_command eq 'multitable')
    {
        pop @html_default_multitable_stack;
        return &$format('multitable', 'table', $text);
    }
    return $text;
}

# format an index summary. This is a list of letters linking to the letter
# entries.
#
# arguments:
# array reference containing the formatted alphabetical letters
# array reference containing the formatted non lphabetical letters
$index_summary     = \&mediawiki_index_summary;
sub mediawiki_index_summary($$)
{
    my $alpha = shift;
    my $nonalpha = shift;
    my $join = '';
    my $nonalpha_text = '';
    my $alpha_text = '';
    return "" if !@$nonalpha and !@$alpha;
    $nonalpha_text = join ("", map {"$_	"} @$nonalpha) . "\n"
	if @$nonalpha;
    $alpha_text = join ("", @$alpha) . "\n   \n"
	if @$alpha;
    return '
'
	   . "
" . gdt('Jump to') .":	\n"
    	   . join ("", map {"$_	\n"} @$nonalpha, @$alpha)
	   . "

\n";
}

$line_command = \&mediawiki_line_command;

sub mediawiki_line_command($$$$)
{
    my $command = shift;
    my $arg_text = shift;
    my $arg_texi = shift;
    my $state = shift;

    return '' if ($arg_text eq '' or ($command eq 'author' and (!$state->{'region'} or $state->{'region'} ne 'titlepage')));
    if ($command eq 'title')
    {
        $arg_text = '== ' .$arg_text. " ==\n";
    }
    elsif ($command eq 'subtitle')
    {
        $arg_text = '=== ' .$arg_text. " ===\n";
    }
    elsif ($command eq 'author')
    {
        $arg_text = ' ' .$arg_text. "
\n";
    }
    return $arg_text;
}

$image = \&mediawiki_default_image;

sub mediawiki_default_image($$$$$$$$$$$$$$$$$)
{
    my $file = shift;
    my $base = shift;
    my $preformatted = shift;
    my $file_name = shift;
    my $alt = shift;
    my $width = shift;
    my $height = shift;
    my $raw_alt = shift;
    my $extension = shift;
    my $working_dir = shift;
    my $file_path = shift;
    my $in_paragraph = shift;
    my $file_locations = shift;
    my $base_simple_format = shift;
    my $extension_simple_format = shift;
    my $file_name_simple_format = shift;
    my $line_nr = shift;

    if (!defined($file_path) or $file_path eq '')
    {
        if (defined($extension) and $extension ne '')
        {
            $file = "$base.$extension";
        }
        else
        {
            $file = "$base.jpg";
        }
        main::line_warn (sprintf(__("\@image file `%s' not found, using `%s'"), $base, $file), $line_nr);
    }
    elsif (! get_conf('COMPLETE_IMAGE_PATHS'))
    {
        $file = $file_name;
    }
    my $alt_text = '';
    $alt_text = "|alt=$alt" if (defined($alt) and $alt ne '');
    # it is possible that $file_name is more correct as it allows the user
    # to chose the relative path.
    $file = &$protect_text($file);
    return "[[Image:$file$alt_text]]";
}

# FIXME <math> in mediawiki is only valid for one formula, not for
# random TeX.
# One possibility could be to use TeX -> html -> html2wiki
#$raw = \&mediawiki_default_raw;
sub mediawiki_default_raw($$;$)
{
    my $style = shift;
    my $text = shift;
    my $line_nr = shift;
    my $expanded = 1 if (grep {$style eq $_} @EXPAND);
    if ($style eq 'verbatim' or $style eq 'verbatiminclude')
    {
        $style = 'verbatim' if ($style eq 'verbatiminclude');
        return html_default_attribute_class('pre', $style).">" . &$protect_text($text) . '
';
    }
    elsif ($style eq 'html' and $expanded)
    {
        chomp ($text);
        return $text;
    }
    elsif ($style eq 'tex' and $expanded)
    {
        chomp ($text);
        return "<math>$text</math>\n";
    }
    elsif ($expanded)
    {
        main::line_warn (sprintf(__("Raw format %s is not converted"), $style), $line_nr);
        return &$protect_text($text);
    }
    else
    {
        return '';
    }
}

## a simple menu entry ref in case we aren't in a standard menu context
#$simple_menu_link  = \&mediawiki_simple_menu_link;

# a menu link. We are always in preformatted because of SIMPLE_MENU.
# currently not used.
#$menu_link  = \&mediawiki_simple_menu_link;

sub mediawiki_simple_menu_link($$$$$$$)
{
    my $entry = shift;
#    my $preformatted = shift; # We assume this is true.
    my $state = shift;
    my $href = shift;
    my $node = shift;
    my $title = shift;
    my $ending = shift;
    my $has_title = shift;
    my $command_stack = shift;
    my $preformatted = shift;

    $title = '' unless ($has_title);
    $ending = '' unless defined $ending;
    $entry = "</nowiki>";
    $entry .= "$MENU_SYMBOL";
    if ($href)
    {
	$entry .= &$anchor ('', $href, $node);
    }
    else
    {
	$title .= ":" if ($title ne '');
	$entry .= "$title$node";
    }
    $entry .= $ending;
    $entry .= "<nowiki>";
    return $entry;
}

repo_name: mthl/texinfo

license: mit


code:
# -*-perl-*-

#+##############################################################################
#
# tex4ht.pm: use tex4ht to convert tex to html
#
#    Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License,
# or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Originally written by Patrice Dumas.
#
#-##############################################################################
# To customize the command and the options, you could set
# $Texi2HTML::TeX4HT::STYLE_MATH to latex/tex
# $Texi2HTML::TeX4HT::STYLE_TEX to latex/texi
# and/or change
# $Texi2HTML::TeX4HT::tex4ht_command_math
#    and $Texi2HTML::TeX4HT::tex4ht_options_math
# $Texi2HTML::TeX4HT::tex4ht_command_tex
#    and $Texi2HTML::TeX4HT::tex4ht_options_tex

use strict;

if (defined($OUTPUT_FORMAT) and $OUTPUT_FORMAT eq 'html')
{
push @command_handler_init, \&Texi2HTML::TeX4HT::tex4ht_init;
push @command_handler_process, \&Texi2HTML::TeX4HT::tex4ht_process;
# do it once here to have something ready for special regions formatting
push @command_handler_process, \&Texi2HTML::TeX4HT::tex4ht_output;
# do it once more if the file was modified (for example see mediawiki.pm)
push @command_handler_output, \&Texi2HTML::TeX4HT::tex4ht_output;
push @command_handler_finish, \&Texi2HTML::TeX4HT::tex4ht_finish;

$command_handler{'math'} =
     { 'init' => \&Texi2HTML::TeX4HT::tex4ht_to_latex,
       'expand' => \&Texi2HTML::TeX4HT::tex4ht_do_tex
     };
$command_handler{'tex'} =
     { 'init' => \&Texi2HTML::TeX4HT::tex4ht_to_latex,
       'expand' => \&Texi2HTML::TeX4HT::tex4ht_do_tex
     };
}

{
use Cwd;

package Texi2HTML::TeX4HT;

use vars qw(
$STYLE_MATH
$STYLE_TEX
$tex4ht_command_math
$tex4ht_command_tex
$tex4ht_options_math
$tex4ht_options_tex
);

$STYLE_MATH = 'texi' if (!defined($STYLE_MATH));
$STYLE_TEX = 'tex' if (!defined($STYLE_TEX));

if (!defined($tex4ht_command_math))
{
   $tex4ht_command_math = 'httexi';
   $tex4ht_command_math = 'htlatex' if ($STYLE_MATH eq 'latex');
   $tex4ht_command_math = 'httex' if ($STYLE_MATH eq 'tex');
}
if (!defined($tex4ht_command_tex))
{
   $tex4ht_command_tex = 'httex';
   $tex4ht_command_tex = 'htlatex' if ($STYLE_TEX eq 'latex');
   $tex4ht_command_tex = 'httexi' if ($STYLE_TEX eq 'texi');
}

my %commands = ();

my $tex4ht_initial_dir;
my $tex4ht_out_dir;
my $tex4ht_latex_failed = 0;
my %tex4ht_results;

sub tex4ht_init
{
  # set file names
  $tex4ht_initial_dir = Cwd::abs_path;
  if ($Texi2HTML::Config::null_device_file{$Texi2HTML::THISDOC{'filename'}->{'top'}})
  {
    # when output is a null device we skip entirely the tex4ht stuff.
    $tex4ht_latex_failed = 1;
    return;
  }
  $tex4ht_out_dir = "$Texi2HTML::THISDOC{'destination_directory'}";
  $tex4ht_out_dir = './' if (!defined($tex4ht_out_dir) or $tex4ht_out_dir =~ /^\s*$/);
  my $tex4ht_basename = "$Texi2HTML::THISDOC{'file_base_name'}_tex4ht";
  %tex4ht_results = ();
  $tex4ht_latex_failed = 0;
  # this initialization doesn't seems to be needed, but it is cleaner anyway
  %commands = ();
  $commands{'math'}->{'style'} = $STYLE_MATH;
  $commands{'tex'}->{'style'} = $STYLE_TEX;
  $commands{'math'}->{'exec'} = $tex4ht_command_math;
  $commands{'tex'}->{'exec'} = $tex4ht_command_tex;
  foreach my $command ('math', 'tex')
  {
    my $style = $commands{$command}->{'style'};
    $commands{$command}->{'basename'} = $tex4ht_basename . "_$command";
    my $suffix = '.tex';
    $suffix = '.texi' if ($style eq 'texi');
    $commands{$command}->{'basefile'} = $commands{$command}->{'basename'} . $suffix;
    $commands{$command}->{'html_file'} = $commands{$command}->{'basename'} . '.html';
    $commands{$command}->{'rfile'} = $tex4ht_out_dir . $commands{$command}->{'basefile'};
    my $rfile = $commands{$command}->{'rfile'};
    local *TEX4HT_TEXFILE;
    unless (open (*TEX4HT_TEXFILE, ">$rfile"))
    {
       main::document_warn ("t2h_tex4ht error opening $rfile: $!");
       $tex4ht_latex_failed = 1;
       return;
    }
    $commands{$command}->{'handle'} = *TEX4HT_TEXFILE;
  }
  foreach my $command ('math', 'tex')
  {
    $commands{$command}->{'counter'} = 0;
    my $style = $commands{$command}->{'style'};
    my $fh = $commands{$command}->{'handle'};
    my $comment = '@c';
    $comment = '%' if ($style ne 'texi');
    $comment .= " Automatically generated\n";
    if ($style eq 'texi')
    {
      print $fh "\\input texinfo
\@setfilename $commands{$command}->{'basename'}.info\n";
      print $fh "$comment";
    }
    else
    {
      print $fh "$comment";
      if ($style eq 'latex')
      {
        print $fh "\\documentstyle{article}\n\\begin{document}\n";
      }
      elsif ($style eq 'tex')
      {
        print $fh "\\csname tex4ht\\endcsname\n";
      }
    }
  }
  $Texi2HTML::THISDOC{'extensions'}->{'tex4ht'} = 1;
}

sub tex4ht_to_latex
{
  my $command = shift;
  my $text = shift;
  my $counter = shift;
  my $style = $commands{$command}->{'style'};
  my $fh = $commands{$command}->{'handle'};

  # write to tex file
  my $before_comment_open = "\@verbatim\n\n";
  my $after_comment_open = "\n\@end verbatim\n";
  my $before_comment_close = "\@verbatim\n";
  my $after_comment_close = "\n\n\@end verbatim\n";

  if ($style ne 'texi')
  {
    $before_comment_open = "\\HCode{\\Hnewline \\Hnewline ";
    $after_comment_open = "\\Hnewline}\n";
    $before_comment_close = "\\HCode{\\Hnewline ";
    $after_comment_close = "\\Hnewline \\Hnewline}\n";
  }

  my $begin_comment = "<!-- tex4ht_begin $commands{$command}->{'basename'} $command $counter -->";
  print $fh "$before_comment_open$begin_comment$after_comment_open";
  if ($command eq 'tex')
  {
     print $fh $text;
  }
  elsif ($command eq 'math')
  {
     if ($style eq 'texi')
     {
         print $fh '@math{' . $text . "}\n";
     }
     else
     {
         print $fh "\\IgnorePar \$" . $text . "\$";
     }
  }
  my $end_comment = "<!-- tex4ht_end $commands{$command}->{'basename'} $command $counter -->";
  print $fh "$before_comment_close$end_comment$after_comment_close";
  $commands{$command}->{'counter'}++;
  return 1;
}

sub tex4ht_process
{
  foreach my $command ('math', 'tex')
  {
     tex4ht_finish_latex($command);
  }
  unless (chdir $tex4ht_out_dir)
  {
     main::document_warn ("t2h_tex4ht chdir to $tex4ht_out_dir failed");
     $tex4ht_latex_failed = 1;
     return;
  }
  print STDERR "cwd($tex4ht_out_dir):" . Cwd::cwd() ."\n" if (Texi2HTML::Config::get_conf('VERBOSE'));

  foreach my $command ('math', 'tex')
  {
     tex4ht_process_command($command);
  }
  tex4ht_return_to_dir();
}

my $tex4ht_output_counter;

sub tex4ht_output
{
  $tex4ht_output_counter = 0;
  unless (chdir $tex4ht_out_dir)
  {
     main::document_warn ("t2h_tex4ht chdir to $tex4ht_out_dir failed");
     $tex4ht_latex_failed = 1;
     return;
  }
  foreach my $command ('math', 'tex')
  {
     tex4ht_output_command($command);
  }
  tex4ht_return_to_dir();
}

sub tex4ht_finish_latex
{
#print STDERR "$style $tex4ht_latex_failed $tex4ht_counter\n";
  my $command = shift;
  return if ($tex4ht_latex_failed);

  my $style = $commands{$command}->{'style'};
  my $fh = $commands{$command}->{'handle'};
  # finish the tex file
  if ($style eq 'latex')
  {
     print $fh "\\end{document}\n";
  }
  elsif ($style eq 'tex')
  {
     print $fh "\n\\bye\n";
  }
  else
  {
     print $fh "\n\@bye\n";
  }
  close ($fh);
}

sub tex4ht_process_command($)
{
  my $command = shift;
  return unless ($commands{$command}->{'counter'});
  main::document_warn ("t2h_tex4ht $commands{$command}->{'basefile'} missing") unless (-f $commands{$command}->{'basefile'});
  my $style = $commands{$command}->{'style'};
  # now run tex4ht
  my $options = '';
  $options = $tex4ht_options_math if (($style eq 'math') and defined($tex4ht_options_math));
  $options = $tex4ht_options_tex if (($style eq 'tex') and defined($tex4ht_options_tex));
  my $cmd = "$commands{$command}->{'exec'} $commands{$command}->{'basefile'} $options";
  print STDERR "tex4ht command: $cmd\n" if (Texi2HTML::Config::get_conf('VERBOSE'));
  if (system($cmd))
  {
     main::document_warn ("t2h_tex4ht command: $cmd failed");
     tex4ht_return_to_dir();
     $tex4ht_latex_failed = 1;
     return;
  }
  # this have to be done during the 'process' phase, in 'output' it is
  # too late.
  push @{$Texi2HTML::THISDOC{'css_import_lines'}}, "\@import \"$commands{$command}->{'basename'}.css\";\n";
}

sub tex4ht_output_command($)
{
  my $command = shift;
  return unless ($commands{$command}->{'counter'});
  # extract the html from the file created by tex4ht
  my $html_basefile = $commands{$command}->{'html_file'};
  unless (open (TEX4HT_HTMLFILE, $html_basefile))
  {
     main::document_warn ("t2h_tex4ht error opening $html_basefile: $!");
     tex4ht_return_to_dir();
     $tex4ht_latex_failed = 1;
     return;
  }
  my $got_count = 0;
  my $line;
  while ($line = <TEX4HT_HTMLFILE>)
  {
     #print STDERR "$html_basefile: while $line";
     if ($line =~ /!-- tex4ht_begin $commands{$command}->{'basename'} (\w+) (\d+) --/)
     {
        my $command = $1;
        my $count = $2;
        my $text = '';
        my $end_found = 0;
        while ($line = <TEX4HT_HTMLFILE>)
        {
           #print STDERR "while search $command $count $line";
           if ($line =~ /!-- tex4ht_end $commands{$command}->{'basename'} $command $count --/)
           {
              $got_count++;
              chomp($text);
              $tex4ht_results{"${command}_$count"} = $text;
              $end_found = 1;
              last;
           }
           else
           {
              $text .= $line;
           }
        }
        unless ($end_found)
        {
           main::document_warn ("t2h_tex4ht: end of $command $count not found");
        }
     }
  }
  if ($got_count != $commands{$command}->{'counter'} and (Texi2HTML::Config::get_conf('VERBOSE')))
  {
     main::document_warn ("t2h_tex4ht: got $got_count for $commands{$command}->{'counter'} items entered");
  }
  close (TEX4HT_HTMLFILE);

}

sub tex4ht_return_to_dir
{
  unless (chdir $tex4ht_initial_dir)
  {
     die "* t2h_tex4ht unable to return to the initial dir\n";
  }
}

sub tex4ht_do_tex
{
  my $command = shift;
  my $counter = shift;
  # return the resulting html
  if (exists ($tex4ht_results{"${command}_$counter"}) and defined($tex4ht_results{"${command}_$counter"}))
  {
     $tex4ht_output_counter++;
     return $tex4ht_results{"${command}_$counter"};
  }
  else
  {
    main::document_warn ("t2h_tex4ht: cannot find text to output for $command number $counter");
    return '';
  }
}

sub tex4ht_finish
{
  my $tex4ht_in_counter = 0;
  foreach my $command (keys(%commands))
  {
    $tex4ht_in_counter += $commands{$command}->{'counter'};
  }
  if (($tex4ht_output_counter != $tex4ht_in_counter) and (Texi2HTML::Config::get_conf('VERBOSE')))
  {
     main::document_warn ("t2h_tex4ht: output $tex4ht_output_counter for $tex4ht_in_counter items entered");
  }
}

}
1;


code:
#! @PERL@ -w
#+##############################################################################
#
# manage_i18n.pl: manage translation files
#
#    Copyright (C) 2003, 2005, 2009, 2010 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License,
# or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Originally written by Patrice Dumas.
#
#-##############################################################################

# for file in ../i18n/*; do echo $file | grep -qs 'old\|CVS' && continue; bfile=`basename $file .thl`; post='.us-ascii.po'; msgen texi2html_document.pot > $bfile$post-1; sed -i -e 's/CHARSET/us-ascii/' $bfile$post-1 ; msgfilter --keep-header -i $bfile$post-1 -o $bfile$post ../manage_i18n.pl filter -I ../ --lang $bfile;  done
#  for file in ../i18n/hu.thl ../i18n/it.thl ; do echo $file | grep -qs 'old\|CVS' && continue; bfile=`basename $file .thl`; post='.po'; msgen texi2html_document.pot > $bfile$post-1; sed -i -e 's/CHARSET/utf-8/' $bfile$post-1 ; msgfilter --keep-header -i $bfile$post-1 -o $bfile$post ../manage_i18n.pl filter -I ../ --lang $bfile;  done

# remove every translations while keeping the header
#  msgfilter --keep-header -i es.us-ascii.po 'true' > es.us-ascii.po-head
# duplicate english messages to msgstr
#  msgen es.us-ascii.po-head > es.us-ascii.po-en
# use the new translations
#  msgfilter --keep-header -i es.us-ascii.po-en ../manage_i18n.pl filter -I ../ --lang es > es.us-ascii.po-new
#
# mv es.us-ascii.po-new es.us-ascii.po

# This requires perl version 5 or higher
require 5.0;

use strict;

use File::Copy;
#use Data::Dumper;
@REQUIRE_DATA_DUMPER@;
use Getopt::Long qw(GetOptions);

my $USE_DATA_DUMPER = '@USE_DATA_DUMPER@';
select(STDERR);
$| = 1;
select(STDOUT);
$| = 1;

my $help = 0;
my $language;
my $dir = 'i18n'; # name of the directory containing the per language files
my $output; # file containing all the translations or output directory
# = 'translations.pl'; # file containing all the translations
my @known_languages = ('en', 'de', 'nl', 'es', 'no', 'pt', 'pt_BR', 'ja',
  'fr', 'it', 'hu'); # The supported languages
my @searched_dirs = (); # dir searched for sources and language files

#my $template = 'template';
my $template_lang = 'en';
my @sources = ('texi2html.pl', 'texi2html.pm', 'T2h_i18n.pm',
 'examples/roff.pm', 'examples/noheaders.pm');
my $lang;
my $charset;

GetOptions('Include=s' => \@searched_dirs, 'output=s' => \$output,
  'directory=s' => \$dir, 'help+' => \$help, 'lang=s' => \$lang,
  'charset=s' => \$charset);

if ($help)
{
    my $command_basename = $0;
    $command_basename =~ s%.*/%%;
    my $usage_text = <<EOT;
Usage:
  $command_basename -h
  $command_basename [-I <dir>][-d <i18n_dir>][-o <out_dir>] template source_files...
  $command_basename [-I <dir>][-d <i18n_dir>][-o <out_dir>] update [ language... ]
  $command_basename [-I <dir>][-d <i18n_dir>][-o <result_file>] merge

Default languages are files in the i18n_dir with .thl extension.
EOT
    print $usage_text;
    exit 0;
}

if (!@searched_dirs)
{
    @searched_dirs = ('.');
}

if (@ARGV < 1)
{
    die "Need a command\n";
}

my $command = shift @ARGV;

my $output_dir = $dir;
$output_dir = $output if (defined($output));

my $translations_file = 'translations.pl';
$translations_file = $output if (defined($output));

sub locate_file($$)
{
    my $file = shift;
    my $directories = shift;

    $directories = \@searched_dirs if !defined($directories);

    if ($file =~ /^\//)
    {
         return $file if (-e $file and -r $file);
    }
    else
    {
         foreach my $dir (@$directories)
         {
              next unless (-d "$dir");
              return "$dir/$file" if (-e "$dir/$file" and -r "$dir/$file");
         }
    }
    return undef;
}

my $defaults_file = "$dir/$template_lang";

use vars qw(
$LANGUAGES
$T2H_OBSOLETE_STRINGS
);

# Strings not in code
my $template_strings =
{
 'January' => '',
 'February' => '',
 'March' => '',
 'April' => '',
 'May' => '',
 'June' => '',
 'July' => '',
 'August' => '',
 'September' => '',
 'October' => '',
 'November' => '',
 'December' => '',
 'T2H_today' => '%s, %d %d',
};

# Handle per language files
if ($USE_DATA_DUMPER)
{
   $Data::Dumper::Sortkeys = 1;
}

sub update_language_file($$$$$);

#die "No suitable $dir directory\n" unless (-d $dir and -r $dir);

sub get_languages($$)
{
    my $directories = shift;
    my $i18n_dir = shift;
    my @languages = ();
    foreach my $searched_dir (@$directories)
    {
         my $dir = "$searched_dir/$i18n_dir";
         if (opendir DIR, $dir)
         {
             my @new_languages = grep {
                 ! /^\./ &&
                 ! /\.(bak|orig|old|dpkg-old|rpmnew|rpmsave)$/ &&
                 ! /~$/ &&
                 ! /^#.*#$/ &&
                 /\.thl$/ &&
                -f $dir . '/' . $_
             } readdir DIR;
             closedir DIR;
             foreach my $language (@new_languages)
             {
                 $language =~ s/\.thl$//;
                 push @languages, $language unless grep {$_ eq $language}
                       @languages;
             }
         }
    }
    my @known = @known_languages;
    foreach my $lang (@languages)
    {
         if (grep {$_ eq $lang} @known)
         {
              @known = grep {$_ ne $lang} @known;
         }
         else
         {
             warn "Remark: you could update the known languages array for `$lang'\n";
         }
    }
    warn "Remark: the following known languages have no corresponding file: @known\n" if (@known);
    return @languages;
}

sub merge_i18n_files($$$)
{
    my $directories = shift;
    my $i18n_dir = shift;
    my $translation_file = shift;
    my @languages = get_languages($directories, $i18n_dir);
    die "No languages found\n" unless (@languages);
    if (-f $translation_file)
    {
        unless (File::Copy::copy ($translation_file, "$translation_file.old"))
        {
            die "Error copying $translation_file to $translation_file.old\n";
        }
    }

    open (TRANSLATIONS, ">$translation_file")
      || die "open(>$translation_file) failed: $!";

    foreach my $lang (@languages)
    {
         my $file = locate_file("$i18n_dir/$lang.thl", $directories);
         next unless defined($file);
         unless (open (FILE, $file))
         {
              warn "open $file failed: $!\n";
              return;
         }
         while (<FILE>)
         {
              print TRANSLATIONS;
         }
         close FILE;
    }
    print TRANSLATIONS "\n1;\n"; # ensure end with true value
    close (TRANSLATIONS) || warn "close(>$translation_file) failed: $!";
}

sub get_language_hashes($$)
{
    my $from_file = shift;
    my $lang = shift;
    if (defined($from_file) and -f $from_file)
    {
        eval { require($from_file) ;};
        if ($@)
        {
            warn "require $from_file failed: $@\n";
            return (undef,undef);
        }
        if (!defined($LANGUAGES->{$lang}))
        {
            warn "LANGUAGES->{$lang} not defined in $from_file\n";
            return (undef,undef);
        }
    }
    return ($LANGUAGES->{$lang}, $T2H_OBSOLETE_STRINGS->{$lang})
}

sub get_translation_string($$$$)
{
    my $directories = shift;
    my $i18n_dir = shift;
    my $lang = shift;
    my $string_to_find = shift;
    my $from_file = locate_file("$i18n_dir/$lang.thl", $directories);

    my ($strings, $obsolete_strings) = get_language_hashes($from_file, $lang);

    return $strings->{$string_to_find} if (defined($strings) and defined($strings->{$string_to_find}));
    return $obsolete_strings->{$string_to_find} if (defined($obsolete_strings) and defined($obsolete_strings->{$string_to_find}));
    return undef;
}

sub update_language_hash($$$)
{
    my $from_file = shift;
	my $lang = shift;
	my $reference = shift;

    if (defined($from_file) and -f $from_file)
    {
        eval { require($from_file) ;};
        if ($@)
        {
            warn "require $from_file failed: $@\n";
            return;
        }
        if (!defined($LANGUAGES->{$lang}))
        {
            warn "LANGUAGES->{$lang} not defined in $from_file\n";
            return;
        }
    }
    if (!defined($T2H_OBSOLETE_STRINGS->{$lang}))
    {
        $T2H_OBSOLETE_STRINGS->{$lang} = {};
    }
    if (!defined($LANGUAGES->{$lang}))
    {
        $LANGUAGES->{$lang} = {};
    }

	foreach my $string (keys %{$LANGUAGES->{$lang}})
	{
        $T2H_OBSOLETE_STRINGS->{$lang}->{$string} = $LANGUAGES->{$lang}->{$string}
            if (defined($LANGUAGES->{$lang}->{$string}) and ($LANGUAGES->{$lang}->{$string} ne ''));
    }

    $LANGUAGES->{$lang} = {};

    foreach my $string (keys (%{$reference}))
    {
        if (exists($T2H_OBSOLETE_STRINGS->{$lang}->{$string}) and
            defined($T2H_OBSOLETE_STRINGS->{$lang}->{$string}) and
            ($T2H_OBSOLETE_STRINGS->{$lang}->{$string} ne ''))
        {
             $LANGUAGES->{$lang}->{$string} = $T2H_OBSOLETE_STRINGS->{$lang}->{$string};
             delete $T2H_OBSOLETE_STRINGS->{$lang}->{$string};
        }
        else
        {
             $LANGUAGES->{$lang}->{$string} = '';
        }
    }
	return 1;
}

# Based on the template file, update the different language files
sub update_i18n_files($$$$@)
{
    my $directories = shift;
    my $i18n_dir = shift;
    my $out_i18n_dir = shift;
    my $template_language = shift;

    my @languages = grep {$template_language ne $_}
         get_languages($directories, $i18n_dir);
    if (@_)
    {
        @languages = ();
        foreach my $lang (@_)
        {
            unless (grep {$lang eq $_} @known_languages)
            {
                warn "Remark: you could update the known languages array for `$lang'\n";
            }
            push (@languages, $lang) unless (grep {$lang eq $_} @languages);
        }
    }
    unless (@languages)
    {
        warn "No languages to update\n" ;
        return;
    }

    my $template_file = locate_file("$i18n_dir/$template_language.thl",
         $directories);
    die "No $i18n_dir/$template_language.thl found\n" unless
         (defined($template_file));
    eval { require($template_file) ;};
    if ($@)
    {
        die "require $template_file failed: $@\n";
    }
    die "LANGUAGE->{'$template_language'} undef after require $template_file\n" unless
         (defined($LANGUAGES) and defined($LANGUAGES->{$template_language}));
    foreach my $string (keys(%$template_strings))
    {
        die "template string $string undef"
           unless (defined($LANGUAGES->{$template_language}->{$string}));
    }
    unless (-d $out_i18n_dir)
    {
        if (!mkdir($out_i18n_dir, oct(755)))
        {
            die "cannot mkdir $out_i18n_dir: $!\n";
        }
    }
    foreach my $lang (@languages)
    {
        update_language_file($directories, $i18n_dir, $out_i18n_dir,
            $template_language, $lang);
    }
    return 1;
}

sub copy_or_touch($$)
{
    my $from_file = shift;
    my $to_file = shift;
    my $atime = time;
    my $mtime = $atime;
    if ($to_file eq $from_file)
    {
        utime $atime, $mtime, $from_file;
        return;
    }
    elsif (-f $to_file)
    {
        my $identical_files = 1;
        if (open(FROMFILE, $from_file))
        {
             if (open(TOFILE, $to_file))
             {
                  my $to_file_lines = '';
                  my $from_file_lines = '';
                  while (<FROMFILE>)
                  {
                       $from_file_lines .= $_;
                  }
                  while (<TOFILE>)
                  {
                       $to_file_lines .= $_;
                  }
                  if ($from_file_lines eq $to_file_lines)
                  {
                       utime $atime, $mtime, $from_file;
                       return;
                  }
             }
        }
        else
        {
             warn "Error opening $from_file\n";
             utime $atime, $mtime, $to_file;
        }
    }
    unless (File::Copy::copy($from_file, $to_file))
    {
        warn "Error copying $from_file to $to_file\n";
    }
}

sub update_language_file($$$$$)
{
    my $directories = shift;
    my $i18n_dir = shift;
    my $out_i18n_dir = shift;
    my $template_language = shift;
    my $lang = shift;
    my $from_file = locate_file("$i18n_dir/$lang.thl", $directories);
    my $to_file = "$out_i18n_dir/$lang.thl";

    return unless (defined($from_file));

    return unless (update_language_hash($from_file, $lang,
        $LANGUAGES->{$template_language}));

    if (-f $to_file)
    {
        unless (File::Copy::copy($to_file, "$to_file.old"))
        {
            warn "Error copying $to_file to $to_file.old\n";
            return;
        }
    }
    if (!$USE_DATA_DUMPER)
    {
        copy_or_touch($from_file, $to_file);
        return;
    }
    unless (open(FILE, ">$to_file"))
    {
         warn "open $to_file failed: $!\n";
         return;
    }

    print FILE "" . Data::Dumper->Dump([$LANGUAGES->{$lang}], [ "LANGUAGES->{'$lang'}" ]);
    print FILE "\n";
    print FILE Data::Dumper->Dump([$T2H_OBSOLETE_STRINGS->{$lang}], [ "T2H_OBSOLETE_STRINGS->{'$lang'}"]);
    print FILE "\n";
    print FILE "\n";
    close FILE;
}

sub update_template($$$$@)
{
    my $directories = shift;
    my $i18n_dir = shift;
    my $template_language = shift;
    my $out_dir = shift;
    my $source_strings = {};
    unless (@_)
    {
        die "No source files\n";
    }
    foreach my $source (@_)
    {
        my $source_file = locate_file($source, $directories);
        unless (defined($source_file))
        {
            warn "$source_file not found\n";
            next;
        }
        unless (open (FILE, "$source_file"))
        {
            warn "open $source_file failed: $!\n";
            next;
        }
        my $line_nr = 0;
        while (<FILE>)
        {
             $line_nr++;
             my $string;
             next if /^\s*#/;
             while ($_)
             {
                  if (defined($string))
                  {
                       if (s/^([^\\']*)(\\|')//)
                       {
                            $string .= $1 if (defined($1));
                            if ($2 eq "'")
                            {
                                 $source_strings->{$string} = '' ;
                                 $string = undef;
                            }
                            else
                            {
                                 if (s/^(.)//)
                                 {
                                      #$string .= '\\' . $1;
                                      $string .= $1;
                                 }
                                 else
                                 {
                                      warn "\\ at end of line, file $source_file, line nr $line_nr\n";
                                      $source_strings->{$string} = '' ;
                                      $string = undef;
                                 }
                            }
                       }
                       else
                       {
                            warn "string not closed file $source_file, line nr $line_nr\n";
                            $source_strings->{$string} = '' ;
                            $string = undef;
                       }
                  }
                  elsif (s/^.*?&\$I\s*\('// or s/^.*? gdt\('//)
                  #elsif (s/^.*?&\$I\s*\('//)
                  {
                       $string = '';
                  }
                  else
                  {
                       last;
                  }
             }
        }
        close FILE;
    }
    foreach my $string (keys(%$template_strings))
    {
        $source_strings->{$string} = $template_strings->{$string};
    }
    my $template_file =
        locate_file("$i18n_dir/$template_language.thl",$directories);
    die unless (update_language_hash($template_file,
            $template_language, $source_strings));
	foreach my $string (keys(%$template_strings))
	{ # use values in template_srings if it exists
        my $existing_string = $LANGUAGES->{$template_language}->{$string};
        $LANGUAGES->{$template_language}->{$string} = $template_strings->{$string}
          if ((!defined($existing_string)) or ($existing_string eq ''));
    }
    unless (-d $out_dir)
    {
        if (!mkdir($out_dir, oct(755)))
        {
            die "cannot mkdir $out_dir: $!\n";
        }
    }
    my $out_template_file = "$out_dir/$template_language";

    if (!$USE_DATA_DUMPER)
    {
        return if (!defined($template_file));
        copy_or_touch($template_file, $out_template_file);
        return;
    }
    unless (open(TEMPLATE, ">$out_template_file"))
    {
        die "open $out_template_file failed: $!\n";
    }
    print TEMPLATE "" . Data::Dumper->Dump([$LANGUAGES->{$template_language}], [ "LANGUAGES->{'$template_language'}" ]);
    print TEMPLATE "\n";
    print TEMPLATE Data::Dumper->Dump([$T2H_OBSOLETE_STRINGS->{$template_language}], [ "T2H_OBSOLETE_STRINGS->{'$template_language'}"]);
    print TEMPLATE "\n";
    print TEMPLATE "\n";
    close TEMPLATE;
}

if ($command eq 'update')
{
    update_i18n_files(\@searched_dirs, $dir, $output_dir,
         $template_lang, @ARGV);
}
elsif ($command eq 'merge')
{
    merge_i18n_files(\@searched_dirs, $dir, $translations_file);
}
elsif ($command eq 'template')
{
    my @source_files = @ARGV;
    unless (@source_files)
    {
         @source_files = @sources;
    }
    update_template(\@searched_dirs, $dir, $template_lang, $output_dir,
          @source_files);
}

#elsif ($command eq 'all')
#{
#    my @source_files = @ARGV;
#    unless (@source_files)
#    {
#         @source_files = @sources;
#    }
#    update_template(\@searched_dirs, $dir, $output_dir, $template_lang,
#         @source_files);
#    update_i18n_files(\@searched_dirs, $dir, $dir,
#          $template_lang, "$output_dir/$template_lang");
#    merge_i18n_files(\@searched_dirs, $dir, $translations_file);
#}
elsif ($command eq 'filter')
{
    die "filter requires --lang\n" if (!defined($lang));
    $/ = undef;
    my $string_to_find = <STDIN>;
    my $translated_string = get_translation_string(\@searched_dirs, $dir, $lang, $string_to_find);
    $translated_string = '' if (!defined($translated_string));
#print STDERR "LLL $string_to_find|$translated_string\n";
    if (defined($charset))
    { # this doesn't work, and is not needed
       binmode(STDOUT, ":encoding($charset)");
    }
    print STDOUT "$translated_string";
}
else
{
    warn "Unknown i18n command: $command\n";
}
exit 0;

1;


code:
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
# Copyright 1996, 1997, 1999, 2000, 2005 Free Software Foundation, Inc.
# Copyright (C) 2005 Derek Price <derek@ximbiot.com>,
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

if test $# -eq 0; then
  echo 1>&2 "Try \`$0 --help' for more information"
  exit 1
fi

run=:

case "$1" in
--run)
  # Try to run requested program, and just exit if it succeeds.
  run=
  shift
  "$@" && exit 0
  ;;
esac

# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in

  -h|--h|--he|--hel|--help)
    echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...

Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.

Options:
  -h, --help      display this help and exit
  -v, --version   output version information and exit
  --run           try to run the given command, and emulate it if it fails

Supported PROGRAM values:
  texi2html      touch output file"
    ;;

  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
    echo "missing 0.3 - GNU automake (modified in texi2html)"
    ;;

  -*)
    echo 1>&2 "$0: Unknown \`$1' option"
    echo 1>&2 "Try \`$0 --help' for more information"
    exit 1
    ;;

  */perl)
    case "$2" in
      */texi2html.pl)
        ;;
      *)
	echo 1>&2 "\
WARNING: \`$1 $2' is needed, and you do not seem to have it handy on your
         system.  You might have modified some files without having the
         proper tools for further handling them.  Check the \`README' file,
         it often tells you about the needed prerequirements for installing
         this package.  You may also peek at any GNU archive site, in case
         some other package would contain this missing \`$1' program."
	exit 1
	;;
    esac

    echo 1>&2 "\
WARNING: \`$1 $2' is missing or broken on your system.
         You should only need it if you modified \`texi2html.info'.
         You might want to install the \`Perl' package.  Grab it from
         any GNU archive site."

    if test -z "$3"; then
	echo 1>&2 "ERROR: No output file specified!"
	exit 1
    fi
    while test -n "$4"; do
      shift
    done
    file=`echo "$3" |sed 's/\.texi$/.html/'`
    file=`echo "$file" |sed 's/\.texinfo$/.html/'`
    touch "$file"
    ;;

  *)
    echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
         system.  You might have modified some files without having the
         proper tools for further handling them.  Check the \`README' file,
         it often tells you about the needed prerequirements for installing
         this package.  You may also peek at any GNU archive site, in case
         some other package would contain this missing \`$1' program."
    exit 1
    ;;
esac

exit 0


code:
#! /usr/bin/perl -w

# Patrice Dumas pertusus at free.fr, 2008:
# this file is in the public domain

# the resulting code may be under the texinfo/makeinfo/lang.c license.

# ./parse_8bit_makeinfo_maps.pl > eigth_bit_makeinfo_maps.pl

use strict;

my $lang_file = '../texinfo/makeinfo/lang.c';

open (LANGF, "$lang_file") or die "Cannot open $lang_file: $!\n";

my $in_map=0;
my %unicode_translit = ();

print "%makeinfo_eight_bit_map = (\n";

while (<LANGF>)
{
  if ($in_map)
  {
    if  (/^\s*\{\s*NULL\s*,\s*0\s*,\s*0\s*\}/)
    {
       $in_map=0;
       print "   },\n";
       next;
    }
    elsif (/^\s*\{\s*\"(\w*)\"\s*,\s*0x([0-9abcdef]{2})\s*,\s*0x([0-9abcdef]{4})\s*(,\s*\"(\w*)\"\s*)?\}/i)
    {
       my $entity = $1;
       my $eight_bit = uc($2);
       my $unicode = uc($3);
       my $transliteration_str = 'UNDEF';
       my $transliteration;
       if (defined($5))
       {
          $transliteration_str = $transliteration = $5;

          if (exists($unicode_translit{$unicode}) and $unicode_translit{$unicode} ne $transliteration)
          {
             print STDERR "$in_map,$eight_bit,$unicode: $unicode_translit{$unicode} ne $transliteration\n";
          }
          $unicode_translit{$unicode} = $transliteration;
       }
       print "      '$unicode' => '$eight_bit',\n";
#print STDERR "$entity $eight_bit $unicode $transliteration_str\n";
    }
  }
  elsif (/^\s*static\s+iso_map_type\s+(\w+?)_map/)
  {
    next if /\s*\{\s*NULL\s*,\s*0\s*,\s*0\s*\}/;
    $in_map = $1;
    #print STDERR "$in_map\n";
    print "   '$in_map' => {\n";
  }
}

print ");\n\n";

print "%makeinfo_transliterate_map = (\n";
foreach my $unicode (keys(%unicode_translit))
{
  print "  '$unicode' => '$unicode_translit{$unicode}',\n";
}
print ");\n\n";


code:
de.us-ascii
es.us-ascii
fr.us-ascii
hu
it
ja
nl.us-ascii
no.us-ascii
pt_BR.us-ascii
pt.us-ascii


code:
# Makefile for PO directory in any package using GNU gettext.
# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
#
# This file can be copied and used freely without restrictions.  It can
# be used in projects which are not available under the GNU General Public
# License but which still want to provide support for the GNU gettext
# functionality.
# Please note that the actual code of GNU gettext is covered by the GNU
# General Public License and is *not* in the public domain.
#
# Origin: gettext-0.18.3
GETTEXT_MACRO_VERSION = 0.18

PACKAGE = @PACKAGE@
VERSION = @VERSION@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@

SED = @SED@
SHELL = /bin/sh
@SET_MAKE@

srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@

prefix = @prefix@
exec_prefix = @exec_prefix@
datarootdir = @datarootdir@
datadir = @datadir@
localedir = @localedir@
gettextsrcdir = $(datadir)/gettext/po

INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@

# We use $(mkdir_p).
# In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as
# "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions,
# @install_sh@ does not start with $(SHELL), so we add it.
# In automake >= 1.10, @mkdir_p@ is derived from ${MKDIR_P}, which is defined
# either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake
# versions, $(mkinstalldirs) and $(install_sh) are unused.
mkinstalldirs = $(SHELL) @install_sh@ -d
install_sh = $(SHELL) @install_sh@
MKDIR_P = @MKDIR_P@
mkdir_p = @mkdir_p@

GMSGFMT_ = @GMSGFMT@
GMSGFMT_no = @GMSGFMT@
GMSGFMT_yes = @GMSGFMT_015@
GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT))
MSGFMT_ = @MSGFMT@
MSGFMT_no = @MSGFMT@
MSGFMT_yes = @MSGFMT_015@
MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
XGETTEXT_ = @XGETTEXT@
XGETTEXT_no = @XGETTEXT@
XGETTEXT_yes = @XGETTEXT_015@
XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
MSGMERGE = msgmerge
MSGMERGE_UPDATE = @MSGMERGE@ --update
MSGINIT = msginit
MSGCONV = msgconv
MSGFILTER = msgfilter

POFILES = @POFILES@
GMOFILES = @GMOFILES@
UPDATEPOFILES = @UPDATEPOFILES@
DUMMYPOFILES = @DUMMYPOFILES@
DISTFILES.common = Makefile.in.in remove-potcdate.sin \
$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3)
DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \
$(POFILES) $(GMOFILES) \
$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3)

POTFILES = \

CATALOGS = @CATALOGS@

# Makevars gets inserted here. (Don't remove this line!)

.SUFFIXES:
.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update

.po.mo:
	@echo "$(MSGFMT) -c -o $@ $<"; \
	$(MSGFMT) -c -o t-$@ $< && mv t-$@ $@

.po.gmo:
	@lang=`echo $* | sed -e 's,.*/,,'`; \
	test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
	echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \
	cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo

.sin.sed:
	sed -e '/^#/d' $< > t-$@
	mv t-$@ $@

all: all-@USE_NLS@

all-yes: stamp-po
all-no:

# Ensure that the gettext macros and this Makefile.in.in are in sync.
CHECK_MACRO_VERSION = \
	test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \
	  || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \
	       exit 1; \
	     }

# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no
# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because
# we don't want to bother translators with empty POT files). We assume that
# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty.
# In this case, stamp-po is a nop (i.e. a phony target).

# stamp-po is a timestamp denoting the last time at which the CATALOGS have
# been loosely updated. Its purpose is that when a developer or translator
# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS,
# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent
# invocations of "make" will do nothing. This timestamp would not be necessary
# if updating the $(CATALOGS) would always touch them; however, the rule for
# $(POFILES) has been designed to not touch files that don't need to be
# changed.
stamp-po: $(srcdir)/$(DOMAIN).pot
	@$(CHECK_MACRO_VERSION)
	test ! -f $(srcdir)/$(DOMAIN).pot || \
	  test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
	@test ! -f $(srcdir)/$(DOMAIN).pot || { \
	  echo "touch stamp-po" && \
	  echo timestamp > stamp-poT && \
	  mv stamp-poT stamp-po; \
	}

# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update',
# otherwise packages like GCC can not be built if only parts of the source
# have been downloaded.

# This target rebuilds $(DOMAIN).pot; it is an expensive operation.
# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed.
# The determination of whether the package xyz is a GNU one is based on the
# heuristic whether some file in the top level directory mentions "GNU xyz".
# If GNU 'find' is available, we avoid grepping through monster files.
$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed
	if { if (LC_ALL=C find --version) 2>/dev/null | grep GNU >/dev/null; then \
	       LC_ALL=C find -L $(top_srcdir) -maxdepth 1 -type f -size -10000000c -exec grep 'GNU @PACKAGE@' /dev/null '{}' ';' 2>/dev/null; \
	     else \
	       LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null; \
	     fi; \
	   } | grep -v 'libtool:' >/dev/null; then \
	  package_gnu='GNU '; \
	else \
	  package_gnu=''; \
	fi; \
	if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \
	  msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \
	else \
	  msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \
	fi; \
	case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
	  '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \
	    $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
	      --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \
	      --files-from=$(srcdir)/POTFILES.in \
	      --copyright-holder='$(COPYRIGHT_HOLDER)' \
	      --msgid-bugs-address="$$msgid_bugs_address" \
	    ;; \
	  *) \
	    $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
	      --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \
	      --files-from=$(srcdir)/POTFILES.in \
	      --copyright-holder='$(COPYRIGHT_HOLDER)' \
	      --package-name="$${package_gnu}@PACKAGE@" \
	      --package-version='@VERSION@' \
	      --msgid-bugs-address="$$msgid_bugs_address" \
	    ;; \
	esac
	test ! -f $(DOMAIN).po || { \
	  if test -f $(srcdir)/$(DOMAIN).pot; then \
	    sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \
	    sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \
	    if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \
	      rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \
	    else \
	      rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \
	      mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \
	    fi; \
	  else \
	    mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \
	  fi; \
	}

# This rule has no dependencies: we don't need to update $(DOMAIN).pot at
# every "make" invocation, only create it when it is missing.
# Only "make $(DOMAIN).pot-update" or "make dist" will force an update.
$(srcdir)/$(DOMAIN).pot:
	$(MAKE) $(DOMAIN).pot-update

# This target rebuilds a PO file if $(DOMAIN).pot has changed.
# Note that a PO file is not touched if it doesn't need to be changed.
$(POFILES): $(srcdir)/$(DOMAIN).pot
	@lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
	if test -f "$(srcdir)/$${lang}.po"; then \
	  test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
	  echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \
	  cd $(srcdir) \
	    && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
	           '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
	             $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \
	           *) \
	             $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \
	         esac; \
	       }; \
	else \
	  $(MAKE) $${lang}.po-create; \
	fi

install: install-exec install-data
install-exec:
install-data: install-data-@USE_NLS@
	if test "$(PACKAGE)" = "gettext-tools"; then \
	  $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \
	  for file in $(DISTFILES.common) Makevars.template; do \
	    $(INSTALL_DATA) $(srcdir)/$$file \
			    $(DESTDIR)$(gettextsrcdir)/$$file; \
	  done; \
	  for file in Makevars; do \
	    rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
	  done; \
	else \
	  : ; \
	fi
install-data-no: all
install-data-yes: all
	@catalogs='$(CATALOGS)'; \
	for cat in $$catalogs; do \
	  cat=`basename $$cat`; \
	  lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
	  dir=$(localedir)/$$lang/LC_MESSAGES; \
	  $(mkdir_p) $(DESTDIR)$$dir; \
	  if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \
	  $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \
	  echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \
	  for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
	    if test -n "$$lc"; then \
	      if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
	        link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
	        mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
	        mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
	        (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
	         for file in *; do \
	           if test -f $$file; then \
	             ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
	           fi; \
	         done); \
	        rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
	      else \
	        if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
	          :; \
	        else \
	          rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
	          mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
	        fi; \
	      fi; \
	      rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
	      ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
	      ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
	      cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
	      echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \
	    fi; \
	  done; \
	done

install-strip: install

installdirs: installdirs-exec installdirs-data
installdirs-exec:
installdirs-data: installdirs-data-@USE_NLS@
	if test "$(PACKAGE)" = "gettext-tools"; then \
	  $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \
	else \
	  : ; \
	fi
installdirs-data-no:
installdirs-data-yes:
	@catalogs='$(CATALOGS)'; \
	for cat in $$catalogs; do \
	  cat=`basename $$cat`; \
	  lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
	  dir=$(localedir)/$$lang/LC_MESSAGES; \
	  $(mkdir_p) $(DESTDIR)$$dir; \
	  for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
	    if test -n "$$lc"; then \
	      if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
	        link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
	        mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
	        mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
	        (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
	         for file in *; do \
	           if test -f $$file; then \
	             ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
	           fi; \
	         done); \
	        rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
	      else \
	        if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
	          :; \
	        else \
	          rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
	          mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
	        fi; \
	      fi; \
	    fi; \
	  done; \
	done

# Define this as empty until I found a useful application.
installcheck:

uninstall: uninstall-exec uninstall-data
uninstall-exec:
uninstall-data: uninstall-data-@USE_NLS@
	if test "$(PACKAGE)" = "gettext-tools"; then \
	  for file in $(DISTFILES.common) Makevars.template; do \
	    rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
	  done; \
	else \
	  : ; \
	fi
uninstall-data-no:
uninstall-data-yes:
	catalogs='$(CATALOGS)'; \
	for cat in $$catalogs; do \
	  cat=`basename $$cat`; \
	  lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
	  for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \
	    rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
	  done; \
	done

check: all

info dvi ps pdf html tags TAGS ctags CTAGS ID:

mostlyclean:
	rm -f remove-potcdate.sed
	rm -f stamp-poT
	rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po
	rm -fr *.o

clean: mostlyclean

distclean: clean
	rm -f Makefile Makefile.in POTFILES *.mo

maintainer-clean: distclean
	@echo "This command is intended for maintainers to use;"
	@echo "it deletes files that may require special tools to rebuild."
	rm -f stamp-po $(GMOFILES)

distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
dist distdir:
	$(MAKE) update-po
	@$(MAKE) dist2
# This is a separate target because 'update-po' must be executed before.
dist2: stamp-po $(DISTFILES)
	dists="$(DISTFILES)"; \
	if test "$(PACKAGE)" = "gettext-tools"; then \
	  dists="$$dists Makevars.template"; \
	fi; \
	if test -f $(srcdir)/$(DOMAIN).pot; then \
	  dists="$$dists $(DOMAIN).pot stamp-po"; \
	fi; \
	if test -f $(srcdir)/ChangeLog; then \
	  dists="$$dists ChangeLog"; \
	fi; \
	for i in 0 1 2 3 4 5 6 7 8 9; do \
	  if test -f $(srcdir)/ChangeLog.$$i; then \
	    dists="$$dists ChangeLog.$$i"; \
	  fi; \
	done; \
	if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \
	for file in $$dists; do \
	  if test -f $$file; then \
	    cp -p $$file $(distdir) || exit 1; \
	  else \
	    cp -p $(srcdir)/$$file $(distdir) || exit 1; \
	  fi; \
	done

update-po: Makefile
	$(MAKE) $(DOMAIN).pot-update
	test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES)
	$(MAKE) update-gmo

# General rule for creating PO files.

.nop.po-create:
	@lang=`echo $@ | sed -e 's/\.po-create$$//'`; \
	echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \
	exit 1

# General rule for updating PO files.

.nop.po-update:
	@lang=`echo $@ | sed -e 's/\.po-update$$//'`; \
	if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \
	tmpdir=`pwd`; \
	echo "$$lang:"; \
	test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
	echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \
	cd $(srcdir); \
	if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
	       '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
	         $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
	       *) \
	         $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
	     esac; \
	   }; then \
	  if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
	    rm -f $$tmpdir/$$lang.new.po; \
	  else \
	    if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
	      :; \
	    else \
	      echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
	      exit 1; \
	    fi; \
	  fi; \
	else \
	  echo "msgmerge for $$lang.po failed!" 1>&2; \
	  rm -f $$tmpdir/$$lang.new.po; \
	fi

$(DUMMYPOFILES):

update-gmo: Makefile $(GMOFILES)
	@:

# Recreate Makefile by invoking config.status. Explicitly invoke the shell,
# because execution permission bits may not work on the current file system.
# Use @SHELL@, which is the shell determined by autoconf for the use by its
# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient.
Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@
	cd $(top_builddir) \
	  && @SHELL@ ./config.status $(subdir)/$@.in po-directories

force:

# Tell versions [3.59,3.63) of GNU make not to export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:


code:
# Makefile variables for PO directory in any package using GNU gettext.

# Usually the message domain is the same as the package name.
DOMAIN = texi2html_document

# These two variables depend on the location of this directory.
subdir = @t2h_po_dir@po_document
top_builddir = @t2h_po_top_builddir@

# These options get passed to xgettext.
XGETTEXT_OPTIONS = --language=Perl --keyword=gdt --keyword=pgdt:1,2c

# This is the copyright holder that gets inserted into the header of the
# $(DOMAIN).pot file.  Set this to the copyright holder of the surrounding
# package.  (Note that the msgstr strings, extracted from the package's
# sources, belong to the copyright holder of the package.)  Translators are
# expected to transfer the copyright for their translations to this person
# or entity, or to disclaim their copyright.  The empty string stands for
# the public domain; in this case the translators are expected to disclaim
# their copyright.
COPYRIGHT_HOLDER = Free Software Foundation, Inc.

# This is the email address or URL to which the translators shall report
# bugs in the untranslated strings:
# - Strings which are not entire sentences, see the maintainer guidelines
#   in the GNU gettext documentation, section 'Preparing Strings'.
# - Strings which use unclear terms or require additional context to be
#   understood.
# - Strings which make invalid assumptions about notation of date, time or
#   money.
# - Pluralisation problems.
# - Incorrect English spelling.
# - Incorrect formatting.
# It can be your email address, or a mailing list address where translators
# can write to without being subscribed, or the URL of a web page through
# which the translators can contact you.
MSGID_BUGS_ADDRESS =

# This is the list of locale categories, beyond LC_MESSAGES, for which the
# message catalogs shall be used.  It is usually empty.
EXTRA_LOCALE_CATEGORIES =


code:
# Makefile variables for PO directory in any package using GNU gettext.

# Usually the message domain is the same as the package name.
DOMAIN = $(PACKAGE)

# These two variables depend on the location of this directory.
subdir = po
top_builddir = ..

# These options get passed to xgettext.
XGETTEXT_OPTIONS = --keyword=_ --keyword=N_

# This is the copyright holder that gets inserted into the header of the
# $(DOMAIN).pot file.  Set this to the copyright holder of the surrounding
# package.  (Note that the msgstr strings, extracted from the package's
# sources, belong to the copyright holder of the package.)  Translators are
# expected to transfer the copyright for their translations to this person
# or entity, or to disclaim their copyright.  The empty string stands for
# the public domain; in this case the translators are expected to disclaim
# their copyright.
COPYRIGHT_HOLDER = Free Software Foundation, Inc.

# This is the email address or URL to which the translators shall report
# bugs in the untranslated strings:
# - Strings which are not entire sentences, see the maintainer guidelines
#   in the GNU gettext documentation, section 'Preparing Strings'.
# - Strings which use unclear terms or require additional context to be
#   understood.
# - Strings which make invalid assumptions about notation of date, time or
#   money.
# - Pluralisation problems.
# - Incorrect English spelling.
# - Incorrect formatting.
# It can be your email address, or a mailing list address where translators
# can write to without being subscribed, or the URL of a web page through
# which the translators can contact you.
MSGID_BUGS_ADDRESS =

# This is the list of locale categories, beyond LC_MESSAGES, for which the
# message catalogs shall be used.  It is usually empty.
EXTRA_LOCALE_CATEGORIES =

# This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt'
# context.  Possible values are "yes" and "no".  Set this to yes if the
# package uses functions taking also a message context, like pgettext(), or
# if in $(XGETTEXT_OPTIONS) you define keywords with a context argument.
USE_MSGCTXT = no

# These options get passed to msgmerge.
# Useful options are in particular:
#   --previous            to keep previous msgids of translated messages,
#   --quiet               to reduce the verbosity.
MSGMERGE_OPTIONS =


code:
# List of source files which contain translatable strings.

@t2h_po_dir@texi2html.pl
@t2h_po_dir@texi2html.pm
@t2h_po_dir@T2h_l2h.pm
@t2h_po_dir@T2h_i18n.pm
@t2h_po_dir@formats/docbook.pm
@t2h_po_dir@formats/html.pm
@t2h_po_dir@formats/info.pm
@t2h_po_dir@formats/plaintext.pm
@t2h_po_dir@formats/xml.pm
@t2h_po_dir@maintained_extra/book.pm
@t2h_po_dir@maintained_extra/chm.pm
@t2h_po_dir@maintained_extra/html32.pm
@t2h_po_dir@maintained_extra/tex4ht.pm
@t2h_po_dir@maintained_extra/mediawiki.pm
@t2h_po_dir@examples/roff.pm


code:
# Special Makefile rules for English message catalogs with quotation marks.

DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot

.SUFFIXES: .insert-header .po-update-en

en@quot.po-create:
	$(MAKE) en@quot.po-update
en@boldquot.po-create:
	$(MAKE) en@boldquot.po-update

en@quot.po-update: en@quot.po-update-en
en@boldquot.po-update: en@boldquot.po-update-en

.insert-header.po-update-en:
	@lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \
	if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \
	tmpdir=`pwd`; \
	echo "$$lang:"; \
	ll=`echo $$lang | sed -e 's/@.*//'`; \
	LC_ALL=C; export LC_ALL; \
	cd $(srcdir); \
	if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$lang -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) $(SED) -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \
	  if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
	    rm -f $$tmpdir/$$lang.new.po; \
	  else \
	    if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
	      :; \
	    else \
	      echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
	      exit 1; \
	    fi; \
	  fi; \
	else \
	  echo "creation of $$lang.po failed!" 1>&2; \
	  rm -f $$tmpdir/$$lang.new.po; \
	fi

en@quot.insert-header: insert-header.sin
	sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header

en@boldquot.insert-header: insert-header.sin
	sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header

mostlyclean: mostlyclean-quot
mostlyclean-quot:
	rm -f *.insert-header