texinfo-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

texinfo/tp MANIFEST texi2any.pl Texinfo/Convert...


From: Patrice Dumas
Subject: texinfo/tp MANIFEST texi2any.pl Texinfo/Convert...
Date: Sun, 11 Sep 2011 02:18:23 +0000

CVSROOT:        /sources/texinfo
Module name:    texinfo
Changes by:     Patrice Dumas <pertusus>        11/09/11 02:18:23

Modified files:
        tp             : MANIFEST texi2any.pl 
        tp/Texinfo/Convert: Converter.pm XML.pm 
        tp/t           : 02coverage.t test_utils.pl 
Added files:
        tp/Texinfo/Convert: DocBook.pm 

Log message:
        Add a backend for conversion to DocBook, based on XML backend, and 
unfinished.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/MANIFEST?cvsroot=texinfo&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/texi2any.pl?cvsroot=texinfo&r1=1.58&r2=1.59
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/Texinfo/Convert/Converter.pm?cvsroot=texinfo&r1=1.35&r2=1.36
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/Texinfo/Convert/XML.pm?cvsroot=texinfo&r1=1.28&r2=1.29
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/Texinfo/Convert/DocBook.pm?cvsroot=texinfo&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/t/02coverage.t?cvsroot=texinfo&r1=1.59&r2=1.60
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/t/test_utils.pl?cvsroot=texinfo&r1=1.96&r2=1.97

Patches:
Index: MANIFEST
===================================================================
RCS file: /sources/texinfo/texinfo/tp/MANIFEST,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- MANIFEST    4 Sep 2011 13:41:45 -0000       1.3
+++ MANIFEST    11 Sep 2011 02:18:23 -0000      1.4
@@ -19,6 +19,7 @@
 Texinfo/Convert/XML.pm
 Texinfo/Convert/Plaintext.pm
 Texinfo/Convert/HTML.pm
+Texinfo/Convert/DocBook.pm
 Texinfo/Convert/Text.pm
 Texinfo/Convert/UnFilled.pm
 Texinfo/Convert/Paragraph.pm

Index: texi2any.pl
===================================================================
RCS file: /sources/texinfo/texinfo/tp/texi2any.pl,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -b -r1.58 -r1.59
--- texi2any.pl 6 Sep 2011 20:20:43 -0000       1.58
+++ texi2any.pl 11 Sep 2011 02:18:23 -0000      1.59
@@ -187,7 +187,7 @@
 require Texinfo::Convert::Info;
 require Texinfo::Convert::HTML;
 require Texinfo::Convert::XML;
-#require Texinfo::Convert::DocBook;
+require Texinfo::Convert::DocBook;
 require DebugTexinfo::DebugCount;
 
 # determine configuration directories.
@@ -745,7 +745,8 @@
  },
  'html' => sub {$format = set_format($_[0]);},
  'info' => sub {$format = set_format($_[0]);},
- 'docbook' => sub {$format = set_format($_[0]);},
+ 'docbook' => sub {$format = set_format($_[0]);
+                   set_from_cmdline('SHOW_MENU', 0)},
  'xml' => sub {$format = set_format($_[0]);},
  'dvi' => sub {$format = set_texi2dvi_format($_[0]);},
  'ps' => sub {$format = set_texi2dvi_format($_[0]);},
@@ -780,9 +781,9 @@
              'nodes_tree' => 1,
              'converter' => sub{Texinfo::Convert::XML->converter(@_)},
            },
-#  'docbook' => {
-#             'converter' => sub{Texinfo::Convert::DocBook->converter(@_)},
-#           },
+  'docbook' => {
+             'converter' => sub{Texinfo::Convert::DocBook->converter(@_)},
+           },
   'pdf' => {
              'texi2dvi_format' => 1,
            },

Index: Texinfo/Convert/Converter.pm
===================================================================
RCS file: /sources/texinfo/texinfo/tp/Texinfo/Convert/Converter.pm,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -b -r1.35 -r1.36
--- Texinfo/Convert/Converter.pm        8 Sep 2011 21:13:07 -0000       1.35
+++ Texinfo/Convert/Converter.pm        11 Sep 2011 02:18:23 -0000      1.36
@@ -458,6 +458,75 @@
   return $tree;
 }
 
+# This is used when the formatted text has no comment nor new line, but
+# one want to add the comment or new line from the original arg
+sub _end_line_or_comment($$)
+{
+  my $self = shift;
+  my $contents_possible_comment = shift;
+  my $end_line;
+  if ($contents_possible_comment
+      and $contents_possible_comment->[-1]->{'cmdname'}
+      and ($contents_possible_comment->[-1]->{'cmdname'} eq 'c'
+          or $contents_possible_comment->[-1]->{'cmdname'} eq 'comment')) {
+    $end_line = $self->_convert($contents_possible_comment->[-1]);
+  } elsif ($contents_possible_comment      
+           and $contents_possible_comment->[-1]->{'text'}) {
+    my $text = $contents_possible_comment->[-1]->{'text'};
+    if (chomp($text)) {
+      $end_line = "\n";
+    } else {
+      $end_line = '';
+    }
+  } else {
+    $end_line = '';
+  }
+  return $end_line;
+}
+
+sub _tree_without_comment($)
+{
+  my $contents_possible_comment = shift;
+  my $comment;
+  my $tree;
+
+  if ($contents_possible_comment->{'contents'}
+      and $contents_possible_comment->{'contents'}->[-1]->{'cmdname'}
+      and ($contents_possible_comment->{'contents'}->[-1]->{'cmdname'} eq 'c'
+           or $contents_possible_comment->{'contents'}->[-1]->{'cmdname'} eq 
'comment')) {
+    my @contents = @{$contents_possible_comment->{'contents'}};
+    $comment = pop @contents;
+    $tree = {'contents' => address@hidden;
+    foreach my $key ('extra', 'type', 'cmdname', 'parent', 'line_nr') {
+      $tree->{$key} = $contents_possible_comment->{$key}
+        if (exists($contents_possible_comment->{$key}));
+    }
+  } else {
+   $tree = $contents_possible_comment;
+  }
+  return ($comment, $tree);
+}
+
+sub _convert_argument_and_end_line($$)
+{
+  my $self = shift;
+  my $root = shift;
+  my ($comment, $tree) 
+    = _tree_without_comment($root);
+  my $converted = $self->_convert($tree);
+  my $end_line;
+  if ($comment) {
+    $end_line = $self->_convert($comment);
+  } else {
+    if (chomp($converted)) {
+      $end_line = "\n";
+    } else {
+      $end_line = "";
+    }
+  }
+  return ($converted, $end_line);
+}
+
 my @inline_types = ('def_line', 'paragraph', 'preformatted',
   'misc_command_arg', 'misc_line_arg', 'block_line_arg',
   'menu_entry_name', 'menu_entry_node');

Index: Texinfo/Convert/XML.pm
===================================================================
RCS file: /sources/texinfo/texinfo/tp/Texinfo/Convert/XML.pm,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -b -r1.28 -r1.29
--- Texinfo/Convert/XML.pm      10 Sep 2011 13:16:19 -0000      1.28
+++ Texinfo/Convert/XML.pm      11 Sep 2011 02:18:23 -0000      1.29
@@ -136,7 +136,7 @@
   'setfilename' => 'file',
   'documentencoding' => 'encoding',
   'verbatiminclude' => 'file',
-  'documentlanguage' => 'languge',
+  'documentlanguage' => 'language',
 );
 
 # FIXME printindex is special?
@@ -367,75 +367,6 @@
   return '';
 }
 
-# This is used when the formatted text has no comment nor new line, but
-# one want to add the comment or new line from the original arg
-sub _end_line_or_comment($$)
-{
-  my $self = shift;
-  my $contents_possible_comment = shift;
-  my $end_line;
-  if ($contents_possible_comment
-      and $contents_possible_comment->[-1]->{'cmdname'}
-      and ($contents_possible_comment->[-1]->{'cmdname'} eq 'c'
-          or $contents_possible_comment->[-1]->{'cmdname'} eq 'comment')) {
-    $end_line = $self->_convert($contents_possible_comment->[-1]);
-  } elsif ($contents_possible_comment      
-           and $contents_possible_comment->[-1]->{'text'}) {
-    my $text = $contents_possible_comment->[-1]->{'text'};
-    if (chomp($text)) {
-      $end_line = "\n";
-    } else {
-      $end_line = '';
-    }
-  } else {
-    $end_line = '';
-  }
-  return $end_line;
-}
-
-sub _tree_without_comment($)
-{
-  my $contents_possible_comment = shift;
-  my $comment;
-  my $tree;
-
-  if ($contents_possible_comment->{'contents'}
-      and $contents_possible_comment->{'contents'}->[-1]->{'cmdname'}
-      and ($contents_possible_comment->{'contents'}->[-1]->{'cmdname'} eq 'c'
-           or $contents_possible_comment->{'contents'}->[-1]->{'cmdname'} eq 
'comment')) {
-    my @contents = @{$contents_possible_comment->{'contents'}};
-    $comment = pop @contents;
-    $tree = {'contents' => address@hidden;
-    foreach my $key ('extra', 'type', 'cmdname', 'parent', 'line_nr') {
-      $tree->{$key} = $contents_possible_comment->{$key}
-        if (exists($contents_possible_comment->{$key}));
-    }
-  } else {
-   $tree = $contents_possible_comment;
-  }
-  return ($comment, $tree);
-}
-
-sub _convert_argument_and_end_line($$)
-{
-  my $self = shift;
-  my $root = shift;
-  my ($comment, $tree) 
-    = _tree_without_comment($root);
-  my $converted = $self->_convert($tree);
-  my $end_line;
-  if ($comment) {
-    $end_line = $self->_convert($comment);
-  } else {
-    if (chomp($converted)) {
-      $end_line = "\n";
-    } else {
-      $end_line = "";
-    }
-  }
-  return ($converted, $end_line);
-}
-
 sub _infoenclose_attribute($$) {
   my $self = shift;
   my $root = shift;

Index: t/02coverage.t
===================================================================
RCS file: /sources/texinfo/texinfo/tp/t/02coverage.t,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -b -r1.59 -r1.60
--- t/02coverage.t      6 Sep 2011 20:20:44 -0000       1.59
+++ t/02coverage.t      11 Sep 2011 02:18:23 -0000      1.60
@@ -692,6 +692,7 @@
   push @{$test->[2]->{'test_formats'}}, 'plaintext';
   push @{$test->[2]->{'test_formats'}}, 'html_text';
   push @{$test->[2]->{'test_formats'}}, 'xml';
+  #push @{$test->[2]->{'test_formats'}}, 'docbook';
 }
 
 our ($arg_test_case, $arg_generate, $arg_debug);

Index: t/test_utils.pl
===================================================================
RCS file: /sources/texinfo/texinfo/tp/t/test_utils.pl,v
retrieving revision 1.96
retrieving revision 1.97
diff -u -b -r1.96 -r1.97
--- t/test_utils.pl     8 Sep 2011 22:53:10 -0000       1.96
+++ t/test_utils.pl     11 Sep 2011 02:18:23 -0000      1.97
@@ -14,6 +14,7 @@
 use Texinfo::Convert::Info;
 use Texinfo::Convert::HTML;
 use Texinfo::Convert::XML;
+use Texinfo::Convert::DocBook;
 use DebugTexinfo::DebugCount;
 use File::Basename;
 use Data::Dumper;
@@ -47,6 +48,7 @@
   'html' => \&convert_to_html,
   'html_text' => \&convert_to_html,
   'xml' => \&convert_to_xml,
+  'docbook' => \&convert_to_docbook,
   'debugcount' => \&debugcount,
 );
 
@@ -325,6 +327,31 @@
   return ($errors, $result);
 }
 
+sub convert_to_docbook($$$$$;$)
+{
+  my $self = shift;
+  my $format = shift;
+  my $tree = shift;
+  my $parser = shift;
+  my $parser_options = shift;
+  my $converter_options = shift;
+  if (!defined($converter_options)) {
+    $converter_options = {};
+    $converter_options->{'expanded_formats'} = ['docbook']
+      if (!defined($parser_options->{'expanded_formats'}));
+  }
+  my $converter =
+     Texinfo::Convert::DocBook->converter ({'DEBUG' => $self->{'DEBUG'},
+                                         'parser' => $parser,
+                                         'OUTFILE' => '',
+                                         'output_format' => 'docbook',
+                                          %$converter_options });
+  my $result = $converter->convert($tree);
+  die if (!defined($result));
+  my ($errors, $error_nrs) = $converter->errors();
+  return ($errors, $result);
+}
+
 sub debugcount($$$$$;$)
 {
   my $self = shift;

Index: Texinfo/Convert/DocBook.pm
===================================================================
RCS file: Texinfo/Convert/DocBook.pm
diff -N Texinfo/Convert/DocBook.pm
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ Texinfo/Convert/DocBook.pm  11 Sep 2011 02:18:23 -0000      1.1
@@ -0,0 +1,984 @@
+# DocBook.pm: output tree as DocBook.
+#
+# Copyright 2011 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/>.
+# 
+# Original author: Patrice Dumas <address@hidden>
+
+# TODO @*ref, block commands, abbrev, image, 
+
+package Texinfo::Convert::DocBook;
+
+use 5.00405;
+use strict;
+
+use Texinfo::Convert::Converter;
+use Texinfo::Common;
+use Texinfo::Convert::Unicode;
+# for debugging
+use Texinfo::Convert::Texinfo;
+use Data::Dumper;
+use Carp qw(cluck);
+
+require Exporter;
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
address@hidden = qw(Exporter Texinfo::Convert::Converter);
+
+# Items to export into callers namespace by default. Note: do not export
+# names by default without a very good reason. Use EXPORT_OK instead.
+# Do not simply export all your public functions/methods/constants.
+
+# This allows declaration       use Texinfo::Convert::Text ':all';
+# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
+# will save memory.
+%EXPORT_TAGS = ( 'all' => [ qw(
+  convert
+) ] );
+
address@hidden = ( @{ $EXPORT_TAGS{'all'} } );
+
address@hidden = qw(
+);
+
+$VERSION = '0.01';
+
+my $mdash = '&#'.hex('2014').';';
+my $ndash = '&#'.hex('2013').';';
+my $ldquo = '&#'.hex('201C').';';
+my $rdquo = '&#'.hex('201D').';';
+my $rsquo = '&#'.hex('2019').';';
+my $lsquo = '&#'.hex('2018').';';
+
+my %defaults = (
+  #'ENABLE_ENCODING'      => 0,
+  'SHOW_MENU'            => 0,
+  'EXTENSION'            => 'xml', # dbk?
+  'perl_encoding'        => 'utf8',
+  'encoding_name'        => 'utf-8',
+  'OUTFILE'              => undef,
+  'SUBDIR'               => undef,
+  'output_format'        => 'docbook',
+  'SPLIT'                => 0,
+  'documentlanguage'     => 'en',
+  'OPEN_QUOTE_SYMBOL'    => $lsquo,
+  'CLOSE_QUOTE_SYMBOL'   => $rsquo,
+);
+
+
+my %docbook_specific_formatting = (
+  'TeX' => '&tex;',
+  'LaTeX' => '&latex;',
+);
+my %docbook_commands_formatting
+  = %{$Texinfo::Convert::Converter::default_xml_commands_formatting{'normal'}};
+
+foreach my $command (keys(%Texinfo::Convert::Unicode::unicode_map)) {
+  $docbook_commands_formatting{$command}
+   = '&#'.hex($Texinfo::Convert::Unicode::unicode_map{$command}).';'
+    if ($Texinfo::Convert::Unicode::unicode_map{$command} ne '');
+}
+
+foreach my $command (keys(%docbook_specific_formatting)) {
+  $docbook_commands_formatting{$command} 
+    = $docbook_specific_formatting{$command};
+}
+
+my %quoted_style_commands = (
+  'samp' => 1,
+);
+
+my %style_attribute_commands;
+%style_attribute_commands = (
+      'b'           => 'emphasis role="bold"',
+      'cite'        => 'citetitle',
+      'code'        => 'literal',
+      'command'     => 'command',
+      'dfn'         => 'firstterm',
+      'emph'        => 'emphasis',
+      'env'         => 'envar',
+      'file'        => 'filename',
+      'headitemfont' => 'emphasis role="bold"', # not really that, in fact it 
is 
+                             # in <th> rather than <td>
+      'i'           => 'wordasword',
+      'indicateurl' => 'wordasword',
+      'sansserif'   => 'span class="sansserif"',
+      'kbd'         => 'userinput',
+      'key'         => 'keycap',
+      'option'      => 'option',
+      'r'           => 'span class="roman"',
+      'samp'        => 'literal',
+      'strong'      => 'emphasis role="bold"',
+      't'           => 'literal',
+      'var'         => 'replaceable',
+      'verb'        => 'literal',
+      'footnote'    => 'footnote',
+#      'math'        => 'em',
+);
+
+# this weird construct does like uniq, it avoids duplicates.
+# it may be required since math is not in the %style_commands as it is 
+# in context command.
+my @all_style_commands = keys %{{ map { $_ => 1 }
+    (keys(%Texinfo::Common::style_commands), keys(%style_attribute_commands),
+     'dmn', 'math', 'titlefont') }};
+# 'w' is special
+
+my %style_commands_formatting;
+foreach my $command(@all_style_commands) {
+  $style_commands_formatting{$command} = {};
+  if ($style_attribute_commands{$command}) {
+    $style_commands_formatting{$command}->{'attribute'} 
+      = $style_attribute_commands{$command};
+  }
+  if ($quoted_style_commands{$command}) {
+    $style_commands_formatting{$command}->{'quote'} = 1;
+  }
+}
+
+my %misc_command_line_attributes = (
+  'setfilename' => 'file',
+  'documentencoding' => 'encoding',
+  'verbatiminclude' => 'file',
+  'documentlanguage' => 'language',
+);
+
+# FIXME printindex is special?
+my %misc_command_numbered_arguments_attributes = (
+  'definfoenclose' => [ 'command', 'open', 'close' ],
+  'alias' => [ 'new', 'existing' ],
+  'syncodeindex' => [ 'from', 'to' ],
+  'synindex' => [ 'from', 'to' ],
+#  'sp' => [ 'lines' ],
+);
+
+my %docbook_misc_elements_with_arg_map = (
+  'settitle' => 'title',
+);
+
+my %docbook_misc_commands = %Texinfo::Common::misc_commands;
+
+foreach my $command ('item', 'headitem', 'itemx', 'tab', 
+                      keys %Texinfo::Common::def_commands) {
+  delete $docbook_misc_commands{$command};
+}
+
+my %default_args_code_style 
+  = %Texinfo::Convert::Converter::default_args_code_style;
+
+my %commands_args_elements = (
+  'inforef' => ['inforefnodename', 'inforefrefname', 'inforefinfoname'],
+  'image' => ['imagefile', 'imagewidth', 'imageheight', 
+              'alttext', 'imageextension'],
+  'quotation' => ['quotationtype'],
+  'float' => ['floattype', 'floatname'],
+  'itemize' => ['itemfunction'],
+);
+
+foreach my $ref_cmd ('pxref', 'xref', 'ref') {
+  $commands_args_elements{$ref_cmd} 
+    = ['xrefnodename', 'xrefinfoname', 'xrefprinteddesc', 'xrefinfofile', 
+       'xrefprintedname'];
+}
+
+foreach my $explained_command (keys(%Texinfo::Common::explained_commands)) {
+  $commands_args_elements{$explained_command} = ["${explained_command}word",
+                                                 "${explained_command}desc"];
+}
+
+my %commands_elements;
+foreach my $command (keys(%Texinfo::Common::brace_commands)) {
+  $commands_elements{$command} = [$command];
+  if ($commands_args_elements{$command}) {
+    push @{$commands_elements{$command}}, @{$commands_args_elements{$command}};
+  }
+}
+
+my %defcommand_name_type = (
+ 'deffn'     => 'function',
+ 'defvr'     => 'variable',
+ 'deftypefn' => 'function',
+ 'deftypeop' => 'operation',
+ 'deftypevr' => 'variable',
+ 'defcv'     => 'classvar',
+ 'deftypecv' => 'classvar',
+ 'defop'     => 'operation',
+ 'deftp'     => 'datatype',
+);
+
+my %ignored_types;
+foreach my $type (#'empty_line_after_command',
+            'preamble',
+            'empty_spaces_after_command', 
+            #'spaces_at_end',
+            'empty_spaces_before_argument', 'empty_spaces_before_paragraph',
+            'empty_spaces_after_close_brace', 
+            'empty_space_at_end_def_bracketed',
+            # FIXME keep those? Information is lost...
+            'menu_entry_separator',
+            'menu_entry_leading_text',
+  ) {
+  $ignored_types{$type} = 1;
+}
+
+my %type_elements = (
+  'paragraph' => 'para',
+  'table_item' => 'listitem',
+  'table_entry' => 'varlistentry',
+  'row' => 'row',
+  'multitable_head' => 'thead',
+  'multitable_body' => 'tbody',
+  # FIXME is this right?
+  'def_item' => 'blockquote',
+);
+
+my %context_block_commands = (
+  'float' => 1,
+);
+
+sub _defaults($)
+{
+  return %defaults;
+}
+
+sub _initialize($)
+{
+  my $self = shift;
+
+  $self->{'document_context'} = [{}];
+}
+
+sub _global_commands($)
+{
+  return ('documentlanguage', 'documentencoding');
+}
+
+sub _informative_command($$)
+{
+  my $self = shift;
+  my $root = shift;
+
+  my $cmdname = $root->{'cmdname'};
+  return if ($self->{'set'}->{$cmdname});
+
+  if (exists($root->{'extra'}->{'text_arg'})) {
+    $self->set_conf($cmdname, $root->{'extra'}->{'text_arg'});
+    if ($cmdname eq 'documentencoding'
+        and defined($root->{'extra'})
+        and defined($root->{'extra'}->{'perl_encoding'})
+       ){
+        #and !$self->{'perl_encoding'}) {
+      $self->{'encoding_name'} = $root->{'extra'}->{'encoding_name'};
+      $self->{'perl_encoding'} = $root->{'extra'}->{'perl_encoding'};
+    }
+  }
+}
+
+sub _initialize_document($$)
+{
+  my $self = shift;
+  my $root = shift;
+
+  my $elements;
+
+  $self->_set_global_multiple_commands(-1);
+  $elements = Texinfo::Structuring::split_by_section($root);
+  $self->{'elements'} = $elements;
+  return $elements;
+}
+
+sub convert($$)
+{
+  my $self = shift;
+  my $root = shift;
+
+  my $elements = $self->_initialize_document($root);
+
+  my $result = '';
+  if (!defined($elements)) {
+    $result = $self->_convert($root);
+  } else {
+    foreach my $element (@$elements) {
+      my $element_text = $self->_convert($element);
+      $result .= $element_text;
+    }
+  }
+
+  return $result;
+}
+
+sub _normalize_top_node($)
+{
+  my $node = shift;
+  return Texinfo::Common::normalize_top_node($node);
+}
+
+# output fo $fh if defined, otherwise return the text.
+sub _output_text($$)
+{
+  my $text = shift;
+  my $fh = shift;
+  if ($fh) {
+    print $fh $text;
+    return '';
+  } else {
+    return $text;
+  }
+}
+
+sub output($$)
+{
+  my $self = shift;
+  my $root = shift;
+
+  $self->_set_outfile();
+  return undef unless $self->_create_destination_directory();
+
+  my $fh;
+  if (! $self->get_conf('OUTFILE') eq '') {
+    $fh = $self->Texinfo::Common::open_out ($self->get_conf('OUTFILE'),
+                                            $self->{'perl_encoding'});
+    if (!$fh) {
+      $self->document_error(sprintf($self->__("Could not open %s for writing: 
%s"),
+                                    $self->get_conf('OUTFILE'), $!));
+      return undef;
+    }
+  }
+
+  my $elements = $self->_initialize_document($root);
+
+  my $id;
+  if ($self->get_conf('OUTFILE') ne '') {
+    my $output_filename = $self->{'output_filename'};
+    $id = " id=\"".$self->xml_protect_text($output_filename)."\"";
+  } else {
+    $id = '';
+  }
+
+  my $header = '<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" 
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"; [
+  <!ENTITY tex "TeX">
+  <!ENTITY latex "LaTeX">
+]>
+'. "<book${id} lang=\"".$self->get_conf('documentlanguage') ."\">\n";
+
+  my $result = '';
+  $result .= _output_text($header, $fh);
+  if (!defined($elements)) {
+    $result .= _output_text($self->_convert($root), $fh);
+  } else {
+    foreach my $element (@$elements) {
+      $result .= _output_text($self->_convert($root), $fh);
+    }
+  }
+
+  $result .= _output_text("</book>\n", $fh);
+  return $result;
+}
+
+my %docbook_sections = (
+  'top'  => 'chapter',
+  'part' => 'part',
+  'chapter'  => 'chapter',
+  'unnumbered'  => 'chapter',
+  'centerchap'  => 'chapter',
+  'appendix' => 'appendix',
+  'majorheading' => 'other',
+  'chapheading' => 'other',
+  'heading' => 'sect1',
+  'subheading' => 'sect2',
+  'subsubheading' => 'sect3',
+  2 => 'sect1',
+  3 => 'sect2',
+  4 => 'sect3'
+);
+
+
+sub _level_corrected_section($)
+{
+  my $root = shift;
+  my $heading_level = $root->{'level'};
+  if (exists $docbook_sections{$heading_level}) {
+    return $docbook_sections{$heading_level};
+  }
+  my $command;
+  if ($heading_level ne 
$Texinfo::Common::command_structuring_level{$root->{'cmdname'}}) {
+    $command
+      = 
$Texinfo::Common::level_to_structuring_command{$root->{'cmdname'}}->[$heading_level];
+  } else {
+    $command = $root->{'cmdname'};
+  }
+  return $docbook_sections{$command};
+}
+
+sub _index_entry($$)
+{
+  my $self = shift;
+  my $root = shift;
+  if ($root->{'extra'} and $root->{'extra'}->{'index_entry'}) {
+    my $index_entry = $root->{'extra'}->{'index_entry'};
+    my $result = "<indexterm role=\"$index_entry->{'index_name'}\"><primary>";
+    push @{$self->{'document_context'}}, {};
+    $self->{'document_context'}->[-1]->{'code'}++ 
+      if ($index_entry->{'in_code'});
+    $result .= $self->_convert({'contents' => $index_entry->{'content'}});
+    pop @{$self->{'document_context'}};
+    return $result ."</primary></indexterm>"
+  }
+  return '';
+}
+
+sub docbook_accent($$;$$)
+{
+  my $text = shift;
+  my $command = shift;
+  my $in_upper_case = shift;
+  my $accent = $command->{'cmdname'};
+
+  if ($in_upper_case and $text =~ /^\w$/) {
+    $text = uc ($text);
+  }
+  if (exists($Texinfo::Convert::Unicode::unicode_accented_letters{$accent})
+      and 
exists($Texinfo::Convert::Unicode::unicode_accented_letters{$accent}->{$text})) 
{
+    return '&#' .
+      
hex($Texinfo::Convert::Unicode::unicode_accented_letters{$accent}->{$text}). 
';';
+  }
+  return $text . '&lt;' if ($accent eq 'v');
+  # FIXME it is not possible to call xml_protect_text since what is in $text
+  # may already be xml.  But this means that each time ascii_accent changes
+  # it should be changed here too.
+  return Texinfo::Convert::Text::ascii_accent($text, $command);
+}
+
+sub _parse_attribute($)
+{
+  my $element = shift;
+  return ('', '') if (!defined($element));
+  my $attributes = '';
+  if ($element =~ /^(\w+)(\s+.*)/)
+  {
+    $element = $1;
+    $attributes = $2;
+  }
+  return ($element, $attributes);
+}
+
+
+sub _convert($$;$);
+
+
+
+sub _convert($$;$)
+{
+  my $self = shift;
+  my $root = shift;
+
+  if (0) {
+  #if (1) {
+    print STDERR "root\n";
+    print STDERR "  Command: $root->{'cmdname'}\n" if ($root->{'cmdname'});
+    print STDERR "  Type: $root->{'type'}\n" if ($root->{'type'});
+    print STDERR "  Text: $root->{'text'}\n" if (defined($root->{'text'}));
+    #print STDERR "  Special def_command: $root->{'extra'}->{'def_command'}\n"
+    #  if (defined($root->{'extra'}) and $root->{'extra'}->{'def_command'});
+  }
+
+  return '' if ($root->{'type'} and $ignored_types{$root->{'type'}});
+  my $result = '';
+  if (defined($root->{'text'})) {
+    $result = $self->xml_protect_text($root->{'text'});
+    if (! defined($root->{'type'}) or $root->{'type'} ne 'raw') {
+      if (!$self->{'document_context'}->[-1]->{'code'}) {
+        $result =~ s/``/$ldquo/g;
+        $result =~ s/\'\'/$rdquo/g;
+        $result =~ s/`/$lsquo/g;
+        $result =~ s/\'/$rsquo/g;
+        $result =~ s/---/$mdash/g;
+        $result =~ s/--/$ndash/g;
+      }
+    }
+    return $result;
+  }
+  my $close_element;
+  if ($root->{'cmdname'}) {
+    if (defined($docbook_commands_formatting{$root->{'cmdname'}})) {
+      my $command;
+      if ($root->{'cmdname'} eq 'click' 
+          and $root->{'extra'} 
+          and defined($root->{'extra'}->{'clickstyle'})) {
+        $command = $root->{'extra'}->{'clickstyle'};
+      } else {
+        $command = $root->{'cmdname'};
+      }
+      return $docbook_commands_formatting{$command};
+    } elsif ($Texinfo::Common::accent_commands{$root->{'cmdname'}}) {
+      return $self->xml_accents($root, undef, \&docbook_accent);#, 
$self->in_upper_case());
+   # } elsif ($root->{'cmdname'} eq 'item' and 
+    } elsif ($root->{'cmdname'} eq 'item' or $root->{'cmdname'} eq 'itemx'
+             or $root->{'cmdname'} eq 'headitem' or $root->{'cmdname'} eq 
'tab') {
+      if ($root->{'cmdname'} eq 'item'
+          and $root->{'parent'}->{'cmdname'}
+          and ($root->{'parent'}->{'cmdname'} eq 'itemize'
+               or $root->{'parent'}->{'cmdname'} eq 'enumerate')) {
+        $result .= "<listitem>";
+        $close_element = 'listitem';
+      } elsif (($root->{'cmdname'} eq 'item' or $root->{'cmdname'} eq 'itemx')
+               and $root->{'parent'}->{'type'} 
+               and $root->{'parent'}->{'type'} eq 'table_term') {
+        my $table_command = $root->{'parent'}->{'parent'}->{'parent'};
+        my $format_item_command;
+        my $arg_tree;
+        if ($table_command->{'extra'} 
+            and $table_command->{'extra'}->{'command_as_argument'}) {
+          $format_item_command 
+           = $table_command->{'extra'}->{'command_as_argument'}->{'cmdname'};
+          $arg_tree = { 'cmdname' => $format_item_command,
+             'contents' => $root->{'args'}->[0]->{'contents'}};
+        } else {
+          $arg_tree = $root->{'args'}->[0];
+        }
+        $result .= "<term>";
+        # Is it automaticcally entered in docbook?
+        #$result .= $self->_index_entry($root);
+        # FIXME
+        my $in_code;
+        $in_code = 1
+          if ($format_item_command 
+              and defined($default_args_code_style{$format_item_command})
+              and 
defined($default_args_code_style{$format_item_command}->[0]));
+        $self->{'document_context'}->[-1]->{'code'}++ if ($in_code);
+        $result .= $self->_convert($arg_tree);
+        $self->{'document_context'}->[-1]->{'code'}-- if ($in_code);
+        chomp ($result);
+        $result .= "</term>\n";
+      } else {
+        unless (($root->{'cmdname'} eq 'item' 
+                     or $root->{'cmdname'} eq 'headitem'
+                     or $root->{'cmdname'} eq 'tab')
+                    and $root->{'parent'}->{'type'}
+                    and $root->{'parent'}->{'type'} eq 'row') {
+          print STDERR "BUG: multitable cell command not in a row "
+            .Texinfo::Parser::_print_current($root);
+        }
+        
+        $result .= "<entry>";
+        $close_element = 'entry';
+      }
+    } elsif ($root->{'type'} and $root->{'type'} eq 'index_entry_command') {
+      my $end_line;
+      if ($root->{'args'}->[0]) {
+        $end_line = 
$self->_end_line_or_comment($root->{'args'}->[0]->{'contents'});
+      } else {
+        # May that happen?
+        $end_line = '';
+      }
+      return $self->_index_entry($root).${end_line};
+    } elsif (exists($docbook_misc_commands{$root->{'cmdname'}})) {
+      my $command;
+      if (exists ($docbook_misc_elements_with_arg_map{$root->{'cmdname'}})) {
+        $command = $docbook_misc_elements_with_arg_map{$root->{'cmdname'}};
+      } else {
+        $command = $root->{'cmdname'};
+      }
+      my $type = $docbook_misc_commands{$root->{'cmdname'}};
+      if ($type eq 'text') {
+        return '' if ($root->{'cmdname'} eq 'end');
+        my $attribute = '';
+        if ($misc_command_line_attributes{$root->{'cmdname'}}) {
+          if ($root->{'extra'} and defined($root->{'extra'}->{'text_arg'})) {
+            $attribute = " 
$misc_command_line_attributes{$root->{'cmdname'}}=\""
+                . $self->xml_protect_text($root->{'extra'}->{'text_arg'}) 
."\"";
+          }
+        }
+        my $arg = $self->_convert($root->{'args'}->[0]);
+        my $end_line;
+        if (chomp ($arg)) {
+          $end_line = "\n";
+        } else {
+          $end_line = "";
+        }
+        return "<$command${attribute}>$arg</$command>$end_line";
+      } elsif ($type eq 'line') {
+        if ($root->{'cmdname'} eq 'node') {
+          if (!$root->{'extra'} or !$root->{'extra'}->{'associated_section'}) {
+            $result .= "<anchor id=\"$root->{'extra'}->{'normalized'}\"/>\n";
+          }
+        } elsif ($Texinfo::Common::root_commands{$root->{'cmdname'}}) {
+          my $attribute;
+          if ($root->{'extra'} and $root->{'extra'}->{'associated_node'}) {
+            $attribute = " 
id=\"$root->{'extra'}->{'associated_node'}->{'normalized'}\"";
+          }
+          $command = _level_corrected_section($root);
+          $result .= "<$command${attribute}>\n";
+          if ($root->{'args'} and $root->{'args'}->[0]) {
+            my ($arg, $end_line)
+              = $self->_convert_argument_and_end_line($root->{'args'}->[0]);
+            $result .= "<title>$arg</title>$end_line";
+          }
+        } elsif ($Texinfo::Common::sectioning_commands{$root->{'cmdname'}}) {
+          if ($root->{'args'} and $root->{'args'}->[0]) {
+            my ($arg, $end_line)
+              = $self->_convert_argument_and_end_line($root->{'args'}->[0]);
+            return "<bridgehead 
renderas=\"$docbook_sections{$root->{'cmdname'}}>$arg</bridgehead>$end_line";
+          }
+          return '';
+        } else {
+          my $attribute = '';
+          my ($arg, $end_line)
+            = $self->_convert_argument_and_end_line($root->{'args'}->[0]);
+          return "<$command${attribute}>$arg</$command>$end_line";
+        }
+      } elsif ($type eq 'skipline' or $type eq 'noarg') {
+        return "<$command></$command>\n";
+      } elsif ($type eq 'special') {
+      } elsif ($type eq 'lineraw') {
+        if ($root->{'cmdname'} eq 'c' or $root->{'cmdname'} eq 'comment') {
+          return $self->xml_default_comment($root->{'args'}->[0]->{'text'})
+        } else {
+          my $value = '';
+          if ($root->{'args'} and $root->{'args'}->[0]
+              and defined($root->{'args'}->[0]->{'text'})) {
+            $value = $self->xml_protect_text($root->{'args'}->[0]->{'text'});
+          }
+          return "<${command}>$value</${command}>\n";
+        }
+      } else {
+        print STDERR "BUG: unknown misc_command style $type" if ($type !~ 
/^\d$/);
+        my $args_attributes;
+        if ($misc_command_numbered_arguments_attributes{$root->{'cmdname'}}) {
+          $args_attributes = 
$misc_command_numbered_arguments_attributes{$root->{'cmdname'}};
+        } else {
+          $args_attributes = ['value'];
+        }
+        my $attribute = '';
+        my $arg_index = 0;
+        if (defined($root->{'extra'}) 
+            and defined($root->{'extra'}->{'misc_args'})) {
+          foreach my $arg_attribute (@{$args_attributes}) {
+            if (defined ($root->{'extra'}->{'misc_args'}->[$arg_index])) {
+              $attribute .= " $arg_attribute=\""
+               
.$self->xml_protect_text($root->{'extra'}->{'misc_args'}->[$arg_index])."\"";
+            }
+            $arg_index++;
+          }
+        }
+        return "<$command${attribute}></$command>\n";
+      }
+    } elsif ($root->{'type'}
+             and $root->{'type'} eq 'definfoenclose_command') {
+      my $in_code;
+      $in_code = 1
+        if (defined($default_args_code_style{$root->{'cmdname'}})
+            and defined($default_args_code_style{$root->{'cmdname'}}->[0]));
+      $self->{'document_context'}->[-1]->{'code'}++ if ($in_code);
+      my $arg = $self->_convert($root->{'args'}->[0]);
+      $result .= $self->xml_protect_text($root->{'extra'}->{'begin'}).$arg
+                .$self->xml_protect_text($root->{'extra'}->{'end'});
+      $self->{'document_context'}->[-1]->{'code'}-- if ($in_code);
+    } elsif ($root->{'args'}
+             and exists($Texinfo::Common::brace_commands{$root->{'cmdname'}})) 
{
+      if ($Texinfo::Common::context_brace_commands{$root->{'cmdname'}}) {
+        push @{$self->{'document_context'}}, {};
+      }
+      if ($style_commands_formatting{$root->{'cmdname'}}) {
+        my $formatting = $style_commands_formatting{$root->{'cmdname'}};
+        my $in_code;
+        $in_code = 1
+          if (defined($default_args_code_style{$root->{'cmdname'}})
+              and defined($default_args_code_style{$root->{'cmdname'}}->[0]));
+        $self->{'document_context'}->[-1]->{'code'}++ if ($in_code);
+        my ($style, $attribute_text) = 
_parse_attribute($formatting->{'attribute'});
+        my $result = $self->_convert($root->{'args'}->[0]);
+        if ($style ne '') {
+          $result = "<$style${attribute_text}>$result</$style>";
+        }
+        if (defined($formatting->{'quote'})) {
+          $result = $self->get_conf('OPEN_QUOTE_SYMBOL') . $result
+                   . $self->get_conf('CLOSE_QUOTE_SYMBOL');
+        }
+        $self->{'document_context'}->[-1]->{'code'}-- if ($in_code);
+        return $result;
+      } elsif ($root->{'cmdname'} eq 'anchor') {
+        return "<anchor id=\"$root->{'extra'}->{'normalized'}\"/>";
+      } elsif ($root->{'cmdname'} eq 'email') {
+        if ($root->{'extra'} and $root->{'extra'}->{'brace_command_contents'}) 
{
+          my $name;
+          my $email;
+          my $email_text;
+          if (scalar (@{$root->{'extra'}->{'brace_command_contents'}}) == 2
+              and defined($root->{'extra'}->{'brace_command_contents'}->[-1])) 
{
+            $name = $root->{'extra'}->{'brace_command_contents'}->[1];
+          }
+          if (defined($root->{'extra'}->{'brace_command_contents'}->[0])) {
+            $email = $root->{'extra'}->{'brace_command_contents'}->[0];
+            $email_text 
+              = $self->xml_protect_text(Texinfo::Convert::Text::convert(
+                                         {'contents' => $email},
+                                         {'converter' => $self, 'code' => 1}));
+          }
+          if ($name and $email) {
+            return "<ulink url=\"mailto:$email_text\";>"
+              .$self->_convert({'contents' => $name}).'</ulink>';
+          } elsif ($email) {
+            return "<email>$email_text</email>";
+          } elsif ($name) {
+            return $self->_convert({'contents' => $name});
+          }
+        } else {
+          return '';
+        }
+      } elsif ($root->{'cmdname'} eq 'uref' or $root->{'cmdname'} eq 'url') {
+        if ($root->{'extra'} and $root->{'extra'}->{'brace_command_contents'}) 
{
+          my ($url_text, $url_content);
+          if (defined($root->{'extra'}->{'brace_command_contents'}->[0])) {
+            $url_content = $root->{'extra'}->{'brace_command_contents'}->[0];
+            $url_text = 
$self->xml_protect_text(Texinfo::Convert::Text::convert(
+                                         {'contents' => $url_content},
+                                         {'converter' => $self, 'code' => 1}));
+          } else {
+            $url_text = '';
+          }
+          my $replacement;
+          if (scalar(@{$root->{'extra'}->{'brace_command_contents'}}) >= 2 
+              and defined($root->{'extra'}->{'brace_command_contents'}->[1])) {
+            $replacement = $self->_convert({'contents' 
+                      => $root->{'extra'}->{'brace_command_contents'}->[1]});
+          }
+          if (!defined($replacement) or $replacement eq '') {
+            if (scalar(@{$root->{'extra'}->{'brace_command_contents'}}) == 3
+                and 
defined($root->{'extra'}->{'brace_command_contents'}->[2])) {
+              $replacement = $self->_convert({'contents' 
+                      => $root->{'extra'}->{'brace_command_contents'}->[2]});
+            }
+          }
+          if (!defined($replacement) or $replacement eq '') {
+            $replacement = $url_text;
+          }
+          return "<ulink url=\"$url_text\">$replacement</ulink>";
+        }
+      }
+      my @elements = @{$commands_elements{$root->{'cmdname'}}};
+      my $command;
+      if (scalar(@elements) > 1) {
+        $command = shift @elements;
+      }
+      my $attribute = '';
+      # TODO after, it is wrong.
+      my $arg_index = 0;
+      foreach my $element (@elements) {
+        if (defined($root->{'args'}->[$arg_index])) {
+          my $in_code;
+          $in_code = 1
+            if (defined($default_args_code_style{$root->{'cmdname'}})
+              and 
defined($default_args_code_style{$root->{'cmdname'}}->[$arg_index]));
+          $self->{'document_context'}->[-1]->{'code'}++ if ($in_code);
+          my $arg = $self->_convert($root->{'args'}->[$arg_index]);
+          if (!defined($command) or $arg ne '') {
+            # ${attribute} is only set for @verb
+            $result .= "<$element${attribute}>$arg</$element>";
+          }
+          $self->{'document_context'}->[-1]->{'code'}-- if ($in_code);
+        } else {
+          last;
+        }
+        $arg_index++;
+      }
+      if (defined($command)) {
+        $result = "<$command>$result<$command>";
+      }
+      if ($Texinfo::Common::context_brace_commands{$root->{'cmdname'}}) {
+        pop @{$self->{'document_context'}};
+      }
+    } elsif (exists($Texinfo::Common::block_commands{$root->{'cmdname'}})) {
+      if ($context_block_commands{$root->{'cmdname'}}) {
+        push @{$self->{'document_context'}}, {};
+      }
+      my $attribute = '';
+      if ($root->{'extra'} and $root->{'extra'}->{'command_as_argument'}) {
+        $attribute 
+         .= " 
commandarg=\"$root->{'extra'}->{'command_as_argument'}->{'cmdname'}\"";
+      } elsif ($root->{'extra'}
+               and $root->{'extra'}->{'enumerate_specification'}) {
+        $attribute .= " first=\""
+          
.$self->xml_protect_text($root->{'extra'}->{'enumerate_specification'})
+          ."\"";
+      } elsif ($root->{'cmdname'} eq 'float' and $root->{'extra'}) {
+        if (defined($root->{'extra'}->{'normalized'})) {
+          $attribute .= " name=\"$root->{'extra'}->{'normalized'}\"";
+        }
+        if ($root->{'extra'}->{'type'} and 
+            defined($root->{'extra'}->{'type'}->{'normalized'})) {
+          $attribute .= " type=\"$root->{'extra'}->{'type'}->{'normalized'}\"";
+        }
+      } elsif ($root->{'cmdname'} eq 'verbatim') {
+        $attribute = " xml:space=\"preserve\"";
+      }
+      $result .= "<$root->{'cmdname'}${attribute}>";
+      if ($root->{'args'}) {
+        if ($commands_args_elements{$root->{'cmdname'}}) {
+          my $arg_index = 0;
+          foreach my $element (@{$commands_args_elements{$root->{'cmdname'}}}) 
{
+            if (defined($root->{'args'}->[$arg_index])) {
+              my $in_code;
+               $in_code = 1
+                if (defined($default_args_code_style{$root->{'cmdname'}})
+                  and 
defined($default_args_code_style{$root->{'cmdname'}}->[$arg_index]));
+              $self->{'document_context'}->[-1]->{'code'}++ if ($in_code);
+              my $arg = $self->_convert($root->{'args'}->[$arg_index]);
+              chomp($arg);
+              if ($arg ne '') {  
+                $result .= "<$element>$arg</$element>\n";
+              }
+              $self->{'document_context'}->[-1]->{'code'}-- if ($in_code);
+            } else {
+              last;
+            }
+            $arg_index++;
+          }
+        } elsif ($root->{'cmdname'} eq 'multitable' and $root->{'extra'}) {
+          if ($root->{'extra'}->{'prototypes'}) {
+            $result .= "<columnprototypes>";
+            foreach my $prototype (@{$root->{'extra'}->{'prototypes'}}) {
+              $result .= "<columnprototype>".$self->_convert($prototype)
+                         ."</columnprototype>";
+            }
+            $result .= "</columnprototypes>";
+          } elsif ($root->{'extra'}->{'columnfractions'}) {
+            $result .= "<columnfractions>";
+            foreach my $fraction (@{$root->{'extra'}->{'columnfractions'}}) {
+              $result .= "<columnfraction 
value=\"$fraction\"></columnfraction>";
+            }
+            $result .= "</columnfractions>";
+          }
+        }
+      }
+      #chomp($result);
+      #$result .= "\n";
+      $close_element = $root->{'cmdname'};
+    }
+  }
+  if ($root->{'type'}) {
+    if (defined($type_elements{$root->{'type'}})) {
+      $result .= "<$type_elements{$root->{'type'}}>";
+    }
+    if ($root->{'type'} eq 'def_line') {
+      if ($root->{'cmdname'}) {
+        $result .= "<$root->{'cmdname'}>";
+      }
+      $result .= "<definitionterm>";
+      $result .= $self->_index_entry($root);
+      $self->{'document_context'}->[-1]->{'code'}++;
+      if ($root->{'extra'} and $root->{'extra'}->{'def_args'}) {
+        my $main_command;
+        my $alias;
+        if ($Texinfo::Common::def_aliases{$root->{'extra'}->{'def_command'}}) {
+          $main_command = 
$Texinfo::Common::def_aliases{$root->{'extra'}->{'def_command'}};
+          $alias = 1;
+        } else {
+          $main_command = $root->{'extra'}->{'def_command'};
+          $alias = 0;
+        }
+        foreach my $arg (@{$root->{'extra'}->{'def_args'}}) {
+          my $type = $arg->[0];
+          my $content = $self->_convert($arg->[1]);
+          if ($type eq 'spaces') {
+            $result .= $content;
+          } else {
+            my $attribute;
+            if ($type eq 'category' and $alias) {
+              $attribute = " automatic=\"on\"";
+            } else {
+              $attribute = "";
+            }
+            my $element;
+            if ($type eq 'name') {
+              $element = $defcommand_name_type{$main_command};
+            } elsif ($type eq 'arg') {
+              $element = 'param';
+            } elsif ($type eq 'argtype') {
+              $element = 'paramtype';
+            } else {
+              $element = $type;
+            }
+            $result .= "<def$element${attribute}>$content</def$element>";
+          }
+        }
+      }
+      $self->{'document_context'}->[-1]->{'code'}--;
+      $result .= "</definitionterm>";
+      if ($root->{'cmdname'}) {
+        $result .= "</$root->{'cmdname'}>";
+      }
+      chomp ($result);
+      $result .= "\n";
+    }
+  }
+  if ($root->{'contents'}) {
+    my $in_code;
+    if ($root->{'cmdname'} 
+        and $Texinfo::Common::preformatted_code_commands{$root->{'cmdname'}}) {
+      $in_code = 1;
+    }
+    $self->{'document_context'}->[-1]->{'code'}++ if ($in_code);
+    if (ref($root->{'contents'}) ne 'ARRAY') {
+      cluck "contents not an array($root->{'contents'}).";
+    }
+    foreach my $content (@{$root->{'contents'}}) {
+      $result .= $self->_convert($content);
+    }
+    $self->{'document_context'}->[-1]->{'code'}-- if ($in_code);
+  }
+  if ($root->{'type'}) {
+    if (defined($type_elements{$root->{'type'}})) {
+      $result .= "</$type_elements{$root->{'type'}}>";
+    }
+  }
+  $result = '{'.$result.'}' 
+     if ($root->{'type'} and $root->{'type'} eq 'bracketed'
+         and (!$root->{'parent'}->{'type'} or
+              ($root->{'parent'}->{'type'} ne 'block_line_arg'
+               and $root->{'parent'}->{'type'} ne 'misc_line_arg')));
+  if ($close_element) {
+    $result .= "</$close_element>";
+  }
+  if ($root->{'cmdname'} 
+      and exists($Texinfo::Common::block_commands{$root->{'cmdname'}})) {
+    #$result .= "</$root->{'cmdname'}>\n";
+    $result .= "\n";
+    if ($context_block_commands{$root->{'cmdname'}}) {
+      pop @{$self->{'document_context'}};
+    }
+  } elsif ($root->{'cmdname'} 
+           and $Texinfo::Common::root_commands{$root->{'cmdname'}}
+           and $root->{'cmdname'} ne 'node') {
+    my $command = _level_corrected_section($root);
+    if (!($root->{'section_childs'} and scalar(@{$root->{'section_childs'}}))
+        or $command eq 'top') {
+      $result .= "</$command>\n";
+      my $current = $root;
+      while ($current->{'section_up'}
+             # the most up element is a virtual sectioning root element, this
+             # condition avoids getting into it
+             and $current->{'section_up'}->{'cmdname'}
+             and !$current->{'section_next'}
+             and _level_corrected_section($current->{'section_up'}) ne 'top') {
+        $current = $current->{'section_up'};
+        $result .= '</'._level_corrected_section($current) .">\n";
+      }
+    }
+  }
+  return $result;
+}
+
+1;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]