############################################################# ## ## This is the file mathinst.lib, part of the MathInst package ## (version 1.0, August, 1998) for math font ## generation. (Author: Alan Hoenig, ajhjj@cunyvm.cuny.edu) ## ############################################################# #!/usr/local/bin/perl ## This is a common file containing variables and common routines ## used by all Perl modules in the MathInst package. ## Begin by setting lots of environment-like variables. ## NONE of these should end with a backslash. $mathinstver_ = 1.0; ## Some misc constants and constructs ... $false = 0; # these are valid for numeric tests only. $true = 1; ## Now for some common routines. ## Let's get the date and time. ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $curmonth = (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec)[$mon]; $curday = (Sun, Mon, Tues, Wednes, Thurs, Fri, Satur)[$wday]; $mday = "0$mday" if $mday < 10; $curdate = "$mday $curmonth $year"; $today = $curdate; $hour = "0$hour" if $hour < 10; $min = "0$min" if $min < 10; $sec = "0$sec" if $sec < 10; $now = "$hour:$min:$sec"; ## Math font parameters... @mathinstmanifest = ( "mathinst", "mathinst.tex", "mathinst.lib", "map.a2d", "map.sup", "mt_ihax.mtx", "eu_ihax.mtx", "lu_ihax.mtx", "mt_iskew.mtx", "eu_iskew.mtx", "lu_iskew.mtx", "rhax.mtx", ); %mathid_ = ( mt => "m", eu => "e", cm => "c", lu => "l", ma => "a", ); %mathname_ = ( mt => "MathTime", eu => "Euler", cm => "Computer Modern", lu => "Lucida New Math", ma => "Mathematica", ); %mathxheights_ = ( mt => 464, eu => 459, cm => 431, lu => 530, ma => 452, ); %nfssencoding = ( t1 => "8t", ot1 => "7t", t1x => "9e", ti9 => "9d", ot1x => "9t", ot19 => "9o", ); %bold2nfss = ( b => "b", s => "sb", d => "db", ); %reg2nfss = ( r => "m", k => "bk", l => "l", m => "md", ); %ital2nfss = ( o => "sl", i => "it", ); ############################################################################## ## ## MATHTIME ## ############################################################################## @mt_manifest = ( "MTSY.etx", "MTMI.etx", "OMLmt.etx", "OMLmts.etx", "OMLmtss.etx", "OMSmt.etx", "OMSmts.etx", "OMSmtss.etx", "OMXmt.etx", "OT1s.etx", "OT1ss.etx", "accsoff.mtx", "alphoff.mtx", "newmtsy.mtx", "newrmtmi.mtx", "newmtex.mtx", "noslash.mtx", "numoff.mtx", "regreek.mtx", "unfake.mtx", "xdotless.mtx", ); ## In all arrays storing font name info for math font families, ## the first two elements contain supplier and typeface info for ## use by TDS (ignored totally by traditional systems). The remaining ## elements contain raw font names. @mt_fonts = ( $masup_, $matyp_, # math fonts---supplier and typeface "RMTMI", # the math italic "MTSY", # the math symbols "MTEX", # math extension (large operator) font ); if ($mathfam_ eq "mt") { %comment = ( accsoff => "unsets accents, operators, and uppercase Greeks", alphoff => "unsets alphabets (U&l/c) and some metric parameters", dotlessj => "constructs a virtual dotless j", newmtsy => "renames some glyphs in conformance with 8r", newrmtmi => "renames some glyphs in conformance with 8r", newmtex => "renames some glyphs in conformance with 8r", noslash => "unsets glyphs `less', `equal', `slash'; get from MathTime", numoff => "discards digits", regreek => "constructs Greek uppercase letters", unfake => "declares some math glyphs unfakable", xdotless => "discards dotless i and j", mymathit => "MathTime math italic characters", mymathsy => "MathTime math symbols characters", mymathex => "MathTime math extension (large symbols) glyphs", ); } ## Here is some special purpose stuff that needs to be added to ## the beginning of the installation file. $mt_prelude_ = <<"End_mt_prelude"; \\declareencoding{MTEX}{OMX} \\declareencoding{MTSY}{MTSY} \\declareencoding{MTMI}{MTMI} \\pltomtx{MTEX}{mymathex} \\pltomtx{MTSY}{mymathsy} \\pltomtx{RMTMI}{mymathit} %% \\pltomtx{cmmi10}{cmmi10} %% \\pltomtx{cmmi7}{cmmi7} %% \\pltomtx{cmmi5}{cmmi5} End_mt_prelude ############################################################################## ## ## EULER ## ############################################################################## @eu_manifest = ( "euex.etx", "eufm.etx", "eurm.etx", "OMSeu.etx", "OMSeus.etx", "OMSeuss.etx", "OT1eu.etx", "OT1eus.etx", "OT1euss.etx", "eusm.etx", "dotlessj.mtx", "notequal.mtx", "numoff.mtx", "ucgrkoff.mtx", "upsilon.mtx", ); @eu_fonts = ( $masup_, $matyp_, # math fonts---supplier and typeface "eurm", # math `roman' "eusm", # math symbols "euex", # math large symbols "eufm", # fraktur "eurb", # `roman' bold ); if ($mathfam_ eq "eu") { %comment = ( dotlessj => "creates a virtual dotless j", notequal => "discards equal, asterisk, and plus", numoff => "discards digits", ucgrkoff => "discards U/C Greek letters", upsilon => "renames the upsilon letter properly", ); } ## Here is some special purpose stuff that needs to be added to ## the beginning of the installation file. $eu_prelude_ = <<"End_eu_prelude"; \\declareencoding{TEX MATH ITALIC SUBSET}{eurm} \\declareencoding{TEX MATH SYMBOLS SUBSET}{eusm} \\declareencoding{TEX TEXT SUBSET}{eufm} \\declareencoding{EULER SUBSTITUTIONS ONLY}{euex} \\pltomtx{euex10}{euex10} \\pltomtx{eurm10}{eurm10} \\pltomtx{eurm7}{eurm7} \\pltomtx{eurm5}{eurm5} \\pltomtx{eufm10}{eufm10} \\pltomtx{eufm7}{eufm7} \\pltomtx{eufm5}{eufm5} \\pltomtx{eusm10}{eusm10} \\pltomtx{eusm7}{eusm7} \\pltomtx{eusm5}{eusm5} End_eu_prelude ############################################################################## ## ## LUCIDA ## ############################################################################## @lu_manifest = ( "lbmo.etx", "lbma.etx", "lbms.etx", "lbme.etx", "OMXlu.etx", "OMLluss.etx", "OMLlus.etx", "OMSlu.etx", "OMSlus.etx", "OMSluss.etx", "OT1lus.etx", "OT1luss.etx", "alphoff.mtx", "newlbme.mtx", "newlbmo.mtx", "newlbms.mtx", "notequa.mtx", "numoff.mtx", "ucgrkoff.mtx", "upsilon.mtx", ); @lu_fonts = ( $masup_, $matyp_, # math fonts---supplier and typeface "lbmo", "lbms", "lbme", ); if ($mathfam_ eq "lu") { %comment = ( lbme => "Lucida New Math large symbols", lbms => "Lucida New Math math symbols", lbmo => "Lucida New Math italics", dotlessj => "virtually crafts the dotless j", newlbme => "renames Lucida large symbols to OT1 standard", newlbms => "renames Lucida symbols to OT1 standard", newlbmo => "renames Lucida italic characters to OT1 standard", ucgrkoff => "unsets eppercase Greek letters", upsilon => "renames the upsilon letter properly", notequa => "unsets equal and plus signs", alphoff => "unsets alphabets (U&l/c) and some metric parameters", ); } $lu_prelude_ = <<"End_lu_prelude"; \\declareencoding{TEX MATH ITALIC}{lbmo} \\declareencoding{TEX MATH SYMBOLS}{lbms} \\declareencoding{LUCIDA MATH EXTENSION}{lbme} \\declareencoding{LUCIDA MATH ARROWS}{lbma} \\pltomtx{lbmo}{lbmo} \\pltomtx{lbms}{lbms} \\pltomtx{lbme}{lbme} End_lu_prelude ############################################################################## ## ## MATHEMATICA ## ############################################################################## @ma_manifest = ( "dotlessj.mtx", "newxht.mtx", "nodotles.mtx", "notequal.mtx", "ucgrkoff.mtx", "unfake.mtx", ); ## In all arrays storing font name info for math font families, ## the first two elements contain supplier and typeface info for ## use by TDS (ignored totally by traditional systems). The remaining ## elements contain raw font names. @ma_fonts = ( $masup_, $matyp_, # math fonts---supplier and typeface "mmami", # the math italic "mmasy", # the math symbols "mmaex", # math extension (large operator) font ); if ($mathfam_ eq "ma") { %comment = ( dotlessj => "constructs a virtual dotless j", mmaex => "Mathematica math extension (large symbols) glyphs", mmami => "Mathematica math italic characters", mmasy => "Mathematica math symbols characters", newxht => "restores proper x-height to math italic font", nodotles => "throws Mathematica's dotless i away!", notequal => "discards equal, asterisk, and plus", ucgrkoff => "discards U/C Greek letters", unfake => "declares some math glyphs unfakable", ); } ## Here is some special purpose stuff that needs to be added to ## the beginning of the installation file. $ma_prelude_ = <<"End_ma_prelude"; \\declareencoding{mmaex}{OMX} \\declareencoding{mmasy}{OMS} \\declareencoding{mmami}{OML} \\pltomtx{mmaex}{mmaex} \\pltomtx{mmasy}{mmasy} \\pltomtx{mmami}{mmami} End_ma_prelude ############################################################################## ## ## COMMON MATERIAL FOLLOWS NOW... ## ############################################################################## ## VARIOUS COMMON SUBROUTINES sub pv{# print variable name and value; eg &pv(font); local($tmp) = $_[0]; local($var) = $$tmp; print "\[\$$tmp = $var\] "; } sub mpv{ # print multiple variable values foreach $var (@_) { &pv($var); } print "\n"; } sub scale{# divides two numbers, multiplies by 1000, and int's it. local($temp) = 1000 * $_[0]/$_[1] + 0.5; int($temp); } sub smul{# scaled multiplication local($temp) = $_[0]/1000 * $_[1]; int($temp); } sub isTDS{ defined($texmf_); } sub isfile{ -e $_[0]; } sub isfileorlink{ -e $_[0] or -l $_[0]; } sub isdir{ -d $_[0]; } sub isvariable{ defined($_[0]); } sub iscmfont{# is a fontname a Computer Modern font? $_[0] =~ /^cm/i; } sub wlog{# write to a log file only print LOG "$_[0]\n"; } sub display{# print to console only print "$_[0]\n"; } sub dwlog{# display on console and write to log file &wlog($_[0]); &display($_[0]); } sub openlog{# open (LOG, ">$mathpkg_.mlg"); &dwlog ("This is MathInst$mathinstver_ + Perl$], ${curday}day, $curdate $now."); &dwlog("Called with options $mathfam_ and $fontfam_."); &dwlog("This is log file $mathpkg_.mlg."); } sub closelog{ close LOG; } sub copy{ die "`copy' can't find file $_[0]" unless -e $_[0]; open(IN, $_[0]); # the source open(OUT, ">$_[1]"); # the target while () {print OUT $_;} close OUT; } sub safecopy{# copy source to target ONLY if target doesn't exist if ((not -e $_[1]) and (not -e "..$sep$_[1]")) { # target doesn't exist ©(@_); } else { &display("Copy operation skipped; file $_[1] already exists."); } } ## Lines in map.sup look like this: ## a autologi Autologic ## b bitstrea Bitstream sub getTDSsupplier{ open (SUP, "..${sep}map.sup") or die "Where is supplier file map.sup?"; while () { next if /^\#/; # ignore comments last if /^$s/; # } ($s, $supplier, $suppliername) = split(/\s+/, $_, 3); $supplier; } ## Lines in map.a2d look like ## ac acaslon ## ad agaramon ## We don't load in the whole file as a hash in case this unduly ## overloads certain systems. sub getTDStypeface{ open(ATOD, "..${sep}map.a2d") or die "Cannot open map.a2d"; $directory = "unknown"; $upperbound = $typefam; $upperbound++; $lowerbound = $typefam; while () { next if /^\#/; # ignore comments chomp $_; last if $_ gt $upperbound; next if $_ lt $lowerbound; ($abb, $dir) = split(/ /, $_, 2); last if $abb eq $typefam; } close ATOD; $directory = $dir if $abb eq $typefam; if ($directory eq "unknown") { print "I couldn't figure out the directory for $fontfam_.\n"; print "Help me out by typing a directory name.>> "; $directory = ; chomp $directory; while ($directory eq "" or length $directory > 8) { print "$tmp is either too long or too short."; print "Enter another name please.>> "; $directory = ; chomp $directory; } } $directory; } ## This rtn takes the @missingdirlist and suggests a script for creating ## the missing directories, which are stored in @neededdirs. $mkdir="mkdir"; # system dependent open(SCRIPT, ">mkdirs.bat"); sub makemkdirs{ foreach $miss (@missingdirlist) { # check each missing path $misss = "$miss$sep"; $Sep = $sep; $Sep = "\\\\" if $sep eq "\\"; # special case for DOS while ($misss =~ m/$Sep/g) { if (($know_about{$`} == $false) and (not -d $`)) { print SCRIPT "$mkdir $`\n" unless $` eq ""; $know_about{$`} = $true; } } } undef %know_about; # preserve resources } sub verifydir{ if (not &isdir($_[0])) { $missingdirs++; push(@missingdirlist,$_[0]); } } sub verifydirs{ local($missingdirs)=0; foreach $directory (@_) { &verifydir($directory); } if ($missingdirs == 0) { &display("All directories in place."); } else { # something rotten... &dwlog("Pardon me. Some directories are not present:"); foreach $directory (@missingdirlist) { &dwlog(" $directory"); } &dwlog("Use `mkdirs' to create them, and rerun your installation."); &makemkdirs; # here's a script for missing directories &dwlog("Use the `mkdirs' script to create them."); } } sub checkinstallation{# checks that a file list exists in PARENT dir local($missing, @missinglist, @presentlist); $missing = $false; foreach $i (@_) { if (&isfile("..${sep}$i") == $false) { $missing = $true; push(@missinglist, $i); } else { push(@presentlist, $i); } } local($misslist) = join("\n",@missinglist); local($preslist) = join("\n ",@presentlist); &wlog("The files "); &wlog(" $preslist"); &wlog("properly located."); &dwlog("Can't find \n $misslist \nfiles...$!") if $missing; } ## Problem: bold face weights can be in any of several flavors--- ## bold (b), semibold (s), or demibold (d)---and we don't which we have. ## We have to test for all of them, stopping as soon as we find something. ## Similarly for roman-like fonts, which can actually be regular (r), ## book (k), medium (m), or light (l). ## The following tiny routine helps make this testing faster. sub testforfontflavor{ local($b) = $_[0]; $encvariant = "$lc_encoding_$famvariant"; $nfssvar = $nfssencoding{$encvariant}; $fullfontname = "$vf_${sep}$fontfam_$_[0]$nfssvar\.vf"; $flavor = $b if -e $fullfontname; if ($flavor) { # test for matching italic... TYPE_SEARCH: foreach $italic_type ("i", "o") { $rit = $italic_type if -e "$vf_${sep}$fontfam_$flavor$italic_type$nfssvar\.vf"; last TYPE_SEARCH if -e "$vf_${sep}$fontfam_$flavor$italic_type$nfssvar\.vf"; } } } sub letterheight{# gets the height of the argument local($ascii) = ord($_[0]); # the Ascii code of the glyph $_[0] ## assumes the AFM file has previously been opened while () {last if /C\s+$ascii\s;\s/;}# seeking the glyph $_ =~ /[A-Za-z0-9\s]+;[A-Za-z0-9\s]+;[A-Za-z0-9\s]+;\sB\s[-0-9]+\s[-0-9]+\s[0-9]+\s([0-9]+)\s;/; $1; } ## This next routines verifies that some text fonts exist (at least ## that their virtual fonts do) and extracts some metric info re the ## heights of letters. (The scaling factors for later use by the ## math fonts is determined here.) sub verifytextfont{ # eg., &verifytextfont("Roman", "r") $encvariant = "$lc_encoding_$famvariant"; $nfssvar = $nfssencoding{$encvariant}; $fullfontname = "$vf_${sep}$fontfam_$_[1]$nfssvar\.vf"; if (&isfileorlink($fullfontname)) { &display(" Font $fullfontname: found."); } else { # font is missing! &display(" Missing $_[0] $fullfontname ...$!"); push (@missingfonts, $fullfontname); } } sub verifytextfonts{ local($var) = "r i";# will ident the weights/shapes of fonts local($curfont, $fullfontname); ## $foundfile contains the full path and name of the fd file. It was ## set by the calling routine &DoIt in file 'mathinst'. ## We read this file and examine the first \DeclareFontShape command ## in order to learn the default series. This is usually 'm' ## (medium), but can be something else. In ITC Garamond,eg, it is ## 'bk' (book). if ($foundfile) { open (TMP, $foundfile) || die "Where is $foundfile?"; while ($_=) { next unless /\\DeclareFontShape/; $_=~ /\\DeclareFontShape{.*T1}{[a-zA-Z0-9]+}{([a-z]+)}{([a-z]+)}/; $thisseries=$1; $thisshape=$2; last; } close TMP; } &dwlog("\nNow verifying text fonts:"); undef $flavor; # initialize variable foreach $variant ("r", "k", "m", "l") { &testforfontflavor($variant); last if $flavor; } # We also need the italic variant---italic (usually) or oblique. if ($flavor) { $rreg=$flavor; &verifytextfont("Roman", "$flavor"); &verifytextfont("Italic", "${flavor}$rit"); } else { # font is missing! &dwlog(" ROMAN-like fonts are all MISSING. Find them!"); push (@missingfonts, "Roman"); } ## Now for bold fonts... undef $flavor; foreach $variant ("s", "b", "d") { &testforfontflavor($variant); last if $flavor; } if ($flavor) { $rbold=$flavor; # save this variant for later use... &verifytextfont("bold ($flavor)", $rbold); &verifytextfont("bold italic(${rbold}$rit)", "${rbold}$rit"); } else { # font is missing... &display(" BOLD-like fonts are all MISSING. Find them!"); push (@missingfonts, "Bold"); } if (defined @missingfonts) { &dwlog("\nThe following missing fonts NEED to be present:"); $tmp = " ".join("\n ", @missingfonts); &dwlog("$tmp"); &dwlog("You may wish to find them and run me again.\n"); } $nfssbold = $bold2nfss{$rbold}; &dwlog("Something wrong with the bold weight $rbold...") unless $nfssbold; &dwlog("My default NFSS weight for these fonts is $nfssbold.") if $flavor ne "b"; ## Let's get some metric info we need from the roman .afm file. local($afmfile) = "$afm_${sep}${fontfam_}${rreg}8a.afm"; if (&isfile($afmfile)) {# get some font info # we can't rely on the `xheight' info at the top of file, since # sometimes, as in the Bitstream fonts, these values are wrong. open(AFM, $afmfile) || die "Cannot open the file $afmfile. Help..."; $capheight = &letterheight("B"); $xheight = &letterheight("x"); close AFM; &dwlog("\nText font cap height: $capheight units."); &dwlog("Text font x-height: $xheight units."); $textSF7 = &scale($ssize_, 7); $textSF5 = &scale($sssize_, 5); &dwlog("Text font scale factors:"); &dwlog(" script: $textSF7"); &dwlog(" sscript: $textSF5"); } else { &dwlog("I can't find afm file $afmfile, and I desperately need help."); } } sub verifymathfonts{# verify that math fonts are in place local($mathname) = $mathname_{$mathfam_}; $mathxheight = $mathxheights_{$mathfam_}; local($fontlist) = "${mathfam_}fonts"; &dwlog("\nNow verifying math fonts:"); foreach $i (2.. $#$fontlist) { if (&isfileorlink("$tfm_${sep}$$fontlist[$i].tfm")) { &dwlog(" Math font: $$fontlist[$i] found."); } else { # font missing &dwlog(" Math font $$fontlist[$i] MISSING!!"); &dwlog(" Please find and re-run me!!!"); } } $mathSF_ = &scale($xheight, $mathxheight) unless &isvariable($mathSF_); $mathSF7 = &smul($textSF7, $mathSF_); $mathSF5 = &smul($textSF5, $mathSF_); &dwlog("Math font scale factors:"); &dwlog(" text: $mathSF_"); &dwlog(" script: $mathSF7"); &dwlog(" sscript: $mathSF5"); } ## FOR SPECIAL FONTS: USERS ARE NOT ONLY RESPONSIBLE FOR PROPER NAMING ## THESE FONTS, BUT ALSO FOR PLACING THEM IN PROPER DIRECTORIES IN TDS ## SYSTEMS. THE SUPPLIER AND TYPEFACE DIRECTORIES SHOULD BE STORED, EG, ## IN VARIABLES LIKE $ttsup_ AND $tttyp_. ## The purpose of `verification' is basically to get the x-height of the ## font from which to compute the scaling factor. As a side purpose, ## we need to make sure that the font is placed where it's supposed to ## be. If the font is a bitmap, we don't scale it at all. ## ## If the font is an `8r' font (ie, it's name ends in 8r), we look to make ## sure the corresponding `8a' afm file exists, and then read it for the ## x-heght. If it's not 8r, we check that an afm with the identical ## font name exists. If it doesn't we assume it's a bitmap. ## ## Routine `verifyspecialfont' tkes 5 parameters---a string designating ## the font type, the font name, a field to store the height of a given ## special character, the special character whose height we want (usually ## an `x'), and the variable to hold the new scale factor. The font types ## should be drawn from this list: ## tt (typewriter) ## ss (sans serif) ## ca (calligraphy) ## fr (fraktur) ## bb (blackboard bold) ## gb (Greek bold) $specialfonttypes = "tt ss ca fr bb gb"; ## The special font is assumed installed according to ## the Berry fontnaming scheme. ## &verifyspecialfont("sans",$sansserif_, "x") ## IT'S THE USERS RESPONSIBILITY TO MAKE SURE NAMING, INSTALLATION, ## ETC. FOLLOW THE FONTNAME2.1 CONVENTIONS!!!! Caveat user! sub deduce_rawfont_from{ local($rawfont) = $_[0]; if ($rawfont =~ /(7t|8t|9e|9d|9t|9o)$/) { substr($rawfont,-2,2) = "8r"; } $rawfont; } sub checkmapfileforafmentry{ local($font) = $_[0]; local($mapfilepluspath) = "$map_${sep}psfonts.map"; open (MAP, $mapfilepluspath) or die "Where the heck is $mapfilepluspath?"; while () { $font_is_scalable = $true; last if /$font\s+/; $font_is_scalable = $false; } close MAP; } ## The routine makeafmtest checks to see that both an afm file exists ## for a special file _and_ that an entry exists for it in the map ## file. If possible, it computes $specxheight as the height of $char. sub makeafmtest{ $rawfont = &deduce_rawfont_from($font); if ($typestyle eq "ss") { # special treatment for sans serif, ## since raw sans serif fonts may contain an `s' variant if (&isfile($pathplusafm)) { # don't make any revisions } else { # try these instead... $pathplusafm =~ s/8a\.afm/s8a\.afm/; $rawfont =~ s/r8r/rs8r/; } } if (&isfile($pathplusafm)) { # afm file exists &checkmapfileforafmentry($rawfont); # entry exist in psfonts.map? if ($font_is_scalable) { $rawfont =~ s/8r/8a/; # points now to un-reencoded font open(AFM, "$pathplusafm") or die "Can't open afm file $pathplusafm."; $specxheight = &letterheight($char); close AFM; } } else { # no afm file $specSF_ = 1000; } } sub deduce_afmname_from{ local($font) = $_[0]; local($afm) = $font; # default for bitmap and 8a fonts if ($afm =~ /8r/) { # an 8r font $afm =~ s/8r/8a/; } if ($afm =~ /(7t|8t|9e|9d|9t|9o)$/) { # for fontname fonts $afm = substr($font,0,4) . "8a"; } $afm; } sub verifyspecialfont{ $refheight = $xheight; local($typestyle, $font, $char) = @_; local($styleSFname) = "${typestyle}SF_"; while (not $specialfonttypes =~ /$typestyle/) { print "The font type $typestyle must be one of: "; print "$specialfonttypes\nPlease enter a font type>>> "; $typestyle = ; chomp $typestyle; } local($myafm_, $mytfm_) = ($afm_, $tfm_); $font_is_scalable = $false; undef $specSF_; undef $specxheight; if (&isTDS) { local($supname, $typname) = ("${typestyle}sup_", "${typestyle}typ_"); &dwlog( "WARNING ($supname): I need a TDS supplier directory for $typestyle.") unless $$supname; &dwlog( "WARNING ($typname): I need a TDS typeface directory for $typestyle.") unless $$typname; local($pathname) = "$$supname${sep}$$typname"; local($postfix) = "$pathname"; $myafm_ = "$texmf_${sep}fonts${sep}afm$sep$postfix"; $mytfm_ = "$texmf_${sep}fonts${sep}tfm$sep$postfix"; } ## Now to ascertain the nature of the font, and to verify the ## existence of the font for use by TeX. $afm = &deduce_afmname_from($font); if (not &isfile("$mytfm_$sep$font.tfm")) {# no tfm file---BAD NEWS &dwlog("Font $font NOT FOUND! Please install and run MathInst again."); } else { # font found---check for afm local($font_is_scalable) = $true; # just a guess... local($pathplusafm) = "$myafm_$sep$afm.afm"; &makeafmtest; } ## We need to save the tfm location for the calligraphic font. $ca_tfm_=$mytfm_ if $typestyle eq "ca"; $specSF_ = 1000 if $specSF_ == 0; if ($specxheight) { $specSF_ = &scale($refheight, $specxheight); $$styleSFname = $specSF_ unless $$styleSFname; &dwlog("$typestyle font $font scale factor: $$styleSFname."); } else {# for non-scalable font &dwlog("$typestyle font $font takes natural size."); $$styleSFname = 1000; } $refheight = $xheight; # reset the default } sub verifyspecialfonts{ ## Verify tt font... &verifyspecialfont("tt", $tt_, "x") if $tt_; &dwlog("No tt font being installed today.") if not $tt_; ## Blackboard bold... if ($bbold_) { $refheight = $capheight; &verifyspecialfont("bb", $bbold_, "B"); } else { &dwlog("No bboard bold font being installed today."); } ## the fraktur &verifyspecialfont("fr", $fraktur_, "x") if $fraktur_; &dwlog("No fraktur font being installed today.") if not $fraktur_; ## the sans serif &verifyspecialfont("ss",$sansserif_,"x") if $sansserif_; &dwlog("No sans serif fonts being installed today.") if not $sansserif_; ## the calligraphic if ($cal_) { $refheight = $xheight; &verifyspecialfont("ca",$cal_,"B"); ## Need to recompute SF because cal uses cap heights. $caSF7 = &smul($textSF7, $caSF_); $caSF5 = &smul($textSF5, $caSF_); &dwlog("Calligraphic font $cal_ scale factors:"); &dwlog(" text: $caSF_."); &dwlog(" script: $caSF7."); &dwlog(" sscript: $caSF5."); } else { &dwlog("No calligraphic font being installed today."); } ## Finally, uppercase greek font (used for bold math) if (&isvariable($greekbold_)) { &verifyspecialfont("gb", $greekbold_, "x"); $gbSF7 = &smul($textSF7, $gbSF_);# grb = Greek bold $gbSF5 = &smul($textSF5, $gbSF_); @gscale = ( " scaled $gbSF_", " scaled $gbSF7", " scaled $gbSF5", ); &dwlog("Greek bold font $greekbold_ scale factors:"); &dwlog(" text: $gbSF_."); &dwlog(" script: $gbSF7."); &dwlog(" sscript: $gbSF5."); } else { &dwlog("No Greek bold font being installed today."); } } $FH_ = "STDOUT"; # default value sub out{# same as Out, but no automatic \n foreach $str (@_){ print $FH_ $str; } } sub Out{ &out(@_, "\n"); } open(MAKEPL, ">makepl.bat"); print MAKEPL "echo \" \" >makepl.mlg\n"; # start things off ## makepl now needs two arguments---the source of the tfm file is the first, ## and the string giving the font name is the second. sub makepl{# some existing tfm fonts need a pl file #eg., &makepl($tfm_, "mbvr7t") print MAKEPL "echo \"$_[1]\" >> makepl.mlg\n"; print MAKEPL "tftopl $_[0]${sep}$_[1].tfm $_[1].pl >> makepl.mlg\n"; } $linelength = 75; # max chars on a line sub fancyout{ local($tmp) = "%" x $linelength; &Out($tmp); &Out("%%"); &Out("%% $_[0]"); &Out("%%"); &Out($tmp); } ## The format for each list of mtx files can have ## ``arguments''. A number $n$ surrounded by colons ## (eg, "this :1: is it") will have the colon'ed unit ## replaced by the appropirate argument in the called ## routine. (Note, though, the zeroth argument is ## the format string.) Names surrounded by angle ## brackets name the array that whose element is used ## at each font size. For ex, if ## $test = "This is test:1:", ## and we call ## &makemtxlist($test,$wt), ## then the text font file list becomes ## "This is $a[0] test$wt" ## while the script file list ## becomes ## "This is $a[1] test$wt" ## and so on. ## The addcomments routine is used by makemtxlist. It takes a key and a ## a line. If a hash yields a comments for the key, it is added to ## the line, padded to the right to make a line of length $linelength ## characters. sub addcomments{ local($key, $line) = @_; chomp $line; # get rid of newlines if any if ($comment{$key}) { local($comm) = $comment{$key}; local($lcomm, $lline) = (length($comm), length($line)); local($room) = $linelength - $lline; if ($lcomm > $room) { # no room on line for full comment! $comm = substr($comm, 0, $room); $lcomm = $room; } $line = $line . " " x ($room-$lcomm) . "$comm"; } $line .= "\n"; $_[1] = $line; } sub makemtxlist{ ## Some additional comments for makemath.tex... $comment{"${fontfam_}${rreg}$enc"} = "the Roman glyphs"; $comment{"${fontfam_}${rreg}$rit$enc"} = "the italic glyphs"; $comment{"${fontfam_}$rbold$enc"} = "the boldface glyphs"; $comment{"${fontfam_}rhax"} = "adjustments to the roman math fonts"; $comment{"${fontfam_}ihax"} = "adjustments to the italic math glyphs"; $comment{"${fontfam_}iskew"} = "adjustments to accents for math italics"; $comment{"${fontfam_}${rreg}8r"} ="reencoded font supplies some characters"; $comment{"$times_"} = "a raw Times Roman font" if $times_; $comment{"$greekbold_"} = "Greek boldface letters" if $greekbold_; $comment{"$cal_"} = "the calligraphic font" if $cal_; $comment{"${fontfam_}${rreg}8x"} = "the expert font contains oldstyle figs" if $expert; local($temp, $tmp); foreach $i (0 .. 2) { $mtxlist[$i] = $_[0]; foreach $j (1 .. $#_) {# deal with all fixed arguments $mtxlist[$i] =~ s/:$j:/$_[$j]/g; } $temp = $mtxlist[$i]; while ( $temp =~ /(<([A-Za-z0-9]+)>)/ ) {# are there angle-bracketed args? $tmp = eval "\$$2\[$i\]"; $temp =~ s/$1/$tmp/; } $temp =~ s/,/,\%\n /g; # make the list multiline $temp = "\%\n $temp\%\n ";# add initial and final newlines local(@pieces) = split(/\n/, $temp); $temp = ""; # initialize foreach $piece (@pieces) { $piece =~ /\s+([A-Za-z0-9]+)[ ,\%]+/; &addcomments($1, $piece); $temp .= "$piece"; } chomp $temp; $mtxlist[$i] = $temp; } } ## The fontinst install commands need encoding files. Sometimes, we'll ## use the defaults, but other times, we'll need special variations on ## the default. As an example, consider OML. If OML*.etx are not ## part of the manifest, we can assume the default is sufficient. On ## the other hand, if there are 2 members, say OMLs.etx and OMLss.etx, ## it is clear that we use OML for text, OMLs for script, and OMLss for ## scriptscript. If there are 3 members, OMLmt, OMLmts, and OMLmtss, ## then these 3 get applied to the text, script, and scriptscript ## fonts. We use the routine getetx to do the decision work for us. ## The results are stored in the array @etx_ (that is, $etx_[0], etc). ## Ex: &getetx("OML",*EUmanifest); sub getetx{ @etx_ = ($_[0], $_[0], $_[0]); # default values local(*tmp) = $_[1]; local(@temp); foreach $i (0 .. $#tmp) { if ($tmp[$i] =~ /$_[0]/) { $tmp[$i] =~ s/(.+)\.etx$/$1/; # strip off file extension push(@temp, $tmp[$i]); } } @temp = sort @temp; if ($#temp == 0) {# the case @temp has a single element @etx_ = ($temp[0], $temp[0], $temp[0]); } if ($#temp == 1) {# the case @temp has 2 members @etx_ = ($_[0],$temp[0], $temp[1]); } if ($#temp == 2) {# the case @temp has 3 members @etx_ = @temp; } } ## The get_special_tfm routine takes a short string like "ma", "tt", etc ## and determines the source. Use it as a function: ## $math_tfm_ = &get_special_tfm("ma"); sub get_special_tfm{ local($spec_sup_, $spec_typ_); local($spec_tfm_)=$tfm_; # default; non-TDS system if (&isTDS) { ($spec_sup_, $spec_typ_)=("$_[0]sup_", "$_[0]typ_"); $spec_tfm_= "$texmf_${sep}fonts${sep}tfm$sep$$spec_sup_$sep$$spec_typ_"; } $spec_tfm_; } sub make_mt_math{# make the MathTime install file ## Set up convenient variables... $tmp = "${mathfam_}_fonts"; ($mathital, $mathsym, $mathext) = @$tmp[2,3,4]; $reencodedfont = $fontfam_ . "${rreg}8r"; $rawfont = $fontfam_ . "${rreg}8a"; #$rreg = "r"; $wt = $rreg; # the font's weight $comment{"RMTMI"} = "MathTime raw math italic font"; $comment{"MTMI"} = "MathTime math italic font"; $comment{"MTSY"} = "MathTime math symbols font"; $comment{"MTEX"} = "MathTime math extension font"; $comment{"cmmi10"} = $comment{"cmmi7"} = $comment{"cmmi5"} = "Computer Modern math italic (for O/S figs)"; local(@myexp); # is an expert font available for oldstyle digits? $expert = $false; $expfont = "${fontfam_}r8x"; $pathplusexpfont = "$afm_${sep}$expfont.afm"; $expert = $true if &isfile($pathplusexpfont); $myexp[0] = $myexp[1] = $myexp[2] = ""; @myexp = ("$expfont","$expfont scaled $textSF7","$expfont scaled $textSF5") if $expert; $math_tfm_=&get_special_tfm("ma"); $gb_tfm_=&get_special_tfm("gb"); $ca_tfm_=&get_special_tfm("ca"); $expert_font=$false; # no expert Roman font (default value) $expert_font=$true if &isfile("$afm_${sep}${fontfam_}r8x.afm"); print MAKEPL "$cp $afm_${sep}${fontfam_}${rreg}8a.afm .\n"; # local copy print MAKEPL "$cp $afm_${sep}${fontfam_}${rreg}8x.afm .\n" # expert font if $expert_font; # if it exists... &makepl($math_tfm_, "$mathital"); &makepl($math_tfm_, "$mathsym"); &makepl($math_tfm_, "$mathext"); &makepl($tfm_, "${fontfam_}$wt${enc}"); &makepl($tfm_, "${fontfam_}${wt}$rit${enc}"); if ($expert) { ## &makepl($tfm_, "${fontfam_}${wt}8x"); } else { $cmtfmplace = $tfm_; # for traditional systems if (&isTDS) { $cmtfmplace = "$texmf_${sep}fonts${sep}tfm${sep}public${sep}cm"; } &makepl($cmtfmplace, "cmmi10"); &makepl($cmtfmplace, "cmmi7"); &makepl($cmtfmplace, "cmmi5"); } if (&isvariable($greekbold_)) { &makepl($gb_tfm_, "$greekbold_"); # pl for greek font &makepl($tfm_, "${fontfam_}$rbold${enc}"); # pl for matching bold } #&makepl($gb_tfm_, "${fontfam_}$rbold${enc}") if &isvariable($greekbold_); &makepl($ca_tfm_, $cal_) if $cal_; local(@mtxlist,$romanmtx,$boldmtx,$italicmtx,$symbolmtx); # the mtx lists @msize = (10,7,5); @mscale = (# math scale factors " scaled $mathSF_", " scaled $mathSF7", " scaled $mathSF5", ); @tscale = (# text scale factors "", " scaled $textSF7", " scaled $textSF5", ); @calscale = (# Calligraphic scaling info " scaled $caSF_", " scaled $caSF7", " scaled $caSF5", ); ## MATH EXTENSION $exmtx = "mymathex,newmtex"; ## MATH ROMAN $romanmtx = "${fontfam_}:1:${enc},accsoff,mymathit,"; $romanmtx .= "mymathsy,${fontfam_}rhax,regreek,"; $romanmtx .= "numoff,$times_," if &isvariable($times_); $romanmtx .= "unfake"; ## MATH BOLD (only if a greek bold font exists) $boldmtx = "${fontfam_}:1:${enc},accsoff,$greekbold_,"; $boldmtx .= "mymathit,mymathsy,"; $boldmtx .= "${fontfam_}rhax,unfake"; ## MATH ITALIC $italicmtx = "${fontfam_}iskew,mymathit,newrmtmi,alphoff,"; $italicmtx .= "${fontfam_}:1:$rit${enc},"; #$italicmtx .= "," if $expert; if ($expert) { # use expert fonts for oldstyle figs (preferable) $italicmtx .= ","; } else { # no choice---get OSF from cmmi $italicmtx .= "cmmi,"; } $italicmtx .= "mymathsy,dotlessj,${fontfam_}ihax"; ## MATH SYMBOL $symbolmtx = "mymathsy,newmtsy,${fontfam_}:1:8r,"; $symbolmtx = "${symbolmtx}alphoff,$cal_"; &makemakemath; } sub make_eu_math{ $tmp = "${mathfam_}_fonts"; ($mathital, $mathsym, $mathext, $mathfrak, $mathitalb) = @$tmp[2,3,4,5,6]; $comment{"euex10"} = "Euler large operators"; $comment{"cmex10"} = "Computer Modern large operators"; $comment{"eurm10"} = $comment{"eurm7"} = $comment{"eurm5"} = "Euler math `italic'"; $comment{"eusm10"} = $comment{"eusm7"} = $comment{"eusm5"} = "Euler math symbols"; $comment{"eufm10"} = $comment{"eufm7"} = $comment{"eufm5"} = "Euler math fraktur"; $comment{"eurb10"} = $comment{"eurb7"} = $comment{"eurb5"} = "Euler bold math `italic'"; $comment{"cmmi10"} = $comment{"cmmi7"} = $comment{"cmmi5"} = "Computer Modern math italic"; $comment{"cmsy10"} = $comment{"cmsy7"} = $comment{"cmsy5"} = "Computer Modern math symbols"; $comment{"cmr10"} = $comment{"cmr7"} = $comment{"cmr5"} = "Computer Modern Roman font"; $comment{"harpoons"}="renames harpoon characters"; $comment{"euexs"}="renames some ext glyphs to agree with OMX encoding"; $comment{"eusyms"}="renames some symbol glyphs to agree with OMS encoding"; $reencodedfont = $fontfam_ . "${rreg}8r"; $rawfont = $fontfam_ . "${rreg}8a"; $wt = $rreg; # the font's weight local(@myexp); # is an expert font available for oldstyle digits? $expert = $false; $expfont = $fontfam_ . "r8x"; $fullexpfont = "$afm_${sep}$expfont.afm"; $expert = $true if &isfile($fullexpfont); $myexp[0] = ""; $myexp[1] = ""; $myexp[2] = ""; $myexp[0] = "$expfont" if $expert == $true; $myexp[1] = "$expfont scaled $textSF7" if $expert == $true; $myexp[2] = "$expfont scaled $textSF5" if $expert == $true; &makepl($tfm_, "${fontfam_}$wt${enc}"); &makepl($tfm_, "${fontfam_}${wt}$rit${enc}"); ## we use $italb for Greek bold, no matter what was set in eu.par... $greekbold_ = $italb; &makepl($tfm_, "${fontfam_}$rbold${enc}") if $greekbold_; $cmtfmplace = $eutfmplace = $tfm_; # for traditional systems if (&isTDS) { $cmtfmplace = "$texmf_${sep}fonts${sep}tfm${sep}public${sep}cm"; $eutfmplace = "$texmf_${sep}fonts${sep}tfm${sep}ams${sep}euler"; } $savetfm_ = $tfm_; foreach $i ("10", "7", "5") { $tfm_ = $cmtfmplace; &makepl($tfm_, "cmr$i"); &makepl($tfm_, "cmmi$i"); &makepl($tfm_, "cmsy$i"); $tfm_=$eutfmplace; &makepl($tfm_, "eurm$i"); &makepl($tfm_, "eurb$i"); &makepl($tfm_, "eufm$i"); &makepl($tfm_, "eusm$i"); } $tfm_=$eutfmplace; &makepl($tfm_, "euex10"); $tfm_=$cmtfmplace; &makepl($tfm_, "cmex10"); $ca_tfm_=&get_special_tfm("ca"); &makepl($ca_tfm_, $cal_) if $cal_; $tfm_ = $savetfm_; # restore default (if any) local(@mtxlist,$romanmtx,$boldmtx,$italicmtx,$symbolmtx); # the mtx lists local(@msize) = (10,7,5); @mscale = (# math scale factors " scaled $mathSF_", " scaled $mathSF7", " scaled $mathSF5", ); @tscale = (# text scale factors "", " scaled $textSF7", " scaled $textSF5", ); @calscale = (# Calligraphic scaling info " scaled $calSF_", " scaled $calSF7", " scaled $calSF5", ); $exmtx = "$mathext,cmex,euexs"; ## MATH ROMAN $romanmtx = "${fontfam_}:1:${enc},dotlessj,notequal,ucgrkoff,"; $romanmtx = "${romanmtx}numoff,$mathital,upsilon,"; $romanmtx = "${romanmtx}cmr,${fontfam_}rhax"; ## MATH BOLD (only if a greek bold font exists) $boldmtx = "${fontfam_}:1:${enc},dotlessj,notequal,ucgrkoff,"; $boldmtx = "${boldmtx}numoff,$mathitalb,upsilon,"; $boldmtx = "${boldmtx}cmr,${fontfam_}rhax"; ## MATH ITALIC $italicmtx = "${fontfam_}iskew,$mathital,upsilon,"; $italicmtx = "${italicmtx}$mathfrak,cmmi,"; $italicmtx = "${italicmtx}harpoons,${fontfam_}ihax"; ## MATH SYMBOL $symbolmtx = "$mathsym,cmsy,eusyms"; &makemakemath; } sub make_lu_math{ ## Set up convenient variables... $tmp = "${mathfam_}_fonts"; ($mathital, $mathsym, $mathext) = @$tmp[2,3,4]; $reencodedfont = $fontfam_ . "${rreg}8r"; $rawfont = $fontfam_ . "${rreg}8a"; #$rreg = "r"; $wt = $rreg; # the font's weight local(@myexp); # is an expert font available for oldstyle digits? $expert = $false; $expfont = "${fontfam_}r8x"; $fullexpfont = "$afm_${sep}$expfont.afm"; $expert = $true if &isfile($fullexpfont); $myexp[0] = $myexp[1] = $myexp[2] = ""; @myexp = ("$expfont", "$expfont scaled $textSF7", "$expfont scaled $textSF5") if $expert; $math_tfm_=&get_special_tfm("ma"); $gb_tfm_=&get_special_tfm("gb"); &makepl($math_tfm_, "$mathext"); &makepl($math_tfm_, "$mathsym"); &makepl($math_tfm_, "$mathital"); &makepl($tfm_, "${fontfam_}$wt${enc}"); &makepl($tfm_, "${fontfam_}${wt}$rit${enc}"); &makepl($gb_tfm_, "${fontfam_}$rbold${enc}") if &isvariable($greekbold_); local(@mtxlist,$exmtx,$romanmtx,$boldmtx,$italicmtx,$symbolmtx); # the mtx lists local(@msize) = (10,7,5); @mscale = (# math scale factors " scaled $mathSF_", " scaled $mathSF7", " scaled $mathSF5", ); @tscale = (# text scale factors "", " scaled $textSF7", " scaled $textSF5", ); @calscale = (# Calligraphic scaling info " scaled $calSF_", " scaled $calSF7", " scaled $calSF5", ); ## MATH EXTENSION $exmtx = "$mathext,newlbme"; ## MATH ROMAN $romanmtx = "${fontfam_}:1:${enc},dotlessj,ucgrkoff,$mathext,"; $romanmtx .= "upsilon,notequa,$mathsym,newlbms,${fontfam_}rhax"; ## No Math Bold in Lucida... undef $greekbold_; # just in case... ## MATH ITALIC $italicmtx = "${fontfam_}iskew,$mathital,newlbmo,upsilon,alphoff,"; $italicmtx .= "${fontfam_}:1:$rit${enc},dotlessj,${fontfam_}ihax"; ## MATH SYMBOL $symbolmtx = "$mathsym,newlbms"; &makemakemath; } sub make_ma_math{# make the Mathematica install file ## Set up convenient variables... $tmp = "${mathfam_}_fonts"; ($mathital, $mathsym, $mathext) = @$tmp[2,3,4]; $reencodedfont = $fontfam_ . "${rreg}8r"; $rawfont = $fontfam_ . "${rreg}8a"; #$rreg = "r"; $wt = $rreg; # the font's weight local(@myexp); # is an expert font available for oldstyle digits? $expert = $false; $expfont = "${fontfam_}r8x"; $pathplusexpfont = "$afm_${sep}$expfont.afm"; $expert = $true if &isfile($pathplusexpfont); $myexp[0] = $myexp[1] = $myexp[2] = ""; @myexp = ("$expfont", "$expfont scaled $textSF7", "$expfont scaled $textSF5") if $expert; $math_tfm_=&get_special_tfm("ma"); $gb_tfm_=&get_special_tfm("gb"); $ca_tfm_=&get_special_tfm("ca"); $cm_tfm_=$tfm_; $cm_tfm_="$texmf_${sep}fonts${sep}tfm${sep}public${sep}cm" if &isTDS; &makepl($math_tfm_, "$mathital"); &makepl($math_tfm_, "$mathsym"); &makepl($math_tfm_, "$mathext"); &makepl($math_tfm_, "mmamio"); &makepl($cm_tfm_, "cmex10"); &makepl($tfm_, "${fontfam_}$wt${enc}"); &makepl($tfm_, "${fontfam_}${wt}$rit${enc}"); &makepl($tfm_, "${fontfam_}${wt}8x") if $expert; if (not $expert) { # if non-experts, pluck OSF from these fonts... &makepl($cm_tfm_, "cmmi10"); &makepl($cm_tfm_, "cmmi7"); &makepl($cm_tfm_, "cmmi5"); } if (&isvariable($greekbold_)) { &makepl($tfm_, "${fontfam_}$rbold${enc}"); &makepl($gb_tfm_, $greekbold_); &makepl($math_tfm_, "mmamib"); } &makepl($ca_tfm_, $cal_) if $cal_; local(@mtxlist,$romanmtx,$boldmtx,$italicmtx,$symbolmtx); # the mtx lists @msize = (10,7,5); # canonical math sizes @mscale = ( # math scale factors " scaled $mathSF_", " scaled $mathSF7", " scaled $mathSF5", ); @tscale = ( # text scale factors "", " scaled $textSF7", " scaled $textSF5", ); @calscale = ( # Calligraphic scaling info " scaled $caSF_", " scaled $caSF7", " scaled $caSF5", ); $comment{"mmamio"} = "obliqued math italic for UC Greek letters"; $comment{"cmex10"} = "get some symbols from CM large symbols font"; $comment{"cmmi10"} = $comment{"cmmi7"} = $comment{"cmmi5"} = "Computer Modern math italic (for O/S figs)"; $comment{"mma1"} = "need a few symbols from the raw Mathematica font"; $comment{"mmagrb"} = "Mathematica's bold greek letters"; $comment{"mmamib"} = "Mathematica's bold math italic"; ## MATH EXTENSION $exmtx = "mmaex,cmex10"; ## MATH ROMAN $romanmtx = "${fontfam_}:1:${enc},ucgrkoff,notequal,"; $romanmtx .= "mma1,mmami,${fontfam_}rhax,"; $romanmtx .= "numoff,$times_," if &isvariable($times_); $romanmtx .= "dotlessj,unfake"; ## MATH BOLD (only if a greek bold font exists) $boldmtx = "${fontfam_}:1:${enc},$greekbold_,"; $boldmtx .= "mmamib,"; $boldmtx .= "${fontfam_}rhax,unfake"; ## MATH ITALIC $italicmtx = "${fontfam_}iskew,mmami,nodotles,"; $italicmtx .= "${fontfam_}:1:$rit${enc},ucgrkoff,mmamio,"; $italicmtx .= "," if $expert; $italicmtx .= "cmmi," unless $expert; $italicmtx .= "newxht,dotlessj,${fontfam_}ihax"; ## MATH SYMBOL $symbolmtx = "mmasy,$cal_"; &makemakemath; } ## We include the possibility of 3 hooks. Anything to be added ## at the begining of the makemath file (after \input fontinst.sty ## but before the \installfonts command) should be stored in ## a variable called $prelude_. Anything to be included at the end ## of the file, after \endinstallfonts but before \bye, should ## be in a variable called $postlude_. If the extension font needs to ## be generated, create the variable $EX_ with the proper commands. ## If these variables don't exist, nothing will be done. sub makemakemath{ $FH_ = "MAKEMATH"; ## Prelims... &Out("%\&plain\n"); &fancyout("This is the file makemath.tex."); &Out(" "); &Out("% Created by MathInst$mathinstver_ on ${curday}day, $today, at $now."); &Out("THIS FILE MAY BE DELETED."); &Out("\n\\input fontinst.sty\n"); local($tmp, $curprelude); $tmp = "${mathfam_}_prelude_"; $curprelude = $$tmp; &Out($curprelude) if $curprelude; $tmp = "${mathfam_}_postlude_"; local($curpostlude) = $$tmp; ## We need a raw font for some operators, etc... &out("\\transformfont{$reencodedfont}{\\reencodefont{8r}"); &Out("{\\fromafm{$rawfont}}}"); if ($expert) { &Out("\\afmtomtx{${fontfam_}r8x}{${fontfam_}r8x}\n"); } &Out("\\installfonts"); ## MATH EXTENSION &fancyout("MATH EXTENSION"); &makemtxlist($exmtx); &getetx("OMX", *thismanifest); &Out(" \\installfamily{OMX}{$shortmathpkg_}{}"); &Out(" \\installfont{${fontfam_}$wt${mathid}7v}", "{$mtxlist[0]}{$etx_[0]}{OMX}{$shortmathpkg_}{m}{n}{}"); ## MATH ROMAN &makemtxlist($romanmtx,"$rreg"); &fancyout("MATH ROMAN"); &Out(" \\installfamily{$mathencoding_}{$shortmathpkg_}{}"); ## Math Roman 10pt (text size) &getetx($mathencoding_, *thismanifest); &Out(" \\installfont{${fontfam_}$wt${mathid}7t}", "{$mtxlist[0]}{$etx_[0]}", "{$mathencoding_}{$shortmathpkg_}{m}{n}{<8->}"); ## Math Roman 7pt (script size) &Out(" \\installfont{${fontfam_}$wt${mathid}7t7}", "{$mtxlist[1]}{$etx_[1]}", "{$mathencoding_}{$shortmathpkg_}{m}{n}{<6-8>}"); ## Math Roman 5pt (scriptscript size) &Out(" \\installfont{${fontfam_}$wt${mathid}7t5}", "{$mtxlist[2]}{$etx_[2]}", "{$mathencoding_}{$shortmathpkg_}{m}{n}{<-6>}"); ## MATH BOLD? Only if a greek uppercase font exists... if ($greekbold_) { &makemtxlist($boldmtx,$rbold); ## Math bold10pt (text size) &fancyout("MATH BOLD"); &Out(" \\installfont{${fontfam_}${rbold}${mathid}7t}", "{$mtxlist[0]}{$etx_[0]}{$mathencoding_}", "{$shortmathpkg_}{${nfssbold}}{n}{<8->}"); ## Math bold 7pt (script size) &Out(" \\installfont{${fontfam_}${rbold}${mathid}7t7}", "{$mtxlist[1]}", "{$etx_[1]}{$mathencoding_}{$shortmathpkg_}", "{${nfssbold}}{n}{<6-8>}"); ## Math bold 5pt (scriptscript size) &Out(" \\installfont{${fontfam_}${rbold}${mathid}7t5}", "{$mtxlist[2]}{$etx_[2]}", "{$mathencoding_}{$shortmathpkg_}{${nfssbold}}{n}{<-6>}"); } ## MATH ITALIC &makemtxlist($italicmtx,$rreg); &getetx("OML", *thismanifest); &fancyout("MATH ITALIC"); &Out("\\installfamily{OML}{$shortmathpkg_}{\\skewchar\\font=127}"); ## Math Italic 10pt &Out(" \\installfont{${fontfam_}$wt${mathid}7m}{$mtxlist[0]}", "{$etx_[0]}{OML}{$shortmathpkg_}", "{m}{it}{<8->}"); ## Math Italic 7pt &Out(" \\installfont{${fontfam_}$wt${mathid}7m7}", "{$mtxlist[1]}", "{$etx_[1]}{OML}{$shortmathpkg_}", "{m}{it}{<6-8>}"); ## Math Italic 5pt &Out(" \\installfont{${fontfam_}$wt${mathid}7m5}", "{$mtxlist[2]}", "{$etx_[2]}{OML}{$shortmathpkg_}", "{m}{it}{<-6>}"); ## MATH SYMBOL &fancyout("MATH SYMBOLS"); &makemtxlist($symbolmtx,$rreg); &getetx("OMS", *thismanifest); &Out("\\installfamily{OMS}{$shortmathpkg_}{\\skewchar\\font=48}"); ## Mathsymbol 10pt &Out(" \\installfont{${fontfam_}$wt${mathid}7y}", "{$mtxlist[0]}{$etx_[0]}{OMS}{$shortmathpkg_}{m}{n}{<8->}"); ## Mathsymbol 7pt &Out(" \\installfont{${fontfam_}$wt${mathid}7y7}", "{$mtxlist[1]}{$etx_[1]}{OMS}{$shortmathpkg_}{m}{n}{<6-8>}"); ## Mathsymbol 5pt &Out(" \\installfont{${fontfam_}$wt${mathid}7y5}", "{$mtxlist[2]}{$etx_[2]}{OMS}{$shortmathpkg_}{m}{n}{<-6>}\n", "\\endinstallfonts\n"); ## Winding down... &Out($curpostlude) if $curpostlude; &Out("\\bye"); } sub makevf{ $FH_ = "GETVF"; local($prefix) = "${fontfam_}${rreg}${mathid}7"; local($mlg) = " > makevf.mlg"; &Out("echo \"${prefix}\"v$mlg"); local($mlg) = " >> makevf.mlg"; &Out("vptovf ${prefix}v.vpl ${prefix}v.vf ${prefix}v.tfm$mlg\n"); foreach $i ("t", "m", "y") {# text, italic, symbols foreach $j ("", "7", "5") { &Out("echo \"$prefix$i$j\" $mlg"); &Out("vptovf $prefix$i$j.vpl $prefix$i$j.vf $prefix$i$j.tfm$mlg"); } &Out(""); } if ($greekbold_) {# greek bold math font? local($font_) = "${fontfam_}${rbold}${mathid}7t"; &Out("echo \"${font_}\"$mlg"); &Out("vptovf $font_.vpl $font_.vf $font_.tfm$mlg"); &Out("echo \"${font_}7\"$mlg"); &Out("vptovf ${font_}7.vpl ${font_}7.vf ${font_}7.tfm$mlg"); &Out("echo \"${font_}5\"$mlg"); &Out("vptovf ${font_}5.vpl ${font_}5.vf ${font_}5.tfm$mlg"); } } ## This routine reads an fd file and discards comments, the `\endinput' ## statement, and the `\ProvidesPackage' statement. It adds font scaling ## info specified as an argument to the routine into all ## `\DeclareFontShape' statements. One catch: scaling info may have ## been placed in the fd file by fontinst, so we want to catch this and ## replace it by our current scaling factor. sub get_fd_info_and_scale_it{ local($fdfile, $mysize) = @_; local($pathandfdfile) = "$inputs_${sep}$fdfile.fd"; open(FD, $pathandfdfile) or die "Can't find $pathandfdfile. Help"; while () { # skips comments and ProvidesPackage last if /\\DeclareFontFamily/; } &Out("\n%% Extracting font info from file $fdfile.fd..."); FDLINE: for (;;) { if ( $_ =~ /\[\d*\.\d+\]/ ) { # scaling factor found! $_ =~ s/\[\d*\.\d+\]/\[$mysize\]/g; } else { # no s.f. found s/(>\s*)([^<\s])/\1\[$mysize\] \2/g; # AH 21 Mar 97 } &out("$_") unless /^%/; # ignore comments last FDLINE if eof(FD); $_ = ; last FDLINE if /\\endinput/; } &Out("%% End of file $fdfile.fd.\n"); close FD; } ## Sometimes, we have a font name from which we want to deduce the ## fd file which describes it. This next routine helps. sub deduce_fdfile_from{ local($fam) = substr($_[0],0,3); local($fdname) = "${encoding_}$fam"; $fdname; } ## We often need the NFSS family from a font name. If it ends in 7t, 8t, ## 9e,9d, 9t, 90, then the first 3 chars are the family. Otherwise, ## replace all digits by nulls (cmtt10 --> cmtt) sub deduce_fontfam_from{ local($spfont) = $_[0]; local($fontfam); if ($spfont =~ /(7t|8t|9e|9d|9t|9o)$/) { # a fontname font $fontfam = substr($spfont,0,3); } else { # a bitmap font $fontfam = $spfont; $fontfam =~ s/\d+//; # eliminate all digits } $fontfam; } ## The plain macros use the next routine to get the four members ## (up, up italic, bold, bold italic) of the sansserif. sub deduce_family_members_from_font{ local($spfont) = $_[0]; local($r,$ri,$b,$bi,$fam,$end); local($tfmplace) = $tfm_; if ( $spfont =~ /(8a|8r|7t|8t|9e|9d|9t|9o)$/ ) { # a fontname font $fam = $`; chop $fam; $end = $&; $tfmplace = "$texmf_${sep}fonts${sep}tfm$sep$sssup_$sep$sstyp_" if &isTDS; $r = $spfont; $ri = "${fam}ro$&"; # default is oblique $ri = "${fam}ri$&" if -e "$tfmplace${sep}${fam}ri$&\.tfm"; $b = $r; $bi = $ri; # defaults: bold are same as regular $b = "${fam}b$&" if -e "$tfmplace${sep}${fam}b$&\.tfm"; $bi = "${fam}bi$&" if -e "$tfmplace${sep}${fam}bi$&\.tfm"; } else { # cm, bitmap font $fam = $spfont; $fam =~ s/(\d+)$//; $r = "$spfont"; $ri = "${fam}i$&"; $b = "${fam}b$&"; $bi = "${fam}bi$&"; } ($r, $ri, $b, $bi); } sub makelatexstyle{ $fontfamx_ = $fontfam_; $fontfamx_ = "${fontfam_}x" if &isfile("$inputs_/$mathencoding_${fontfam_}x.fd");# expert fonts? $stylefile = "z$_[0]$fontfam_.sty"; open(LTXSTY, ">$stylefile"); $FH_ = "LTXSTY"; &Out("%% Created by MathInst$mathinstver_ on $curday, $today at $now."); &Out("%% This is a LaTeX style file for MathTime + $fontfam_ fonts.\n"); &Out("\\ProvidesPackage{z$_[0]$fontfam_}\n"); &Out("\n%% The gory details..."); &out("\\SetSymbolFont{operators}{normal}{$mathencoding_}"); &Out("{$shortmathpkg_}{$reg2nfss{$rreg}}{n}"); &out("\\SetSymbolFont{letters}{normal}{OML}"); &Out("{$shortmathpkg_}{m}{it}"); &out("\\SetSymbolFont{symbols}{normal}{OMS}"); &Out("{$shortmathpkg_}{m}{n}"); &Out("\\SetSymbolFont{largesymbols}{normal}{OMX}{$shortmathpkg_}{m}{n}\n"); &out("\n\\SetMathAlphabet{\\mathit}{normal}{$mathencoding_}"); &Out("{$fontfamx_}{$reg2nfss{$rreg}}{$ital2nfss{$rit}}"); &out("\\SetMathAlphabet{\\mathbf}{normal}{$mathencoding_}"); if (&isvariable($greekbold_)) {# real math bold font exists! &Out("{$shortmathpkg_}{$nfssbold}{n}"); } else {# use standard text bold &Out("{${fontfamx_}}{$nfssbold}{n}"); } &out("\\SetSymbolFont{operators}{bold}{$mathencoding_}"); &Out("{$shortmathpkg_}{$nfssbold}{n}"); &out("\\SetSymbolFont{letters}{bold}{OML}"); &Out("{$shortmathpkg_}{$nfssbold}{it}"); &out("\n\\SetMathAlphabet{\\mathit}{bold}{$mathencoding_}"); &Out("{$fontfam_}{$nfssbold}{it}"); if (&isvariable($greekbold_)) {# greek bold => special math bold &out("\\SetMathAlphabet{\\mathbf}{bold}{$mathencoding_}"); &Out("{$shortmathpkg_}{$nfssbold}{n}"); } else { &out("\\SetMathAlphabet{\\mathbf}{bold}{$mathencoding_}"); &Out("{$fontfam_}{$nfssbold}{n}"); } &Out("\n\\renewcommand{\\rmdefault}{$fontfamx_}"); &Out("\\renewcommand{\\encodingdefault}{$mathencoding_}"); &Out("\\renewcommand{\\seriesdefault}{$thisseries}") unless $thisseries eq "m"; &Out("\\renewcommand{\\shapedefault}{$thisshape}") unless $thisshape eq "n"; $nfssbold=$bold2nfss{$rbold}; &Out("\\renewcommand{\\bfdefault}{$nfssbold}"); # Now, the tt font. if ($tt_) { &Out("\n%% Typewriter fonts."); local($ttsize) = sprintf("%5.3f", $ttSF_ / 1000); local($ttfam) = &deduce_fontfam_from($tt_); if (-e "$inputs_$sep${encoding_}$ttfam.fd") { &get_fd_info_and_scale_it("${encoding_}$ttfam", $ttsize); } else { # no fd file for tt... &out("\\DeclareFontFamily\{$encoding_\}\{$ttfam\}"); &Out("\{\\hyphenchar \\font\\m\@ne\}"); &out(" \\DeclareFontShape{$encoding_}"); &Out("{$ttfam}{m}{n}{<-> [$ttsize] $tt_}{}\n"); } &Out("\\renewcommand{\\ttdefault}{$ttfam}"); &out("\\SetMathAlphabet{\\mathtt}{normal}{$encoding_}"); &Out("{\\ttdefault}{m}{n}"); } # Now, the sans serif info. if ($sansserif_) { &Out("\n%% Sans serif fonts."); local($sssize) = sprintf("%5.3f", $ssSF_ / 1000); local($ssfam) = &deduce_fontfam_from($sansserif_); if (-e "$inputs_$sep${encoding_}$ssfam.fd") { &get_fd_info_and_scale_it("${encoding_}$ssfam", $sssize); } else { # no fd file for tt... &Out("\\DeclareFontFamily\{$encoding_\}\{$ssfam\}\{\}"); &out(" \\DeclareFontShape{$encoding_}"); &Out("{$ssfam}{m}{n}{<-> [$sssize] $sansserif_}{}\n"); } &Out("\\renewcommand{\\sfdefault}{$ssfam}"); &out("\\SetMathAlphabet{\\mathsf}{normal}{$encoding_}"); &Out("{\\sfdefault}{m}{n}"); } if (&isvariable($cal_)) { local($calsize) = sprintf("%5.3f", $caSF_ / 1000); &Out("\n%% Math Calligraphic."); &Out("\\DeclareFontFamily{$mathencoding_}{cal}{}"); &out("\\DeclareFontShape{$mathencoding_}"); &Out("{cal}{m}{it}{<-> [$calsize] $cal_}{}"); &Out("\\newcommand{\\caldefault}{cal}"); &out("\\SetMathAlphabet{\\mathcal}{normal}{$mathencoding_}"); &Out("{\\caldefault}{m}{it}"); } if (&isvariable($fraktur_)) { local($fraksize) = sprintf("%5.3f", $frSF_ / 1000); &Out("\n%% Math Fraktur."); &Out("\\DeclareFontFamily{$mathencoding_}{frak}{}"); &out("\\DeclareFontShape{$mathencoding_}"); &Out("{frak}{m}{n}{<-> [$fraksize] $fraktur_}{}"); &Out("\\newcommand{\\frakdefault}{frak}"); &out("\\DeclareMathAlphabet{\\mathfr}{$mathencoding_}"); &Out("{\\frakdefault}{m}{n}"); } if (&isvariable($bbold_)) { local($bbsize) = sprintf("%5.3f", $bbSF_ / 1000); &Out("\n%% Math Blackboard Bold."); &Out("\\DeclareFontFamily{$mathencoding_}{bbold}{}"); &out("\\DeclareFontShape{$mathencoding_}"); &Out("{bbold}{m}{n}{<-> [$bbsize] $bbold_}{}"); &Out("\\newcommand{\\bbdefault}{bbold}"); &out("\\DeclareMathAlphabet{\\mathbb}{$mathencoding_}"); &Out("{\\bbdefault}{m}{n}"); } &out("\n\\renewcommand{\\l}{\\char170\\relax} "); # since lslashslash &Out("\\renewcommand{\\L}{\\char138\\relax} "); # doesn't exist &Out($mt_hax) if $_[0] eq "mt"; &Out($lu_hax) if $_[0] eq "lu"; &Out("\n\\endinput"); close LTXSTY; } $mt_hax = <<'EOMTHax'; %% Now for some hacks... \mathchardef\varkappa="0180 \mathchardef\comp="2181 \def\vec{\mathaccent"717E } \mathchardef\Relbar="3280 \mathcode`\;="6281 EOMTHax $lu_hax = <<'EOLUHax'; %% Now for some hacks... \def\joinrel{\mathrel{\mkern-6mu}} \mathchardef\Relbar="3280 \mathcode`\;="6281 \catcode`\@=11 \def\Lbrack{\delimiter"4382384 } \def\Rbrack{\delimiter"5383385 } \mathchardef\surfint="1390 \mathchardef\lsurfint="1394 \mathchardef\lointop="1393 \def\loint{\lointop\nolimits} \mathchardef\lintop="1392 \def\lint{\lintop\nolimits} \def\@intrad{\radical"352392 }% ``radicalized'' integral sign \def\@ointrad{\radical"348393 }% ``radicalized'' contour integral \def\@sintrad{\radical"390394 }% ``radicalized'' surface integral \newtoks\@subtoks \newtoks\@suptoks \def\varint{\@int{\@intrad}} \def\varoint{\@int{\@ointrad}} \def\varsint{\@int{\@sintrad}} \def\@int#1{\@subtoks={}\@suptoks={}\let\@limits=\nolimits \let\@thisint=#1 \futurelet\@nextchar \@testnextchar} \def\@testnextchar{\let\next=\@getintegrand \ifx\@nextchar_ \let\next=\@getsubscript\fi \ifx\@nextchar^ \let\next=\@getsuperscript\fi \next} \def\@getsubscript_#1{\@subtoks=\expandafter{#1}% \futurelet\@nextchar \@testnextchar} \def\@getsuperscript^#1{\@suptoks=\expandafter{#1}% \futurelet\@nextchar \@testnextchar} \def\@getintegrand{\mathpalette\@integrand} \def\@integrand#1#2{\setbox0=\hbox{$\m@th #1 #2$}\dimen@=\ht0 \advance\dimen@ by\dp0 \mathop{\vcenter{\hbox{$\@thisint{% \vcenter to\dimen@{}}$}}}\@limits^{\the\@suptoks}_{\the\@subtoks}% \box0} \def\setlimits{\global\let\@limits=\limits} \def\setnolimits{\global\let\@limits=\nolimits} \catcode`\@=12 EOLUHax sub makeplainstyle{ $stylefile = "z$_[0]$fontfam_.tex"; local($mysize); open(PLNSTY, ">$stylefile"); $FH_ = "PLNSTY"; require("..${sep}plainsty.tpl") or die "Where is the plain template?"; close PLNSTY; } sub makeLaTeXtestfile{ $q = q!"!; $FH_ = "LTXTEST"; open($FH_, ">testmath.tex"); require("..${sep}testmath.tpl"); &out($Caltest) if $cal_; &out($Sanstest) if $sansserif_; &out($Fraktest) if $fraktur_; &out($BBoldtest) if $bbold_; &out($DD); close $FH_; } sub makeplaintestfile{ $FH_ = "PLNTEST"; open($FH_, ">testmatp.tex"); require("..${sep}testmatp.tpl"); &out($GreekBoldTest) if $greekbold_; &out($CalTest) if $cal_; &out($SansTest) if $sansserif_; &out($FrakTest) if $fraktur_; &out($BBoldTest) if $bbold_; &out($BBplain); close $FH_; } sub makecleanupfile{ $FH_ = "PUTFONTS"; open($FH_, ">putfonts.bat"); if (&isTDS) { &Out( "$mv \*.vf $texmf_${sep}fonts${sep}vf${sep}$installer_${sep}$mathpkg_"); &Out( "$mv \*.tfm $texmf_${sep}fonts${sep}tfm${sep}$installer_${sep}$mathpkg_"); &Out("$mv z\*.tex $texmf_${sep}tex${sep}plain${sep}mathinst"); &Out("$mv z\*.sty $texmf_${sep}tex${sep}latex${sep}mathinst"); } else { # traditional systems &Out("$mv \*.vf $vf_"); &Out("$mv \*.tfm $tfm_"); &Out("$mv z\*.\* $inputs_"); } ## Everyone... &Out("$mv \*.fd $inputs_"); close $FH_; ## Now to change executables to `execute' status for Unix systems... if ($sep eq "/") { chmod 0755, "mkdirs.bat" if -e "mkdirs.bat"; local($cnt) = chmod 0755, "makepl.bat", "makevf.bat", "putfonts.bat"; &Out("I couldn't make the .bat files executable. Check permissions.") if $cnt == 0; } }