layout/mathml/updateOperatorDictionary.pl

Wed, 31 Dec 2014 07:53:36 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:53:36 +0100
branch
TOR_BUG_3246
changeset 5
4ab42b5ab56c
permissions
-rwxr-xr-x

Correct small whitespace inconsistency, lost while renaming variables.

michael@0 1 #!/usr/bin/perl
michael@0 2 # -*- Mode: Perl; tab-width: 2; indent-tabs-mode: nil; -*-
michael@0 3 # This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 # License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 6
michael@0 7 use XML::LibXSLT;
michael@0 8 use XML::LibXML;
michael@0 9 use LWP::Simple;
michael@0 10
michael@0 11 # output files
michael@0 12 $FILE_UNICODE = "unicode.xml";
michael@0 13 $FILE_DICTIONARY = "dictionary.xml";
michael@0 14 $FILE_DIFFERENCES = "differences.txt";
michael@0 15 $FILE_NEW_DICTIONARY = "new_dictionary.txt";
michael@0 16 $FILE_SYNTAX_ERRORS = "syntax_errors.txt";
michael@0 17 $FILE_JS = "tests/stretchy-and-large-operators.js";
michael@0 18
michael@0 19 # our dictionary (property file)
michael@0 20 $MOZ_DICTIONARY = "mathfont.properties";
michael@0 21
michael@0 22 # dictionary provided by the W3C in "XML Entity Definitions for Characters"
michael@0 23 $WG_DICTIONARY_URL = "http://www.w3.org/2003/entities/2007xml/unicode.xml";
michael@0 24
michael@0 25 # XSL stylesheet to extract relevant data from the dictionary
michael@0 26 $DICTIONARY_XSL = "operatorDictionary.xsl";
michael@0 27
michael@0 28 # dictionary provided by the W3C transformed with operatorDictionary.xsl
michael@0 29 $WG_DICTIONARY = $FILE_DICTIONARY;
michael@0 30
michael@0 31 if (!($#ARGV >= 0 &&
michael@0 32 ((($ARGV[0] eq "download") && $#ARGV <= 1) ||
michael@0 33 (($ARGV[0] eq "compare") && $#ARGV <= 1) ||
michael@0 34 (($ARGV[0] eq "check") && $#ARGV <= 0) ||
michael@0 35 (($ARGV[0] eq "make-js") && $#ARGV <= 0) ||
michael@0 36 (($ARGV[0] eq "clean") && $#ARGV <= 0)))) {
michael@0 37 &usage;
michael@0 38 }
michael@0 39
michael@0 40 if ($ARGV[0] eq "download") {
michael@0 41 if ($#ARGV == 1) {
michael@0 42 $WG_DICTIONARY_URL = $ARGV[1];
michael@0 43 }
michael@0 44 print "Downloading $WG_DICTIONARY_URL...\n";
michael@0 45 getstore($WG_DICTIONARY_URL, $FILE_UNICODE);
michael@0 46
michael@0 47 print "Converting $FILE_UNICODE into $FILE_DICTIONARY...\n";
michael@0 48 my $xslt = XML::LibXSLT->new();
michael@0 49 my $source = XML::LibXML->load_xml(location => $FILE_UNICODE);
michael@0 50 my $style_doc = XML::LibXML->load_xml(location => $DICTIONARY_XSL,
michael@0 51 no_cdata=>1);
michael@0 52 my $stylesheet = $xslt->parse_stylesheet($style_doc);
michael@0 53 my $results = $stylesheet->transform($source);
michael@0 54 open($file, ">$FILE_DICTIONARY") || die ("Couldn't open $FILE_DICTIONARY!");
michael@0 55 print $file $stylesheet->output_as_bytes($results);
michael@0 56 close($file);
michael@0 57 exit 0;
michael@0 58 }
michael@0 59
michael@0 60 if ($ARGV[0] eq "clean") {
michael@0 61 unlink($FILE_UNICODE,
michael@0 62 $FILE_DICTIONARY,
michael@0 63 $FILE_DIFFERENCES,
michael@0 64 $FILE_NEW_DICTIONARY,
michael@0 65 $FILE_SYNTAX_ERRORS);
michael@0 66 exit 0;
michael@0 67 }
michael@0 68
michael@0 69 if ($ARGV[0] eq "compare" && $#ARGV == 1) {
michael@0 70 $WG_DICTIONARY = $ARGV[1];
michael@0 71 }
michael@0 72
michael@0 73 ################################################################################
michael@0 74 # structure of the dictionary used by this script:
michael@0 75 # - key: same as in mathfont.properties
michael@0 76 # - table:
michael@0 77 # index | value
michael@0 78 # 0 | description
michael@0 79 # 1 | lspace
michael@0 80 # 2 | rspace
michael@0 81 # 3 | minsize
michael@0 82 # 4 | largeop
michael@0 83 # 5 | movablelimits
michael@0 84 # 6 | stretchy
michael@0 85 # 7 | separator
michael@0 86 # 8 | accent
michael@0 87 # 9 | fence
michael@0 88 # 10 | symmetric
michael@0 89 # 11 | priority
michael@0 90 # 12 | linebreakstyle
michael@0 91 # 13 | direction
michael@0 92 # 14 | integral
michael@0 93 # 15 | mirrorable
michael@0 94
michael@0 95 # 1) build %moz_hash from $MOZ_DICTIONARY
michael@0 96
michael@0 97 print "loading $MOZ_DICTIONARY...\n";
michael@0 98 open($file, $MOZ_DICTIONARY) || die ("Couldn't open $MOZ_DICTIONARY!");
michael@0 99
michael@0 100 print "building dictionary...\n";
michael@0 101 while (<$file>) {
michael@0 102 next unless (m/^operator\.(.*)$/);
michael@0 103 (m/^([\w|\.|\\]*)\s=\s(.*)\s#\s(.*)$/);
michael@0 104
michael@0 105 # 1.1) build the key
michael@0 106 $key = $1;
michael@0 107
michael@0 108 # 1.2) build the array
michael@0 109 $_ = $2;
michael@0 110 @value = ();
michael@0 111 $value[0] = $3;
michael@0 112 if (m/^(.*)lspace:(\d)(.*)$/) { $value[1] = $2; } else { $value[1] = "5"; }
michael@0 113 if (m/^(.*)rspace:(\d)(.*)$/) { $value[2] = $2; } else { $value[2] = "5"; }
michael@0 114 if (m/^(.*)minsize:(\d)(.*)$/) { $value[3] = $2; } else { $value[3] = "1"; }
michael@0 115 $value[4] = (m/^(.*)largeop(.*)$/);
michael@0 116 $value[5] = (m/^(.*)movablelimits(.*)$/);
michael@0 117 $value[6] = (m/^(.*)stretchy(.*)$/);
michael@0 118 $value[7] = (m/^(.*)separator(.*)$/);
michael@0 119 $value[8] = (m/^(.*)accent(.*)$/);
michael@0 120 $value[9] = (m/^(.*)fence(.*)$/);
michael@0 121 $value[10] = (m/^(.*)symmetric(.*)$/);
michael@0 122 $value[11] = ""; # we don't store "priority" in our dictionary
michael@0 123 $value[12] = ""; # we don't store "linebreakstyle" in our dictionary
michael@0 124 if (m/^(.*)direction:([a-z]*)(.*)$/) { $value[13] = $2; }
michael@0 125 else { $value[13] = ""; }
michael@0 126 $value[14] = (m/^(.*)integral(.*)$/);
michael@0 127 $value[15] = (m/^(.*)mirrorable(.*)$/);
michael@0 128
michael@0 129 # 1.3) save the key and value
michael@0 130 $moz_hash{$key} = [ @value ];
michael@0 131 }
michael@0 132
michael@0 133 close($file);
michael@0 134
michael@0 135 ################################################################################
michael@0 136 # 2) If mode "make-js", generate tests/stretchy-and-large-operators.js and quit.
michael@0 137 # If mode "check", verify validity of our operator dictionary and quit.
michael@0 138 # If mode "compare", go to step 3)
michael@0 139
michael@0 140 if ($ARGV[0] eq "make-js") {
michael@0 141 print "generating file $FILE_JS...\n";
michael@0 142 open($file_js, ">$FILE_JS") ||
michael@0 143 die ("Couldn't open $FILE_JS!");
michael@0 144 print $file_js "// This file is automatically generated. Do not edit.\n";
michael@0 145 print $file_js "var stretchy_and_large_operators = [";
michael@0 146 @moz_keys = (keys %moz_hash);
michael@0 147 while ($key = pop(@moz_keys)) {
michael@0 148 @moz = @{ $moz_hash{$key} };
michael@0 149
michael@0 150 $_ = $key;
michael@0 151 (m/^operator\.([\w|\.|\\]*)\.(prefix|infix|postfix)$/);
michael@0 152 $opname = "\\$1.$2: ";
michael@0 153
michael@0 154 if (@moz[4]) {
michael@0 155 print $file_js "['$opname', '$1','l','$2'],";
michael@0 156 }
michael@0 157
michael@0 158 if (@moz[6]) {
michael@0 159 $_ = substr(@moz[13], 0, 1);
michael@0 160 print $file_js "['$opname', '$1','$_','$2'],";
michael@0 161 }
michael@0 162 }
michael@0 163 print $file_js "];\n";
michael@0 164 close($file_js);
michael@0 165 exit 0;
michael@0 166 }
michael@0 167
michael@0 168 if ($ARGV[0] eq "check") {
michael@0 169 print "checking operator dictionary...\n";
michael@0 170 open($file_syntax_errors, ">$FILE_SYNTAX_ERRORS") ||
michael@0 171 die ("Couldn't open $FILE_SYNTAX_ERRORS!");
michael@0 172
michael@0 173 $nb_errors = 0;
michael@0 174 $nb_warnings = 0;
michael@0 175 @moz_keys = (keys %moz_hash);
michael@0 176 # check the validity of our private data
michael@0 177 while ($key = pop(@moz_keys)) {
michael@0 178 @moz = @{ $moz_hash{$key} };
michael@0 179 $entry = &generateEntry($key, @moz);
michael@0 180 $valid = 1;
michael@0 181
michael@0 182 if (!(@moz[13] eq "" ||
michael@0 183 @moz[13] eq "horizontal" ||
michael@0 184 @moz[13] eq "vertical")) {
michael@0 185 $valid = 0;
michael@0 186 $nb_errors++;
michael@0 187 print $file_syntax_errors "error: invalid direction \"$moz[13]\"\n";
michael@0 188 }
michael@0 189
michael@0 190 if (!@moz[4] && @moz[14]) {
michael@0 191 $valid = 0;
michael@0 192 $nb_warnings++;
michael@0 193 print $file_syntax_errors "warning: operator is integral but not largeop\n";
michael@0 194 }
michael@0 195
michael@0 196 $_ = @moz[0];
michael@0 197 if ((m/^(.*)[iI]ntegral(.*)$/) && !@moz[14]) {
michael@0 198 $valid = 0;
michael@0 199 $nb_warnings++;
michael@0 200 print $file_syntax_errors "warning: operator contains the term \"integral\" in its comment, but is not integral\n";
michael@0 201 }
michael@0 202
michael@0 203 if (!$valid) {
michael@0 204 print $file_syntax_errors $entry;
michael@0 205 print $file_syntax_errors "\n";
michael@0 206 }
michael@0 207 }
michael@0 208
michael@0 209 # check that all forms have the same direction.
michael@0 210 @moz_keys = (keys %moz_hash);
michael@0 211 while ($key = pop(@moz_keys)) {
michael@0 212
michael@0 213 if (@{ $moz_hash{$key} }) {
michael@0 214 # the operator has not been removed from the hash table yet.
michael@0 215
michael@0 216 $_ = $key;
michael@0 217 (m/^([\w|\.|\\]*)\.(prefix|infix|postfix)$/);
michael@0 218 $key_prefix = "$1.prefix";
michael@0 219 $key_infix = "$1.infix";
michael@0 220 $key_postfix = "$1.postfix";
michael@0 221 @moz_prefix = @{ $moz_hash{$key_prefix} };
michael@0 222 @moz_infix = @{ $moz_hash{$key_infix} };
michael@0 223 @moz_postfix = @{ $moz_hash{$key_postfix} };
michael@0 224
michael@0 225 $same_direction = 1;
michael@0 226
michael@0 227 if (@moz_prefix) {
michael@0 228 if (@moz_infix &&
michael@0 229 !($moz_infix[13] eq $moz_prefix[13])) {
michael@0 230 $same_direction = 0;
michael@0 231 }
michael@0 232 if (@moz_postfix &&
michael@0 233 !($moz_postfix[13] eq $moz_prefix[13])) {
michael@0 234 $same_direction = 0;
michael@0 235 }
michael@0 236 }
michael@0 237 if (@moz_infix) {
michael@0 238 if (@moz_postfix &&
michael@0 239 !($moz_postfix[13] eq $moz_infix[13])) {
michael@0 240 $same_direction = 0;
michael@0 241 }
michael@0 242 }
michael@0 243
michael@0 244 if (!$same_direction) {
michael@0 245 $nb_errors++;
michael@0 246 print $file_syntax_errors
michael@0 247 "error: operator has a stretchy form, but all forms";
michael@0 248 print $file_syntax_errors
michael@0 249 " have not the same direction\n";
michael@0 250 if (@moz_prefix) {
michael@0 251 $_ = &generateEntry($key_prefix, @moz_prefix);
michael@0 252 print $file_syntax_errors $_;
michael@0 253 }
michael@0 254 if (@moz_infix) {
michael@0 255 $_ = &generateEntry($key_infix, @moz_infix);
michael@0 256 print $file_syntax_errors $_;
michael@0 257 }
michael@0 258 if (@moz_postfix) {
michael@0 259 $_ = &generateEntry($key_postfix, @moz_postfix);
michael@0 260 print $file_syntax_errors $_;
michael@0 261 }
michael@0 262 print $file_syntax_errors "\n";
michael@0 263 }
michael@0 264
michael@0 265 if (@moz_prefix) {
michael@0 266 delete $moz_hash{$key.prefix};
michael@0 267 }
michael@0 268 if (@moz_infix) {
michael@0 269 delete $moz_hash{$key_infix};
michael@0 270 }
michael@0 271 if (@moz_postfix) {
michael@0 272 delete $moz_hash{$key_postfix};
michael@0 273 }
michael@0 274 }
michael@0 275 }
michael@0 276
michael@0 277 close($file_syntax_errors);
michael@0 278 print "\n";
michael@0 279 if ($nb_errors > 0 || $nb_warnings > 0) {
michael@0 280 print "$nb_errors error(s) found\n";
michael@0 281 print "$nb_warnings warning(s) found\n";
michael@0 282 print "See output file $FILE_SYNTAX_ERRORS.\n\n";
michael@0 283 } else {
michael@0 284 print "No error found.\n\n";
michael@0 285 }
michael@0 286
michael@0 287 exit 0;
michael@0 288 }
michael@0 289
michael@0 290 ################################################################################
michael@0 291 # 3) build %wg_hash and @wg_keys from the page $WG_DICTIONARY
michael@0 292
michael@0 293 print "loading $WG_DICTIONARY...\n";
michael@0 294 my $parser = XML::LibXML->new();
michael@0 295 my $doc = $parser->parse_file($WG_DICTIONARY);
michael@0 296
michael@0 297 print "building dictionary...\n";
michael@0 298 @wg_keys = ();
michael@0 299
michael@0 300 foreach my $entry ($doc->findnodes('/root/entry')) {
michael@0 301 # 3.1) build the key
michael@0 302 $key = "operator.";
michael@0 303
michael@0 304 $_ = $entry->getAttribute("unicode");
michael@0 305 $_ = "$_-";
michael@0 306 while (m/^U?0(\w*)-(.*)$/) {
michael@0 307 # Concatenate .\uNNNN
michael@0 308 $key = "$key\\u$1";
michael@0 309 $_ = $2;
michael@0 310 }
michael@0 311
michael@0 312 $_ = $entry->getAttribute("form"); # "Form"
michael@0 313 $key = "$key.$_";
michael@0 314
michael@0 315 # 3.2) build the array
michael@0 316 @value = ();
michael@0 317 $value[0] = lc($entry->getAttribute("description"));
michael@0 318 $value[1] = $entry->getAttribute("lspace");
michael@0 319 if ($value[1] eq "") { $value[1] = "5"; }
michael@0 320 $value[2] = $entry->getAttribute("rspace");
michael@0 321 if ($value[2] eq "") { $value[2] = "5"; }
michael@0 322 $value[3] = $entry->getAttribute("minsize");
michael@0 323 if ($value[3] eq "") { $value[3] = "1"; }
michael@0 324
michael@0 325 $_ = $entry->getAttribute("properties");
michael@0 326 $value[4] = (m/^(.*)largeop(.*)$/);
michael@0 327 $value[5] = (m/^(.*)movablelimits(.*)$/);
michael@0 328 $value[6] = (m/^(.*)stretchy(.*)$/);
michael@0 329 $value[7] = (m/^(.*)separator(.*)$/);
michael@0 330 $value[8] = (m/^(.*)accent(.*)$/);
michael@0 331 $value[9] = (m/^(.*)fence(.*)$/);
michael@0 332 $value[10] = (m/^(.*)symmetric(.*)$/);
michael@0 333 $value[15] = (m/^(.*)mirrorable(.*)$/);
michael@0 334 $value[11] = $entry->getAttribute("priority");
michael@0 335 $value[12] = $entry->getAttribute("linebreakstyle");
michael@0 336
michael@0 337 # not stored in the WG dictionary
michael@0 338 $value[13] = ""; # direction
michael@0 339 $value[14] = ""; # integral
michael@0 340
michael@0 341 # 3.3) save the key and value
michael@0 342 push(@wg_keys, $key);
michael@0 343 $wg_hash{$key} = [ @value ];
michael@0 344 }
michael@0 345 @wg_keys = reverse(@wg_keys);
michael@0 346
michael@0 347 ################################################################################
michael@0 348 # 4) Compare the two dictionaries and output the result
michael@0 349
michael@0 350 print "comparing dictionaries...\n";
michael@0 351 open($file_differences, ">$FILE_DIFFERENCES") ||
michael@0 352 die ("Couldn't open $FILE_DIFFERENCES!");
michael@0 353 open($file_new_dictionary, ">$FILE_NEW_DICTIONARY") ||
michael@0 354 die ("Couldn't open $FILE_NEW_DICTIONARY!");
michael@0 355
michael@0 356 $conflicting = 0; $conflicting_stretching = 0;
michael@0 357 $new = 0; $new_stretching = 0;
michael@0 358 $obsolete = 0; $obsolete_stretching = 0;
michael@0 359 $unchanged = 0;
michael@0 360
michael@0 361 # 4.1) look to the entries of the WG dictionary
michael@0 362 while ($key = pop(@wg_keys)) {
michael@0 363
michael@0 364 @wg = @{ $wg_hash{$key} };
michael@0 365 delete $wg_hash{$key};
michael@0 366 $wg_value = &generateCommon(@wg);
michael@0 367
michael@0 368 if (exists($moz_hash{$key})) {
michael@0 369 # entry is in both dictionary
michael@0 370 @moz = @{ $moz_hash{$key} };
michael@0 371 delete $moz_hash{$key};
michael@0 372 $moz_value = &generateCommon(@moz);
michael@0 373 if ($moz_value ne $wg_value) {
michael@0 374 # conflicting entry
michael@0 375 print $file_differences "[conflict]";
michael@0 376 $conflicting++;
michael@0 377 if ($moz[6] != $wg[6]) {
michael@0 378 print $file_differences "[stretching]";
michael@0 379 $conflicting_stretching++;
michael@0 380 }
michael@0 381 print $file_differences " - $key ($wg[0])\n";
michael@0 382 print $file_differences "-$moz_value\n+$wg_value\n\n";
michael@0 383 $_ = &completeCommon($wg_value, $key, @moz, @wg);
michael@0 384 print $file_new_dictionary $_;
michael@0 385 } else {
michael@0 386 # unchanged entry
michael@0 387 $unchanged++;
michael@0 388 $_ = &completeCommon($wg_value, $key, @moz, @wg);
michael@0 389 print $file_new_dictionary $_;
michael@0 390 }
michael@0 391 } else {
michael@0 392 # we don't have this entry in our dictionary yet
michael@0 393 print $file_differences "[new entry]";
michael@0 394 $new++;
michael@0 395 if ($wg[6]) {
michael@0 396 print $file_differences "[stretching]";
michael@0 397 $new_stretching++;
michael@0 398 }
michael@0 399 print $file_differences " - $key ($wg[0])\n";
michael@0 400 print $file_differences "-\n+$wg_value\n\n";
michael@0 401 $_ = &completeCommon($wg_value, $key, (), @wg);
michael@0 402 print $file_new_dictionary $_;
michael@0 403 }
michael@0 404 }
michael@0 405
michael@0 406 print $file_new_dictionary
michael@0 407 "\n# Entries below are not part of the official MathML dictionary\n\n";
michael@0 408 # 4.2) look in our dictionary the remaining entries
michael@0 409 @moz_keys = (keys %moz_hash);
michael@0 410 @moz_keys = reverse(sort(@moz_keys));
michael@0 411
michael@0 412 while ($key = pop(@moz_keys)) {
michael@0 413 @moz = @{ $moz_hash{$key} };
michael@0 414 $moz_value = &generateCommon(@moz);
michael@0 415 print $file_differences "[obsolete entry]";
michael@0 416 $obsolete++;
michael@0 417 if ($moz[6]) {
michael@0 418 print $file_differences "[stretching]";
michael@0 419 $obsolete_stretching++;
michael@0 420 }
michael@0 421 print $file_differences " - $key ($moz[0])\n";
michael@0 422 print $file_differences "-$moz_value\n+\n\n";
michael@0 423 $_ = &completeCommon($moz_value, $key, (), @moz);
michael@0 424 print $file_new_dictionary $_;
michael@0 425 }
michael@0 426
michael@0 427 close($file_differences);
michael@0 428 close($file_new_dictionary);
michael@0 429
michael@0 430 print "\n";
michael@0 431 print "- $obsolete obsolete entries ";
michael@0 432 print "($obsolete_stretching of them are related to stretching)\n";
michael@0 433 print "- $unchanged unchanged entries\n";
michael@0 434 print "- $conflicting conflicting entries ";
michael@0 435 print "($conflicting_stretching of them are related to stretching)\n";
michael@0 436 print "- $new new entries ";
michael@0 437 print "($new_stretching of them are related to stretching)\n";
michael@0 438 print "\nSee output files $FILE_DIFFERENCES and $FILE_NEW_DICTIONARY.\n\n";
michael@0 439 print "After having modified the dictionary, please run";
michael@0 440 print "./updateOperatorDictionary check\n\n";
michael@0 441 exit 0;
michael@0 442
michael@0 443 ################################################################################
michael@0 444 sub usage {
michael@0 445 # display the accepted command syntax and quit
michael@0 446 print "usage:\n";
michael@0 447 print " ./updateOperatorDictionary.pl download [unicode.xml]\n";
michael@0 448 print " ./updateOperatorDictionary.pl compare [dictionary.xml]\n";
michael@0 449 print " ./updateOperatorDictionary.pl check\n";
michael@0 450 print " ./updateOperatorDictionary.pl make-js\n";
michael@0 451 print " ./updateOperatorDictionary.pl clean\n";
michael@0 452 exit 0;
michael@0 453 }
michael@0 454
michael@0 455 sub generateCommon {
michael@0 456 # helper function to generate the string of data shared by both dictionaries
michael@0 457 my(@v) = @_;
michael@0 458 $entry = "lspace:$v[1] rspace:$v[2]";
michael@0 459 if ($v[3] ne "1") { $entry = "$entry minsize:$v[3]"; }
michael@0 460 if ($v[4]) { $entry = "$entry largeop"; }
michael@0 461 if ($v[5]) { $entry = "$entry movablelimits"; }
michael@0 462 if ($v[6]) { $entry = "$entry stretchy"; }
michael@0 463 if ($v[7]) { $entry = "$entry separator"; }
michael@0 464 if ($v[8]) { $entry = "$entry accent"; }
michael@0 465 if ($v[9]) { $entry = "$entry fence"; }
michael@0 466 if ($v[10]) { $entry = "$entry symmetric"; }
michael@0 467 if ($v[15]) { $entry = "$entry mirrorable"; }
michael@0 468 return $entry;
michael@0 469 }
michael@0 470
michael@0 471 sub completeCommon {
michael@0 472 # helper to add key and private data to generateCommon
michael@0 473 my($entry, $key, @v_moz, @v_wg) = @_;
michael@0 474
michael@0 475 $entry = "$key = $entry";
michael@0 476
michael@0 477 if ($v_moz[13]) { $entry = "$entry direction:$v_moz[13]"; }
michael@0 478 if ($v_moz[14]) { $entry = "$entry integral"; }
michael@0 479 if ($v_moz[15]) { $entry = "$entry mirrorable"; }
michael@0 480
michael@0 481 if ($v_moz[0]) {
michael@0 482 # keep our previous comment
michael@0 483 $entry = "$entry # $v_moz[0]";
michael@0 484 } else {
michael@0 485 # otherwise use the description given by the WG
michael@0 486 $entry = "$entry # $v_wg[0]";
michael@0 487 }
michael@0 488
michael@0 489 $entry = "$entry\n";
michael@0 490 return $entry;
michael@0 491 }
michael@0 492
michael@0 493 sub generateEntry {
michael@0 494 # helper function to generate an entry of our operator dictionary
michael@0 495 my($key, @moz) = @_;
michael@0 496 $entry = &generateCommon(@moz);
michael@0 497 $entry = &completeCommon($entry, $key, @moz, @moz);
michael@0 498 return $entry;
michael@0 499 }

mercurial