5 # status.txt file generator
6 # (c)2004 Stepan Roh (PUBLIC DOMAIN)
7 # usage: ./status.pl version_tag status_file sfd_files+
8 # will print new status file on standard output
10 sub parse_status_file
(\
%$);
11 sub parse_sfd_file
(\
%$$);
12 sub print_status_file
(\
%);
13 sub parse_versions
($);
14 sub format_versions
(\
%);
15 sub normalize_version
($);
16 sub denormalize_version
($);
17 sub detect_full_typefaces_support
(@
);
19 # internal parsed format:
20 # _ => ( header lines* )
21 # hexadecimal character encoding => ( 'name' => name, 'versions' => ( version => ( typefaces* ) ) )
30 $Data::Dumper
::Indent
= 1;
31 $Data::Dumper
::Sortkeys
= 1;
32 $Data::Dumper
::Purity
= 1;
35 %parsed_typefaces = ();
37 sub normalize_version
($) {
40 if ($version eq 'original') {
43 return join ('_', map { sprintf ("%02s", $_) } split (/\./, $version));
46 sub denormalize_version
($) {
49 $version = join ('.', map { $_ + 0 } split (/_/, $version));
50 if ($version eq '0.0') {
51 $version = 'original';
56 sub parse_versions
($) {
60 while ($versions =~ s
,^\s
*(\S
+)\s
*(?
:\
((.*?
)\
)|),,) {
61 my ($version, $typefaces) = ($1, $2);
62 $version = normalize_version
($version);
64 my @typefaces = split (/\s*,\s*/, $typefaces);
65 $ret{$version} = \
@typefaces;
73 sub parse_status_file
(\
%$) {
74 my ($parsed_ref, $status_file) = @_;
76 open (STATUS
, $status_file) || die "Unable to open $status_file : $!\n";
79 my ($hex_enc, $name, $versions) = ($_ =~ /^U\+(\S+)\s+(\S+)\s+(.*?)\s*$/);
80 my %versions = parse_versions
($versions);
81 $$parsed_ref{$hex_enc}{'name'} = $name;
82 $$parsed_ref{$hex_enc}{'versions'} = \
%versions;
84 push (@
{$$parsed_ref{'_'}}, $_);
90 sub parse_sfd_file
(\
%$$) {
91 my ($parsed_ref, $version_tag, $sfd_file) = @_;
93 open (SFD
, $sfd_file) || die "Unable to open $sfd_file : $!\n";
98 $version_tag = normalize_version
($version_tag);
100 if (/^FullName:\s+\S+\s+(.*?)\s*$/) {
101 # DejaVu is not included in typeface
103 $parsed_typefaces{$typeface} = 1;
104 } elsif (/^StartChar:\s*(\S+)\s*$/) {
108 } elsif (/^Colour:/) {
109 # XXX this is quick'n'dirty hack to detect non-empty glyphs
111 } elsif (/^Encoding:\s*\d+\s*(\d+)\s*\d+\s*$/) {
112 $hex_enc = sprintf ('%04x', $1);
113 } elsif ($hex_enc && !$empty && /^EndChar\s*$/) {
114 $$parsed_ref{$hex_enc}{'name'} = $curchar;
115 push (@
{$$parsed_ref{$hex_enc}{'versions'}{$version_tag}}, $typeface);
121 sub detect_full_typefaces_support
(@
) {
123 foreach $typeface (@_) {
124 $typefaces{$typeface} = 1;
126 foreach $typeface (keys %parsed_typefaces) {
127 return 0 if (!exists $typefaces{$typeface});
132 sub format_versions
(\
%) {
133 my ($versions_ref) = @_;
136 my %done_typefaces = ();
137 foreach $version (sort keys %{$versions_ref}) {
138 my ($str) = denormalize_version
($version);
140 if (@
{$$versions_ref{$version}}) {
141 my @print_typefaces = ();
142 foreach $typeface (@
{$$versions_ref{$version}}) {
143 if (!exists ($done_typefaces{$typeface})) {
144 $done_typefaces{$typeface} = 1;
145 push (@print_typefaces, $typeface);
148 next if (!@print_typefaces);
149 if (!detect_full_typefaces_support
(@print_typefaces)) {
150 $str .= ' (' . join (', ', sort @print_typefaces) . ')';
157 return join (' ', @ret);
160 sub print_status_file
(\
%) {
161 my ($parsed_ref) = @_;
163 print @
{$$parsed_ref{'_'}};
164 delete $$parsed_ref{'_'};
165 foreach $hex_enc (sort {hex($a) <=> hex($b)} keys %{$parsed_ref}) {
166 my ($versions) = format_versions
(%{$$parsed_ref{$hex_enc}{'versions'}});
167 printf ('U+%s %-'.$name_width.'s %s'."\n", $hex_enc, $$parsed_ref{$hex_enc}{'name'}, $versions);
172 print STDERR
"usage: version_tag status_file sfd_files+\n";
176 $version_tag = shift @ARGV;
177 $status_file = shift @ARGV;
182 parse_status_file
(%parsed, $status_file);
183 foreach $sfd_file (@sfd_files) {
184 parse_sfd_file
(%parsed, $version_tag, $sfd_file);
188 print STDERR Data
::Dumper
->Dump([\
%parsed], ['*parsed']);
189 print STDERR
"Parsed typefaces: ", join (', ', @parsed_typefaces), "\n";
192 print_status_file
(%parsed);