texinfo-commits
[Top][All Lists]
Advanced

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

texinfo/tp/Texinfo/Convert IXIN.pm TexinfoXML.pm


From: Patrice Dumas
Subject: texinfo/tp/Texinfo/Convert IXIN.pm TexinfoXML.pm
Date: Sat, 26 Jan 2013 21:34:12 +0000

CVSROOT:        /sources/texinfo
Module name:    texinfo
Changes by:     Patrice Dumas <pertusus>        13/01/26 21:34:12

Modified files:
        tp/Texinfo/Convert: IXIN.pm TexinfoXML.pm 

Log message:
        Add nodes and sectioning tree to IXIN.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/Texinfo/Convert/IXIN.pm?cvsroot=texinfo&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/Texinfo/Convert/TexinfoXML.pm?cvsroot=texinfo&r1=1.4&r2=1.5

Patches:
Index: IXIN.pm
===================================================================
RCS file: /sources/texinfo/texinfo/tp/Texinfo/Convert/IXIN.pm,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- IXIN.pm     26 Jan 2013 14:49:00 -0000      1.1
+++ IXIN.pm     26 Jan 2013 21:34:11 -0000      1.2
@@ -83,18 +83,52 @@
   $header .= "\n";
 }
 
-sub ixin_empty($$)
+my %attribute_string_names = (
+  'nodeentry' => {'name' => 1},
+  'filename' => {'name' => 1},
+  'settingvalue' => {'value' => 1},
+  'nodetweakvalue' => {'value' => 1},
+);
+
+sub _ixin_attributes($$$)
+{
+  my $self = shift;
+  my $name = shift;
+  my $attributes = shift;
+  my $result = '';
+  if ($attributes) {
+    for (my $i = 0; $i < scalar(@$attributes); $i += 2) {
+      if ($attribute_string_names{$name} 
+          and $attribute_string_names{$name}->{$attributes->[$i]}) {
+        $result .= '"'
+          
.Texinfo::Convert::TexinfoSXML->protect_text($attributes->[$i+1]).'"';
+      } else {
+        $result .= $attributes->[$i+1];
+      }
+      $result .= ' ';
+    }
+  }
+  return $result;
+}
+
+sub ixin_open_element($$;$)
 {
   my $self = shift;
   my $name = shift;
-  return '-';
+  my $attributes = shift;
+  my $result = '(';
+  $result .= $self->_ixin_attributes($name, $attributes);
+  return $result;
 }
 
-sub ixin_open_element($$)
+sub ixin_list_element($$$)
 {
   my $self = shift;
   my $name = shift;
-  return '(';
+  my $attributes = shift;
+  my $result = $self->_ixin_attributes($name, $attributes);
+  $result =~ s/ $//;
+  return $result;
 }
 
 sub ixin_close_element($$)
@@ -102,14 +136,17 @@
   my $self = shift;
   my $name = shift;
   return ')';
+  #return "|$name)";
 }
 
-sub ixin_string_element($$$)
+sub ixin_element($$;$)
 {
   my $self = shift;
   my $name = shift;
-  my $string = shift;
-  return '"'.Texinfo::Convert::TexinfoSXML->protect_text($string).'"';
+  my $attributes = shift;
+  my $opening = $self->ixin_open_element($name, $attributes);
+  $opening =~ s/ $//;
+  return $opening . $self->ixin_close_element($name);
 }
 
 sub ixin_symbol_element($$$)
@@ -120,6 +157,14 @@
   return $string;
 }
 
+sub ixin_none_element($$)
+{
+  my $self = shift;
+  my $name = shift;
+  return ' - ';
+}
+
+
 # end output specific subs
 
 # FIXME this is rather non specific. Move to Converter?
@@ -151,6 +196,16 @@
   }
 }
 
+sub _count_bytes($$) 
+{
+  my $self = shift;
+  my $string = shift;
+
+  return Texinfo::Common::count_bytes($self, $string);
+}
+
+my @node_directions = ('Next', 'Prev', 'Up');
+
 sub output_ixin($$)
 {
   my $self = shift;
@@ -170,14 +225,18 @@
   }
 
   $self->_set_global_multiple_commands(-1);
+  # we ignore everything before the first node
+  $self->_set_ignored_type('text_root');
 
-  my $header = $self->ixin_header();
-  my $result = $self->ixin_open_element('meta');
+  my $result = $self->ixin_header();
+
+  $result .= $self->ixin_open_element('meta');
   $result .= $self->ixin_open_element('xid');
 
-  my $output_file = $self->ixin_empty('filename');
+  my $output_file = $self->ixin_none_element('filename');
   if ($self->{'output_file'} ne '') {
-    $result .= $self->ixin_string_element('filename', $self->{'output_file'});
+    $result .= $self->ixin_list_element('filename', 
+                           ['name', $self->{'output_file'}]);
   }
   my $lang = $self->get_conf('documentlanguage');
   #my $lang_code = $lang;
@@ -187,7 +246,7 @@
   #  $region_code = $2;
   #}
   $result .= ' ';
-  $result .= $self->ixin_string_element('lang', $lang);
+  $result .= $self->ixin_list_element('lang', ['name', $lang]);
   # FIXME title: use simpletitle or fulltitle
   
   if ($self->{'info'}->{'dircategory_direntry'}) {
@@ -215,17 +274,21 @@
   # FIXME vars: wait for Thien-Thi answer.
 
   my $elements = Texinfo::Structuring::split_by_node($root);
-
   # setting_commands is for @-commands appearing before the first node,
   # while end_of_nodes_setting_commands holds, for @-commands names, the 
   # last @-command element.
   my %setting_commands;
   my %end_of_nodes_setting_commands;
+  my %setting_commands_defaults;
   foreach my $global_command (keys(%{$self->{'extra'}})) {
     if (($Texinfo::Common::misc_commands{$global_command}
          and $Texinfo::Common::misc_commands{$global_command} =~ /^\d/)
         or $additional_setting_commands{$global_command}) {
       if (ref($self->{'extra'}->{$global_command}) eq 'ARRAY') {
+        if 
(defined($Texinfo::Common::document_settable_at_commands{$global_command})) {
+          $setting_commands_defaults{$global_command} 
+            = $Texinfo::Common::document_settable_at_commands{$global_command};
+        }
         foreach my $command (@{$self->{'extra'}->{$global_command}}) {
           my ($element, $root_command) = _get_element($self, $command);
           # before first node
@@ -240,6 +303,10 @@
           #print STDERR "$element $root_command->{'extra'} $global_command\n";
         }
       } else {
+        if 
(defined($Texinfo::Common::document_settable_unique_at_commands{$global_command}))
 {
+          $setting_commands_defaults{$global_command} 
+            = 
$Texinfo::Common::document_settable_unique_at_commands{$global_command};
+        }
         $setting_commands{$global_command} = 
$self->{'extra'}->{$global_command};
       }
     }
@@ -251,7 +318,10 @@
         if ($setting_command_name eq 'summarycontents');
     my $value = $self->_informative_command_value($setting_command);
     #print STDERR "$setting_command_name $value\n";
-    if (defined($value)) {
+    # do not register settings if sete at the default value.
+    if (defined($value) 
+        and !(defined($setting_commands_defaults{$setting_command_name}) 
+              and $setting_commands_defaults{$setting_command_name} eq 
$value)) {
       $settings{$setting_command_name} = $value;
     }
   }
@@ -264,7 +334,8 @@
       $result .= $self->ixin_symbol_element('settingname', $command_name);
       $result .= ' ';
       if ($Texinfo::Common::misc_commands{$command_name} eq 'lineraw') {
-        $result .= $self->ixin_string_element('settingvalue', 
$settings{$command_name});
+        $result .= $self->ixin_list_element('settingvalue', 
+                                   ['value', $settings{$command_name}]);
       } else {
         $result .= $self->ixin_symbol_element('settingvalue', 
$settings{$command_name});
       }
@@ -272,26 +343,202 @@
     }
   }
   $result .= $self->ixin_close_element('settings');
+
+  foreach my $region ('copying', 'titlepage') {
+    if ($self->{'extra'}->{$region}) {
+      $result .= $self->convert_tree($self->{'extra'}->{$region});
+    } else {
+      $result .= $self->ixin_none_element($region);
+    }
+  }
+
+  # FIXME toc: wait for Thien-Thi answer.
+
   $result .= $self->ixin_close_element('meta');
   $result .= "\n";
 
+  # to do the nodes index, one need the size of each node.
+  # to do the counts list, one need to know the sizze of the node index.
+  # So we have to start by the node data.
+  my $node_nr = 0;
+  my %current_settings;
+  my %node_label_number;
+  my %node_byte_sizes;
+  my %node_tweaks;
+  my @nodes;
   my $document_output = '';
   if ($elements) {
     foreach my $node_element (@$elements) {
-      my $node_result = $self->convert_tree($node_element);
-      if ($node_element->{'extra'}->{'no_node'}) {
-        print STDERR "FIXME No node.  What to do?\n";
+      next if ($node_element->{'extra'}->{'no_node'});
+      $node_nr++;
+      my $node = $node_element->{'extra'}->{'element_command'};
+      push @nodes, $node;
+      my $normalized_node_name = $node->{'extra'}->{'normalized'};
+      foreach my $setting_command_name (keys(%current_settings)) {
+        $node_tweaks{$normalized_node_name}->{$setting_command_name}
+          = $current_settings{$setting_command_name};
       }
-      # get node length.
+      $node_label_number{$normalized_node_name} = $node_nr;
+
+      my $node_result = $self->convert_tree($node_element);
       $document_output .= $node_result;
+
+      # get node length.
+      $node_byte_sizes{$normalized_node_name} 
+         = $self->_count_bytes($node_result);
+      # update current settings
+      if (defined($end_of_nodes_setting_commands{$normalized_node_name})) {
+        foreach my $setting_command_name 
(keys(%{$end_of_nodes_setting_commands{$normalized_node_name}})) {
+          my $value = $self->_informative_command_value(
+            
$end_of_nodes_setting_commands{$normalized_node_name}->{$setting_command_name});
+          if ((defined($settings{$setting_command_name}) 
+               and $settings{$setting_command_name} eq $value)
+              or (!defined($settings{$setting_command_name})
+                  and 
defined($setting_commands_defaults{$setting_command_name})
+                  and $setting_commands_defaults{$setting_command_name} eq 
$value)) {
+            delete $current_settings{$setting_command_name}; 
+          } else {
+            $current_settings{$setting_command_name} = $value;
+          }
+        }
+      }
     }
   } else {
     # not a full document.
-    return $self->_output_text($self->convert_tree($root), $fh);
   }
 
+  my $nodes_index = $self->ixin_open_element('nodesindex');
+  foreach my $node (@nodes) {
+    my $normalized_node_name = $node->{'extra'}->{'normalized'};
+    my @attributes = ('name', $normalized_node_name,
+                      'length', $node_byte_sizes{$normalized_node_name});
+    foreach my $direction (@node_directions) {
+      if ($node->{'node_'.lc($direction)}) {
+        my $node_direction = $node->{'node_'.lc($direction)};
+        if ($node_direction->{'extra'}->{'manual_content'}) {
+          # FIXME?
+          push @attributes, ('node'.lc($direction), -2);
+        } else {
+          push @attributes, ('node'.lc($direction), 
+                 
$node_label_number{$node_direction->{'extra'}->{'normalized'}})
+        }
+      } else {
+        push @attributes, ('node'.lc($direction), -1);
+      }
+    }
+    $nodes_index .= $self->ixin_open_element('nodeentry', address@hidden);
+    
+    if ($node_tweaks{$normalized_node_name}) {
+      $nodes_index .= $self->ixin_open_element('nodetweaks');
+      foreach my $command_name 
(sort(keys(%{$node_tweaks{$normalized_node_name}}))) {
+        $nodes_index .= $self->ixin_open_element('nodetweak');
+        $nodes_index .= $self->ixin_symbol_element('nodetweakname', 
$command_name);
+        $nodes_index .= ' ';
+        if ($Texinfo::Common::misc_commands{$command_name} eq 'lineraw') {
+          $nodes_index .= $self->ixin_list_element('nodetweakvalue', 
+            ['value', $node_tweaks{$normalized_node_name}->{$command_name}]);
+        } else {
+          $nodes_index .= $self->ixin_symbol_element('nodetweakvalue', 
+                       $node_tweaks{$normalized_node_name}->{$command_name});
+        }
+        $nodes_index .= $self->ixin_close_element('nodetweak');
+        
+      }
+      $nodes_index .= $self->ixin_close_element('nodetweaks');
+    }
+    $nodes_index .= $self->ixin_close_element('nodeentry');
+  }
+  $nodes_index .= $self->ixin_close_element('nodesindex');
+  $nodes_index .= "\n";
+
+  # do sectioning tree
+  my $sectioning_tree = '';
+  $sectioning_tree  .= $self->ixin_open_element('sectioningtree');
+  if ($self->{'structuring'} and $self->{'structuring'}->{'sectioning_root'}) {
+    my $section_root = $self->{'structuring'}->{'sectioning_root'};
+    foreach my $top_section (@{$section_root->{'section_childs'}}) {
+      my $section = $top_section;
+ SECTION:
+      while ($section) {
+        my ($element, $root_command) = $self->_get_element($section);
+        my $associated_node_id;
+        if (defined($root_command) 
+            and defined($root_command->{'extra'}->{'normalized'})) {
+          $associated_node_id 
+            = $node_label_number{$root_command->{'extra'}->{'normalized'}};
+        } else {
+          $associated_node_id = -1;
+        }
+        my @attributes = ('nodeid', $associated_node_id, 'type', 
+              $self->_level_corrected_section($section));
+        $sectioning_tree .= $self->ixin_open_element('sectionentry',
+                 address@hidden);
+        $sectioning_tree .= $self->ixin_open_element('sectiontitle');
+        if ($section->{'args'} and $section->{'args'}->[0]) {
+          $sectioning_tree .= $self->convert_tree($section->{'args'}->[0]);
+        }
+        $sectioning_tree .= $self->ixin_close_element('sectiontitle');
+        # top is special and never considered to contain anything.  So
+        # it is closed here and not below.
+        if ($section->{'cmdname'} eq 'top') {
+          $sectioning_tree .= $self->ixin_close_element('sectionentry');
+        }
+        if ($section->{'section_childs'}) {
+          $section = $section->{'section_childs'}->[0];
+        } elsif ($section->{'section_next'}) {
+          $sectioning_tree .= $self->ixin_close_element('sectionentry');
+          last if ($section eq $top_section);
+          $section = $section->{'section_next'};
+        } else {
+          if ($section eq $top_section) {
+            $sectioning_tree .= $self->ixin_close_element('sectionentry')
+              unless ($section->{'cmdname'} eq 'top');
+            last;
+          }
+          while ($section->{'section_up'}) {
+            $section = $section->{'section_up'};
+            $sectioning_tree .= $self->ixin_close_element('sectionentry');
+            if ($section eq $top_section) {
+              $sectioning_tree .= $self->ixin_close_element('sectionentry')
+                 unless ($section->{'cmdname'} eq 'top');
+              last SECTION;
+            }
+            if ($section->{'section_next'}) {
+              $sectioning_tree .= $self->ixin_close_element('sectionentry');
+              $section = $section->{'section_next'};
+              last;
+            }
+          }
+        }
+      }
+    }
+  }
+  $sectioning_tree  .= $self->ixin_close_element('sectioningtree') . "\n";
+
+  # do labels
+
+  # do document-term sets (indices)
+
+  # do floats
+
+  # do blobs
+
+  my @counts_attributes = ('nodeindexlen', $self->_count_bytes($nodes_index),
+                    'nodecounts', $node_nr, 
+                    'sectioningtreelen', 
$self->_count_bytes($sectioning_tree));
+
   my $output = $self->_output_text($result, $fh);
 
+  $output .= $self->_output_text(
+               $self->ixin_element('counts', address@hidden) ."\n", $fh);
+
+  $output .= $self->_output_text($nodes_index, $fh);
+  $output .= $self->_output_text($sectioning_tree, $fh);
+
+  $output .= $self->_output_text($document_output ."\n", $fh);
+
+  # output blobs
+
   if ($fh and $self->{'output_file'} ne '-') {
     $self->register_close_file($self->{'output_file'});
     if (!close ($fh)) {
@@ -303,4 +550,3 @@
 }
 
 1;
-

Index: TexinfoXML.pm
===================================================================
RCS file: /sources/texinfo/texinfo/tp/Texinfo/Convert/TexinfoXML.pm,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- TexinfoXML.pm       26 Jan 2013 14:09:32 -0000      1.4
+++ TexinfoXML.pm       26 Jan 2013 21:34:12 -0000      1.5
@@ -360,6 +360,15 @@
   $ignored_types{$type} = 1;
 }
 
+# this is used in IXIN, to ignore everything before first node.
+sub _set_ignored_type($$)
+{
+  my $self = shift;
+  my $type = shift;
+
+  $ignored_types{$type} = 1;
+}
+
 my %type_elements = (
   'paragraph' => 'para',
   'preformatted' => 'pre',



reply via email to

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