2
# The contents of this file are subject to the Mozilla Public
3
# License Version 1.1 (the "License"); you may not use this file
4
# except in compliance with the License. You may obtain a copy of
5
# the License at http://www.mozilla.org/MPL/
7
# Software distributed under the License is distributed on an "AS
8
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9
# implied. See the License for the specific language governing
10
# rights and limitations under the License.
12
# The Original Code is Mozilla MathML Project.
14
# The Initial Developer of the Original Code is The University Of
15
# Queensland. Portions created by The University Of Queensland are
16
# Copyright (C) 2001 The University Of Queensland. All
20
# Roger B. Sidje <rbs@maths.uq.edu.au> - Original Author
23
# Utilities to save and retrieve the PUA
24
# RBS - Last Modified: March 20, 2001.
26
# $UNIDATA{$unicode} holds a whitespace-separated list of entities and
27
# annotated unicode points that all resolve to that $unicode point
29
#######################################################################
30
# Initialize the starting point from where we want to make assignments
31
# to the PUA (0xE000 - 0xF8FF).
33
# De-facto zones owned by others:
34
# . Mozilla: 0xF780 - 0xF7FF for the "User Defined" font (bug 6588)
35
# . Apple: 0xF8A1 - 0xF8FF for Apple specific chars
36
# . Microsoft: 0xE000 - 0xEDE7 for CJK's EUDCs (i.e., Chinese/Japanese/Korean's
37
# end user defined characters)
38
# . Linux: 0xF000 - 0xF8FF for DEC VT100 graphics chars and console chars
39
# Hopefully we won't get into troubles within the <math>...</math> environment!
40
$UNIDATA{'PUA'} = '0xEEEE';
42
#########################################################################
45
# To avoid collisions, populate the PUA with code points that are already
46
# taken (or reserved) so that we don't pick them up again
47
#########################################################################
50
my($mathfontPUAproperties) = @_;
55
open(FILE, $mathfontPUAproperties) || die "Cannot open $mathfontPUAproperties\n";
57
if (m/^\\u(\S+)\s*=\s*\\u(\S+)/) {
58
# 1) the annotated unicode point is on the left hand side
59
# 2) the assignment to the PUA is on the right hand side
60
($owner, $pua) = ("0x$1", "0x$2");
61
# convert dot-to-colon for compatibility with the encoding file
63
if (defined $UNIDATA{$pua}) {
64
$UNIDATA{$pua} .= ' ' . $owner;
67
$UNIDATA{$pua} = $owner;
70
elsif (m/^#>\\u(\S+)\s*=\s*([^#]*)/) {
71
# 1) the assignment to the PUA is on the LHS, 2) the entity list is
72
# on the RHS, the list can be empty (a _special case_ where it is not
73
# yet known if there is an entity for that PUA code point)
74
($pua, $owner) = ("0x$1", $2);
75
$owner =~ s/\s*,\s*/ /g; # convert to whitespace-separated
77
# don't bother with empty owner
79
if (defined $UNIDATA{$pua}) {
80
$UNIDATA{$pua} .= ' ' . $owner
83
$UNIDATA{$pua} = $owner;
90
#########################################################################
93
# When we are done with the PUA, save it to preserve our changes
94
#########################################################################
97
my($old_mathfontPUAproperties, $new_mathfontPUAproperties) = @_;
99
# first, load the PUA again because we want to preserve the same
100
# ordering, comments, etc, that are there -- like in a context-diff...
102
open(FILE, $old_mathfontPUAproperties) || die "Cannot open $old_mathfontPUAproperties\n";
107
my($line, $pua, $owner);
108
open(FILE, ">$new_mathfontPUAproperties") || die "Cannot open $new_mathfontPUAproperties\n";
110
foreach $line (@lines) {
111
$line =~ s/\cM\n/\n/; # dos2unix end of line
113
if ($line =~ m/^\\u(\S+)\s*=\s*\\u(\S+)/) {
114
# mark this data as saved
115
$saved{"\\u$1"} = "\\u$2";
117
elsif ($line =~ m/^#>EndSection1/) {
118
# output the new assignments that have been made
119
foreach $pua (sort keys %UNIDATA) {
120
# sanity check: the only foreign key should be the special 'PUA'
121
next if $pua eq 'PUA';
122
# assignments outside the PUA are not saved
123
my($numeric) = hex($pua);
124
next unless ($numeric >= 0xE000 && $numeric <= 0xF8FF);
125
$tmp = $UNIDATA{$pua};
126
die("something is wrong somewhere: $pua") unless $pua =~ m/^0x(....)$/;
128
foreach $owner (split(' ', $tmp)) {
129
# skip entries that are intended for section 2
130
next unless $owner =~ m/^0x(....:.)$/;
132
# convert colon-to-dot for compatibility with the property file
134
# skip entries that are already saved
135
next if defined $saved{$owner};
136
# mark this data as saved
137
$saved{$owner} = $pua;
138
print FILE "$owner = $pua\n";
143
elsif ($line =~ m/^#>\\u(\S+)\s*=\s*([^#]*)(.*)/) {
144
($pua, $owner, $tmp) = ($1, $2, $3);
145
# the owner list may have expanded, update and keep the comment
146
$owner = $UNIDATA{"0x$pua"};
147
$tmp = ' ' . $tmp if $tmp;
148
# remove references handled in section1, there could be a mix of owners
149
# no check for empty owner to preserve what was already saved
150
$owner =~ s/\s*0x....:.//g;
151
$owner =~ s/^\s+//; $owner =~ s/\s+$//;
152
$owner =~ s/ /, /g; # saved as comma-separated
153
$line = "#>\\u$pua = $owner$tmp\n";
154
# mark this data as saved
155
$saved{"\\u$pua"} = $owner;
157
elsif ($line =~ m/^#>EndSection2/) {
158
# output the new assignments that have been made
159
foreach $pua (keys %UNIDATA) {
160
# sanity check: the only foreign key should be the special 'PUA'
161
next if $pua eq 'PUA';
162
($owner, $tmp) = ($1, $2) if $UNIDATA{$pua} =~ /([^#]+)(.*)/;
163
die("something is wrong somewhere: $pua") unless $pua =~ m/^0x(....)$/;
166
$tmp = ' ' . $tmp if $tmp;
167
# skip entries that were saved above
168
next if defined $saved{$pua};
169
# remove references handled in section1, there could be a mix of owners
170
my($count) = $owner =~ s/\s*0x....:.//g;
175
die("something is wrong somewhere: $owner") unless $owner =~ m/^[A-Za-z]/;
176
# mark this data as saved
177
$owner =~ s/ /, /g; # saved as comma-separated
178
$saved{$pua} = $owner;
179
print FILE "#>$pua = $owner$tmp\n";
187
#########################################################################
190
# all the elements on the given whitespace-separated list are assigned to
191
# the same slot in the PUA. The list can contain a mix of entities and
192
# annotated Unicode points.
193
#########################################################################
196
my($owners, $comment) = @_;
198
# verify that nobody is already associated to a unicode point
199
foreach $entry (split(' ', $owners)) {
200
foreach (values %UNIDATA) {
201
die "ERROR *** Redefinition of $entry" if /\b$entry\b/;
205
# get a new slot in the PUA
206
my($pua) = $UNIDATA{'PUA'}; # this holds the current slot in the PUA
207
my($numeric) = hex($pua);
208
while (defined $UNIDATA{$pua}) {
209
$pua = sprintf("0x%04X", ++$numeric);
211
die "ERROR *** PUA is fulled!!!" unless $numeric <= 0xF8FF;
212
$UNIDATA{'PUA'} = $pua; # cache current slot in the PUA
214
# all the owners given on the list should resolve to the same code point
215
if (defined $UNIDATA{$pua}) {
216
$UNIDATA{$pua} .= $owners . ' ' . $UNIDATA{$pua} . $comment;
219
$UNIDATA{$pua} = $owners . $comment;
225
# lookup the unicode of an entry
231
foreach $unicode (keys %UNIDATA) {
232
return $unicode if $UNIDATA{$unicode} =~ /\b$entry\b/;