texinfo-commits
[Top][All Lists]
Advanced

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

[no subject]


From: Patrice Dumas
Date: Tue, 8 Nov 2022 03:29:24 -0500 (EST)

branch: master
commit 710f48d473770cb0ff2f73992de5147eb059676e
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Sun Oct 30 22:19:46 2022 +0100

    * doc/texi2any_api.texi (Direction Strings Customization)
    (Getting Direction Strings), tp/Texinfo/Config.pm
    (texinfo_register_direction_string_info), tp/Texinfo/Convert/HTML.pm
    (direction_string, converter_initialize): add context information to
    direction strings customization to be able to convert in string
    and in normal context.  Update calls of direction_string() to use the
    string context for strings that end up in attributes.
---
 ChangeLog                                          |  10 ++
 doc/texi2any_api.texi                              |  29 ++--
 tp/Texinfo/Commands.pod                            |   2 +-
 tp/Texinfo/Config.pm                               |  15 +-
 tp/Texinfo/Convert/HTML.pm                         | 155 +++++++++++++++------
 .../init_files_tests/customize_translations.pl     |   6 +-
 6 files changed, 156 insertions(+), 61 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 31e6d90faf..ae33f9f8e7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2022-10-30  Patrice Dumas  <pertusus@free.fr>
+
+       * doc/texi2any_api.texi (Direction Strings Customization)
+       (Getting Direction Strings), tp/Texinfo/Config.pm
+       (texinfo_register_direction_string_info), tp/Texinfo/Convert/HTML.pm
+       (direction_string, converter_initialize): add context information to
+       direction strings customization to be able to convert in string
+       and in normal context.  Update calls of direction_string() to use the
+       string context for strings that end up in attributes.
+
 2022-10-30  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/Translations.pm (gdt, replace_convert_substrings):
diff --git a/doc/texi2any_api.texi b/doc/texi2any_api.texi
index 1491b5e13b..2e025489a0 100644
--- a/doc/texi2any_api.texi
+++ b/doc/texi2any_api.texi
@@ -1031,19 +1031,28 @@ The direction strings can be customized with
 @code{texinfo_register_direction_string_info}:
 
 @defun texinfo_register_direction_string_info ($direction, @
-                  $type, $converted_string, $string_to_convert)
+          $type, $converted_string, $string_to_convert, $context)
 @var{$direction} is a direction (@pxref{Directions}), @var{$type}
-is the type of string (@pxref{Direction Strings}).  Both
-@var{$converted_string} and @var{$string_to_convert} are optional,
-if both are unset or @code{undef}, the direction string is unset.
-@var{$converted_string} is the string, already converted to HTML.
+is the type of string (@pxref{Direction Strings}).  The other
+arguments are optional.  @var{$context} is @samp{normal} or @samp{string}.
+@xref{Init File Expansion Contexts}.  If
+$context is @code{undef}, the @samp{normal} context is assumed.
+
+@var{$converted_string} is the string, already converted to HTML
+that is used for the specified context.  If the @samp{normal} context
+@var{$converted_string} only is specified, the same string will be
+used for the @samp{string} context.
+
 Alternatively, @var{$string_to_convert} can be specified to set the
 string to the corresponding Texinfo code after translation
-and conversion to HTML.
+and conversion to HTML.  In that case, the context is ignored, as
+it will be set at the time of the conversion.
 
 @var{$string_to_convert} is ignored for
 special strings that do not need to be translated and cannot contain
 Texinfo @@-commands (@samp{accesskey}, @samp{rel} and @samp{example}).
+@var{$string_to_convert} is also ignored if @var{$converted_string} is set
+for any context.
 @end defun
 
 
@@ -3105,10 +3114,12 @@ directions, links, labels and files information.
 To get direction strings, use @code{direction_string}:
 
 @deftypefun {@var{$string} =} @var{$converter}->direction_string @
-                                     (@var{$direction}, @var{string_type})
+                    (@var{$direction}, @var{string_type}, @var{$context})
 Retrieve the @var{$direction} (@pxref{Directions}) string of type
-@var{string_type} (@pxref{Direction Strings}).  The string will be translated
-if needed.
+@var{string_type} (@pxref{Direction Strings}).  @var{$context} is
+@samp{normal} or @samp{string}.  @xref{Init File Expansion Contexts}.  If
+$context is @code{undef}, the @samp{normal} context is assumed.
+The string will be translated if needed.
 @end deftypefun
 
 
diff --git a/tp/Texinfo/Commands.pod b/tp/Texinfo/Commands.pod
index c1265ebc9d..c07d588a2b 100644
--- a/tp/Texinfo/Commands.pod
+++ b/tp/Texinfo/Commands.pod
@@ -126,7 +126,7 @@ Set to the number of arguments separated by commas that may 
appear in braces or
 on the @-command line.  That means 0 or unset for most block commands,
 including C<@example> which has an unlimited (variadic) number of arguments, 1
 for C<@quotation>, 2 for C<@float>, 1 for most brace commands, 2 for C<@email>
-or C<@abbr>, 5 for C<@image> of C<@ref>.
+and C<@abbr>, 5 for C<@image> and C<@ref>.
 
 Values are not necessarily set for all the commands, as commands are
 also classified by type of command, some type of commands implying a
diff --git a/tp/Texinfo/Config.pm b/tp/Texinfo/Config.pm
index e7d46365ec..cb7603edc2 100644
--- a/tp/Texinfo/Config.pm
+++ b/tp/Texinfo/Config.pm
@@ -669,17 +669,26 @@ sub GNUT_get_types_formatting_info()
 
 # no check on type and direction, but only the ones known in the HTML
 # converted will be used
-sub texinfo_register_direction_string_info($$;$$)
+sub texinfo_register_direction_string_info($$;$$$)
 {
   my $direction = shift;
   my $type = shift;
   my $converted_string = shift;
   my $string_to_convert = shift;
+  my $context = shift;
+
+  $context = 'normal' if (!defined($context));
 
   $GNUT_direction_string_info->{$type} = {}
     if (not exists($GNUT_direction_string_info->{$type}));
-  $GNUT_direction_string_info->{$type}->{$direction}
-     = {'to_convert' => $string_to_convert, 'converted' => $converted_string};
+  $GNUT_direction_string_info->{$type}->{$direction} = {}
+    if (not exists($GNUT_direction_string_info->{$type}->{$direction}));
+  $GNUT_direction_string_info->{$type}->{$direction}->{'to_convert'}
+     = $string_to_convert;
+  $GNUT_direction_string_info->{$type}->{$direction}->{'converted'} = {}
+   if 
(!defined($GNUT_direction_string_info->{$type}->{$direction}->{'converted'}));
+  $GNUT_direction_string_info->{$type}->{$direction}->{'converted'}->{$context}
+    = $converted_string;
 }
 
 sub GNUT_get_direction_string_info()
diff --git a/tp/Texinfo/Convert/HTML.pm b/tp/Texinfo/Convert/HTML.pm
index c4ab4a374f..5c05c8e1c3 100644
--- a/tp/Texinfo/Convert/HTML.pm
+++ b/tp/Texinfo/Convert/HTML.pm
@@ -1352,40 +1352,82 @@ my %valid_direction_string_type = (
   'text' => 1,
 );
 
-sub direction_string($$$)
+my %valid_direction_string_context = (
+  'normal' => 1,
+  'string' => 1,
+);
+
+sub direction_string($$$;$)
 {
   my $self = shift;
   my $direction = shift;
   my $string_type = shift;
+  my $context = shift;
 
   if (!$valid_direction_string_type{$string_type}) {
     print STDERR "Incorrect type $string_type in direction_string call\n";
     return undef;
   }
 
-  if (not exists($self->{'directions_strings'}->{$string_type}->{$direction})) 
{
+  $context = 'normal' if (!defined($context));
+
+  if (!$valid_direction_string_context{$context}) {
+    print STDERR "Incorrect context $context in direction_string call\n";
+    return undef;
+  }
+
+  if (not exists($self->{'directions_strings'}->{$string_type}->{$direction})
+      or not exists($self->{'directions_strings'}->{$string_type}
+                                                 ->{$direction}->{$context})) {
+    $self->{'directions_strings'}->{$string_type}->{$direction} = {}
+      if not 
exists($self->{'directions_strings'}->{$string_type}->{$direction});
     my $translated_directions_strings = 
$self->{'translated_direction_strings'};
-    if 
(defined($translated_directions_strings->{$string_type}->{$direction}->{'converted'}))
 {
+    if (defined($translated_directions_strings->{$string_type}
+                                                
->{$direction}->{'converted'})) {
       # translate already converted direction strings
-      my $result_string
-        = 
$self->gdt($translated_directions_strings->{$string_type}->{$direction}->{'converted'},
-                     undef, undef, 'translated_text');
-      $self->{'directions_strings'}->{$string_type}->{$direction}
-        = $self->substitute_html_non_breaking_space($result_string);
-    } elsif 
(defined($translated_directions_strings->{$string_type}->{$direction}->{'to_convert'}))
 {
+      my $converted_directions
+       = 
$translated_directions_strings->{$string_type}->{$direction}->{'converted'};
+      my $context_converted_string;
+      if ($converted_directions->{$context}) {
+        $context_converted_string = $converted_directions->{$context};
+      } elsif ($context eq 'string'
+               and defined($converted_directions->{'normal'})) {
+        $context_converted_string = $converted_directions->{'normal'};
+      }
+      if (defined($context_converted_string)) {
+        my $result_string
+          = $self->gdt($context_converted_string, undef, undef, 
'translated_text');
+        $self->{'directions_strings'}->{$string_type}->{$direction}->{$context}
+          = $self->substitute_html_non_breaking_space($result_string);
+      } else {
+        $self->{'directions_strings'}->{$string_type}->{$direction}->{$context}
+          = undef;
+      }
+    } elsif (defined($translated_directions_strings->{$string_type}
+                                            ->{$direction}->{'to_convert'})) {
       # translate direction strings that need to be translated and converted
       my $translated_tree
-        = 
$self->gdt($translated_directions_strings->{$string_type}->{$direction}->{'to_convert'});
-      my $result_string = 
$self->convert_tree_new_formatting_context($translated_tree,
+        = $self->gdt($translated_directions_strings->{$string_type}
+                                            ->{$direction}->{'to_convert'});
+      my $converted_tree;
+      if ($context eq 'string') {
+        $converted_tree = {
+              'type' => '_string',
+              'contents' => [$translated_tree]};
+      } else {
+        $converted_tree = $translated_tree;
+      }
+      my $result_string = 
$self->convert_tree_new_formatting_context($converted_tree,
                              "direction $direction", undef, "direction 
$direction");
-      $self->{'directions_strings'}->{$string_type}->{$direction}
+      $self->{'directions_strings'}->{$string_type}->{$direction}->{$context}
         = $result_string;
     } else {
       # FIXME or ''
-      $self->{'directions_strings'}->{$string_type}->{$direction} = undef;
+      $self->{'directions_strings'}->{$string_type}->{$direction}->{$context}
+         = undef;
     }
   }
-  return $self->{'directions_strings'}->{$string_type}->{$direction};
+  return 
$self->{'directions_strings'}->{$string_type}->{$direction}->{$context};
 }
 
 # API for misc conversion and formatting functions
@@ -3394,13 +3436,13 @@ sub _direction_href_attributes($$)
 
   my $href_attributes = '';
   if ($self->get_conf('USE_ACCESSKEY')) {
-    my $accesskey = $self->direction_string($direction, 'accesskey');
+    my $accesskey = $self->direction_string($direction, 'accesskey', 'string');
     if (defined($accesskey) and ($accesskey ne '')) {
       $href_attributes = " accesskey=\"$accesskey\"";
     }
   }
   if ($self->get_conf('USE_REL_REV')) {
-    my $button_rel = $self->direction_string($direction, 'rel');
+    my $button_rel = $self->direction_string($direction, 'rel', 'string');
     if (defined($button_rel) and ($button_rel ne '')) {
       $href_attributes .= " rel=\"$button_rel\"";
     }
@@ -3471,9 +3513,10 @@ sub _default_format_button($$;$)
     if ($self->get_conf('ICONS') and $self->get_conf('ACTIVE_ICONS')
         and defined($self->get_conf('ACTIVE_ICONS')->{$button})
         and $self->get_conf('ACTIVE_ICONS')->{$button} ne '') {
-      my $button_name = $self->direction_string($button, 'button');
+      my $button_name_string = $self->direction_string($button, 'button', 
'string');
+      # FIXME button_name used in string context
       $active = &{$self->formatting_function('format_button_icon_img')}($self,
-                        $button_name, $self->get_conf('ACTIVE_ICONS')->{' '});
+                        $button_name_string, 
$self->get_conf('ACTIVE_ICONS')->{' '});
     } else {
       $active = $self->direction_string($button, 'text');
     }
@@ -3484,18 +3527,18 @@ sub _default_format_button($$;$)
     if ($href) {
       # button is active
       my $btitle = '';
-      my $description = $self->direction_string($button, 'description');
+      my $description = $self->direction_string($button, 'description', 
'string');
       if (defined($description)) {
         $btitle = ' title="' . $description . '"';
       }
       if ($self->get_conf('USE_ACCESSKEY')) {
-        my $accesskey = $self->direction_string($button, 'accesskey');
+        my $accesskey = $self->direction_string($button, 'accesskey', 
'string');
         if (defined($accesskey) and $accesskey ne '') {
           $btitle .= " accesskey=\"$accesskey\"";
         }
       }
       if ($self->get_conf('USE_REL_REV')) {
-        my $button_rel = $self->direction_string($button, 'rel');
+        my $button_rel = $self->direction_string($button, 'rel', 'string');
         if (defined($button_rel) and $button_rel ne '') {
           $btitle .= " rel=\"$button_rel\"";
         }
@@ -3503,13 +3546,12 @@ sub _default_format_button($$;$)
       my $use_icon;
       if ($self->get_conf('ICONS') and $self->get_conf('ACTIVE_ICONS')) {
         my $active_icon = $self->get_conf('ACTIVE_ICONS')->{$button};
-        my $button_name = $self->direction_string($button, 'button');
-        if (defined($active_icon) and $active_icon ne ''
-            and defined($button_name)) {
+        my $button_name_string = $self->direction_string($button, 'button', 
'string');
+        if (defined($active_icon) and $active_icon ne '') {
           # use icon
           $active = "<a href=\"$href\"${btitle}>".
              &{$self->formatting_function('format_button_icon_img')}($self,
-                      $button_name, $active_icon,
+                      $button_name_string, $active_icon,
                       $self->from_element_direction($button, 'string')) 
."</a>";
           $use_icon = 1;
         }
@@ -3524,10 +3566,10 @@ sub _default_format_button($$;$)
       my $use_icon;
       if ($self->get_conf('ICONS') and $self->get_conf('PASSIVE_ICONS')) {
         my $passive_icon = $self->get_conf('PASSIVE_ICONS')->{$button};
-        my $button_name = $self->direction_string($button, 'button');
+        my $button_name_string = $self->direction_string($button, 'button', 
'string');
         if ($passive_icon and $passive_icon ne '') {
           $passive = &{$self->formatting_function('format_button_icon_img')}(
-                      $self, $button_name, $passive_icon,
+                      $self, $button_name_string, $passive_icon,
                       $self->from_element_direction($button, 'string'));
           $use_icon = 1;
         }
@@ -7102,19 +7144,25 @@ sub converter_initialize($)
   my $customized_direction_strings = 
Texinfo::Config::GNUT_get_direction_string_info();
   foreach my $string_type (keys(%default_converted_directions_strings)) {
     foreach my $direction 
(keys(%{$default_converted_directions_strings{$string_type}})) {
-      my $string = '';
+      my $string_contexts;
       if ($customized_direction_strings->{$string_type}
           and $customized_direction_strings->{$string_type}->{$direction}) {
         if 
(defined($customized_direction_strings->{$string_type}->{$direction}->{'converted'}))
 {
-          $string
+          $string_contexts
             = 
$customized_direction_strings->{$string_type}->{$direction}->{'converted'}
         }
       } else {
-        $string
+        my $string
           = $default_converted_directions_strings{$string_type}->{$direction};
+        $string_contexts
+          = {'normal' => $string};
+      }
+      $string_contexts->{'string'} = $string_contexts->{'normal'}
+        if (not defined($string_contexts->{'string'}));
+      foreach my $context (keys(%$string_contexts)) {
+        $self->{'directions_strings'}->{$string_type}->{$direction}->{$context}
+          = 
$self->substitute_html_non_breaking_space($string_contexts->{$context});
       }
-      $self->{'directions_strings'}->{$string_type}->{$direction}
-        = $self->substitute_html_non_breaking_space($string);
     }
   }
   $self->{'translated_direction_strings'} = {};
@@ -7126,8 +7174,18 @@ sub converter_initialize($)
         $self->{'translated_direction_strings'}->{$string_type}->{$direction}
           = $customized_direction_strings->{$string_type}->{$direction};
       } else {
-        $self->{'translated_direction_strings'}->{$string_type}->{$direction}
-          = $default_translated_directions_strings{$string_type}->{$direction};
+        if ($default_translated_directions_strings{$string_type}->{$direction}
+                                                                
->{'converted'}) {
+          foreach my $context ('normal', 'string') {
+            $self->{'translated_direction_strings'}->{$string_type}
+                     ->{$direction}->{'converted'}->{$context}
+               = $default_translated_directions_strings{$string_type}
+                                                     
->{$direction}->{'converted'};
+          }
+        } else {
+          $self->{'translated_direction_strings'}->{$string_type}->{$direction}
+            = 
$default_translated_directions_strings{$string_type}->{$direction};
+        }
       }
     }
   }
@@ -9057,7 +9115,7 @@ sub _get_links($$$$)
         my $link_title = '';
         $link_title = " title=\"$link_string\"" if (defined($link_string));
         my $rel = '';
-        my $button_rel = $self->direction_string($link, 'rel');
+        my $button_rel = $self->direction_string($link, 'rel', 'string');
         $rel = " rel=\"".$button_rel.'"' if (defined($button_rel));
         $links .= $self->close_html_lone_element(
                     "<link href=\"$link_href\"${rel}${link_title}")."\n";
@@ -9242,7 +9300,9 @@ sub _default_format_special_body_about($$$)
   $about .= <<EOT;
 <p>
 EOT
-  $about .= $self->convert_tree($self->gdt('  The buttons in the navigation 
panels have the following meaning:')) . "\n";
+  $about .= $self->convert_tree(
+    $self->gdt('  The buttons in the navigation panels have the following 
meaning:'))
+            . "\n";
   $about .= <<EOT;
 </p>
 <table border="1">
@@ -9251,20 +9311,25 @@ EOT
   $about .= '    <th> ' . $self->convert_tree($self->gdt('Button')) . " 
</th>\n" .
    '    <th> ' . $self->convert_tree($self->gdt('Name')) . " </th>\n" .
    '    <th> ' . $self->convert_tree($self->gdt('Go to')) . " </th>\n" .
-   '    <th> ' . $self->convert_tree($self->gdt('From 1.2.3 go to')) . 
"</th>\n" . "  </tr>\n";
+   '    <th> ' . $self->convert_tree($self->gdt('From 1.2.3 go to')) . 
"</th>\n"
+ . "  </tr>\n";
 
   foreach my $button (@{$self->get_conf('SECTION_BUTTONS')}) {
-    next if ($button eq ' ' or ref($button) eq 'CODE' or ref($button) eq 
'SCALAR'
-              or ref($button) eq 'ARRAY');
-    my $button_name = $self->direction_string($button, 'button');
+    next if ($button eq ' ' or ref($button) eq 'CODE'
+             or ref($button) eq 'SCALAR' or ref($button) eq 'ARRAY');
+    my $button_name_string
+          = $self->direction_string($button, 'button', 'string');
     $about .= "  <tr>\n    ".$self->html_attribute_class('td',
-                                             ['button-direction-about']) .'>';
+                                          ['button-direction-about']) .'>';
     $about .=
-      ($self->get_conf('ICONS') && $self->get_conf('ACTIVE_ICONS')->{$button} ?
-       &{$self->formatting_function('format_button_icon_img')}($self,
-                     $button_name, $self->get_conf('ACTIVE_ICONS')->{$button}) 
:
-           ' [' . $self->direction_string($button, 'text') . '] ');
+      (($self->get_conf('ICONS') &&
+         $self->get_conf('ACTIVE_ICONS')->{$button}) ?
+          &{$self->formatting_function('format_button_icon_img')}($self,
+             $button_name_string, $self->get_conf('ACTIVE_ICONS')->{$button})
+        : ' [' . $self->direction_string($button, 'text') . '] ');
     $about .= "</td>\n";
+    my $button_name
+          = $self->direction_string($button, 'button');
     $about .=
 '    '.$self->html_attribute_class('td', ['name-direction-about']).'>'
     .$button_name."</td>
diff --git a/tp/t/results/init_files_tests/customize_translations.pl 
b/tp/t/results/init_files_tests/customize_translations.pl
index 653116be3d..ef406821bd 100644
--- a/tp/t/results/init_files_tests/customize_translations.pl
+++ b/tp/t/results/init_files_tests/customize_translations.pl
@@ -871,7 +871,7 @@ ul.toc-numbered-mark {list-style: none}
 <div class="chapter-level-extent" id="Chapter-fr">
 <div class="nav-panel">
 <p>
-N&oelig; suivant: <a href="#Chapter-de" accesskey="n" rel="next">chap de</a>, 
Pr&eacute;c&eacute;dent: <a href="#Chapter" accesskey="p" rel="prev">chap</a>, 
Monter: <a href="#Top" accesskey="u" rel="up">top</a> &nbsp; [<a 
href="#SEC_Contents" title="La <em class="emph">Table des mati&egrave;res</em>" 
rel="contents">Table des mati&egrave;res</a>]</p>
+N&oelig; suivant: <a href="#Chapter-de" accesskey="n" rel="next">chap de</a>, 
Pr&eacute;c&eacute;dent: <a href="#Chapter" accesskey="p" rel="prev">chap</a>, 
Monter: <a href="#Top" accesskey="u" rel="up">top</a> &nbsp; [<a 
href="#SEC_Contents" title="La Table des mati&egrave;res" rel="contents">Table 
des mati&egrave;res</a>]</p>
 </div>
 <h2 class="chapter" id="chap-fr">2 chap fr</h2>
 
@@ -882,7 +882,7 @@ N&oelig; suivant: <a href="#Chapter-de" accesskey="n" 
rel="next">chap de</a>, Pr
 <div class="chapter-level-extent" id="Chapter-de">
 <div class="nav-panel">
 <p>
-Nächster Knoten: <a href="#Last-chapter" accesskey="n" rel="next">Last 
Chapter</a>, Vorige: <a href="#Chapter-fr" accesskey="p" rel="prev">chap 
fr</a>, Nach oben: <a href="#Top" accesskey="u" rel="up">top</a> &nbsp; [<a 
href="#SEC_Contents" title="Das <em class="emph">Inhaltsverzeichnis</em>" 
rel="contents">Inhalt</a>]</p>
+Nächster Knoten: <a href="#Last-chapter" accesskey="n" rel="next">Last 
Chapter</a>, Vorige: <a href="#Chapter-fr" accesskey="p" rel="prev">chap 
fr</a>, Nach oben: <a href="#Top" accesskey="u" rel="up">top</a> &nbsp; [<a 
href="#SEC_Contents" title="Das Inhaltsverzeichnis" 
rel="contents">Inhalt</a>]</p>
 </div>
 <h2 class="chapter" id="chap-de">3 chap de</h2>
 
@@ -893,7 +893,7 @@ Nächster Knoten: <a href="#Last-chapter" accesskey="n" 
rel="next">Last Chapter<
 <div class="chapter-level-extent" id="Last-chapter">
 <div class="nav-panel">
 <p>
-Vorige: <a href="#Chapter-de" accesskey="p" rel="prev">chap de</a>, Nach oben: 
<a href="#Top" accesskey="u" rel="up">top</a> &nbsp; [<a href="#SEC_Contents" 
title="Das <em class="emph">Inhaltsverzeichnis</em>" 
rel="contents">Inhalt</a>]</p>
+Vorige: <a href="#Chapter-de" accesskey="p" rel="prev">chap de</a>, Nach oben: 
<a href="#Top" accesskey="u" rel="up">top</a> &nbsp; [<a href="#SEC_Contents" 
title="Das Inhaltsverzeichnis" rel="contents">Inhalt</a>]</p>
 </div>
 <h2 class="chapter" id="Last-Chapter">4 Last Chapter</h2>
 



reply via email to

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