/[suikacvs]/markup/html/html5/spec-ja/common.pl
Suika

Contents of /markup/html/html5/spec-ja/common.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.18 - (hide annotations) (download)
Sun Nov 2 04:49:55 2008 UTC (17 years, 2 months ago) by wakaba
Branch: MAIN
Changes since 1.17: +9 -1 lines
File MIME type: text/plain
Do width normalization

1 wakaba 1.1 use strict;
2 wakaba 1.18 use utf8;
3 wakaba 1.1
4 wakaba 1.7 my $data_dir_name = q[data/];
5 wakaba 1.8 my $data2_dir_name = q[data2/];
6     my $data2_suffix = q[.dat];
7     my $lock_suffix = q[.lock];
8 wakaba 1.13
9     ## SEE ALSO: |Makefile|.
10 wakaba 1.8 my $fallback_file_name = $data2_dir_name . 'fallback' . $data2_suffix;
11 wakaba 1.12
12     ## SEE ALSO: |Makefile|.
13 wakaba 1.11 my $patch_file_name = $data2_dir_name . 'modified.txt';
14 wakaba 1.8
15     our $UseCVS //= 1;
16 wakaba 1.1
17     sub normalize ($) {
18     my $s = shift;
19     $s =~ s/\s+/ /g;
20     $s =~ s/^ //;
21     $s =~ s/ $//g;
22     return $s;
23     } # normalize
24    
25 wakaba 1.8 sub get_hash ($) {
26     require Digest::MD5;
27 wakaba 1.14 require Encode;
28     return Digest::MD5::md5_hex (Encode::encode ('utf8', normalize ($_[0])));
29 wakaba 1.8 } # get_hash
30    
31 wakaba 1.1 sub create_pattern1 ($) {
32     my $s = quotemeta shift;
33     $s =~ s/\\\*/(.+)/g;
34     return $s;
35     } # create_pattern1
36    
37     sub replace_pattern2 ($@) {
38     my $s = shift;
39     my @arg = @_;
40     $s =~ s/\$(\d+)/$arg[$1 - 1]/g;
41     return $s;
42     } # replace_pattern2
43    
44 wakaba 1.8 sub read_data_file ($) {
45     my $file_name = shift;
46     if (-f $file_name) {
47     warn "Loading $file_name...\n";
48     return do $file_name;
49     } else {
50     warn "File $file_name not found\n";
51     return {};
52     }
53     } # read_data_file
54    
55     sub write_data_file ($$) {
56     my ($file_name, $data) = @_;
57    
58     require Data::Dumper;
59     local $Data::Dumper::Sortkeys = 1;
60 wakaba 1.17 local $Data::Dumper::Useqq = 1;
61     local *Data::Dumper::qquote = sub {
62     my $s = shift;
63     $s =~ s/([\x27\x5C])/sprintf '\x%02X', ord $1/ge;
64     return q<qq'> . $s . q<'>;
65     }; # Data::Dumper::qquote
66    
67 wakaba 1.8 my $had_file = -f $file_name;
68     open my $file, '>:encoding(utf8)', $file_name or die "$0: $file_name: $!";
69 wakaba 1.17 print $file "use utf8;\n";
70 wakaba 1.8 print $file Data::Dumper::Dumper ($data);
71     close $file;
72     unless ($had_file) {
73 apache 1.9 system_ ('cvs', 'add', $file_name) if $UseCVS;
74 wakaba 1.8 }
75     } # write_data_file
76    
77     sub hash_to_file_name ($) {
78     return $data2_dir_name . substr ($_[0], 0, 2) . $data2_suffix;
79     } # hash_to_file_name
80    
81     my $Entry = {};
82 wakaba 1.11 my $ModifiedHash = {};
83 wakaba 1.8
84     sub get_entry ($) {
85     my $hash = shift;
86    
87     my $file_name = hash_to_file_name ($hash);
88     unless ($Entry->{$file_name}) {
89     $Entry->{$file_name} = read_data_file ($file_name);
90     }
91    
92     if ($Entry->{$file_name}->{exact}->{$hash}) {
93     return (0, $Entry->{$file_name}->{exact}->{$hash});
94     } elsif ($Entry->{$file_name}->{pattern}->{$hash}) {
95     return (1, $Entry->{$file_name}->{pattern}->{$hash});
96     } else {
97     return (undef, undef);
98     }
99     } # get_entry
100    
101     sub set_entry ($$$) {
102     my ($hash, $is_pattern, $value) = @_;
103    
104     my $file_name = hash_to_file_name ($hash);
105     unless ($Entry->{$file_name}) {
106     $Entry->{$file_name} = read_data_file ($file_name);
107     }
108    
109     unless ($value) {
110     delete $Entry->{$file_name}->{exact}->{$hash};
111     delete $Entry->{$file_name}->{pattern}->{$hash};
112     } elsif ($is_pattern) {
113     delete $Entry->{$file_name}->{exact}->{$hash};
114     $Entry->{$file_name}->{pattern}->{$hash} = $value;
115     } else {
116     $Entry->{$file_name}->{exact}->{$hash} = $value;
117     delete $Entry->{$file_name}->{pattern}->{$hash};
118     }
119     $Entry->{$file_name}->{modified} = 1;
120 wakaba 1.11 $ModifiedHash->{$hash} = 1;
121 wakaba 1.8 } # set_entry
122    
123     use Fcntl ':flock';
124     my $Lock;
125    
126     sub lock_entry ($) {
127     if ($Lock) {
128     die "$0: lock_entry: Another entry is locked";
129     }
130    
131     my $hash = shift;
132     my $file_name = hash_to_file_name ($hash) . $lock_suffix;
133     open $Lock, '>', $file_name or die "$0: $file_name: $!";
134     flock $Lock, LOCK_EX;
135     } # lock_entry
136    
137     sub commit_entries ($) {
138     for my $file_name (keys %{$Entry}) {
139     if ($Entry->{$file_name}->{modified}) {
140 wakaba 1.11 delete $Entry->{$file_name}->{modified};
141 wakaba 1.8 write_data_file ($file_name => $Entry->{$file_name});
142     }
143     }
144    
145 wakaba 1.11 open my $file, '>>', $patch_file_name or die "$0: $patch_file_name: $!";
146     for (keys %$ModifiedHash) {
147     print $file "$_\n";
148     }
149     close $file;
150    
151 wakaba 1.8 my $msg = shift // $0;
152 wakaba 1.10 system_ ('cvs', 'commit', -m => $msg, $data2_dir_name) if $UseCVS;
153 wakaba 1.8 } # commit_entries
154    
155     sub get_all_entries () {
156     opendir my $dir, $data2_dir_name or die "$0: $data2_dir_name: $!";
157     for (readdir $dir) {
158     next unless /\Q$data2_suffix\E$/;
159     my $file_name = $data2_dir_name . $_;
160     next if $Entry->{$file_name};
161    
162     $Entry->{$file_name} = read_data_file ($file_name);
163     }
164    
165     return $Entry;
166     } # get_all_entries
167    
168 wakaba 1.14 sub for_each_entry_set ($;$) {
169     my $code = shift;
170     my $on_the_fly = shift;
171    
172     opendir my $dir, $data2_dir_name or die "$0: $data2_dir_name: $!";
173     for (readdir $dir) {
174     next unless /\Q$data2_suffix\E$/;
175     my $file_name = $data2_dir_name . $_;
176     next if $file_name eq $fallback_file_name;
177    
178     if ($Entry->{$file_name}) {
179     $code->($file_name, $Entry->{$file_name});
180     } elsif ($on_the_fly) {
181     $code->($file_name, read_data_file ($file_name));
182     } else {
183     $Entry->{$file_name} = read_data_file ($file_name);
184     $code->($file_name, $Entry->{$file_name});
185     }
186     }
187     } # for_each_entry_set
188    
189 wakaba 1.8 my $FallbackEntry;
190     sub get_fallback_entry ($) {
191     my $hash = shift;
192     unless (defined $FallbackEntry) {
193     $FallbackEntry = read_data_file ($fallback_file_name);
194     }
195     return $FallbackEntry->{$hash} // {};
196     } # get_fallback_entry
197    
198 wakaba 1.11 sub get_entry_or_fallback_entry ($) {
199     my $hash = shift;
200    
201     my ($is_pattern, $entry) = get_entry ($hash);
202     unless (defined $entry->{en}) {
203     $entry = get_fallback_entry ($hash);
204     }
205 wakaba 1.13 $entry->{tags} ||= [];
206 wakaba 1.11 $entry->{isPattern} = 1 if $is_pattern;
207    
208     return $entry;
209     } # get_entry_or_fallback_entry
210    
211 wakaba 1.8 sub set_fallback_entry ($$) {
212     my ($hash, $value) = @_;
213     unless (defined $FallbackEntry) {
214     $FallbackEntry = read_data_file ($fallback_file_name);
215     }
216     $FallbackEntry->{$hash} = $value;
217     } # set_fallback_entry
218 wakaba 1.14
219     sub get_fallback_entries () {
220     unless (defined $FallbackEntry) {
221     $FallbackEntry = read_data_file ($fallback_file_name);
222     }
223    
224     return $FallbackEntry;
225     } # get_fallback_entries
226 wakaba 1.8
227     sub save_fallback_entries () {
228     write_data_file ($fallback_file_name => $FallbackEntry)
229     if defined $FallbackEntry;
230     } # save_fallback_entries
231 wakaba 1.11
232     sub get_modified_hashes () {
233     open my $file, '<', $patch_file_name or die "$0: $patch_file_name: $!";
234     return map {tr/\x0D\x0A//d; $_} <$file>;
235     } # get_modified_hashes
236 wakaba 1.8
237 wakaba 1.18 sub normalize_width ($) {
238     my $s = shift;
239     $s =~ tr{\x{3000}\x{FF01}-\x{FF5E}\x{FF61}-\x{FF9F}\x{FFE0}-\x{FFE6}}
240     { !-~。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン\x{3099}\x{309A}\xA2\xA3\xAC\xAF\xA6\xA5\x{20A9}};
241     return $s;
242     } # normalize_width
243    
244 wakaba 1.8 sub htescape ($) {
245     my $s = shift;
246     $s =~ s/&/&amp;/g;
247     $s =~ s/</&lt;/g;
248     $s =~ s/"/&quot;/g;
249     return $s;
250     } # htescape
251 apache 1.9
252     sub system_ (@) {
253 wakaba 1.10 (system join (' ', map {quotemeta $_} @_) . " > /dev/null") == 0
254     or die "$0: $?";
255 apache 1.9 } # system_
256 wakaba 1.1
257     1;
258    
259 wakaba 1.16 ## Author: Wakaba <w@suika.fam.cx>.
260     ## License: Copyright 2008 Wakaba. You are granted a license to use,
261     ## reproduce and create derivative works of this script.
262 wakaba 1.18 ## $Date: 2008/11/01 11:58:32 $

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24