}
-sub quote_html {
- $main::lxdebug->enter_sub(2);
-
- my ($self, $str) = @_;
-
- my %replace =
- ('order' => ['&', '"', '<', '>'],
- '<' => '<',
- '>' => '>',
- '"' => '"',
- '&' => '&',
- );
-
- 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 =
- ('ä' => 'ä',
- 'ö' => 'ö',
- 'ü' => 'ü',
- 'Ä' => 'Ä',
- 'Ö' => 'Ö',
- 'Ü' => 'Ü',
- 'ß' => 'ß',
- '>' => '>',
- '<' => '<',
- '"' => '"',
- );
-
- map { $str =~ s/\Q$_\E/$replace{$_}/g; } keys %replace;
- $str =~ s/\&/\&/g;
-
- $main::lxdebug->leave_sub(2);
-
- return $str;
-}
-
-
sub hide_form {
my $self = shift;
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'
: $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 = "";
}
sub new {
$main::lxdebug->enter_sub();
- my ($type, $file) = @_;
+ my ($type, $file, %options) = @_;
my $id = "";
my $skip;
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 $_;
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;
$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);
"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 {
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;
$self->set_options(@_) if (@_);
- $self->_init_escaped_strings_map();
-
return $self;
}
-sub _init_escaped_strings_map {
- my $self = shift;
-
- $self->{escaped_strings_map} = {
- 'ä' => 'ä',
- 'ö' => 'ö',
- 'ü' => 'ü',
- 'Ä' => 'Ä',
- 'Ö' => 'Ö',
- 'Ü' => 'Ü',
- 'ß' => 'ß',
- '>' => '>',
- '<' => '<',
- '"' => '"',
- };
-
- 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 = @_;
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;
}
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&\E/&/g;
+ $text = $main::locale->unquote_special_chars('HTML', $text);
+ $text = $main::locale->{iconv}->convert($text) if ($main::locale->{iconv});
return $text;
}
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.
my ($self, $variable) = @_;
my $form = $self->{"form"};
- my %replace =
- ('order' => ['<', '>', quotemeta("\n")],
- '<' => '<',
- '>' => '>',
- 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.
my $form = $self->{"form"};
my $iconv = $self->{"iconv"};
- my %replace =
- ('order' => ['&', '<', '>', '"', "'",
- '\x80', # Euro
- quotemeta("\n"), quotemeta("\r")],
- '<' => '<',
- '>' => '>',
- '"' => '"',
- "'" => ''',
- '&' => '&',
- '\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.
my ($self, $variable) = @_;
my $form = $self->{"form"};
- my %replace =
- ('order' => ['<', '>', quotemeta("\n")],
- '<' => '<',
- '>' => '>',
- 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');
$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>|;
# }
# -------------------------------------------------------------------------
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 {
$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}";
$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);
--- /dev/null
+[HTML]
+order=& ä ö ü Ä Ö Ü ß " < >
+ä=ä
+ö=ö
+ü=ü
+Ä=Ä
+Ö=Ö
+Ü=Ü
+ß=ß
+"="
+&=&
+<=<
+>=&ht;
+
+[URL@HTML]
+"="
+
+[XUL]
+order=&
+&="
+
+[Template/HTML]
+order=< > \n
+<=<
+>=>
+\n=<br>
+
+[Template/XML]
+order=< > \n
+<=<
+>=>
+\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
+<=<
+>=>
+"="
+'='
+&=&
+# Euro sign:
+\x80=\xa4
+\n=<text:line-break/>
+\r=
+
+[filenames]
+ä=ae
+ö=oe
+ü=ue
+Ä=Ae
+Ö=Oe
+Ü=Ue
+ß=ss