Das Quoten/Unquoten von speziellen Zeichen in zentrale Hilfsfunktionen in Locale...
authorMoritz Bunkus <m.bunkus@linet-services.de>
Thu, 31 Jan 2008 11:43:02 +0000 (11:43 +0000)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Thu, 31 Jan 2008 11:43:02 +0000 (11:43 +0000)
SL/Form.pm
SL/Inifile.pm
SL/Locale.pm
SL/ReportGenerator.pm
SL/Template.pm
bin/mozilla/bp.pl
bin/mozilla/common.pl
bin/mozilla/rp.pl
locale/de/special_chars [new file with mode: 0644]

index d7da58c..76ae60d 100644 (file)
@@ -376,53 +376,6 @@ sub unquote {
 
 }
 
-sub quote_html {
-  $main::lxdebug->enter_sub(2);
-
-  my ($self, $str) = @_;
-
-  my %replace =
-    ('order' => ['&', '"', '<', '>'],
-     '<'     => '&lt;',
-     '>'     => '&gt;',
-     '"'     => '&quot;',
-     '&'     => '&amp;',
-    );
-
-  map({ $str =~ s/$_/$replace{$_}/g; } @{ $replace{"order"} });
-
-  $main::lxdebug->leave_sub(2);
-
-  return $str;
-}
-
-sub unquote_html {
-  $main::lxdebug->enter_sub(2);
-
-  my ($self, $str) = @_;
-
-  my %replace  =
-    ('&auml;'  => 'ä',
-     '&ouml;'  => 'ö',
-     '&uuml;'  => 'ü',
-     '&Auml;'  => 'Ä',
-     '&Ouml;'  => 'Ö',
-     '&Uuml;'  => 'Ü',
-     '&szlig;' => 'ß',
-     '&gt;'    => '>',
-     '&lt;'    => '<',
-     '&quot;'  => '"',
-    );
-
-  map { $str =~ s/\Q$_\E/$replace{$_}/g; } keys %replace;
-  $str =~ s/\&amp;/\&/g;
-
-  $main::lxdebug->leave_sub(2);
-
-  return $str;
-}
-
-
 sub hide_form {
   my $self = shift;
 
@@ -1279,7 +1232,7 @@ sub get_formname_translation {
 sub generate_attachment_filename {
   my ($self) = @_;
 
-  my $attachment_filename = $self->unquote_html($self->get_formname_translation());
+  my $attachment_filename = $main::locale->unquote_special_chars('HTML', $self->get_formname_translation());
   my $prefix =
       (first { $self->{type} eq $_ } qw(invoice credit_note)) ? 'inv'
     : ($self->{type} =~ /_quotation$/)                        ? 'quo'
@@ -1293,10 +1246,8 @@ sub generate_attachment_filename {
                                : $self->{format} =~ /opendocument/i ? ".odt"
                                : $self->{format} =~ /html/i         ? ".html"
                                :                                      "");
+    $attachment_filename =  lc $main::locale->quote_special_chars('filenames', $attachment_filename);
     $attachment_filename =~ s/ /_/g;
-    my %umlaute = ( "ä" => "ae", "ö" => "oe", "ü" => "ue", 
-                    "Ä" => "Ae", "Ö" => "Oe", "Ü" => "Ue", "ß" => "ss");
-    map { $attachment_filename =~ s/$_/$umlaute{$_}/g } keys %umlaute;
   } else {
     $attachment_filename = "";
   }
index aadec0a..2331ca7 100644 (file)
@@ -40,7 +40,7 @@ use IO::File;
 sub new {
   $main::lxdebug->enter_sub();
 
-  my ($type, $file) = @_;
+  my ($type, $file, %options) = @_;
 
   my $id = "";
   my $skip;
@@ -54,12 +54,16 @@ sub new {
   while (<FH>) {
     chomp;
 
-    # strip comments
-    s/#.*//g;
+    if (!$options{verbatim}) {
+      # strip comments
+      s/\#.*//;
 
-    # remove any trailing whitespace
-    s/^\s*//;
-    s/\s*$//;
+      # remove any trailing whitespace
+      s/^\s*//;
+      s/\s*$//;
+    } else {
+      next if (m/^\s*\#/);
+    }
 
     next unless $_;
 
index f797ed6..1e41344 100644 (file)
@@ -40,17 +40,32 @@ use Text::Iconv;
 
 use SL::LXDebug;
 use SL::Common;
+use SL::Inifile;
 
 sub new {
   $main::lxdebug->enter_sub();
 
   my ($type, $country, $NLS_file) = @_;
+
   my $self = {};
+  bless $self, $type;
 
   $country  =~ s|.*/||;
   $country  =~ s|\.||g;
   $NLS_file =~ s|.*/||;
 
+  $self->_init($country, $NLS_file);
+
+  $main::lxdebug->leave_sub();
+
+  return $self;
+}
+
+sub _init {
+  my $self     = shift;
+  my $country  = shift;
+  my $NLS_file = shift;
+
   if ($country && -d "locale/$country") {
     local *IN;
     $self->{countrycode} = $country;
@@ -70,6 +85,8 @@ sub new {
       $self->{charset} = Common::DEFAULT_CHARSET;
     }
 
+    $self->_read_special_chars_file($country);
+
     my $db_charset         = $main::dbcharset || Common::DEFAULT_CHARSET;
 
     $self->{iconv}         = Text::Iconv->new($self->{charset}, $db_charset);
@@ -85,10 +102,64 @@ sub new {
      "September", "October",  "November", "December");
   push @{ $self->{SHORT_MONTH} },
     (qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec));
+}
 
-  $main::lxdebug->leave_sub();
+sub _handle_markup {
+  my $self = shift;
+  my $str  = shift;
 
-  bless $self, $type;
+  if ($str eq "\\n") {
+    return "\n";
+  } elsif ($str eq "\\r") {
+    return "\r";
+  }
+
+  $str =~ s/\\x(..)/chr(hex($1))/eg;
+  $str =~ s/\\(.)/$1/g;
+
+  return $str;
+}
+
+sub _read_special_chars_file {
+  my $self    = shift;
+  my $country = shift;
+
+  if (! -f "locale/$country/special_chars") {
+    $self->{special_chars_map} = {};
+    return;
+  }
+
+  $self->{special_chars_map} = Inifile->new("locale/$country/special_chars", 'verbatim' => 1);
+
+  foreach my $format (keys %{ $self->{special_chars_map} }) {
+    next if (($format eq 'FILE') || ($format eq 'ORDER') || (ref $self->{special_chars_map}->{$format} ne 'HASH'));
+
+    if ($format ne lc $format) {
+      $self->{special_chars_map}->{lc $format} = $self->{special_chars_map}->{$format};
+      delete $self->{special_chars_map}->{$format};
+      $format = lc $format;
+    }
+
+    my $scmap = $self->{special_chars_map}->{$format};
+    my $order = $scmap->{order};
+    delete $scmap->{order};
+
+    foreach my $key (keys %{ $scmap }) {
+      $scmap->{$key} = $self->_handle_markup($scmap->{$key});
+
+      my $new_key    = $self->_handle_markup($key);
+
+      if ($key ne $new_key) {
+        $scmap->{$new_key} = $scmap->{$key};
+        delete $scmap->{$key};
+      }
+    }
+
+    $self->{special_chars_map}->{"${format}-reverse"}          = { reverse %{ $scmap } };
+
+    $scmap->{order}                                            = [ map { $self->_handle_markup($_) } split m/\s+/, $order ];
+    $self->{special_chars_map}->{"${format}-reverse"}->{order} = [ grep { $_ } map { $scmap->{$_} } reverse @{ $scmap->{order} } ];
+  }
 }
 
 sub text {
@@ -270,4 +341,33 @@ sub reformat_date {
   return $output_format;
 }
 
+sub quote_special_chars {
+  my $self   = shift;
+  my $format = lc shift;
+  my $string = shift;
+
+  if ($self->{special_chars_map} && $self->{special_chars_map}->{$format} && $self->{special_chars_map}->{$format}->{order}) {
+    my $scmap = $self->{special_chars_map}->{$format};
+
+    map { $string =~ s/\Q${_}\E/$scmap->{$_}/g } @{ $scmap->{order} };
+  }
+
+  return $string;
+}
+
+sub unquote_special_chars {
+  my $self    = shift;
+  my $format  = shift;
+
+  return $self->quote_special_chars("${format}-reverse", shift);
+}
+
+sub remap_special_chars {
+  my $self       = shift;
+  my $src_format = shift;
+  my $dst_format = shift;
+
+  return $self->quote_special_chars($dst_format, $self->quote_special_chars("${src_format}-reverse", shift));
+}
+
 1;
index 2034fef..988d295 100644 (file)
@@ -60,34 +60,9 @@ sub new {
 
   $self->set_options(@_) if (@_);
 
-  $self->_init_escaped_strings_map();
-
   return $self;
 }
 
-sub _init_escaped_strings_map {
-  my $self = shift;
-
-  $self->{escaped_strings_map} = {
-    '&auml;'  => 'ä',
-    '&ouml;'  => 'ö',
-    '&uuml;'  => 'ü',
-    '&Auml;'  => 'Ä',
-    '&Ouml;'  => 'Ö',
-    '&Uuml;'  => 'Ü',
-    '&szlig;' => 'ß',
-    '&gt;'    => '>',
-     '&lt;'    => '<',
-    '&quot;'  => '"',
-  };
-
-  my $iconv = $main::locale->{iconv_iso8859};
-
-  if ($iconv) {
-    map { $self->{escaped_strings_map}->{$_} = $iconv->convert($self->{escaped_strings_map}->{$_}) } keys %{ $self->{escaped_strings_map} };
-  }
-}
-
 sub set_columns {
   my $self    = shift;
   my %columns = @_;
@@ -277,7 +252,7 @@ sub html_format {
   my $self  = shift;
   my $value = shift;
 
-  $value =  $self->{form}->quote_html($value);
+  $value =  $main::locale->quote_special_chars('HTML', $value);
   $value =~ s/\r//g;
   $value =~ s/\n/<br>/g;
 
@@ -767,14 +742,12 @@ sub generate_pdf_content {
 }
 
 sub unescape_string {
-  my $self = shift;
-  my $text = shift;
-
-  foreach my $key (keys %{ $self->{escaped_strings_map} }) {
-    $text =~ s/\Q$key\E/$self->{escaped_strings_map}->{$key}/g;
-  }
+  my $self  = shift;
+  my $text  = shift;
+  my $iconv = $main::locale->{iconv};
 
-  $text =~ s/\Q&amp;\E/&/g;
+  $text     = $main::locale->unquote_special_chars('HTML', $text);
+  $text     = $main::locale->{iconv}->convert($text) if ($main::locale->{iconv});
 
   return $text;
 }
index f19e67a..e6d7e10 100644 (file)
@@ -99,38 +99,7 @@ sub format_string {
   my ($self, $variable) = @_;
   my $form = $self->{"form"};
 
-  my %replace =
-    ('order' => [quotemeta("\\"),
-                 '<pagebreak>',
-                 '&', quotemeta("\n"),
-                 '"', '\$', '%', '_', '#', quotemeta('^'),
-                 '{', '}',  '<', '>', '£', "\r", '±', '\xe1',
-                 '²', '³',
-
-                 ],
-     quotemeta("\\") => '\\textbackslash ',
-     '<pagebreak>'   => '',
-     '"'             => "''",
-     '&'             => '\&',
-     '\$'            => '\$',
-     '%'             => '\%',
-     '_'             => '\_',
-     '#'             => '\#',
-     '{'             => '\{',
-     '}'             => '\}',
-     '<'             => '$<$',
-     '>'             => '$>$',
-     '£'             => '\pounds ',
-     "\r"            => "",
-     '±'             => '$\pm$',
-     '\xe1'          => '$\bullet$',
-     quotemeta('^')  => '\^\\',
-     quotemeta("\n") => '\newline ',
-     '²'             => '$^2$',
-     '³'             => '$^3$',
-     );
-
-  map({ $variable =~ s/$_/$replace{$_}/g; } @{ $replace{"order"} });
+  $variable = $main::locale->quote_special_chars('Template/LaTeX', $variable);
 
   # Allow some HTML markup to be converted into the output format's
   # corresponding markup code, e.g. bold or italic.
@@ -594,14 +563,7 @@ sub format_string {
   my ($self, $variable) = @_;
   my $form = $self->{"form"};
 
-  my %replace =
-    ('order' => ['<', '>', quotemeta("\n")],
-     '<'             => '&lt;',
-     '>'             => '&gt;',
-     quotemeta("\n") => '<br>',
-     );
-
-  map({ $variable =~ s/$_/$replace{$_}/g; } @{ $replace{"order"} });
+  $variable = $main::locale->quote_special_chars('Template/HTML', $variable);
 
   # Allow some HTML markup to be converted into the output format's
   # corresponding markup code, e.g. bold or italic.
@@ -1342,21 +1304,7 @@ sub format_string {
   my $form = $self->{"form"};
   my $iconv = $self->{"iconv"};
 
-  my %replace =
-    ('order' => ['&', '<', '>', '"', "'",
-                 '\x80',        # Euro
-                 quotemeta("\n"), quotemeta("\r")],
-     '<'             => '&lt;',
-     '>'             => '&gt;',
-     '"'             => '&quot;',
-     "'"             => '&apos;',
-     '&'             => '&amp;',
-     '\x80'          => chr(0xa4), # Euro
-     quotemeta("\n") => '<text:line-break/>',
-     quotemeta("\r") => '',
-     );
-
-  map({ $variable =~ s/$_/$replace{$_}/g; } @{ $replace{"order"} });
+  $variable = $main::locale->quote_special_chars('Template/OpenDocument', $variable);
 
   # Allow some HTML markup to be converted into the output format's
   # corresponding markup code, e.g. bold or italic.
@@ -1409,14 +1357,7 @@ sub format_string {
   my ($self, $variable) = @_;
   my $form = $self->{"form"};
 
-  my %replace =
-    ('order' => ['<', '>', quotemeta("\n")],
-     '<'             => '&lt;',
-     '>'             => '&gt;',
-     quotemeta("\n") => '<br>',
-     );
-
-  map({ $variable =~ s/$_/$replace{$_}/g; } @{ $replace{"order"} });
+  $variable = $main::locale->quote_special_chars('Template/XML', $variable);
 
   # Allow no markup to be converted into the output format
   my @markup_replace = ('b', 'i', 's', 'u', 'sub', 'sup');
index 8054af5..edbd984 100644 (file)
@@ -608,7 +608,7 @@ sub list_spool {
 
 $form->get_lists(printers=>"ALL_PRINTERS");
 print qq|<select name="printer">|;
-print map(qq|<option value="$_->{id}">| . $form->quote_html($_->{printer_description}) . qq|</option>|, @{ $form->{ALL_PRINTERS} });
+print map(qq|<option value="$_->{id}">| . H($_->{printer_description}) . qq|</option>|, @{ $form->{ALL_PRINTERS} });
 print qq|</select>|;
 
 #  }
index f3fc1e8..42b6676 100644 (file)
@@ -328,11 +328,11 @@ sub set_longdescription {
 # -------------------------------------------------------------------------
 
 sub H {
-  return $form->quote_html($_[0]);
+  return $locale->quote_special_chars('HTML', $_[0]);
 }
 
 sub Q {
-  return $form->quote($_[0]);
+  return $locale->quote_special_chars('URL@HTML', $_[0]);
 }
 
 sub E {
index af3fcf3..8004e92 100644 (file)
@@ -1984,19 +1984,6 @@ sub print_form {
 
   $auth->assert('general_ledger');
 
-  my %replacements =
-    (
-     "ä" => "ae", "ö" => "oe", "ü" => "ue",
-     "Ä" => "Ae", "Ö" => "Oe", "Ü" => "Ue",
-     "ß" => "ss",
-     " " => "_"
-    );
-
-  foreach my $key (keys %replacements) {
-    my $new_key = SL::Iconv::convert("ISO-8859-15", $dbcharset, $key);
-    $replacements{$new_key} = $replacements{$key} if $new_key ne $key;
-  }
-
   $form->{statementdate} = $locale->date(\%myconfig, $form->{todate}, 1);
 
   $form->{templates} = "$myconfig{templates}";
@@ -2075,8 +2062,8 @@ sub print_form {
             $form->format_amount(\%myconfig, $form->{"${_}total"}, 2)
         } (c0, c30, c60, c90, "");
 
-        $form->{attachment_filename} = $locale->text("Statement") . "_$form->{todate}.$attachment_suffix";
-        map({ $form->{attachment_filename} =~ s/$_/$replacements{$_}/g; } keys(%replacements));
+        $form->{attachment_filename} =  $locale->quote_special_chars('filenames', $locale->text("Statement") . "_$form->{todate}.$attachment_suffix");
+        $form->{attachment_filename} =~ s/\s+/_/g;
 
         $form->parse_template(\%myconfig, $userspath);
 
diff --git a/locale/de/special_chars b/locale/de/special_chars
new file mode 100644 (file)
index 0000000..e36bcf5
--- /dev/null
@@ -0,0 +1,76 @@
+[HTML]
+order=& ä ö ü Ä Ö Ü ß " < >
+ä=&auml;
+ö=&ouml;
+ü=&uuml;
+Ä=&Auml;
+Ö=&Ouml;
+Ü=&Uuml;
+ß=&szlig;
+"=&quot;
+&=&amp;
+<=&lt;
+>=&ht;
+
+[URL@HTML]
+"=&quot;
+
+[XUL]
+order=&
+&=&quot;
+
+[Template/HTML]
+order=< > \n
+<=&lt;
+>=&gt;
+\n=<br>
+
+[Template/XML]
+order=< > \n
+<=&lt;
+>=&gt;
+\n=<br>
+
+[Template/LaTeX]
+order=\\ <pagebreak> & \n \r " $ % _ # ^ { } < > £ ± \xe1 ² ³
+\\=\\textbackslash 
+<pagebreak>=
+"=''
+&=\\&
+$=\\$
+%=\\%
+_=\\_
+#=\\#
+{=\\{
+}=\\}
+<=$<$
+>=$>$
+£=\\pounds 
+\n=\\newline 
+\r=
+±=$\\pm$
+\xe1=$\\bullet$
+^=\\^\\ 
+²=$^2$
+³=$^3$
+
+[Template/OpenDocument]
+order=& < > " ' \x80 \n \r
+<=&lt;
+>=&gt;
+"=&quot;
+'=&apos;
+&=&amp;
+# Euro sign:
+\x80=\xa4
+\n=<text:line-break/>
+\r=
+
+[filenames]
+ä=ae
+ö=oe
+ü=ue
+Ä=Ae
+Ö=Oe
+Ü=Ue
+ß=ss