X-Git-Url: http://git.shiar.nl/sheet.git/blobdiff_plain/a0ba9298856b2426c5c66b6d2f2b284d98cee594..96f5f211071a80ac3be647e502cbbb22f97d3db8:/charset.plp?ds=inline diff --git a/charset.plp b/charset.plp index c9ef2b6..18d7c50 100644 --- a/charset.plp +++ b/charset.plp @@ -1,185 +1,459 @@ +<(common.inc.plp)><: + +Html({ + title => 'charset cheat sheet', + version => '1.0', + description => [ + "Reference sheet with all glyphs in common character encoding tables,", + "and an overview of Unicode ranges and UTF-8 bytes.", + ], + keywords => [qw' + charset codepage unicode ascii utf8 latin glyph character encoding + reference common overview table + '], + stylesheet => [qw'light'], + data => [qw'charset-unicode.inc.pl charset-utf8.inc.pl'], +}); + +my @tablist = split m{/+}, $Request || 'default'; + +:> +
â±"; - print ' | ', $_ for @nibble; - print "\n"; + 'cp850' => ['cp437' => '144'], + 'cp860' => ['cp437' => '128-175'], + 'cp861' => ['cp865' => '128-175'], + 'cp863' => ['cp437' => '128-175'], + 'cp865' => ['cp437' => '144-175'], + 'cp852' => ['cp850' => '128', 'cp437' => '128'], + 'cp857' => ['cp850' => '128-175+208-239', 'cp437' => '128'], + 'cp775' => ['cp850' => '128'], # partial cp437 + 'cp866' => ['cp437' => '128-175+224'], + 'cp855' => ['cp437' => '128'], + 'cp1006' => ['iso-8859-6' => '160', 'cp437' => '128'], + 'cp737' => ['cp437' => '128-175+224'], + 'cp869' => ['cp437' => '128'], + 'cp862' => ['cp437' => '128-159'], + 'cp864' => ['MacArabic' => '128', 'iso-8859-6' => '128', 'cp437' => '128'], #TODO: compare form variants + + 'koi8-u' => ['koi8-r' => 128], + 'koi8-f' => ['koi8-u' => 128], + + 'MacRomanian' => ['MacRoman' => '160-191+208-223'], + 'MacRumanian' => ['MacRomanian' => '160-191+208-223', 'MacRoman' => '160-191+208-223'], + 'MacCroatian' => ['MacRoman' => '160'], + 'MacCentralEurRoman' => ['MacRoman' => '128'], + 'MacIcelandic'=> ['MacRoman' => '160-175+208-239'], #TODO: gaps at C/E + 'MacTurkish' => ['MacRoman' => '208-223'], # F5 is unassigned + 'MacSami' => ['MacIcelandic' => '144', 'MacRoman' => '144'], + 'MacGreek' => ['MacRoman' => '128'], + 'MacCyrillic' => ['MacRoman' => '128'], + 'MacHebrew' => ['iso-8859-8' => '128', 'MacRoman' => '128-143+160'], # partial ascii + 'MacArabic' => ['iso-8859-6' => '128', 'cp864' => '128', 'MacRoman' => '128'], #TODO: multiple parents + 'MacFarsi' => ['MacArabic' => '176-191', 'MacRoman' => '128'], + + 'cp37' => ['posix-bc' => '0'], + 'posix-bc' => ['cp1047' => '64'], + 'cp500' => ['cp37' => '64-95+176-191'], + 'cp1047' => ['cp37' => '16-95+160-191'], #TODO: gap at 3/4 + 'cp1026' => ['cp37' => '64'], + 'cp875' => ['cp37' => '48'], + + }; + + my @parents = @{ $INHERIT->{$input} || [] }; + + if (my ($parent, $part) = pairfirst { defined $visible->{$a} } @parents) { + $row{parent} = $parent; + $params = $part; + $params = 128 unless $visible->{$parent} + or ($input eq 'MacCroatian' and defined $visible->{MacRomanian}); + } + elsif (defined $visible->{ascii}) { + $row{parent} = $parents[0]; + $params = $parents[1] // 128; + $params = 128 if $params >= 128; # ascii offset at most + } + elsif (@parents) { + $row{parent} = $parents[0]; + $params = $parents[1] if $parents[1] == 0; # apply ascii end + } + $visible->{$_} //= 0 for $row{parent} || (); } - print ' | |
---|---|---|
', $nibble[$msb]; - for my $lsb (0 .. $#nibble) { - my $glyph = substr $tables[$tablenum], ($msb<<4) + $lsb, 1; - if ($glyph eq $NOCHAR) { - print ' | ';
- next;
+ else {
+ # manual option to double table width
+ $row{cols} *= 2 if $params =~ s/[+]\z//;
+ }
+
+ if (length $params) {
+ $params =~ m{
+ \A (?$paramsis not in format start(-stop)(+restart(-end))", + ]); + + $row{offset} = $+{offset}; + $endpoint = $+{endpoint} if $+{endpoint}; + if (my $restart = $+{restart}) { + my $skip = int(($+{stop} || $row{offset}) / $row{cols}); + for ($skip + 1 .. ($restart / $row{cols}) - 1) { + $row{skip}->{ $_ * $row{cols} - $row{offset} }++; } - my $info = [ord $glyph]; - if (defined (my $mnem = $di{ord $glyph})) { - $info = $diinfo->{$mnem}; + } + } + + if ($input =~ /^U([0-9a-fA-F]+)(?:-([0-9a-fA-F]+))?/) { + my $start = hex($1) << ($2 ? 4 : 8); + my $end = $2 ? (hex($2) << 4) + $row{cols} - 1 : $start + 255; + $row{table} = join '', map { chr } $start .. $end; + utf8::upgrade($row{table}); # prevent latin1 output + $row{endpoint} = $end - $start; + $row{set} = sprintf 'Unicode block U+%02Xxx', $start >> 8; + $row{offset} = $start % 256; + } + elsif ($input eq 'U') { + $row{set} = 'Unicode planes'; + $row{cell} = do 'charset-ucplanes.inc.pl' + or Alert('Table data could not be read', $@ || $!); + $row{cols} *= 2; + $row{endpoint} = 1023 * $row{cell}->{colsize}; + } + elsif ($row{set} = Encode::resolve_alias($input)) { + if ($row{set} eq 'Internal') { + $row{set} = 'Unicode BMP'; + $row{cell} = do 'charset-unicode.inc.pl' + or Alert('Table data could not be read', $@ || $!); + $row{endpoint} = ($endpoint || 8191) * $row{cell}->{colsize}; + } + elsif ($row{set} eq 'utf-8-strict') { + $row{set} = 'UTF-8'; + $row{cell} = do 'charset-utf8.inc.pl' + or Alert('Table data could not be read', $@ || $!); + $row{endpoint} = 255; + } + else { + if ($row{set} eq 'MacHebrew' or $row{set} eq 'MacThai') { + # array of possibly multiple characters per code point + $row{table} = [ + map { Encode::decode($row{set}, pack 'C*', $_) } $row{offset} .. $endpoint + ]; } - my ($codepoint, $name, $prop, $script, $string) = @$info; + else { + # ~16x faster than decoding in loop; + # substr strings is twice as fast as splitting to an array + $row{table} = Encode::decode($row{set}, pack 'C*', $row{offset} .. $endpoint); + } + $row{endpoint} = $endpoint - $row{offset}; + + if ($row{set} eq 'cp437' and !$row{offset}) { + 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 + ); + } + + $visible->{ascii} = # assume common base + $visible->{ $row{set} } = 1; + } + } + else { + Alert("Encoding $inputunknown"); + return; + } + push @request, \%row; +} +tabinput($_) for @tablist; + +my $NOCHAR = chr 0xFFFD; - $glyph = quote($string || $glyph); - my $desc = sprintf 'U+%04X%s', $codepoint, $name && " ($name)"; - my @class = ('X', grep {$_} $prop, $script); +sub range_cell { + my ($info, $offset) = @_; + my $table = $info->{cell} or return; + my $def = $table->{$offset} or return; + my ($len, $class, $name, $title) = @{$def}; - $glyph = "$glyph" if $prop eq 'Zs'; + my $cols = $info->{cols}; + my $colsize = $table->{colsize} || 1; + my $attr = ''; + $len /= $colsize; + $name //= $len <= 2 ? 'res' : 'reserved'; - printf "\n".' %s',
- join(' ', @class), quote($desc), $glyph;
+ if (my $part = $offset/$colsize % $cols) {
+ # continued row
+ my $rest = $cols - $part; # remaining
+ $rest = $len if $len < $rest; #TODO: optimise
+ if ($len -= $rest) {
+ # continued on new row
+ my @next = ($len * $colsize, "$class joinu");
+ if ($len > $rest) {
+ # minority remains
+ push @next, $name, $title;
+ $title ||= $name;
+ $name = '';
+ }
+ else {
+ # minority on next row
+ push @next, '"', $title || $name;
+ }
+ $table->{$offset + $colsize*$rest} //= \@next;
+ $class .= ' joind';
}
- print "\n";
+ $len = $rest;
}
- print " | |
â±"; - print ' | ', $_ for @nibble; + print "<$section> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
", $rowdiv == 1 ? '+' : 'â±'; + printf ' | %0*X', $coldigits, $_ * $colsize for 0 .. $cols - 1; print "\n"; } print ' | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
', $nibble[$msb]; - for my $lsb (0 .. $#nibble) { - my $value = ($msb<<4) + $lsb; - if ($value <= 0x7F) { - print ' | Single byte ASCII' - if $value == 0; - } - elsif ($value <= 0xBF) { - print ' | Multi-byte continuation' - if $value == 0x80; - } - elsif ($value <= 0xC1) { - print ' | (Overl.)' - if $value == 0xC0; - } - elsif ($value <= 0xDF) { - print ' | 2-byte sequence start' - if $value == 0xC2; - print ' | ' - if $value == 0xD0; - } - elsif ($value <= 0xEF) { - print ' | 3-byte sequence start' - if $value == 0xE0; - } - elsif ($value <= 0xF4) { - print ' | 4-byte sequence' - if $value == 0xF0; - } - elsif ($value <= 0xF7) { - print ' | (Overflow)' - if $value == 0xF5; + while ($offset < $row->{endpoint}) { + if ($row->{skip}->{$offset}) { + $offset += $cols * $colsize; + next; + } + + print ' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'; + if (defined $row->{skip}->{$offset}) { + print 'â®'; + } + else { + if (my $rowmod = $offset % $rowdiv) { + # offset in column units + printf '+%X', $rowmod; } - elsif ($value <= 0xFB) { - print ' | 5-byte' - if $value == 0xF8; + else { + # divided row offset + printf '%X', ($offset + $row->{offset}) / $rowdiv; } - elsif ($value <= 0xFD) { - print ' | 6-byte' - if $value == 0xFC; + } + for (1 .. $cols) { + if ($row->{cell}) { + print range_cell($row, $offset); + next; } - elsif ($value <= 0xFF) { - print ' | Invalid' - if $value == 0xFE; + + my $glyph = ref $row->{table} eq 'ARRAY' ? $row->{table}->[$offset] : + substr $row->{table}, $offset, 1; + if ($glyph eq $NOCHAR) { + print ' | '; + next; } - else { - print "\n".' | ?'; + + if (exists $get{compare}) { + state $visible = {}; + my $cp = $offset + $row->{offset}; + printf ' | %2$s', + $cp == ord $glyph ? 'l4' : + $row->{parent} && $glyph eq + Encode::decode($row->{parent}, pack 'C', $cp) ? 'l3' : + $visible->{$glyph} ? 'l2' : + 'l1', + $glyphs->glyph_html($glyph); + $visible->{$glyph}++; + next; } + + print "\n".$glyphs->glyph_cell($glyph); + } + continue { + $offset += $colsize; } print "\n"; } - print " |
unicode + | inherited + | existing + | original + | unassigned +<: } else { :> + | control + | whitespace + | diacritic
| punctuation
| symbol
| numeric + | greek
| aramaic
| syllabic
| alphabetic + |
unicode 7.0 + | proposed + | deprecated + | unassigned + | invalid +<: } :> |