From de663f0175a0b0172587c1415ea84a804ce5c833 Mon Sep 17 00:00:00 2001 From: Mischa POSLAWSKY Date: Fri, 7 Apr 2017 17:04:36 +0200 Subject: [PATCH] charset: recursive function to handle input request --- charset.plp | 148 +++++++++++++++++++++++++++------------------------- 1 file changed, 77 insertions(+), 71 deletions(-) diff --git a/charset.plp b/charset.plp index 28c21c9..42d6a14 100644 --- a/charset.plp +++ b/charset.plp @@ -15,6 +15,8 @@ Html({ data => [qw'charset-unicode.inc.pl charset-utf8.inc.pl'], }); +my @tablist = split /[^\w-]+/, $Request || 'default'; + :>

Character encoding

@@ -23,87 +25,91 @@ use POSIX qw( ceil ); use Shiar_Sheet::FormatChar; my $glyphs = Shiar_Sheet::FormatChar->new; -# generate character table(s) -# (~16x faster than decoding in loop; -# substr strings is twice as fast as splitting to an array) -my %ALIAS = ( -# default => [qw(unicode utf-8 iso-8859-1 cp437 -cp1252- --iso-8859-15- -koi8-f)], - default => [qw(unicode- utf-8 iso-8859-1 -cp1252- --iso-8859-15- cp437 -cp850)], - 0 => [qw(cp437 -cp863)], - 1 => [qw(iso-8859-1 -cp1252 -MacRoman -cp850)], - 2 => [qw(iso-8859-2 -cp1250 -cp852 -MacCentralEurRoman -MacCroatian -MacRumanian)], - 5 => [qw(koi8-f -iso-8859-5 -cp1251 -MacCyrillic -cp855 -cp866)], - 7 => [qw(iso-8859-7 -cp1253 -MacGreek -cp737 -cp869)], - 8 => [qw(iso-8859-8 -cp1255 -MacHebrew -cp862)], -); -my @request = map { - if (my $input = $_) { - my %row = (offset => 0, cols => 16); - my $endpoint = 255; - if ($input =~ s/^--//) { - $row{offset} = $endpoint > 160 ? 160 : 48; - } - elsif ($input =~ s/^-//) { - $row{offset} = $endpoint > 128 ? 128 : 32; - } - if ($input =~ s/-$//) { - $endpoint = $row{offset} ? $row{offset} < 160 ? 159 : 191 : 127; - } - if ($row{offset}) { - $row{setnote} = 'over cp437' if $input eq 'cp850'; - $row{setnote} = 'over iso-8859-1' if $input =~ /^iso-8859-|^cp125/; - } +sub tabinput { + # generate character table(s) + my $input = shift or return; - if ($input =~ /^U([0-9a-f]+)(?:-([0-9a-f]+))?/) { - my $start = hex($1) << ($2 ? 4 : 8); - my $end = $2 ? hex($2) << 4 : $start + 240; - $row{table} = join '', map { chr } $start .. $end+15; - utf8::upgrade($row{table}); # prevent latin1 output - $row{set} = sprintf 'Unicode block U+%02Xxx', $start >> 8; - } - elsif ($input eq 'U') { - $row{table} = ' ' x 1024; - $row{set} = 'Unicode planes'; - $row{cell} = do 'charset-ucplanes.inc.pl' + state $ALIAS = { + default => [qw(unicode- utf-8 iso-8859-1 -cp1252- --iso-8859-15- cp437 -cp850)], + 0 => [qw(cp437 -cp863)], + 1 => [qw(iso-8859-1 -cp1252 -MacRoman -cp850)], + 2 => [qw(iso-8859-2 -cp1250 -cp852 -MacCentralEurRoman -MacCroatian -MacRumanian)], + 5 => [qw(koi8-f -iso-8859-5 -cp1251 -MacCyrillic -cp855 -cp866)], + 7 => [qw(iso-8859-7 -cp1253 -MacGreek -cp737 -cp869)], + 8 => [qw(iso-8859-8 -cp1255 -MacHebrew -cp862)], + }; + if (my $follow = $ALIAS->{$input}) { + return map { tabinput($_) } @{$follow}; + } + + my %row = (offset => 0, cols => 16); + my $endpoint = 255; + if ($input =~ s/^--//) { + $row{offset} = $endpoint > 160 ? 160 : 48; + } + elsif ($input =~ s/^-//) { + $row{offset} = $endpoint > 128 ? 128 : 32; + } + if ($input =~ s/-$//) { + $endpoint = $row{offset} ? $row{offset} < 160 ? 159 : 191 : 127; + } + if ($row{offset}) { + $row{setnote} = 'over cp437' if $input eq 'cp850'; + $row{setnote} = 'over iso-8859-1' if $input =~ /^iso-8859-|^cp125/; + } + + if ($input =~ /^U([0-9a-f]+)(?:-([0-9a-f]+))?/) { + my $start = hex($1) << ($2 ? 4 : 8); + my $end = $2 ? hex($2) << 4 : $start + 240; + $row{table} = join '', map { chr } $start .. $end+15; + utf8::upgrade($row{table}); # prevent latin1 output + $row{set} = sprintf 'Unicode block U+%02Xxx', $start >> 8; + } + elsif ($input eq 'U') { + $row{table} = ' ' x 1024; + $row{set} = 'Unicode planes'; + $row{cell} = do 'charset-ucplanes.inc.pl' + or Alert('Table data could not be read', $@ || $!); + $row{cols} *= 2; + } + elsif ($row{set} = Encode::resolve_alias($input)) { + if ($row{set} eq 'Internal') { + $row{table} = ' ' x ($endpoint < 255 ? 640 : 8192); + $row{set} = 'Unicode BMP'; + $row{cell} = do 'charset-unicode.inc.pl' or Alert('Table data could not be read', $@ || $!); - $row{cols} *= 2; } - elsif ($row{set} = Encode::resolve_alias($input)) { - if ($row{set} eq 'Internal') { - $row{table} = ' ' x ($endpoint < 255 ? 640 : 8192); - $row{set} = 'Unicode BMP'; - $row{cell} = do 'charset-unicode.inc.pl' - or Alert('Table data could not be read', $@ || $!); - } - elsif ($row{set} eq 'utf-8-strict') { - $row{table} = undef; - $row{set} = 'UTF-8'; - $row{cell} = do 'charset-utf8.inc.pl' - or Alert('Table data could not be read', $@ || $!); - } - else { - $row{table} = Encode::decode($row{set}, pack 'C*', $row{offset} .. $endpoint); - } + elsif ($row{set} eq 'utf-8-strict') { + $row{table} = undef; + $row{set} = 'UTF-8'; + $row{cell} = do 'charset-utf8.inc.pl' + or Alert('Table data could not be read', $@ || $!); } else { - Alert("Encoding $input unknown"); + $row{table} = Encode::decode($row{set}, pack 'C*', $row{offset} .. $endpoint); + # (~16x faster than decoding in loop; + # substr strings is twice as fast as splitting to an array) + + if ($row{set} eq 'cp437') { + substr($row{table}, 237, 1) = pack 'U*', 0x3D5; # phi sign + substr($row{table}, 0, 32) = pack 'U*', map {hex} qw( + 2007 263A 263B 2665 2666 2663 2660 2022 + 25D8 25CB 25D9 2642 2640 266A 266B 263C + 25BA 25C4 2195 203C 00B6 00A7 25AC 21A8 + 2191 2193 2192 2190 221F 2194 25B2 25BC + ); + } } - $row{set} ? \%row : (); } else { - (); + Alert("Encoding $input unknown"); + return; } -} map { defined $ALIAS{$_} ? @{ $ALIAS{$_} } : $_ } - $Request =~ /\w/ ? split(m{[/+\s]}, $Request) : 'default'; -my $NOCHAR = chr 0xFFFD; - -for my $cp437 (grep {$request[$_]->{set} eq 'cp437'} 0 .. $#request) { - substr($request[$cp437]->{table}, 237, 1) = pack 'U*', 0x3D5; # phi sign - substr($request[$cp437]->{table}, 0, 32) = pack 'U*', map {hex} qw( - 2007 263A 263B 2665 2666 2663 2660 2022 25D8 25CB 25D9 2642 2640 266A 266B 263C - 25BA 25C4 2195 203C 00B6 00A7 25AC 21A8 2191 2193 2192 2190 221F 2194 25B2 25BC - ); + return \%row; } +my @request = map { tabinput($_) } @tablist; + +my $NOCHAR = chr 0xFFFD; sub range_cell { my ($info, $offset) = @_; -- 2.30.0