summaryrefslogtreecommitdiff
path: root/Master/texmf/scripts/tetex
diff options
context:
space:
mode:
authorPeter Breitenlohner <peb@mppmu.mpg.de>2012-05-15 11:09:26 +0000
committerPeter Breitenlohner <peb@mppmu.mpg.de>2012-05-15 11:09:26 +0000
commitb5e733509570a232123558dc19dba6b949e50aab (patch)
tree01ac4f3ce92c5f78d827f044da073cc559b6342b /Master/texmf/scripts/tetex
parenta9c916deec11708fcfd165d4e3d12675d0c2ff8e (diff)
Moved updmap.pl from texlive/ back to tetex/
git-svn-id: svn://tug.org/texlive/trunk@26402 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf/scripts/tetex')
-rwxr-xr-xMaster/texmf/scripts/tetex/updmap-single.pl1533
-rwxr-xr-xMaster/texmf/scripts/tetex/updmap.pl2059
2 files changed, 2059 insertions, 1533 deletions
diff --git a/Master/texmf/scripts/tetex/updmap-single.pl b/Master/texmf/scripts/tetex/updmap-single.pl
deleted file mode 100755
index ac3720d58bf..00000000000
--- a/Master/texmf/scripts/tetex/updmap-single.pl
+++ /dev/null
@@ -1,1533 +0,0 @@
-#! /usr/bin/env perl
-# updmap: utility to maintain map files for outline fonts.
-#
-# Copyright 2002-2011 Thomas Esser (for the shell version)
-# Copyright 2002-2011 Fabrice Popineau (for the first perl version)
-# Copyright 2009-2011 Reinhard Kotucha
-# Copyright 2011-2012 Norbert Preining
-#
-# Anyone may freely use, modify, and/or distribute this file, without
-# limitation.
-
-BEGIN {
- $^W=1;
- chomp($TEXMFROOT = `kpsewhich -var-value=TEXMFROOT`);
- unshift (@INC, "$TEXMFROOT/tlpkg");
-}
-
-my $version = '$Id: updmap.pl 25346 2012-02-10 12:51:16Z preining $';
-
-use strict;
-use TeXLive::TLUtils qw(mkdirhier mktexupd win32);
-use Getopt::Long;
-$Getopt::Long::autoabbrev=0;
-Getopt::Long::Configure (qw(ignore_case_always));
-
-my $short_progname = "updmap";
-
-my $cnfFile;
-my $cnfFileShort;
-my $outputdir;
-my $dvipsoutputdir;
-my $pdftexoutputdir;
-my $dvipdfmoutputdir;
-my $pxdvioutputdir;
-my $quiet;
-my $nohash;
-my $nomkmap;
-my (@psADOBE, @fileADOBE, @fileADOBEkb, @fileURW);
-
-my $enableItem;
-my @setoptions = ();
-my @showoptions = ();
-my @showoption = ();
-my @disableItem = ();
-my $listmaps;
-my $listavailablemaps;
-my $syncwithtrees;
-
-my $opt_edit;
-my $opt_force;
-my $opt_help;
-my $dry_run;
-my $TEXMFMAIN;
-my $TEXMFVAR;
-
-my $mode;
-my $dvipsPreferOutline;
-my $dvipsDownloadBase35;
-my $pdftexDownloadBase14;
-my $pxdviUse;
-my $kanjiEmbed;
-my $kanjiVariant;
-
-my $dvips35;
-my $pdftex35;
-my $ps2pk35;
-
-my $newcnf;
-my $copy;
-my %link;
-my %maps;
-my @missing;
-my $writelog = 0;
-my $cache = 0; # don't change!
-my $pdftexStripEnc = 0;
-
-# initialize mktexupd
-my $updLSR=&mktexupd();
-$updLSR->{mustexist}(0);
-
-my @cfg = ();
-
-&main;
-exit 0;
-
-
-# return program name + version string.
-sub version {
- my $ret = sprintf "%s (TeX Live) version %s\n", $short_progname, $version;
- return $ret;
-}
-
-###############################################################################
-# help()
-# display help message and exit
-#
-sub help {
- my $usage= <<"EOF";
-Usage: $short_progname [OPTION] ... [COMMAND]
- or: $short_progname-sys [OPTION] ... [COMMAND]
-
-Update the default font map files used by pdftex, dvips, and dvipdfm(x),
-(and optionally pxdvi) as determined by the configuration file updmap.cfg
-(the one returned by running "kpsewhich updmap.cfg").
-
-Among other things, these map files are used to determine which fonts
-should be used as bitmaps and which as outlines, and to determine which
-fonts are included in the output.
-
-By default, the TeX filename database (ls-R) is also updated.
-
-Options:
- --cnffile FILE read FILE for the updmap configuration
- --dvipdfmoutputdir DIR specify output directory (dvipdfm syntax)
- --dvipsoutputdir DIR specify output directory (dvips syntax)
- --pdftexoutputdir DIR specify output directory (pdftex syntax)
- --pxdvioutputdir DIR specify output directory (pxdvi syntax)
- --outputdir DIR specify output directory (for all files)
- --copy cp generic files rather than using symlinks
- --force recreate files even if config hasn't changed
- --nomkmap do not recreate map files
- --nohash do not run texhash
- -n, --dry-run only show the configuration, no output
- --quiet, --silent reduce verbosity
-
-Commands:
- --help show this message and exit
- --version show version information and exit
- --showoptions ITEM show alternatives for options
- --showoption ITEM show value of option
- --setoption OPTION VALUE set option, where OPTION is one of:
- LW35, dvipsPreferOutline, dvipsDownloadBase35,
- pdftexDownloadBase14, pxdviUse, kanjiEmbed,
- or kanjiVariant
- --setoption OPTION=VALUE as above, just different syntax
- --enable MAPTYPE MAPFILE add "MAPTYPE MAPFILE" to updmap.cfg,
- where MAPTYPE is one of: Map, MixedMap, KanjiMap
- --enable Map=MAPFILE add \"Map MAPFILE\" to updmap.cfg
- --enable MixedMap=MAPFILE add \"MixedMap MAPFILE\" to updmap.cfg
- --enable KanjiMap=MAPFILE add \"KanjiMap MAPFILE\" to updmap.cfg
- --disable MAPFILE disable MAPFILE, whether Map, MixedMap, or KanjiMap
- --listmaps list all active and inactive maps
- --listavailablemaps same as --listmaps, but without
- unavailable map files
- --syncwithtrees disable unavailable map files in updmap.cfg
-
-Explanation of the map types: the (only) difference between Map and
-MixedMap is that MixedMap entries are not added to psfonts_pk.map.
-The purpose is to help users with printers that render Type 1 outline
-fonts worse than mode-tuned Type 1 bitmap fonts. So, MixedMap is used
-for fonts that are available as both Type 1 and Metafont.
-
-Explanation of the --setoption possibilities:
-
- dvipsPreferOutline true|false (default true)
- Whether dvips uses bitmaps or outlines, when both are available.
- dvipsDownloadBase35 true|false (default false)
- Whether dvips includes the standard 35 PostScript fonts in its output.
- pdftexDownloadBase14 true|false (default true)
- Whether pdftex includes the standard 14 PDF fonts in its output.
- pxdviUse true|false (default false)
- Whether maps for pxdvi (Japanese-patched xdvi) is under control of updmap.
- LW35 URWkb|URW|ADOBEkb|ADOBE (default URWkb)
- Adapt the font and file names of the standard 35 PostScript fonts.
- URWkb URW fonts with "berry" filenames (e.g. uhvbo8ac.pfb)
- URW URW fonts with "vendor" filenames (e.g. n019064l.pfb)
- ADOBEkb Adobe fonts with "berry" filenames (e.g. phvbo8an.pfb)
- ADOBE Adobe fonts with "vendor" filenames (e.g. hvnbo___.pfb)
- kanjiEmbed (any string)
- kanjiVariant (any string)
-
- These options are only read and acted on by updmap; dvips, pdftex, etc.,
- do not know anything about them. They work by changing the default map
- file which the programs read, so they can be overridden by specifying
- command-line options or configuration files to the programs, as
- explained at the beginning of updmap.cfg.
-
-Explanation of trees and files normally used:
-
- updmap both reads and writes TEXMFCONFIG/web2c/updmap.cfg, according to
- the actions specified.
-
- updmap writes the map files for dvips (psfonts.map) and pdftex
- (pdftex.map) to the TEXMFVAR/fonts/map/updmap/{dvips,pdftex}/
- directories.
-
- The log file is written to TEXMFVAR/web2c/updmap.log.
-
- When updmap-sys is run, TEXMFSYSCONFIG and TEXMFSYSVAR are used
- instead. This is the only difference between updmap-sys and updmap.
-
- Other locations can be used if overridden on the command line, or these
- trees don't exist, or you are not using the original TeX Live.
-
- To see the precise locations of the various files that
- will be read and written, give the -n option (or read the man page).
-
-For step-by-step instructions on making new fonts known to TeX, read
-http://tug.org/fonts/fontinstall.html. For even more terse
-instructions, read the beginning of updmap.cfg.
-
-Report bugs to: tex-k\@tug.org
-TeX Live home page: <http://tug.org/texlive/>
-EOF
-;
- print &version();
- print $usage;
- exit 0;
-}
-
-
-
-###############################################################################
-# processOptions()
-# process cmd line options
-#
-sub processOptions {
- #
- # We parse the command line twice. The first time is to handle
- # --setoption and --enable, which might take either one or two following
- # values, the second to handle everything else. The Getopt::Long feature to
- # handle this is only supported in 5.8.8 (released in 2006) or later,
- # and a few people run older perls.
- #
- my $oldconfig = Getopt::Long::Configure(qw(pass_through));
- #
- sub read_one_or_two {
- my ($opt, $val) = @_;
- # check if = occurs in $val, if not, get the next argument
- if ($val =~ m/=/) {
- if ($opt eq "setoption") {
- push @setoptions, $val;
- } else {
- $enableItem = $val;
- }
- } else {
- my $vv = shift @ARGV;
- die "Try \"$0 --help\" for more information.\n"
- if !defined($vv);
- if ($opt eq "setoption") {
- push @setoptions, "$val=$vv";
- } else {
- $enableItem = "$val=$vv";
- }
- }
- }
- GetOptions("setoption=s@" => \&read_one_or_two,
- "enable=s" => \&read_one_or_two) ||
- die "$0: illegal arguments, try --help for more information.\n";
-
- # restore old getopt config and read everything else.
- Getopt::Long::Configure($oldconfig);
- unless (&GetOptions (
- "cnffile=s" => \$cnfFile,
- "copy" => \$copy,
- "disable=s" => \@disableItem,
- "dvipdfmoutputdir=s" => \$dvipdfmoutputdir,
- "dvipsoutputdir=s" => \$dvipsoutputdir,
- # "enable=s" => \$enableItem,
- "edit" => \$opt_edit,
- "force" => \$opt_force,
- "listavailablemaps" => \$listavailablemaps,
- "l|listmaps" => \$listmaps,
- "nohash" => \$nohash,
- "nomkmap" => \$nomkmap,
- "n|dry-run" => \$dry_run,
- "outputdir=s" => \$outputdir,
- "pdftexoutputdir=s" => \$pdftexoutputdir,
- "pxdvioutputdir=s" => \$pxdvioutputdir,
- "q|quiet|silent" => \$quiet,
- "setoption" =>
- sub {die "$0: --setoption needs an option and value; try --help.\n"},
- "showoptions=s" => \@showoptions,
- "showoption=s" => \@showoption,
- "syncwithtrees" => \$syncwithtrees,
- "version" => sub { print &version(); exit(0); },
- "h|help" => \$opt_help)) {
- die "Try \"$0 --help\" for more information.\n";
- }
-
- if (@ARGV) {
- warn "$0: Ignoring unexpected non-option argument(s): @ARGV.\n";
- }
-
- if ($outputdir) {
- $dvipsoutputdir = $outputdir if (! $dvipsoutputdir);
- $pdftexoutputdir = $outputdir if (! $pdftexoutputdir);
- $dvipdfmoutputdir = $outputdir if (! $dvipdfmoutputdir);
- $pxdvioutputdir = $outputdir if (! $pxdvioutputdir);
- }
- if ($cnfFile && ! -f $cnfFile) {
- die "$0: Config file \"$cnfFile\" not found.\n";
- }
- if ($dvipsoutputdir && ! $dry_run && ! -d $dvipsoutputdir) {
- &mkdirhier ($dvipsoutputdir);
- }
- if ($dvipdfmoutputdir && ! $dry_run && ! -d $dvipdfmoutputdir) {
- &mkdirhier ($dvipdfmoutputdir);
- }
- if ($pdftexoutputdir && ! $dry_run && ! -d $pdftexoutputdir) {
- &mkdirhier ($pdftexoutputdir);
- }
- if ($pxdvioutputdir && ! $dry_run && ! -d $pxdvioutputdir) {
- &mkdirhier ($pxdvioutputdir);
- }
-}
-
-
-###############################################################################
-# equalize_file(filename[, comment_char])
-# read a file and return its processed content as a string.
-# look into the source code for more details.
-#
-sub equalize_file {
- my $file=shift;
- my $comment=shift;
- my @temp;
-
- open IN, "$file";
- my @lines = (<IN>);
- close IN;
- chomp(@lines);
-
- for (@lines) {
- s/\s*${comment}.*// if (defined $comment); # remove comments
- next if /^\s*$/; # remove empty lines
- s/\s+/ /g; # replace multiple whitespace chars by a single one
- push @temp, $_;
- }
- return join('X', sort(@temp));
-}
-
-###############################################################################
-# files_are_different(file_A, file_B[, comment_char])
-# compare two equalized files.
-#
-sub files_are_different {
- my $file_A=shift;
- my $file_B=shift;
- my $comment=shift;
- my $retval=0;
-
- my $A=equalize_file("$file_A", $comment);
- my $B=equalize_file("$file_B", $comment);
- $retval=1 unless ($A eq $B);
- return $retval;
-}
-
-###############################################################################
-# files_are_equal(file_A, file_B[, comment_char])
-# compare two equalized files. Same as files_are_different() with
-# return value inverted.
-#
-sub files_are_equal {
- return (&files_are_different (@_))? 0:1;
-}
-
-###############################################################################
-# files_are_identical(file_A, file_B)
-# compare two files. Same as cmp(1).
-#
-sub files_are_identical {
- my $file_A=shift;
- my $file_B=shift;
- my $retval=0;
-
- open IN, "$file_A";
- my $A=(<IN>);
- close IN;
- open IN, "$file_B";
- my $B=(<IN>);
- close IN;
-
- $retval=1 if ($A eq $B);
- return $retval;
-}
-
-###############################################################################
-# getLines()
-#
-###############################################################################
-sub getLines {
- my @lines = ();
- foreach my $fname (@_) {
- next if (! $fname);
- if (! exists $maps{"$fname"}) {
- open FILE, "<$fname" or die "$0: can't get lines from $fname: $!";
- my @file=<FILE>;
- close FILE;
- if ($writelog) {
- print LOG ("\n$fname:\n");
- foreach my $line (@file) {
- next if $line =~ /^\s*%/; # comment
- next if $line =~ /^\s*#/; # comment
- next if $line =~ /^\s*$/; # empty line
- my $tfm;
- ($tfm)=split ' ', $line;
- print LOG "$tfm\n";
- }
- }
- $maps{"$fname"} = [ @file ] if ($cache);
- push @lines, @file;
- } else {
- push @lines, @{$maps{"$fname"}};
- }
- }
- chomp @lines;
- return @lines;
-}
-
-###############################################################################
-# writeLines()
-# write the lines in $filename
-#
-sub writeLines {
- my ($fname, @lines) = @_;
- map { ($_ !~ m/\n$/ ? s/$/\n/ : $_ ) } @lines;
- open FILE, ">$fname" or die "$0: can't write lines to $fname: $!";
- print FILE @lines;
- close FILE;
-}
-
-###############################################################################
-# copyFile()
-# copy file $src to $dst, sets $dst creation and mod time
-#
-sub copyFile {
- my ($src, $dst) = @_;
- my $dir;
- ($dir=$dst)=~s/(.*)\/.*/$1/;
- mkdirhier $dir;
-
- $src eq $dst && return "can't copy $src to itself!\n";
-
- open IN, "<$src" or die "$0: can't open source file $src for copying: $!";
- open OUT, ">$dst";
-
- binmode(IN);
- binmode(OUT);
- print OUT <IN>;
- close(OUT);
- close(IN);
- my @t = stat($src);
- utime($t[8], $t[9], $dst);
-}
-
-###############################################################################
-# SymlinkOrCopy(dir, src, dest)
-# create symlinks if possible, otherwise copy files
-#
-sub SymlinkOrCopy {
- my ($dir, $src, $dest) = @_;
- if (&win32 || $copy) { # always copy
- &copyFile("$dir/$src", "$dir/$dest");
- } else { # symlink if supported by fs, copy otherwise
- system("cd \"$dir\" && ln -s $src $dest 2>/dev/null || "
- . "cp -p \"$dir/$src\" \"$dir/$dest\"");
- }
- # remember for "Files generated" in &mkMaps.
- $link{"$dest"}="$src";
-}
-
-###############################################################################
-# setupSymlinks()
-# set symlink for psfonts.map according to dvipsPreferOutline variable
-#
-sub setupSymlinks {
- my $src;
-
- if ($dvipsPreferOutline) {
- $src = "psfonts_t1.map";
- } else {
- $src = "psfonts_pk.map";
- }
- unlink "$dvipsoutputdir/psfonts.map";
- &SymlinkOrCopy("$dvipsoutputdir", "$src", "psfonts.map");
-
- if ($pdftexDownloadBase14) {
- $src = "pdftex_dl14.map";
- } else {
- $src = "pdftex_ndl14.map";
- }
- unlink "$pdftexoutputdir/pdftex.map";
- &SymlinkOrCopy("$pdftexoutputdir", "$src", "pdftex.map");
-}
-
-
-###############################################################################
-# transLW35(args ...)
-# transform fontname and filenames according to transformation specified
-# by mode. Possible values:
-# URW|URWkb|ADOBE|ADOBEkb
-#
-sub transLW35 {
- my ($name) = @_;
- my @lines = &getLines($name);
-
- if ($mode eq "" || $mode eq "URWkb") {
- # do nothing
- } elsif ($mode eq "URW") {
- for my $r (@fileURW) {
- map { eval($r); } @lines;
- }
- } elsif ($mode eq "ADOBE" || $mode eq "ADOBEkb") {
- for my $r (@psADOBE) {
- map { eval($r); } @lines;
- }
- my @filemode = eval ("\@file" . $mode);
- for my $r (@filemode) {
- map { eval($r); } @lines;
- }
- }
- return @lines;
-}
-
-###############################################################################
-# locateWeb2c (file ...)
-# apply kpsewhich with format 'web2c files'
-#
-sub locateWeb2c {
- my @files = @_;
- return @files if ($#files < 0);
-
- @files = split (/\n/, `kpsewhich --format="web2c files" @files`);
- if (wantarray) {
- return @files;
- }
- else {
- return $files[0];
- }
-}
-
-###############################################################################
-# locateMap (file ...)
-# apply kpsewhich with format 'map'
-#
-sub locateMap {
- my @maps = @_;
- return @maps if ($#maps < 0);
-
- my @files = `kpsewhich --format=map @maps`;
- chomp @files;
-
- foreach my $map (@maps) {
- push @missing, $map if (! grep /\/$map(\.map)?$/, @files);
- }
-
- if (wantarray) {
- return @files;
- } else {
- return $files[0];
- }
-}
-
-
-###############################################################################
-# cfgval(variable)
-# read variable ($1) from config file
-#
-sub cfgval {
- my ($variable) = @_;
- my $value;
-
- if ($#cfg < 0) {
- open FILE, "<$cnfFile" or die "$0: can't open configuration file $cnfFile: $!";
- while (<FILE>) {
- s/\s*$//; # strip trailing spaces
- push @cfg, $_;
- }
- close FILE;
- chomp (@cfg);
- }
- for my $line (@cfg) {
- if ($line =~ m/^\s*${variable}[\s=]+(.*)\s*$/) {
- $value = $1;
- if ($value =~ m/^(true|yes|t|y|1)$/) {
- $value = 1;
- }
- elsif ($value =~ m/^(false|no|f|n|0)$/) {
- $value = 0;
- }
- last;
- }
- }
- return $value;
-}
-
-###############################################################################
-# configReplace(file, pattern, line)
-# The first line in file that matches pattern gets replaced by line.
-# line will be added at the end of the file if pattern does not match.
-#
-sub configReplace {
- my ($file, $pat, $line) = @_;
- my @lines = &getLines($file);
- my $found = 0;
- map {
- if (/$pat/) {
- $found = 1; $_ = $line;
- }
- } @lines;
- if (! $found) {
- push @lines, $line;
- }
- &writeLines($file, @lines);
-}
-
-###############################################################################
-# setOption (@options)
-# parse @options for "key=value" (one element of @options)
-# or "key", "value" (two elements of @options) pairs.
-# (These were the values provided to --setoption.)
-#
-sub setOptions {
- my (@options) = @_;
- for (my $i = 0; $i < @options; $i++) {
- my $o = $options[$i];
-
- my ($key,$val);
- if ($o =~ /=/) {
- ($key,$val) = split (/=/, $o, 2);
- } else {
- $key = $o;
- die "$0: no value for --setoption $key, goodbye.\n"
- if $i + 1 >= @options;
- $val = $options[$i + 1];
- $i++;
- }
-
- die "$0: unexpected empty key or val for options (@options), goodbye.\n"
- if !$key || !defined($val);
- &setOption ($key, $val);
- }
-}
-
-###############################################################################
-# setOption (option, value)
-# sets option to value in the config file (replacing the existing setting
-# or by adding a new line to the config file).
-#
-sub setOption {
- my ($opt, $val) = @_;
-
- if ($opt eq "LW35") {
- if ($val !~ m/^(URWkb|URW|ADOBE|ADOBEkb)$/) {
- die "$0: Invalid value $val for option $opt; try --help.\n";
- }
- } elsif ($opt =~
-m/^(dvipsPreferOutline|dvipsDownloadBase35|(pdftex|dvipdfm)DownloadBase14|pxdviUse)$/) {
- if ($val !~ m/^(true|false)$/) {
- die "$0: Invalid value $val for option $opt; should be \"true\" or \"false\".\n";
- }
- } elsif ($opt eq "kanjiEmbed" || $opt eq "kanjiVariant"){
- # do nothing
- } else {
- die "$0: Unsupported option $opt (value given: $val).\n";
- }
-
- # silently accept this old option name, just in case.
- return if $opt eq "dvipdfmDownloadBase14";
-
- #print "Setting option $opt to $val...\n" if !$quiet;
- &configReplace("$cnfFile", "^" . "$opt" . "\\s", "$opt $val");
-}
-
-###############################################################################
-# showOption(item item ...)
-# show current value for an item
-#
-sub showOption {
- sub doit {
- my ($a, $b) = @_;
- my $v = &cfgval($a);
- $v = $b unless (defined $v);
- print "$a=$v\n";
- }
- foreach my $item (@_) {
- doit("LW35", "URWkb") if ($item eq "LW35");
- doit("dvipsPreferOutline", 1) if ($item eq "dvipsPreferOutline");
- doit("dvipsDownloadBase35", 1) if ($item eq "dvipsDownloadBase35");
- doit("pdftexDownloadBase14", 1) if ($item eq "pdftexDownloadBase14");
- doit("kanjiEmbed", "noEmbed") if ($item eq "kanjiEmbed");
- doit("kanjiVariant", "") if ($item eq "kanjiVariant");
- doit("pxdviUse", 0) if ($item eq "pxdviUse");
- }
-}
-
-###############################################################################
-# showOptions(item)
-# show Options for an item
-#
-sub showOptions {
- foreach my $item (@_) {
- if ($item eq "LW35") {
- print "URWkb URW ADOBE ADOBEkb\n";
- }
- elsif ($item =~
-m/(dvipsPreferOutline|(dvipdfm|pdftex)DownloadBase14|dvipsDownloadBase35|pxdviUse)/) {
- print "true false\n";
- }
- elsif ($item eq "kanjiEmbed" || $item eq "kanjiVariant") {
- print "(any string)\n";
- }
- else {
- print "Unknown item \"$item\"; should be one of LW35, dvipsPreferOutline,\n"
- . " dvipsDownloadBase35, pdftexDownloadBase14, pxdviUse, kanjiEmbed, or kanjiVariant\n";
- }
- }
- exit 0
-}
-
-
-###############################################################################
-# enableMap (type, map)
-# enables an entry in the config file for map with a given type.
-#
-sub enableMap {
- my ($type, $map) = @_;
-
- if ($type !~ m/^(Map|MixedMap|KanjiMap)$/) {
- die "$0: Invalid mapType $type\n";
- }
- # a map can only have one type, so we carefully disable everything
- # about map here:
- &disableMap("$map");
-
- # now enable with the right type:
- &configReplace("$cnfFile", "^#!\\s*" . "$type" . "\\s*$map", "$type $map");
-}
-
-###############################################################################
-# disableMap (map)
-# disables map in config file (any type)
-#
-sub disableMap {
- my ($map) = @_;
- my %count = ();
- my $type;
-
- my @mapType = grep {
- my @fields = split;
- if ($fields[0] and $fields[0] =~ /^(MixedMap|Map|KanjiMap)$/
- and $fields[1] eq $map and ++$count{$fields[0]}) {
- $_ = $fields[0];
- }
- else {
- $_ = '';
- }
- } &getLines($cnfFile);
-
- foreach $type (@mapType) {
- &configReplace("$cnfFile", "^$type" . "\\s*$map", "#! $type $map");
- }
-}
-
-###############################################################################
-# setupDestDir()
-# find an output directory if none specified on cmd line. First choice is
-# $TEXMFVAR/fonts/map/updmap (if TEXMFVAR is set), next is relative to
-# config file location. Fallback is $TEXMFMAIN/fonts/map/updmap.
-#
-sub setupOutputDir {
- my($od, $driver) = @_;
-
- if (!$od) {
- my $rel = "fonts/map/$driver/updmap";
- my $tf;
- # Try TEXMFVAR tree. Use it if variable is set and $rel can
- # be written.
- chomp($tf = `kpsewhich --var-value=TEXMFVAR`);
- if ($tf) {
- &mkdirhier("$tf/$rel");
- if (! -w "$tf/$rel") {
- die "$0: Directory \"$tf/$rel\" isn't writable.\n";
- }
- }
- $od = "$tf/$rel";
- }
- &mkdirhier($od);
- print "$driver output dir: \"$od\"\n" if !$quiet;
- return $od;
-}
-
-sub setupDestDir {
- $dvipsoutputdir = &setupOutputDir($dvipsoutputdir, "dvips");
- $pdftexoutputdir = &setupOutputDir($pdftexoutputdir, "pdftex");
- $dvipdfmoutputdir = &setupOutputDir($dvipdfmoutputdir, "dvipdfm");
- $pxdvioutputdir = &setupOutputDir($pxdvioutputdir, "pxdvi");
-}
-
-###############################################################################
-# setupCfgFile()
-# find config file if none specified on cmd line.
-#
-sub setupCfgFile {
- if (! $cnfFile) {
- my $tf = `kpsewhich --var-value=TEXMFCONFIG`;
- chomp($tf);
- if ($tf && ! -f "$tf/web2c/$cnfFileShort") {
- &mkdirhier("$tf/web2c") if (! -d "$tf/web2c");
- if (-d "$tf/web2c" && -w "$tf/web2c") {
- unlink "$tf/web2c/$cnfFileShort";
- my $original_cfg=`kpsewhich updmap.cfg`;
- chomp($original_cfg);
- print("copy $original_cfg => $tf/web2c/$cnfFileShort\n") if !$quiet;
- $newcnf="$tf/web2c/$cnfFileShort";
- &copyFile("$original_cfg", "$tf/web2c/$cnfFileShort");
- $updLSR->{add}("$tf/web2c/$cnfFileShort");
- }
- }
- $cnfFile = "$tf/web2c/updmap.cfg";
- if (-s $cnfFile) {
- print "Config file: \"$cnfFile\"\n" if !$quiet;
- } else {
- die "$0: Config file updmap.cfg not found.\n";
- }
- }
-}
-
-###############################################################################
-# catMaps(regex)
-# filter config file by regex for map lines and extract the map filenames.
-# These are then looked up (by kpsewhich in locateMap) and the content of
-# all map files is send to stdout.
-#
-sub catMaps {
- my ($map) = @_;
- my %count = ( );
- my @maps = grep { $_ =~ m/$map/ } @cfg;
- map{
- $_ =~ s/\#.*//;
- # $_ =~ s/\@kanjiEmbed@/$kanjiEmbed/;
- # $_ =~ s/\@kanjiVariant@/$kanjiVariant/;
- $_ =~ s/\s*([^\s]*)\s*([^\s]*)/$2/;
- } @maps;
-
- my @newmaps;
- for my $m (@maps) {
- if ($m =~ m/\@kanjiEmbed@/ || $m =~ m/\@kanjiVariant@/) {
- my $newm = $m;
- $newm =~ s/\@kanjiEmbed@/$kanjiEmbed/;
- $newm =~ s/\@kanjiVariant@/$kanjiVariant/;
- my $mf = `kpsewhich --format=map $newm`;
- chomp($mf);
- if (!$mf) {
- print LOG "\n$short_progname: generated map $newm\n\tfrom $m\n\tdoes not exists, not activating it!\n";
- } else {
- push @newmaps, $newm;
- }
- } else {
- push @newmaps, $m;
- }
- }
- @maps = sort(@newmaps);
- @maps = grep { ++$count{$_} < 2; } @maps;
-
- @maps = &locateMap(@maps);
- return @maps;
-}
-
-###############################################################################
-# listMaps()
-# list all maps mentioned in the config file
-#
-sub listMaps {
- my $what=shift;
- my @mapfiles;
- my @paths;
- $kanjiEmbed = &cfgval("kanjiEmbed");
- $kanjiEmbed = "noEmbed" unless (defined $kanjiEmbed);
- $kanjiVariant = &cfgval("kanjiVariant");
- $kanjiVariant = "" unless (defined $kanjiVariant);
-
- my @lines = grep {
- if ($what eq 'sync') {
- $_ =~ m/^(Mixed|Kanji)?Map/
- } else {
- $_ =~ m/^(\#! *)?(Mixed|Kanji)?Map/
- }
- } &getLines($cnfFile);
-
- if ($what eq 'list') {
- # --listmaps
- map { print "$_\n"; } @lines;
- } else {
- map { $_ =~ s/\@kanjiEmbed@/$kanjiEmbed/ } @lines;
- map { $_ =~ s/\@kanjiVariant@/$kanjiVariant/ } @lines;
- @mapfiles=grep { $_ =~ s/^(\#! *)?(Mixed|Kanji)?Map\s+// } @lines;
- @paths=&locateMap(@mapfiles);
-
- if ($what eq 'avail') {
- # --listavailablemaps
- map {
- my $entry="$_";
- # that was disabled, but I don't understand why (NP)
- print "$entry\n" if (grep { $_ =~ m/\/$entry/ } @paths);
- } @lines;
- } elsif ($what eq 'sync') {
- # --syncwithtrees
- map {
- my $entry="$_";
- unless (grep { $_ =~ m/\/$entry/ } @paths) {
- &disableMap($entry);
- print " $entry disabled\n" if !$quiet;
- }
- } @lines;
- }
- }
-}
-
-###############################################################################
-# normalizeLines()
-# remove comments, whitespace is exactly one space, no empty lines,
-# no whitespace at end of line, one space before and after "
-#
-sub normalizeLines {
- my @lines = @_;
- my %count = ();
-
- @lines = grep { $_ !~ m/^[*#;%]/ } @lines;
- map {$_ =~ s/\s+/ /gx } @lines;
- @lines = grep { $_ !~ m/^\s*$/x } @lines;
- map { $_ =~ s/\s$//x ;
- $_ =~ s/\s*\"\s*/ \" /gx;
- $_ =~ s/\" ([^\"]*) \"/\"$1\"/gx;
- } @lines;
-
- @lines = grep {++$count{$_} < 2 } (sort @lines);
-
- return @lines;
-}
-
-###############################################################################
-# to_pdftex()
-# if $pdftexStripEnc is set, strip "PS_Encoding_Name ReEncodeFont"
-# from map entries; they are ignored by pdftex. But since the sh
-# incarnation of updmap included them, and we want to minimize
-# differences, this is not done by default.
-#
-sub to_pdftex {
- return @_ unless $pdftexStripEnc;
- my @in = @_;
- my @out;
- foreach my $line (@in) {
- if ($line =~ /^(.*\s+)(\S+\s+ReEncodeFont\s)(.*)/) {
- $line = "$1$3";
- $line =~ s/\s+\"\s+\"\s+/ /;
- }
- push @out, $line;
- }
- return @out;
-}
-
-###############################################################################
-# cidx2dvips()
-# reads from stdin, writes to stdout. It transforms "cid-x"-like syntax into
-# "dvips"-like syntax.
-###############################################################################
-sub cidx2dvips {
- my ($s) = @_;
- my @d;
- foreach (@$s) {
- s/,BoldItalic/ -s .3/;
- s/,Bold//;
- s/,Italic/ -s .3/;
- s/\s\s*/ /g;
- if ($_ =~ /.*[@\:\/,]/) {next;}
- elsif ($_ =~ /^[^ ][^ ]* unicode /) {next;}
- s/^([^ ][^ ]* [^ ][^ ]* [^ ][^ ]*)\.[Oo][Tt][Ff]/$1/;
- s/^([^ ][^ ]* [^ ][^ ]* [^ ][^ ]*)\.[Tt][Tt][FfCc]/$1/;
- s/$/ %/;
- s/^(([^ ]*).*)/$1$2/;
- s/^([^ ][^ ]* ([^ ][^ ]*) !*([^ ][^ ]*).*)/$1 $3-$2/;
- s/^(.* -e ([.0-9-][.0-9-]*).*)/$1 "$2 ExtendFont"/;
- s/^(.* -s ([.0-9-][.0-9-]*).*)/$1 "$2 SlantFont"/;
- s/.*%//;
- push(@d, $_);
- }
- return @d
-}
-
-
-###############################################################################
-# mkMaps()
-# the main task of this script: create the output files
-#
-sub mkMaps {
- my @lines;
- my $logfile;
-
- $cache=1;
-
- if (! $dry_run) {
- my $TEXMFVAR = `kpsewhich --var-value=TEXMFVAR`;
- chomp($TEXMFVAR);
- $logfile = "$TEXMFVAR/web2c/updmap.log";
- mkdirhier "$TEXMFVAR/web2c";
- open LOG, ">$logfile"
- or die "$0: Can't open log file \"$logfile\": $!";
- $writelog=1;
- print LOG &version();
- printf LOG "%s\n\n", scalar localtime();
- print LOG "Using config file \"$cnfFile\".\n";
- }
- sub wlog () {
- my $str=shift;
- if ($dry_run) {
- print $str;
- } else {
- print $str if !$quiet;
- print LOG $str;
- }
- }
- sub newline() {
- if ($dry_run) {
- print "\n";
- } else {
- print LOG "\n";
- }
- }
-
- $mode = &cfgval("LW35");
- $mode = "URWkb" unless (defined $mode);
-
- $dvipsPreferOutline = &cfgval("dvipsPreferOutline");
- $dvipsPreferOutline = 1 unless (defined $dvipsPreferOutline);
-
- $dvipsDownloadBase35 = &cfgval("dvipsDownloadBase35");
- $dvipsDownloadBase35 = 1 unless (defined $dvipsDownloadBase35);
-
- $pdftexDownloadBase14 = &cfgval("pdftexDownloadBase14");
- $pdftexDownloadBase14 = 1 unless (defined $pdftexDownloadBase14);
-
- $kanjiEmbed = &cfgval("kanjiEmbed");
- $kanjiEmbed = "noEmbed" unless (defined $kanjiEmbed);
-
- $kanjiVariant = &cfgval("kanjiVariant");
- $kanjiVariant = "" unless (defined $kanjiVariant);
-
- $pxdviUse = &cfgval("pxdviUse");
- $pxdviUse = 0 unless (defined $pxdviUse);
-
- &wlog ("\n$0 "
- . ($dry_run ? "would create" : "is creating") . " new map files"
- . "\nusing the following configuration:"
- . "\n LW35 font names : "
- . $mode
- . "\n prefer outlines : "
- . ($dvipsPreferOutline ? "true" : "false")
- . "\n texhash enabled : "
- . ($nohash ? "false" : "true")
- . "\n download standard fonts (dvips) : "
- . ($dvipsDownloadBase35 ? "true" : "false")
- . "\n download standard fonts (pdftex) : "
- . ($pdftexDownloadBase14 ? "true" : "false")
- . "\n kanjiEmbed/variant replacement : "
- . "$kanjiEmbed/$kanjiVariant"
- . "\n create a mapfile for pxdvi : "
- . ($pxdviUse ? "true" : "false")
- . "\n\n");
-
- &wlog ("Scanning for LW35 support files");
- $dvips35 = &locateMap("dvips35.map");
- $pdftex35 = &locateMap("pdftex35.map");
- $ps2pk35 = &locateMap("ps2pk35.map");
- my $LW35 = "\n$dvips35\n$pdftex35\n$ps2pk35\n\n";
- if ($dry_run) {
- print $LW35;
- } else {
- print LOG $LW35;
- }
- printf " [%3d files]\n", 3 unless ($quiet || $dry_run);
-
- &wlog ("Scanning for MixedMap entries");
- &newline;
- my @tmp1 = &catMaps('^MixedMap');
- foreach my $line (@tmp1) {
- if ($dry_run) {
- print "$line\n";
- } else {
- print LOG "$line\n";
- }
- }
- &newline;
- printf " [%3d files]\n", scalar @tmp1
- unless ($quiet || $dry_run);
-
- &wlog ("Scanning for KanjiMap entries");
- &newline;
- my @tmpkanji0 = &catMaps('^KanjiMap');
- foreach my $line (@tmpkanji0) {
- if ($dry_run) {
- print "$line\n";
- } else {
- print LOG "$line\n";
- }
- }
- &newline;
- printf " [%3d files]\n", scalar @tmpkanji0
- unless ($quiet || $dry_run);
-
- &wlog ("Scanning for Map entries");
- &newline();
- my @tmp2 = &catMaps('^Map');
- foreach my $line (@tmp2) {
- if ($dry_run) {
- print "$line\n";
- } else {
- print LOG "$line\n";
- }
- }
- &newline;
- printf " [%3d files]\n\n", scalar @tmp2
- unless ($quiet || $dry_run);
-
- if (@missing > 0) {
- print STDERR "\nERROR: The following map file(s) couldn't be found:\n\t";
- print STDERR join(' ', @missing);
- print STDERR "\n\n\tDid you run mktexlsr?\n\n" .
- "\tYou can delete non-existent map entries using the option\n".
- "\t --syncwithtrees.\n\n";
- exit (1);
- }
- exit(0) if $dry_run;
-
- # Create psfonts_t1.map, psfonts_pk.map, ps2pk.map and pdftex.map:
- my @managed_files = ("$dvipsoutputdir/download35.map",
- "$dvipsoutputdir/builtin35.map",
- "$dvipsoutputdir/psfonts_t1.map",
- "$dvipsoutputdir/psfonts_pk.map",
- "$pdftexoutputdir/pdftex_dl14.map",
- "$pdftexoutputdir/pdftex_ndl14.map",
- "$dvipdfmoutputdir/kanjix.map",
- "$dvipsoutputdir/ps2pk.map");
- if ($pxdviUse) {
- push @managed_files, "$pxdvioutputdir/xdvi-ptex.map";
- }
- for my $file (@managed_files) {
- open FILE, ">$file";
- print FILE "% $file:\
-% maintained by updmap[-sys].\
-% Don't change this file directly. Use updmap[-sys] instead.\
-% See texmf/web2c/$cnfFileShort and the updmap documentation.\
-% A log of the run that created this file is available here:\
-% $logfile\
-";
- close FILE;
- }
-
- print "Generating output for dvipdfm...\n" if !$quiet;
- my @tmpkanji1;
- push @tmpkanji1, &getLines(@tmpkanji0);
- @tmpkanji1 = &normalizeLines(@tmpkanji1);
- &writeLines(">$dvipdfmoutputdir/kanjix.map",
- @tmpkanji1);
-
- if ($pxdviUse) {
- # we use the very same data as for kanjix.map, but generate
- # a different file, so that in case a user wants to hand-craft it
- print "Generating output for pxdvi...\n" if !$quiet;
- &writeLines(">$pxdvioutputdir/xdvi-ptex.map",
- @tmpkanji1);
- }
-
- print "Generating output for ps2pk...\n" if !$quiet;
- my @ps2pk_map = &transLW35($ps2pk35);
- push @ps2pk_map, &getLines(@tmp1);
- push @ps2pk_map, &getLines(@tmp2);
- &writeLines(">$dvipsoutputdir/ps2pk.map",
- &normalizeLines(@ps2pk_map));
-
- print "Generating output for dvips...\n" if !$quiet;
- my @download35_map = &transLW35($ps2pk35);
- &writeLines(">$dvipsoutputdir/download35.map",
- &normalizeLines(@download35_map));
-
- my @builtin35_map = &transLW35($dvips35);
- &writeLines(">$dvipsoutputdir/builtin35.map",
- &normalizeLines(@builtin35_map));
-
- my $dftdvips = ($dvipsDownloadBase35 ? $ps2pk35 : $dvips35);
-
- my @psfonts_t1_map = &transLW35($dftdvips);
- my @tmpkanji2 = &cidx2dvips(\@tmpkanji1);
- push @psfonts_t1_map, &getLines(@tmp1);
- push @psfonts_t1_map, &getLines(@tmp2);
- push @psfonts_t1_map, @tmpkanji2;
- &writeLines(">$dvipsoutputdir/psfonts_t1.map",
- &normalizeLines(@psfonts_t1_map));
-
- my @psfonts_pk_map = &transLW35($dftdvips);
- push @psfonts_pk_map, &getLines(@tmp2);
- push @psfonts_pk_map, @tmpkanji2;
- &writeLines(">$dvipsoutputdir/psfonts_pk.map",
- &normalizeLines(@psfonts_pk_map));
-
- print "Generating output for pdftex...\n" if !$quiet;
- # remove PaintType due to Sebastian's request
- my @tmp3 = &transLW35($pdftex35);
- push @tmp3, &getLines(@tmp1);
- push @tmp3, &getLines(@tmp2);
- @tmp3 = grep { $_ !~ m/(^%|PaintType)/ } @tmp3;
-
- my @tmp7 = &transLW35($ps2pk35);
- push @tmp7, &getLines(@tmp1);
- push @tmp7, &getLines(@tmp2);
- @tmp7 = grep { $_ !~ m/(^%|PaintType)/ } @tmp7;
-
- my @pdftex_ndl14_map = @tmp3;
- @pdftex_ndl14_map = &normalizeLines(@pdftex_ndl14_map);
- @pdftex_ndl14_map = &to_pdftex(@pdftex_ndl14_map);
- &writeLines(">$pdftexoutputdir/pdftex_ndl14.map", @pdftex_ndl14_map);
-
- my @pdftex_dl14_map = @tmp7;
- @pdftex_dl14_map = &normalizeLines(@pdftex_dl14_map);
- @pdftex_dl14_map = &to_pdftex(@pdftex_dl14_map);
- &writeLines(">$pdftexoutputdir/pdftex_dl14.map", @pdftex_dl14_map);
-
- &setupSymlinks;
-
- &wlog ("\nFiles generated:\n");
- sub dir {
- my ($d, $f, $target)=@_;
- if (-e "$d/$f") {
- my @stat=lstat("$d/$f");
- my ($s,$m,$h,$D,$M,$Y)=localtime($stat[9]);
- my $timestamp=sprintf ("%04d-%02d-%02d %02d:%02d:%02d",
- $Y+1900, $M+1, $D, $h, $m, $s);
- my $date=sprintf "%12d %s %s", $stat[7], $timestamp, $f;
- &wlog ($date);
-
- if (-l "$d/$f") {
- my $lnk=sprintf " -> %s\n", readlink ("$d/$f");
- &wlog ($lnk);
- } elsif ($f eq $target) {
- if (&files_are_identical("$d/$f", "$d/$link{$target}")) {
- &wlog (" = $link{$target}\n");
- } else {
- &wlog (" = ?????\n"); # This shouldn't happen.
- }
- } else {
- &wlog ("\n");
- }
- } else {
- print STDERR "Warning: File $d/$f doesn't exist.\n";
- print LOG "Warning: File $d/$f doesn't exist.\n";
- }
- }
- my $d;
- $d="$dvipsoutputdir"; &wlog (" $d:\n");
- foreach my $f ('builtin35.map', 'download35.map', 'psfonts_pk.map',
- 'psfonts_t1.map', 'ps2pk.map', 'psfonts.map') {
- dir ($d, $f, 'psfonts.map');
- $updLSR->{add}("$d/$f");
- }
- $d="$pdftexoutputdir"; &wlog (" $d:\n");
- foreach my $f ('pdftex_dl14.map', 'pdftex_ndl14.map', 'pdftex.map') {
- dir ($d, $f, 'pdftex.map');
- $updLSR->{add}("$d/$f");
- }
- $d="$dvipdfmoutputdir"; &wlog (" $d:\n");
- foreach my $f ('kanjix.map') {
- dir ($d, $f, '');
- $updLSR->{add}("$d/$f");
- }
- if ($pxdviUse) {
- $d="$pxdvioutputdir"; &wlog (" $d:\n");
- foreach my $f ('xdvi-ptex.map') {
- dir ($d, $f, '');
- $updLSR->{add}("$d/$f");
- }
- }
- close LOG;
- print "\nTranscript written on \"$logfile\".\n" if !$quiet;
-}
-
-
-###############################################################################
-# initVars()
-# initialize global variables
-#
-sub initVars {
- $quiet = 0;
- $nohash = 0;
- $nomkmap = 0;
- $cnfFile = "";
- $cnfFileShort = "updmap.cfg";
- $outputdir = "";
- chomp($TEXMFMAIN =`kpsewhich --var-value=TEXMFMAIN`);
-
- @psADOBE = (
- 's/ URWGothicL-Demi / AvantGarde-Demi /',
- 's/ URWGothicL-DemiObli / AvantGarde-DemiOblique /',
- 's/ URWGothicL-Book / AvantGarde-Book /',
- 's/ URWGothicL-BookObli / AvantGarde-BookOblique /',
- 's/ URWBookmanL-DemiBold / Bookman-Demi /',
- 's/ URWBookmanL-DemiBoldItal / Bookman-DemiItalic /',
- 's/ URWBookmanL-Ligh / Bookman-Light /',
- 's/ URWBookmanL-LighItal / Bookman-LightItalic /',
- 's/ NimbusMonL-Bold / Courier-Bold /',
- 's/ NimbusMonL-BoldObli / Courier-BoldOblique /',
- 's/ NimbusMonL-Regu / Courier /',
- 's/ NimbusMonL-ReguObli / Courier-Oblique /',
- 's/ NimbusSanL-Bold / Helvetica-Bold /',
- 's/ NimbusSanL-BoldCond / Helvetica-Narrow-Bold /',
- 's/ NimbusSanL-BoldItal / Helvetica-BoldOblique /',
- 's/ NimbusSanL-BoldCondItal / Helvetica-Narrow-BoldOblique /',
- 's/ NimbusSanL-Regu / Helvetica /',
- 's/ NimbusSanL-ReguCond / Helvetica-Narrow /',
- 's/ NimbusSanL-ReguItal / Helvetica-Oblique /',
- 's/ NimbusSanL-ReguCondItal / Helvetica-Narrow-Oblique /',
- 's/ CenturySchL-Bold / NewCenturySchlbk-Bold /',
- 's/ CenturySchL-BoldItal / NewCenturySchlbk-BoldItalic /',
- 's/ CenturySchL-Roma / NewCenturySchlbk-Roman /',
- 's/ CenturySchL-Ital / NewCenturySchlbk-Italic /',
- 's/ URWPalladioL-Bold / Palatino-Bold /',
- 's/ URWPalladioL-BoldItal / Palatino-BoldItalic /',
- 's/ URWPalladioL-Roma / Palatino-Roman /',
- 's/ URWPalladioL-Ital / Palatino-Italic /',
- 's/ StandardSymL / Symbol /',
- 's/ NimbusRomNo9L-Medi / Times-Bold /',
- 's/ NimbusRomNo9L-MediItal / Times-BoldItalic /',
- 's/ NimbusRomNo9L-Regu / Times-Roman /',
- 's/ NimbusRomNo9L-ReguItal / Times-Italic /',
- 's/ URWChanceryL-MediItal / ZapfChancery-MediumItalic /',
- 's/ Dingbats / ZapfDingbats /',
- );
-
- @fileADOBEkb = (
- 's/\buagd8a.pfb\b/pagd8a.pfb/',
- 's/\buagdo8a.pfb\b/pagdo8a.pfb/',
- 's/\buagk8a.pfb\b/pagk8a.pfb/',
- 's/\buagko8a.pfb\b/pagko8a.pfb/',
- 's/\bubkd8a.pfb\b/pbkd8a.pfb/',
- 's/\bubkdi8a.pfb\b/pbkdi8a.pfb/',
- 's/\bubkl8a.pfb\b/pbkl8a.pfb/',
- 's/\bubkli8a.pfb\b/pbkli8a.pfb/',
- 's/\bucrb8a.pfb\b/pcrb8a.pfb/',
- 's/\bucrbo8a.pfb\b/pcrbo8a.pfb/',
- 's/\bucrr8a.pfb\b/pcrr8a.pfb/',
- 's/\bucrro8a.pfb\b/pcrro8a.pfb/',
- 's/\buhvb8a.pfb\b/phvb8a.pfb/',
- 's/\buhvb8ac.pfb\b/phvb8an.pfb/',
- 's/\buhvbo8a.pfb\b/phvbo8a.pfb/',
- 's/\buhvbo8ac.pfb\b/phvbo8an.pfb/',
- 's/\buhvr8a.pfb\b/phvr8a.pfb/',
- 's/\buhvr8ac.pfb\b/phvr8an.pfb/',
- 's/\buhvro8a.pfb\b/phvro8a.pfb/',
- 's/\buhvro8ac.pfb\b/phvro8an.pfb/',
- 's/\buncb8a.pfb\b/pncb8a.pfb/',
- 's/\buncbi8a.pfb\b/pncbi8a.pfb/',
- 's/\buncr8a.pfb\b/pncr8a.pfb/',
- 's/\buncri8a.pfb\b/pncri8a.pfb/',
- 's/\buplb8a.pfb\b/pplb8a.pfb/',
- 's/\buplbi8a.pfb\b/pplbi8a.pfb/',
- 's/\buplr8a.pfb\b/pplr8a.pfb/',
- 's/\buplri8a.pfb\b/pplri8a.pfb/',
- 's/\busyr.pfb\b/psyr.pfb/',
- 's/\butmb8a.pfb\b/ptmb8a.pfb/',
- 's/\butmbi8a.pfb\b/ptmbi8a.pfb/',
- 's/\butmr8a.pfb\b/ptmr8a.pfb/',
- 's/\butmri8a.pfb\b/ptmri8a.pfb/',
- 's/\buzcmi8a.pfb\b/pzcmi8a.pfb/',
- 's/\buzdr.pfb\b/pzdr.pfb/',
- );
-
- @fileURW = (
- 's/\buagd8a.pfb\b/a010015l.pfb/',
- 's/\buagdo8a.pfb\b/a010035l.pfb/',
- 's/\buagk8a.pfb\b/a010013l.pfb/',
- 's/\buagko8a.pfb\b/a010033l.pfb/',
- 's/\bubkd8a.pfb\b/b018015l.pfb/',
- 's/\bubkdi8a.pfb\b/b018035l.pfb/',
- 's/\bubkl8a.pfb\b/b018012l.pfb/',
- 's/\bubkli8a.pfb\b/b018032l.pfb/',
- 's/\bucrb8a.pfb\b/n022004l.pfb/',
- 's/\bucrbo8a.pfb\b/n022024l.pfb/',
- 's/\bucrr8a.pfb\b/n022003l.pfb/',
- 's/\bucrro8a.pfb\b/n022023l.pfb/',
- 's/\buhvb8a.pfb\b/n019004l.pfb/',
- 's/\buhvb8ac.pfb\b/n019044l.pfb/',
- 's/\buhvbo8a.pfb\b/n019024l.pfb/',
- 's/\buhvbo8ac.pfb\b/n019064l.pfb/',
- 's/\buhvr8a.pfb\b/n019003l.pfb/',
- 's/\buhvr8ac.pfb\b/n019043l.pfb/',
- 's/\buhvro8a.pfb\b/n019023l.pfb/',
- 's/\buhvro8ac.pfb\b/n019063l.pfb/',
- 's/\buncb8a.pfb\b/c059016l.pfb/',
- 's/\buncbi8a.pfb\b/c059036l.pfb/',
- 's/\buncr8a.pfb\b/c059013l.pfb/',
- 's/\buncri8a.pfb\b/c059033l.pfb/',
- 's/\buplb8a.pfb\b/p052004l.pfb/',
- 's/\buplbi8a.pfb\b/p052024l.pfb/',
- 's/\buplr8a.pfb\b/p052003l.pfb/',
- 's/\buplri8a.pfb\b/p052023l.pfb/',
- 's/\busyr.pfb\b/s050000l.pfb/',
- 's/\butmb8a.pfb\b/n021004l.pfb/',
- 's/\butmbi8a.pfb\b/n021024l.pfb/',
- 's/\butmr8a.pfb\b/n021003l.pfb/',
- 's/\butmri8a.pfb\b/n021023l.pfb/',
- 's/\buzcmi8a.pfb\b/z003034l.pfb/',
- 's/\buzdr.pfb\b/d050000l.pfb/',
- );
-
- @fileADOBE = (
- 's/\buagd8a.pfb\b/agd_____.pfb/',
- 's/\buagdo8a.pfb\b/agdo____.pfb/',
- 's/\buagk8a.pfb\b/agw_____.pfb/',
- 's/\buagko8a.pfb\b/agwo____.pfb/',
- 's/\bubkd8a.pfb\b/bkd_____.pfb/',
- 's/\bubkdi8a.pfb\b/bkdi____.pfb/',
- 's/\bubkl8a.pfb\b/bkl_____.pfb/',
- 's/\bubkli8a.pfb\b/bkli____.pfb/',
- 's/\bucrb8a.pfb\b/cob_____.pfb/',
- 's/\bucrbo8a.pfb\b/cobo____.pfb/',
- 's/\bucrr8a.pfb\b/com_____.pfb/',
- 's/\bucrro8a.pfb\b/coo_____.pfb/',
- 's/\buhvb8a.pfb\b/hvb_____.pfb/',
- 's/\buhvb8ac.pfb\b/hvnb____.pfb/',
- 's/\buhvbo8a.pfb\b/hvbo____.pfb/',
- 's/\buhvbo8ac.pfb\b/hvnbo___.pfb/',
- 's/\buhvr8a.pfb\b/hv______.pfb/',
- 's/\buhvr8ac.pfb\b/hvn_____.pfb/',
- 's/\buhvro8a.pfb\b/hvo_____.pfb/',
- 's/\buhvro8ac.pfb\b/hvno____.pfb/',
- 's/\buncb8a.pfb\b/ncb_____.pfb/',
- 's/\buncbi8a.pfb\b/ncbi____.pfb/',
- 's/\buncr8a.pfb\b/ncr_____.pfb/',
- 's/\buncri8a.pfb\b/nci_____.pfb/',
- 's/\buplb8a.pfb\b/pob_____.pfb/',
- 's/\buplbi8a.pfb\b/pobi____.pfb/',
- 's/\buplr8a.pfb\b/por_____.pfb/',
- 's/\buplri8a.pfb\b/poi_____.pfb/',
- 's/\busyr.pfb\b/sy______.pfb/',
- 's/\butmb8a.pfb\b/tib_____.pfb/',
- 's/\butmbi8a.pfb\b/tibi____.pfb/',
- 's/\butmr8a.pfb\b/tir_____.pfb/',
- 's/\butmri8a.pfb\b/tii_____.pfb/',
- 's/\buzcmi8a.pfb\b/zcmi____.pfb/',
- 's/\buzdr.pfb\b/zd______.pfb/',
- );
-}
-
-
-###############################################################################
-# main()
-#
-sub main {
- &initVars;
- &processOptions;
-
- &help if ($opt_help);
-
- if (@showoptions) {
- &showOptions(@showoptions);
- exit 0;
- }
-
- &setupCfgFile;
-
- if (@showoption) {
- &showOption(@showoption);
- exit 0;
- }
- if ($listmaps) {
- &listMaps ('list');
- exit 0;
- }
- if ($listavailablemaps) {
- &listMaps ('avail');
- exit 0;
- }
- if ($syncwithtrees) {
- &listMaps ('sync');
- exit 0;
- }
-
- my $bakFile = $cnfFile;
- $bakFile =~ s/\.cfg$/.bak/;
- &copyFile($cnfFile, $bakFile);
-
- my $cmd = '';
-
- if ($opt_edit) {
- # it's not a good idea to edit updmap.cfg manually these days,
- # but for compatibility we'll silently keep the option.
- $cmd = 'edit';
- my $editor = $ENV{'VISUAL'} || $ENV{'EDITOR'};
- $editor ||= (&win32 ? "notepad" : "vi");
- system($editor, $cnfFile);
-
- } elsif (@setoptions) {
- $cmd = 'setOption';
- &setOptions (@setoptions);
-
- } elsif ($enableItem) {
- $cmd = 'enableMap';
- if ($enableItem =~ /=/) {
- &enableMap(split('=', $enableItem));
- } else {
- &enableMap($enableItem, shift @ARGV);
- }
-
- } elsif (@disableItem) {
- $cmd = 'disableMap';
- foreach my $m (@disableItem) {
- &disableMap($m);
- }
- }
-
- if ($cmd && !$opt_force && &files_are_equal($bakFile, $cnfFile)) {
- print "$cnfFile unchanged. Map files not recreated.\n" if !$quiet;
- } else {
- if (! $nomkmap) {
- &setupDestDir;
- &mkMaps;
- }
- unlink ($bakFile);
- }
-
- unless ($nohash) {
- print "$0: Updating ls-R files.\n" if !$quiet;
- $updLSR->{exec}()
- }
-}
-__END__
-
-### Local Variables:
-### perl-indent-level: 2
-### tab-width: 2
-### indent-tabs-mode: nil
-### End:
-# vim:set tabstop=2 expandtab: #
diff --git a/Master/texmf/scripts/tetex/updmap.pl b/Master/texmf/scripts/tetex/updmap.pl
new file mode 100755
index 00000000000..dc665fbc81e
--- /dev/null
+++ b/Master/texmf/scripts/tetex/updmap.pl
@@ -0,0 +1,2059 @@
+#!/usr/bin/env perl
+# mupdmap: utility to maintain map files for outline fonts.
+# $Id: updmap.pl 26369 2012-05-14 15:00:53Z preining $
+#
+# Copyright 2011, 2012 Norbert Preining
+# This file is licensed under the GNU General Public License version 2
+# or any later version.
+#
+# History:
+# Original shell script (C) 2002 Thomas Esser
+# first perl variant (C) Fabrice Popineau
+# later adaptions by Reinhard Kotucha and Karl Berry
+# the original versions were licensed under the following agreement:
+# Anyone may freely use, modify, and/or distribute this file, without
+# limitation.
+#
+# TODO
+# - check all other invocations
+# - after TL2012? remove -oldmode version
+# - after TL2012? Maybe remove support for reading updmap-local.cfg
+#
+
+my $TEXMFROOT;
+
+BEGIN {
+ $^W=1;
+ $TEXMFROOT = `kpsewhich -var-value=TEXMFROOT`;
+ if ($?) {
+ print STDERR "(m)updmap: Cannot find TEXMFROOT, aborting!\n";
+ exit 1;
+ }
+ chomp($TEXMFROOT);
+ unshift (@INC, "$TEXMFROOT/tlpkg");
+}
+
+
+my $version = '$Id: updmap.pl 26369 2012-05-14 15:00:53Z preining $';
+
+use Getopt::Long qw(:config no_autoabbrev ignore_case_always);
+use strict;
+use TeXLive::TLUtils qw(mkdirhier mktexupd win32 basename dirname
+ sort_uniq member);
+
+#use Data::Dumper;
+#$Data::Dumper::Indent = 1;
+
+chomp(my $TEXMFMAIN = `kpsewhich --var-value=TEXMFMAIN`);
+chomp(my $TEXMFVAR = `kpsewhich -var-value=TEXMFVAR`);
+chomp(my $TEXMFCONFIG = `kpsewhich -var-value=TEXMFCONFIG`);
+
+# make sure that on windows *everything* is in lower case for comparison
+if (win32()) {
+ $TEXMFMAIN = lc($TEXMFMAIN);
+ $TEXMFVAR = lc($TEXMFVAR);
+ $TEXMFCONFIG = lc($TEXMFCONFIG);
+ $TEXMFROOT = lc($TEXMFROOT);
+}
+
+my $prg = basename($0);
+
+my %opts = ( quiet => 0, nohash => 0, nomkmap => 0 );
+my $alldata;
+my $updLSR;
+
+my @cmdline_options = (
+ "oldmode",
+ "cnffile=s@",
+ "copy",
+ "disable=s@",
+ "dvipdfmoutputdir=s",
+ "dvipdfmxoutputdir=s",
+ "dvipsoutputdir=s",
+ # the following does not work, Getopt::Long looses the first
+ # entry in a multi setting, treat it separately in processOptions
+ # furthermore, it is not supported by older perls, so do it differently
+ #"enable=s{1,2}",
+ "edit",
+ "force",
+ "listavailablemaps",
+ "listmaps|l",
+ "nohash",
+ "nomkmap",
+ "dry-run|n",
+ "outputdir=s",
+ "pdftexoutputdir=s",
+ "pxdvioutputdir=s",
+ "quiet|silent|q",
+ # the following is a correct specification of an option according
+ # to the manual, but it does not work!
+ # we will treat that option by itself in processOptions
+ # furthermore, it is not supported by older perls, so do it differently
+ #"setoption=s@{1,2}",
+ "showoptions=s@",
+ "showoption=s@",
+ "syncwithtrees",
+ "version",
+ "help|h",
+ # some debugging invocations
+ "_readsave=s",
+ "_listupdmap",
+ );
+
+my %settings = (
+ dvipsPreferOutline => {
+ type => "binary",
+ default => "true",
+ },
+ LW35 => {
+ type => "string",
+ possible => [ qw/URW URWkb ADOBE ADOBEkb/ ],
+ default => "URWkb",
+ },
+ dvipsDownloadBase35 => {
+ type => "binary",
+ default => "true",
+ },
+ pdftexDownloadBase14 => {
+ type => "binary",
+ default => "true",
+ },
+ dvipdfmDownloadBase14 => {
+ type => "binary",
+ default => "true",
+ },
+ pxdviUse => {
+ type => "binary",
+ default => "false",
+ },
+ kanjiEmbed => {
+ type => "any",
+ default => "noEmbed",
+ },
+ kanjiVariant => {
+ type => "any",
+ default => "",
+ },
+);
+
+&main();
+
+###############
+
+sub main {
+ processOptions();
+
+ help() if $opts{'help'};
+
+ if ($opts{'version'}) {
+ print version();
+ exit (0);
+ }
+
+ if ($opts{'dvipdfmoutputdir'} && !defined($opts{'dvipdfmxoutputdir'})) {
+ $opts{'dvipdfmxoutputdir'} = $opts{'dvipdfmoutputdir'};
+ printf STDERR "Using --dvipdfmoutputdir options for dvipdfmx, but please use --dvipdfmxoutputdir\n";
+ }
+
+ if ($opts{'dvipdfmoutputdir'} && $opts{'dvipdfmxoutputdir'} &&
+ $opts{'dvipdfmoutputdir'} ne $opts{'dvipdfmxoutputdir'}) {
+ printf STDERR "Options for --dvipdfmoutputdir and --dvipdfmxoutputdir do not agree\nplease use only --dvipdfmxoutputdir. Exiting.\n";
+ exit(1);
+ }
+
+ if ($opts{'_readsave'}) {
+ read_updmap_files($opts{'_readsave'});
+ print "READING DONE ============================\n";
+ #print Dumper($alldata);
+ $alldata->{'updmap'}{$opts{'_readsave'}}{'changed'} = 1;
+ save_updmap($opts{'_readsave'});
+ exit 0;
+ }
+
+ if ($opts{'showoptions'}) {
+ for my $o (@{$opts{'showoptions'}}) {
+ if (defined($settings{$o})) {
+ if ($settings{$o}{'type'} eq "binary") {
+ print "true false\n";
+ } elsif ($settings{$o}{'type'} eq "string") {
+ print "@{$settings{$o}{'possible'}}\n";
+ } elsif ($settings{$o}{'type'} eq "any") {
+ print "(any string)\n";
+ } else {
+ print "strange: unknown type of option $o\nplease report\n";
+ }
+ } else {
+ print "$prg: unknown option: $o\n";
+ }
+ }
+ exit 0;
+ }
+
+ # config file for changes
+ my $changes_config_file;
+
+ # determine which config files should be used
+ # replaces the former "setupCfgFile"
+ #
+ # we also determine here where changes will be saved to
+ if ($opts{'cnffile'}) {
+ for my $f (@{$opts{'cnffile'}}) {
+ if (! -f $f) {
+ die "$prg: Config file \"$f\" not found.";
+ }
+ }
+ # in case that config files are given on the command line, the first
+ # in the list is the one where changes will be written to.
+ ($changes_config_file) = @{$opts{'cnffile'}};
+ } else {
+ my @all_files = `kpsewhich -all updmap.cfg`;
+ chomp(@all_files);
+ my @used_files;
+ #
+ # in --oldmode we ignore texmf/web2c/updmap.cfg and reorder some
+ # order to get things right
+ # without --oldmode everything will be used as default to, i.e.
+ # the order is given by kpsewhich -all updmap.cfg
+ if (!$opts{"oldmode"}) {
+ push @used_files, @all_files;
+ } else {
+ # --oldmode
+ for my $f (@all_files) {
+ # make sure that all file names are lower case on windows for comparison
+ $f = lc($f) if win32();
+ if ($f =~ m!$TEXMFROOT/texmf/web2c/updmap.cfg!) {
+ warning("Ignoring $f, it is only a sample file!\n");
+ } else {
+ push @used_files, $f;
+ }
+ }
+ }
+ #
+ # reorder used files: since we ship and manage with tlmgr
+ # the file in TEXMFSYSCONFIG, and TEXMFLOCAL has *lower* priority
+ # then TEXMFSYSCONFIG, we move a TEXMFLOCAL-updmap.cfg if found
+ # after TEXMFCONFIG TEXMFVAR and TEXMFHOME
+ chomp(my $TEXMFLOCAL =`kpsewhich --var-value=TEXMFLOCAL`);
+ chomp(my $TEXMFHOME =`kpsewhich --var-value=TEXMFHOME`);
+ if (win32()) {
+ $TEXMFLOCAL = lc($TEXMFLOCAL);
+ $TEXMFHOME = lc($TEXMFHOME);
+ }
+ my $found = 0;
+ my $TMLabs = Cwd::abs_path($TEXMFLOCAL);
+ if ($TMLabs) {
+ for my $f (@used_files) {
+ my $absf = Cwd::abs_path($f); #should always work
+ if ($absf =~ m/^$TMLabs/) {
+ $found = 1;
+ last;
+ }
+ }
+ }
+ my $old_updmap_local_found = 0;
+ if (-r "$TMLabs/web2c/updmap-local.cfg") {
+ $old_updmap_local_found = 1;
+ warning("Old configuration file TEXMFLOCAL/web2c/updmap-local.cfg found!\n");
+ if ($found) {
+ warning("Will read this file *instead* of TEXMFLOCAL/web2c/updmap.cfg!!!\n");
+ } else {
+ # if TEXMFLOCAL updmap.cfg does not exist, we have to make sure
+ # that the replacement is added to the list of updmap files
+ push @used_files, "$TMLabs/web2c/updmap-local.cfg";
+ }
+ warning("Please consider moving the information from updmap-local.cfg to TEXMFLOCAL/web2c/updmap.cfg\n");
+ }
+ if ($found || $old_updmap_local_found) {
+ my @tmp;
+ my $local_pushed = 0;
+ for my $f (@used_files) {
+ if ($f =~ m!$TEXMFCONFIG|$TEXMFVAR|$TEXMFHOME!) {
+ push @tmp, $f;
+ } else {
+ if (!$local_pushed) {
+ # should we use the return value of grep here, but we know
+ # what we will find?!?!
+ if ($old_updmap_local_found) {
+ push @tmp, "$TEXMFLOCAL/web2c/updmap-local.cfg";
+ } else {
+ push @tmp, "$TEXMFLOCAL/web2c/updmap.cfg";
+ }
+ $local_pushed = 1;
+ }
+ # push the original
+ push @tmp, $f unless ($f =~ m!$TEXMFLOCAL!);
+ }
+ }
+ @used_files = @tmp;
+ }
+ @{$opts{'cnffile'}} = @used_files;
+ # determine the config file that we will use for changes
+ # if in the list of used files contains either one from
+ # TEXMFHOME or TEXMFCONFIG (which is TEXMFSYSCONFIG in the -sys case)
+ # then use the *top* file (which will be either one of the two),
+ # if none of the two exists, create a file in TEXMFCONFIG and use it
+ my $use_top = 0;
+ for my $f (@used_files) {
+ if ($f =~ m!($TEXMFHOME|$TEXMFCONFIG)/web2c/updmap.cfg!) {
+ $use_top = 1;
+ last;
+ }
+ }
+ if ($use_top) {
+ ($changes_config_file) = @used_files;
+ } else {
+ # add the empty config file
+ my $dn = "$TEXMFCONFIG/web2c";
+ $changes_config_file = "$dn/updmap.cfg";
+ }
+ }
+ if (!$opts{'quiet'}) {
+ print "$prg is using the following updmap.cfg files (in precedence order):\n";
+ for my $f (@{$opts{'cnffile'}}) {
+ print " $f\n";
+ }
+ }
+ $alldata->{'changes_config'} = $changes_config_file;
+
+ if ($opts{'_listupdmap'}) {
+ exit 0;
+ }
+
+ read_updmap_files(@{$opts{'cnffile'}});
+
+ if ($opts{'showoption'}) {
+ for my $o (@{$opts{'showoption'}}) {
+ if (defined($settings{$o})) {
+ my ($v, $vo) = get_cfg($o);
+ $v = "\"$v\"" if ($v =~ m/\s/);
+ print "$o=$v ($vo)\n";
+ } else {
+ printf STDERR "$prg: unknown option: $o\n";
+ }
+ }
+ exit 0;
+ }
+
+ if ($opts{'listmaps'}) {
+ for my $m (keys %{$alldata->{'maps'}}) {
+ my $origin = $alldata->{'maps'}{$m}{'origin'};
+ print $alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'}, " $m ",
+ $alldata->{'updmap'}{$origin}{'maps'}{$m}{'status'}, " in $origin\n";
+ }
+ exit 0;
+ }
+
+ # we do changes always in the used config file with the highest
+ # priority
+ my $bakFile = $changes_config_file;
+ $bakFile =~ s/\.cfg$/.bak/;
+ my $changed = 0;
+
+ if ($opts{'syncwithtrees'}) {
+ my @missing = read_map_files();
+ if (@missing) {
+ print "Missing map files found, disabling\n @missing\nin $changes_config_file\n";
+ $changed ||= enable_disable_maps(@missing);
+ # the original script did not run any update of the map files here,
+ # should we do that?
+ }
+ exit 0;
+ }
+
+ # what does this?
+ $updLSR = &mktexupd();
+ $updLSR->{mustexist}(0);
+
+ my $cmd;
+ if ($opts{'edit'}) {
+ if ($opts{"dry-run"}) {
+ printf STDERR "No, are you joking, you want to edit with --dry-run?\n";
+ printf STDERR "Not doing that, bye bye!\n";
+ exit 1;
+ }
+ # it's not a good idea to edit updmap.cfg manually these days,
+ # but for compatibility we'll silently keep the option.
+ $cmd = 'edit';
+ my $editor = $ENV{'VISUAL'} || $ENV{'EDITOR'};
+ $editor ||= (&win32 ? "notepad" : "vi");
+ if (-r $changes_config_file) {
+ &copyFile($changes_config_file, $bakFile);
+ } else {
+ touch($bakFile);
+ touch($changes_config_file);
+ }
+ system($editor, $changes_config_file);
+ $changed = files_are_different($bakFile, $changes_config_file);
+ } elsif ($opts{'setoption'}) {
+ $cmd = 'setOption';
+ $changed = setOptions (@{$opts{'setoption'}});
+ } elsif ($opts{'enable'} || $opts{'disable'}) {
+ $cmd = 'enableMap';
+ $changed ||= enable_disable_maps(@{$opts{'enable'}}, @{$opts{'disable'}});
+ }
+
+
+ if ($cmd && !$opts{'force'} && !$changed) {
+ print "$changes_config_file unchanged. Map files not recreated.\n"
+ if !$opts{'quiet'};
+ } else {
+ if (!$opts{'nomkmap'}) {
+ # before we continue we have to make sure that a newly created config
+ # file is acually used. So we have to push the $changes_config_file
+ # onto the list of available files. Since it is already properly
+ # initialized and the merging is done later, all settings should be
+ # honored
+ my @aaa = @{$alldata->{'order'}};
+ unshift @aaa, $changes_config_file;
+ $alldata->{'order'} = [ @aaa ];
+ #
+ # since things have changed, reread the whole updmap files
+ if ($changed) {
+ delete $alldata->{'updmap'};
+ delete $alldata->{'maps'};
+ read_updmap_files(@{$opts{'cnffile'}}) if $changed;
+ }
+ #
+ setupOutputDir("dvips");
+ setupOutputDir("pdftex");
+ setupOutputDir("dvipdfmx");
+ setupOutputDir("pxdvi");
+ my @missing = read_map_files();
+ if (@missing) {
+ print STDERR "\nERROR: The following map file(s) couldn't be found:\n";
+ for my $m (@missing) {
+ my $orig = $alldata->{'maps'}{$m}{'origin'};
+ print STDERR "\t$m (in $orig)\n";
+ }
+ print STDERR "\n\tDid you run mktexlsr?\n\n" .
+ "\tYou can disable non-existent map entries using the option\n".
+ "\t --syncwithtrees.\n\n";
+ exit 1;
+ }
+ merge_data();
+ # for inspecting the output
+ #print STDERR Data::Dumper->Dump([$alldata], [qw(mapdata)]);
+ #print Dumper($alldata);
+ mkMaps();
+ }
+ unlink ($bakFile) if (-r $bakFile);
+ }
+
+ if (!$opts{'nohash'}) {
+ print "$prg: Updating ls-R files.\n" if !$opts{'quiet'};
+ $updLSR->{exec}() unless $opts{"dry-run"};
+ }
+
+ return 0;
+}
+
+##################################################################
+#
+#
+
+sub getFonts {
+ my ($first, @rest) = @_;
+ my $getall = 0;
+ my @maps = ();
+ return if !defined($first);
+ if ($first eq "-all") {
+ $getall = 1;
+ @maps = @rest;
+ } else {
+ @maps = ($first, @rest);
+ }
+ my @lines = ();
+ for my $m (@maps) {
+ if (defined($alldata->{'maps'}{$m})) {
+ print LOG "\n" . $alldata->{'maps'}{$m}{'fullpath'} . ":\n" unless $opts{'dry-run'};
+ push @lines, "% $m";
+ for my $k (sort keys %{$alldata->{'maps'}{$m}{'fonts'}}) {
+ if ($getall || $alldata->{'fonts'}{$k}{'origin'} eq $m) {
+ if (defined($alldata->{'maps'}{$m}{'fonts'}{$k})) {
+ push @lines, "$k " . $alldata->{'maps'}{$m}{'fonts'}{$k};
+ } else {
+ print "undefined fonts for $k in $m ?!?!?\n";
+ }
+ print LOG "$k\n" unless $opts{'dry-run'};
+ }
+ }
+ }
+ }
+ chomp @lines;
+ return @lines;
+}
+
+###############################################################################
+# writeLines()
+# write the lines in $filename
+#
+sub writeLines {
+ my ($fname, @lines) = @_;
+ return if $opts{"dry-run"};
+ map { ($_ !~ m/\n$/ ? s/$/\n/ : $_ ) } @lines;
+ open FILE, ">$fname" or die "$prg: can't write lines to $fname: $!";
+ print FILE @lines;
+ close FILE;
+}
+
+###############################################################################
+# to_pdftex()
+# if $pdftexStripEnc is set, strip "PS_Encoding_Name ReEncodeFont"
+# from map entries; they are ignored by pdftex. But since the sh
+# incarnation of updmap included them, and we want to minimize
+# differences, this is not done by default.
+#
+sub to_pdftex {
+ my $pdftexStripEnc = 0;
+ return @_ unless $pdftexStripEnc;
+ my @in = @_;
+ my @out;
+ foreach my $line (@in) {
+ if ($line =~ /^(.*\s+)(\S+\s+ReEncodeFont\s)(.*)/) {
+ $line = "$1$3";
+ $line =~ s/\s+\"\s+\"\s+/ /;
+ }
+ push @out, $line;
+ }
+ return @out;
+}
+
+###############################################################################
+# setupSymlinks()
+# set symlink for psfonts.map according to dvipsPreferOutline variable
+#
+sub setupSymlinks {
+ my ($dvipsPreferOutline, $dvipsoutputdir, $pdftexDownloadBase14, $pdftexoutputdir) = @_;
+ my $src;
+ my %link;
+ my @link;
+
+ if ($dvipsPreferOutline eq "true") {
+ $src = "psfonts_t1.map";
+ } else {
+ $src = "psfonts_pk.map";
+ }
+ unlink "$dvipsoutputdir/psfonts.map" unless $opts{"dry-run"};
+ push @link, &SymlinkOrCopy("$dvipsoutputdir", "$src", "psfonts.map");
+
+ if ($pdftexDownloadBase14 eq "true") {
+ $src = "pdftex_dl14.map";
+ } else {
+ $src = "pdftex_ndl14.map";
+ }
+ unlink "$pdftexoutputdir/pdftex.map" unless $opts{"dry-run"};
+ push @link, &SymlinkOrCopy("$pdftexoutputdir", "$src", "pdftex.map");
+ %link = @link;
+ return \%link;
+}
+
+###############################################################################
+# SymlinkOrCopy(dir, src, dest)
+# create symlinks if possible, otherwise copy files
+#
+sub SymlinkOrCopy {
+ my ($dir, $src, $dest) = @_;
+ return ($src, $dest) if $opts{"dry-run"};
+ if (&win32 || $opts{'copy'}) { # always copy
+ &copyFile("$dir/$src", "$dir/$dest");
+ } else { # symlink if supported by fs, copy otherwise
+ system("cd \"$dir\" && ln -s $src $dest 2>/dev/null || "
+ . "cp -p \"$dir/$src\" \"$dir/$dest\"");
+ }
+ # remember for "Files generated" in &mkMaps.
+ return ($dest, $src);
+}
+
+
+###############################################################################
+# transLW35(mode args ...)
+# transform fontname and filenames according to transformation specified
+# by mode. Possible values:
+# URW|URWkb|ADOBE|ADOBEkb
+#
+sub transLW35 {
+ my ($mode, @lines) = @_;
+
+ my @psADOBE = (
+ 's/ URWGothicL-Demi / AvantGarde-Demi /',
+ 's/ URWGothicL-DemiObli / AvantGarde-DemiOblique /',
+ 's/ URWGothicL-Book / AvantGarde-Book /',
+ 's/ URWGothicL-BookObli / AvantGarde-BookOblique /',
+ 's/ URWBookmanL-DemiBold / Bookman-Demi /',
+ 's/ URWBookmanL-DemiBoldItal / Bookman-DemiItalic /',
+ 's/ URWBookmanL-Ligh / Bookman-Light /',
+ 's/ URWBookmanL-LighItal / Bookman-LightItalic /',
+ 's/ NimbusMonL-Bold / Courier-Bold /',
+ 's/ NimbusMonL-BoldObli / Courier-BoldOblique /',
+ 's/ NimbusMonL-Regu / Courier /',
+ 's/ NimbusMonL-ReguObli / Courier-Oblique /',
+ 's/ NimbusSanL-Bold / Helvetica-Bold /',
+ 's/ NimbusSanL-BoldCond / Helvetica-Narrow-Bold /',
+ 's/ NimbusSanL-BoldItal / Helvetica-BoldOblique /',
+ 's/ NimbusSanL-BoldCondItal / Helvetica-Narrow-BoldOblique /',
+ 's/ NimbusSanL-Regu / Helvetica /',
+ 's/ NimbusSanL-ReguCond / Helvetica-Narrow /',
+ 's/ NimbusSanL-ReguItal / Helvetica-Oblique /',
+ 's/ NimbusSanL-ReguCondItal / Helvetica-Narrow-Oblique /',
+ 's/ CenturySchL-Bold / NewCenturySchlbk-Bold /',
+ 's/ CenturySchL-BoldItal / NewCenturySchlbk-BoldItalic /',
+ 's/ CenturySchL-Roma / NewCenturySchlbk-Roman /',
+ 's/ CenturySchL-Ital / NewCenturySchlbk-Italic /',
+ 's/ URWPalladioL-Bold / Palatino-Bold /',
+ 's/ URWPalladioL-BoldItal / Palatino-BoldItalic /',
+ 's/ URWPalladioL-Roma / Palatino-Roman /',
+ 's/ URWPalladioL-Ital / Palatino-Italic /',
+ 's/ StandardSymL / Symbol /',
+ 's/ NimbusRomNo9L-Medi / Times-Bold /',
+ 's/ NimbusRomNo9L-MediItal / Times-BoldItalic /',
+ 's/ NimbusRomNo9L-Regu / Times-Roman /',
+ 's/ NimbusRomNo9L-ReguItal / Times-Italic /',
+ 's/ URWChanceryL-MediItal / ZapfChancery-MediumItalic /',
+ 's/ Dingbats / ZapfDingbats /',
+ );
+
+ my @fileADOBEkb = (
+ 's/\buagd8a.pfb\b/pagd8a.pfb/',
+ 's/\buagdo8a.pfb\b/pagdo8a.pfb/',
+ 's/\buagk8a.pfb\b/pagk8a.pfb/',
+ 's/\buagko8a.pfb\b/pagko8a.pfb/',
+ 's/\bubkd8a.pfb\b/pbkd8a.pfb/',
+ 's/\bubkdi8a.pfb\b/pbkdi8a.pfb/',
+ 's/\bubkl8a.pfb\b/pbkl8a.pfb/',
+ 's/\bubkli8a.pfb\b/pbkli8a.pfb/',
+ 's/\bucrb8a.pfb\b/pcrb8a.pfb/',
+ 's/\bucrbo8a.pfb\b/pcrbo8a.pfb/',
+ 's/\bucrr8a.pfb\b/pcrr8a.pfb/',
+ 's/\bucrro8a.pfb\b/pcrro8a.pfb/',
+ 's/\buhvb8a.pfb\b/phvb8a.pfb/',
+ 's/\buhvb8ac.pfb\b/phvb8an.pfb/',
+ 's/\buhvbo8a.pfb\b/phvbo8a.pfb/',
+ 's/\buhvbo8ac.pfb\b/phvbo8an.pfb/',
+ 's/\buhvr8a.pfb\b/phvr8a.pfb/',
+ 's/\buhvr8ac.pfb\b/phvr8an.pfb/',
+ 's/\buhvro8a.pfb\b/phvro8a.pfb/',
+ 's/\buhvro8ac.pfb\b/phvro8an.pfb/',
+ 's/\buncb8a.pfb\b/pncb8a.pfb/',
+ 's/\buncbi8a.pfb\b/pncbi8a.pfb/',
+ 's/\buncr8a.pfb\b/pncr8a.pfb/',
+ 's/\buncri8a.pfb\b/pncri8a.pfb/',
+ 's/\buplb8a.pfb\b/pplb8a.pfb/',
+ 's/\buplbi8a.pfb\b/pplbi8a.pfb/',
+ 's/\buplr8a.pfb\b/pplr8a.pfb/',
+ 's/\buplri8a.pfb\b/pplri8a.pfb/',
+ 's/\busyr.pfb\b/psyr.pfb/',
+ 's/\butmb8a.pfb\b/ptmb8a.pfb/',
+ 's/\butmbi8a.pfb\b/ptmbi8a.pfb/',
+ 's/\butmr8a.pfb\b/ptmr8a.pfb/',
+ 's/\butmri8a.pfb\b/ptmri8a.pfb/',
+ 's/\buzcmi8a.pfb\b/pzcmi8a.pfb/',
+ 's/\buzdr.pfb\b/pzdr.pfb/',
+ );
+
+ my @fileURW = (
+ 's/\buagd8a.pfb\b/a010015l.pfb/',
+ 's/\buagdo8a.pfb\b/a010035l.pfb/',
+ 's/\buagk8a.pfb\b/a010013l.pfb/',
+ 's/\buagko8a.pfb\b/a010033l.pfb/',
+ 's/\bubkd8a.pfb\b/b018015l.pfb/',
+ 's/\bubkdi8a.pfb\b/b018035l.pfb/',
+ 's/\bubkl8a.pfb\b/b018012l.pfb/',
+ 's/\bubkli8a.pfb\b/b018032l.pfb/',
+ 's/\bucrb8a.pfb\b/n022004l.pfb/',
+ 's/\bucrbo8a.pfb\b/n022024l.pfb/',
+ 's/\bucrr8a.pfb\b/n022003l.pfb/',
+ 's/\bucrro8a.pfb\b/n022023l.pfb/',
+ 's/\buhvb8a.pfb\b/n019004l.pfb/',
+ 's/\buhvb8ac.pfb\b/n019044l.pfb/',
+ 's/\buhvbo8a.pfb\b/n019024l.pfb/',
+ 's/\buhvbo8ac.pfb\b/n019064l.pfb/',
+ 's/\buhvr8a.pfb\b/n019003l.pfb/',
+ 's/\buhvr8ac.pfb\b/n019043l.pfb/',
+ 's/\buhvro8a.pfb\b/n019023l.pfb/',
+ 's/\buhvro8ac.pfb\b/n019063l.pfb/',
+ 's/\buncb8a.pfb\b/c059016l.pfb/',
+ 's/\buncbi8a.pfb\b/c059036l.pfb/',
+ 's/\buncr8a.pfb\b/c059013l.pfb/',
+ 's/\buncri8a.pfb\b/c059033l.pfb/',
+ 's/\buplb8a.pfb\b/p052004l.pfb/',
+ 's/\buplbi8a.pfb\b/p052024l.pfb/',
+ 's/\buplr8a.pfb\b/p052003l.pfb/',
+ 's/\buplri8a.pfb\b/p052023l.pfb/',
+ 's/\busyr.pfb\b/s050000l.pfb/',
+ 's/\butmb8a.pfb\b/n021004l.pfb/',
+ 's/\butmbi8a.pfb\b/n021024l.pfb/',
+ 's/\butmr8a.pfb\b/n021003l.pfb/',
+ 's/\butmri8a.pfb\b/n021023l.pfb/',
+ 's/\buzcmi8a.pfb\b/z003034l.pfb/',
+ 's/\buzdr.pfb\b/d050000l.pfb/',
+ );
+
+ my @fileADOBE = (
+ 's/\buagd8a.pfb\b/agd_____.pfb/',
+ 's/\buagdo8a.pfb\b/agdo____.pfb/',
+ 's/\buagk8a.pfb\b/agw_____.pfb/',
+ 's/\buagko8a.pfb\b/agwo____.pfb/',
+ 's/\bubkd8a.pfb\b/bkd_____.pfb/',
+ 's/\bubkdi8a.pfb\b/bkdi____.pfb/',
+ 's/\bubkl8a.pfb\b/bkl_____.pfb/',
+ 's/\bubkli8a.pfb\b/bkli____.pfb/',
+ 's/\bucrb8a.pfb\b/cob_____.pfb/',
+ 's/\bucrbo8a.pfb\b/cobo____.pfb/',
+ 's/\bucrr8a.pfb\b/com_____.pfb/',
+ 's/\bucrro8a.pfb\b/coo_____.pfb/',
+ 's/\buhvb8a.pfb\b/hvb_____.pfb/',
+ 's/\buhvb8ac.pfb\b/hvnb____.pfb/',
+ 's/\buhvbo8a.pfb\b/hvbo____.pfb/',
+ 's/\buhvbo8ac.pfb\b/hvnbo___.pfb/',
+ 's/\buhvr8a.pfb\b/hv______.pfb/',
+ 's/\buhvr8ac.pfb\b/hvn_____.pfb/',
+ 's/\buhvro8a.pfb\b/hvo_____.pfb/',
+ 's/\buhvro8ac.pfb\b/hvno____.pfb/',
+ 's/\buncb8a.pfb\b/ncb_____.pfb/',
+ 's/\buncbi8a.pfb\b/ncbi____.pfb/',
+ 's/\buncr8a.pfb\b/ncr_____.pfb/',
+ 's/\buncri8a.pfb\b/nci_____.pfb/',
+ 's/\buplb8a.pfb\b/pob_____.pfb/',
+ 's/\buplbi8a.pfb\b/pobi____.pfb/',
+ 's/\buplr8a.pfb\b/por_____.pfb/',
+ 's/\buplri8a.pfb\b/poi_____.pfb/',
+ 's/\busyr.pfb\b/sy______.pfb/',
+ 's/\butmb8a.pfb\b/tib_____.pfb/',
+ 's/\butmbi8a.pfb\b/tibi____.pfb/',
+ 's/\butmr8a.pfb\b/tir_____.pfb/',
+ 's/\butmri8a.pfb\b/tii_____.pfb/',
+ 's/\buzcmi8a.pfb\b/zcmi____.pfb/',
+ 's/\buzdr.pfb\b/zd______.pfb/',
+ );
+
+ if ($mode eq "" || $mode eq "URWkb") {
+ # do nothing
+ } elsif ($mode eq "URW") {
+ for my $r (@fileURW) {
+ map { eval($r); } @lines;
+ }
+ } elsif ($mode eq "ADOBE" || $mode eq "ADOBEkb") {
+ for my $r (@psADOBE) {
+ map { eval($r); } @lines;
+ }
+ my @filemode = eval ("\@file" . $mode);
+ for my $r (@filemode) {
+ map { eval($r); } @lines;
+ }
+ }
+ return @lines;
+}
+
+###############################################################################
+# cidx2dvips()
+# reads from stdin, writes to stdout. It transforms "cid-x"-like syntax into
+# "dvips"-like syntax.
+###############################################################################
+sub cidx2dvips {
+ my ($s) = @_;
+ my @d;
+ foreach (@$s) {
+ if (m/^%/) {
+ push(@d, $_);
+ next;
+ }
+ s/,BoldItalic/ -s .3/;
+ s/,Bold//;
+ s/,Italic/ -s .3/;
+ s/\s\s*/ /g;
+ if ($_ =~ /.*[@\:\/,]/) {next;}
+ elsif ($_ =~ /^[^ ][^ ]* unicode /) {next;}
+ s/^([^ ][^ ]* [^ ][^ ]* [^ ][^ ]*)\.[Oo][Tt][Ff]/$1/;
+ s/^([^ ][^ ]* [^ ][^ ]* [^ ][^ ]*)\.[Tt][Tt][FfCc]/$1/;
+ s/$/ %/;
+ s/^(([^ ]*).*)/$1$2/;
+ s/^([^ ][^ ]* ([^ ][^ ]*) !*([^ ][^ ]*).*)/$1 $3-$2/;
+ s/^(.* -e ([.0-9-][.0-9-]*).*)/$1 "$2 ExtendFont"/;
+ s/^(.* -s ([.0-9-][.0-9-]*).*)/$1 "$2 SlantFont"/;
+ s/.*%//;
+ push(@d, $_);
+ }
+ return @d
+}
+
+sub get_cfg {
+ my ($v) = @_;
+ if (defined($alldata->{'merged'}{'setting'}{$v})) {
+ return ( $alldata->{'merged'}{'setting'}{$v}{'val'},
+ $alldata->{'merged'}{'setting'}{$v}{'origin'} );
+ } else {
+ return ($settings{$v}{'default'}, "default");
+ }
+}
+
+sub mkMaps {
+ my $logfile;
+
+ $logfile = "$TEXMFVAR/web2c/updmap.log";
+
+ if (! $opts{'dry-run'}) {
+ mkdirhier("$TEXMFVAR/web2c");
+ open LOG, ">$logfile"
+ or die "$prg: Can't open log file \"$logfile\": $!";
+ print LOG &version();
+ printf LOG "%s\n\n", scalar localtime();
+ print LOG "Using the following config files:\n";
+ for (@{$opts{'cnffile'}}) {
+ print LOG " $_\n";
+ }
+ }
+ sub print_and_log {
+ my $str=shift;
+ print $str if !$opts{'quiet'};
+ print LOG $str unless $opts{'dry-run'};
+ }
+ sub only_log {
+ print LOG shift unless $opts{'dry-run'};
+ }
+
+ my ($mode, $mode_origin) = get_cfg('LW35');
+ my ($dvipsPreferOutline, $dvipsPreferOutline_origin) =
+ get_cfg('dvipsPreferOutline');
+ my ($dvipsDownloadBase35, $dvipsDownloadBase35_origin) =
+ get_cfg('dvipsDownloadBase35');
+ my ($pdftexDownloadBase14, $pdftexDownloadBase14_origin) =
+ get_cfg('pdftexDownloadBase14');
+ my ($pxdviUse, $pxdviUse_origin) = get_cfg('pxdviUse');
+ my ($kanjiEmbed, $kanjiEmbed_origin) = get_cfg('kanjiEmbed');
+ my ($kanjiVariant, $kanjiVariant_origin) = get_cfg('kanjiVariant');
+
+ print_and_log ("\n$prg is creating new map files"
+ . "\nusing the following configuration:"
+ . "\n LW35 font names : "
+ . "$mode ($mode_origin)"
+ . "\n prefer outlines : "
+ . "$dvipsPreferOutline ($dvipsPreferOutline_origin)"
+ . "\n texhash enabled : "
+ . ($opts{'nohash'} ? "false" : "true")
+ . "\n download standard fonts (dvips) : "
+ . "$dvipsDownloadBase35 ($dvipsDownloadBase35_origin)"
+ . "\n download standard fonts (pdftex) : "
+ . "$pdftexDownloadBase14 ($pdftexDownloadBase14_origin)"
+ . "\n kanjiEmbed replacement string : "
+ . "$kanjiEmbed ($kanjiEmbed_origin)"
+ . "\n kanjiVariant replacement string : "
+ . "$kanjiVariant ($kanjiVariant_origin)"
+ . "\n create a mapfile for pxdvi : "
+ . "$pxdviUse ($pxdviUse_origin)"
+ . "\n\n");
+
+ print_and_log ("Scanning for LW35 support files");
+ my $dvips35 = $alldata->{'maps'}{"dvips35.map"}{'fullpath'};
+ my $pdftex35 = $alldata->{'maps'}{"pdftex35.map"}{'fullpath'};
+ my $ps2pk35 = $alldata->{'maps'}{"ps2pk35.map"}{'fullpath'};
+ my $LW35 = "\n$dvips35\n$pdftex35\n$ps2pk35\n\n";
+ only_log ("\n");
+ only_log ($LW35);
+ print_and_log (" [ 3 files]\n");
+ only_log ("\n");
+
+ print_and_log ("Scanning for MixedMap entries");
+ my @mixedmaps;
+ my @notmixedmaps;
+ my @kanjimaps;
+ for my $m (keys %{$alldata->{'maps'}}) {
+ my $origin = $alldata->{'maps'}{$m}{'origin'};
+ next if !defined($origin);
+ next if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'status'} eq "disabled");
+ push @mixedmaps, $m
+ if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'} eq "MixedMap");
+ push @notmixedmaps, $m
+ if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'} eq "Map");
+ push @kanjimaps, $m
+ if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'} eq "KanjiMap");
+ }
+
+ @mixedmaps = sort @mixedmaps;
+ @notmixedmaps = sort @notmixedmaps;
+ @kanjimaps = sort @kanjimaps;
+ only_log("\n");
+ foreach my $m (sort @mixedmaps) {
+ if (defined($alldata->{'maps'}{$m}{'fullpath'})) {
+ only_log($alldata->{'maps'}{$m}{'fullpath'} . "\n");
+ } else {
+ only_log("$m (full path not set?)\n");
+ }
+ }
+ only_log("\n");
+ print_and_log (sprintf(" [%3d files]\n", scalar @mixedmaps));
+ only_log("\n");
+
+ print_and_log ("Scanning for KanjiMap entries");
+ only_log("\n");
+ foreach my $m (@kanjimaps) {
+ if (defined($alldata->{'maps'}{$m}{'fullpath'})) {
+ only_log($alldata->{'maps'}{$m}{'fullpath'} . "\n");
+ } else {
+ only_log("$m (full path not set?)\n");
+ }
+ }
+ only_log("\n");
+ print_and_log (sprintf(" [%3d files]\n", scalar @kanjimaps));
+ only_log("\n");
+
+ print_and_log ("Scanning for Map entries");
+ only_log("\n");
+ foreach my $m (@notmixedmaps) {
+ if (defined($alldata->{'maps'}{$m}{'fullpath'})) {
+ only_log($alldata->{'maps'}{$m}{'fullpath'} . "\n");
+ } else {
+ only_log("$m (full path not set?)\n");
+ }
+ }
+ only_log("\n");
+ print_and_log (sprintf(" [%3d files]\n\n", scalar @notmixedmaps));
+ only_log("\n");
+
+ # Create psfonts_t1.map, psfonts_pk.map, ps2pk.map and pdftex.map:
+ my $dvipsoutputdir = $opts{'dvipsoutputdir'};
+ my $pdftexoutputdir = $opts{'pdftexoutputdir'};
+ my $dvipdfmxoutputdir = $opts{'dvipdfmxoutputdir'};
+ my $pxdvioutputdir = $opts{'pxdvioutputdir'};
+ if (!$opts{'dry-run'}) {
+ my @managed_files = ("$dvipsoutputdir/download35.map",
+ "$dvipsoutputdir/builtin35.map",
+ "$dvipsoutputdir/psfonts_t1.map",
+ "$dvipsoutputdir/psfonts_pk.map",
+ "$pdftexoutputdir/pdftex_dl14.map",
+ "$pdftexoutputdir/pdftex_ndl14.map",
+ "$dvipdfmxoutputdir/kanjix.map",
+ "$dvipsoutputdir/ps2pk.map");
+ push @managed_files, "$pxdvioutputdir/xdvi-ptex.map"
+ if ($pxdviUse eq "true");
+ for my $file (@managed_files) {
+ open FILE, ">$file";
+ print FILE "% $file:\
+% maintained by updmap[-sys] (multi).\
+% Don't change this file directly. Use updmap[-sys] instead.\
+% See the updmap documentation.\
+% A log of the run that created this file is available here:\
+% $logfile\
+";
+ close FILE;
+ }
+ }
+
+ my @kanjimaps_fonts = getFonts(@kanjimaps);
+ @kanjimaps_fonts = &normalizeLines(@kanjimaps_fonts);
+ my @ps2pk_fonts = getFonts('-all', "ps2pk35.map");
+ my @dvips35_fonts = getFonts('-all', "dvips35.map");
+ my @pdftex35_fonts = getFonts('-all', "pdftex35.map");
+ my @mixedmaps_fonts = getFonts(@mixedmaps);
+ my @notmixedmaps_fonts = getFonts(@notmixedmaps);
+
+ print "Generating output for dvipdfmx...\n" if !$opts{'quiet'};
+ &writeLines(">$dvipdfmxoutputdir/kanjix.map", @kanjimaps_fonts);
+
+ if ($pxdviUse eq "true") {
+ # we use the very same data as for kanjix.map, but generate
+ # a different file, so that in case a user wants to hand-craft it
+ print "Generating output for pxdvi...\n" if !$opts{'quiet'};
+ &writeLines(">$pxdvioutputdir/xdvi-ptex.map", @kanjimaps_fonts);
+ }
+
+
+ print "Generating output for ps2pk...\n" if !$opts{'quiet'};
+ my @ps2pk_map;
+ push @ps2pk_map, "% ps2pk35.map";
+ push @ps2pk_map, transLW35($mode, @ps2pk_fonts);
+ push @ps2pk_map, @mixedmaps_fonts;
+ push @ps2pk_map, @notmixedmaps_fonts;
+ &writeLines(">$dvipsoutputdir/ps2pk.map",
+ normalizeLines(@ps2pk_map));
+
+ print "Generating output for dvips...\n" if !$opts{'quiet'};
+ my @download35_map;
+ push @download35_map, "% ps2pk35.map";
+ push @download35_map, transLW35($mode, @ps2pk_fonts);
+ &writeLines(">$dvipsoutputdir/download35.map",
+ normalizeLines(@download35_map));
+
+ my @builtin35_map;
+ push @builtin35_map, "% dvips35.map";
+ push @builtin35_map, transLW35($mode, @dvips35_fonts);
+ &writeLines(">$dvipsoutputdir/builtin35.map",
+ normalizeLines(@builtin35_map));
+
+ my @dftdvips_fonts = ($dvipsDownloadBase35 ? @ps2pk_fonts : @dvips35_fonts);
+
+ my @psfonts_t1_map;
+ if ($dvipsDownloadBase35) {
+ push @psfonts_t1_map, "% ps2pk35.map",
+ @dftdvips_fonts = @ps2pk_fonts;
+ } else {
+ push @psfonts_t1_map, "% dvips35.map";
+ @dftdvips_fonts = @dvips35_fonts;
+ }
+ push @psfonts_t1_map, transLW35($mode, @dftdvips_fonts);
+ my @tmpkanji2 = cidx2dvips(\@kanjimaps_fonts);
+ push @psfonts_t1_map, @mixedmaps_fonts;
+ push @psfonts_t1_map, @notmixedmaps_fonts;
+ push @psfonts_t1_map, @tmpkanji2;
+ &writeLines(">$dvipsoutputdir/psfonts_t1.map",
+ normalizeLines(@psfonts_t1_map));
+
+ my @psfonts_pk_map;
+ push @psfonts_pk_map, transLW35($mode, @dftdvips_fonts);
+ push @psfonts_pk_map, @notmixedmaps_fonts;
+ push @psfonts_pk_map, @tmpkanji2;
+ &writeLines(">$dvipsoutputdir/psfonts_pk.map",
+ normalizeLines(@psfonts_pk_map));
+
+ print "Generating output for pdftex...\n" if !$opts{'quiet'};
+ # remove PaintType due to Sebastian's request
+ my @pdftexmaps_ndl;
+ push @pdftexmaps_ndl, "% pdftex35.map";
+ push @pdftexmaps_ndl, transLW35($mode, @pdftex35_fonts);
+ push @pdftexmaps_ndl, @mixedmaps_fonts;
+ push @pdftexmaps_ndl, @notmixedmaps_fonts;
+ @pdftexmaps_ndl = grep { $_ !~ m/(^%\|PaintType)/ } @pdftexmaps_ndl;
+
+ my @pdftexmaps_dl;
+ push @pdftexmaps_dl, "% ps2pk35.map";
+ push @pdftexmaps_dl, transLW35($mode, @ps2pk_fonts);
+ push @pdftexmaps_dl, @mixedmaps_fonts;
+ push @pdftexmaps_dl, @notmixedmaps_fonts;
+ @pdftexmaps_dl = grep { $_ !~ m/(^%\|PaintType)/ } @pdftexmaps_dl;
+
+ my @pdftex_ndl14_map = @pdftexmaps_ndl;
+ @pdftex_ndl14_map = &normalizeLines(@pdftex_ndl14_map);
+ @pdftex_ndl14_map = &to_pdftex(@pdftex_ndl14_map);
+ &writeLines(">$pdftexoutputdir/pdftex_ndl14.map", @pdftex_ndl14_map);
+
+ my @pdftex_dl14_map = @pdftexmaps_dl;
+ @pdftex_dl14_map = &normalizeLines(@pdftex_dl14_map);
+ @pdftex_dl14_map = &to_pdftex(@pdftex_dl14_map);
+ &writeLines(">$pdftexoutputdir/pdftex_dl14.map", @pdftex_dl14_map);
+
+ our $link = &setupSymlinks($dvipsPreferOutline, $dvipsoutputdir, $pdftexDownloadBase14, $pdftexoutputdir);
+
+ print_and_log ("\nFiles generated:\n");
+ sub dir {
+ my ($d, $f, $target)=@_;
+ our $link;
+ if (-e "$d/$f") {
+ my @stat=lstat("$d/$f");
+ my ($s,$m,$h,$D,$M,$Y)=localtime($stat[9]);
+ my $timestamp=sprintf ("%04d-%02d-%02d %02d:%02d:%02d",
+ $Y+1900, $M+1, $D, $h, $m, $s);
+ my $date=sprintf "%12d %s %s", $stat[7], $timestamp, $f;
+ print_and_log ($date);
+
+ if (-l "$d/$f") {
+ my $lnk=sprintf " -> %s\n", readlink ("$d/$f");
+ print_and_log ($lnk);
+ } elsif ($f eq $target) {
+ if (&files_are_identical("$d/$f", "$d/" . $link->{$target})) {
+ print_and_log (" = $link->{$target}\n");
+ } else {
+ print_and_log (" = ?????\n"); # This shouldn't happen.
+ }
+ } else {
+ print_and_log ("\n");
+ }
+ } else {
+ print STDERR "Warning: File $d/$f doesn't exist.\n";
+ print LOG "Warning: File $d/$f doesn't exist.\n"
+ unless $opts{'dry-run'};
+ }
+ }
+
+ my $d;
+ $d = "$dvipsoutputdir";
+ print_and_log(" $d:\n");
+ foreach my $f ('builtin35.map', 'download35.map', 'psfonts_pk.map',
+ 'psfonts_t1.map', 'ps2pk.map', 'psfonts.map') {
+ dir ($d, $f, 'psfonts.map');
+ $updLSR->{add}("$d/$f") unless $opts{'dry-run'};
+ }
+ $d = "$pdftexoutputdir";
+ print_and_log(" $d:\n");
+ foreach my $f ('pdftex_dl14.map', 'pdftex_ndl14.map', 'pdftex.map') {
+ dir ($d, $f, 'pdftex.map');
+ $updLSR->{add}("$d/$f") unless $opts{'dry-run'};
+ }
+ $d="$dvipdfmxoutputdir";
+ print_and_log(" $d:\n");
+ foreach my $f ('kanjix.map') {
+ dir ($d, $f, '');
+ $updLSR->{add}("$d/$f") unless $opts{'dry-run'};
+ }
+ if ($pxdviUse eq "true") {
+ $d="$pxdvioutputdir";
+ print_and_log(" $d:\n");
+ foreach my $f ('xdvi-ptex.map') {
+ dir ($d, $f, '');
+ $updLSR->{add}("$d/$f") unless $opts{'dry-run'};
+ }
+ }
+ close LOG unless $opts{'dry-run'};
+ print "\nTranscript written on \"$logfile\".\n" if !$opts{'quiet'};
+
+}
+
+
+sub locateMap {
+ my $map = shift;
+ my $ret = `kpsewhich --format=map $map`;
+ chomp($ret);
+ return $ret;
+}
+
+sub processOptions {
+ # first process the stupid setoption= s@{1,2} which is not accepted
+ # furthermore, try to work around missing s{1,2} support in older perls
+ my $oldconfig = Getopt::Long::Configure(qw(pass_through));
+ our @setoptions;
+ our @enable;
+ sub read_one_or_two {
+ my ($opt, $val) = @_;
+ our @setoptions;
+ our @enable;
+ # check if = occirs in $val, if not, get the next argument
+ if ($val =~ m/=/) {
+ if ($opt eq "setoption") {
+ push @setoptions, $val;
+ } else {
+ push @enable, $val;
+ }
+ } else {
+ my $vv = shift @ARGV;
+ die "Try \"$prg --help\" for more information.\n"
+ if !defined($vv);
+ if ($opt eq "setoption") {
+ push @setoptions, "$val=$vv";
+ } else {
+ push @enable, "$val=$vv";
+ }
+ }
+ }
+ GetOptions("setoption=s@" => \&read_one_or_two,
+ "enable=s@" => \&read_one_or_two) or
+ die "Try \"$prg --help\" for more information.\n";
+
+ @{$opts{'setoption'}} = @setoptions if (@setoptions);
+ @{$opts{'enable'}} = @enable if (@enable);
+
+ Getopt::Long::Configure($oldconfig);
+
+ # now continue with normal option handling
+
+ GetOptions(\%opts, @cmdline_options) or
+ die "Try \"$prg --help\" for more information.\n";
+}
+
+# determines the output dir for driver from cmd line, or if not given
+# from TEXMFVAR
+sub setupOutputDir {
+ my $driver = shift;
+ if (!$opts{$driver . "outputdir"}) {
+ if ($opts{'outputdir'}) {
+ $opts{$driver . "outputdir"} = $opts{'outputdir'};
+ } else {
+ $opts{$driver . "outputdir"} = "$TEXMFVAR/fonts/map/$driver/updmap";
+ }
+ }
+ my $od = $opts{$driver . "outputdir"};
+ if (!$opts{"dry-run"}) {
+ &mkdirhier($od);
+ if (! -w $od) {
+ die "$prg: Directory \"$od\" isn't writable: $!";
+ }
+ }
+ print "$driver output dir: \"$od\"\n" if !$opts{'quiet'};
+ return $od;
+}
+
+###############################################################################
+# setOption (@options)
+# parse @options for "key=value" (one element of @options)
+# we can only have "key=value" since that is the way it was prepared
+# in process_options
+# (These were the values provided to --setoption.)
+#
+sub setOptions {
+ my (@options) = @_;
+ for (my $i = 0; $i < @options; $i++) {
+ my $o = $options[$i];
+
+ my ($key,$val) = split (/=/, $o, 2);
+
+ die "$prg: unexpected empty key or val for options (@options), goodbye.\n"
+ if !$key || !defined($val);
+
+ &setOption ($key, $val);
+ }
+ return save_updmap($alldata->{'changes_config'});
+}
+
+sub enable_disable_maps {
+ my (@what) = @_;
+ my $tc = $alldata->{'changes_config'};
+ die "$prg: top config file $tc has not been read."
+ if (!defined($alldata->{'updmap'}{$tc}));
+ my $changed = 0;
+ for my $w (@what) {
+ if ($w =~ m/=/) {
+ # this is --enable MapType=MapName
+ my ($type, $map) = split ('=', $w);
+ enable_map($tc, $type, $map);
+ } else {
+ # this is --disable MapName
+ disable_map($tc, $w);
+ }
+ }
+ return save_updmap($tc);
+}
+
+sub enable_map {
+ my ($tc, $type, $map) = @_;
+
+ die "$prg: invalid mapType $type" if ($type !~ m/^(Map|MixedMap|KanjiMap)$/);
+
+ if (defined($alldata->{'updmap'}{$tc}{'maps'}{$map})) {
+ # the map data has already been read in, no special precautions necessary
+ if (($alldata->{'updmap'}{$tc}{'maps'}{$map}{'status'} eq "enabled") &&
+ ($alldata->{'updmap'}{$tc}{'maps'}{$map}{'type'} eq $type)) {
+ # nothing to do here ... be happy!
+ return;
+ } else {
+ $alldata->{'updmap'}{$tc}{'maps'}{$map}{'status'} = "enabled";
+ $alldata->{'updmap'}{$tc}{'maps'}{$map}{'type'} = $type;
+ $alldata->{'maps'}{$map}{'origin'} = $tc;
+ $alldata->{'maps'}{$map}{'status'} = "enabled";
+ $alldata->{'updmap'}{$tc}{'changed'} = 1;
+ }
+ } else {
+ # add a new map file!
+ $alldata->{'updmap'}{$tc}{'maps'}{$map}{'type'} = $type;
+ $alldata->{'updmap'}{$tc}{'maps'}{$map}{'status'} = "enabled";
+ $alldata->{'updmap'}{$tc}{'maps'}{$map}{'line'} = -1;
+ $alldata->{'updmap'}{$tc}{'changed'} = 1;
+ $alldata->{'maps'}{$map}{'origin'} = $tc;
+ $alldata->{'maps'}{$map}{'status'} = "enabled";
+ }
+}
+
+sub disable_map {
+ my ($tc, $map) = @_;
+
+ if (defined($alldata->{'updmap'}{$tc}{'maps'}{$map})) {
+ # the map data has already been read in, no special precautions necessary
+ if ($alldata->{'updmap'}{$tc}{'maps'}{$map}{'status'} eq "disabled") {
+ # nothing to do here ... be happy!
+ } else {
+ $alldata->{'updmap'}{$tc}{'maps'}{$map}{'status'} = "disabled";
+ $alldata->{'maps'}{$map}{'origin'} = $tc;
+ $alldata->{'maps'}{$map}{'status'} = "disabled";
+ $alldata->{'updmap'}{$tc}{'changed'} = 1;
+ }
+ } else {
+ # disable a Map type that might be activated in a lower ranked updmap.cfg
+ if (!defined($alldata->{'maps'}{$map})) {
+ warning("Map is not present anywhere, why should I disable it?\n");
+ return;
+ }
+ my $orig = $alldata->{'maps'}{$map}{'origin'};
+ # add a new entry to the top level where we disable it
+ # copy over the type from the last entry
+ $alldata->{'updmap'}{$tc}{'maps'}{$map}{'type'} =
+ $alldata->{'updmap'}{$orig}{'maps'}{$map}{'type'};
+ $alldata->{'updmap'}{$tc}{'maps'}{$map}{'status'} = "disabled";
+ $alldata->{'updmap'}{$tc}{'maps'}{$map}{'line'} = -1;
+ # rewrite the origin
+ $alldata->{'maps'}{$map}{'origin'} = $tc;
+ $alldata->{'maps'}{$map}{'status'} = "disabled";
+ # go on for writing
+ $alldata->{'updmap'}{$tc}{'changed'} = 1;
+ }
+}
+
+
+# returns 1 if actually saved due to changes
+sub save_updmap {
+ my $fn = shift;
+ return if $opts{'dry-run'};
+ my %upd = %{$alldata->{'updmap'}{$fn}};
+ if ($upd{'changed'}) {
+ mkdirhier(dirname($fn));
+ open (FN, ">$fn") || die "$prg: can't write to $fn: $!";
+ my @lines = @{$upd{'lines'}};
+ if (!@lines) {
+ print "Creating new config file $fn\n";
+ }
+ # collect the lines with data
+ my %line_to_setting;
+ my %line_to_map;
+ my @add_setting;
+ my @add_map;
+ if (defined($upd{'setting'})) {
+ for my $k (keys %{$upd{'setting'}}) {
+ if ($upd{'setting'}{$k}{'line'} == -1) {
+ push @add_setting, $k;
+ } else {
+ $line_to_setting{$upd{'setting'}{$k}{'line'}} = $k;
+ }
+ }
+ }
+ if (defined($upd{'maps'})) {
+ for my $k (keys %{$upd{'maps'}}) {
+ if ($upd{'maps'}{$k}{'line'} == -1) {
+ push @add_map, $k;
+ } else {
+ $line_to_map{$upd{'maps'}{$k}{'line'}} = $k;
+ }
+ }
+ }
+ for my $i (0..$#lines) {
+ if (defined($line_to_setting{$i})) {
+ my $k = $line_to_setting{$i};
+ my $v = $upd{'setting'}{$k}{'val'};
+ print FN "$k $v\n";
+ } elsif (defined($line_to_map{$i})) {
+ my $m = $line_to_map{$i};
+ my $rm;
+ if (defined($upd{'maps'}{$m}{'original'})) {
+ # we have the case that @noEmbed@ was replaced by the respective
+ # setting. Before writing out we have to replace this back with
+ # the original line!A
+ $rm = $upd{'maps'}{$m}{'original'};
+ } else {
+ $rm = $m;
+ }
+ my $t = $upd{'maps'}{$m}{'type'};
+ my $p = ($upd{'maps'}{$m}{'status'} eq "disabled" ? "#! " : "");
+ print FN "$p$t $rm\n";
+ } else {
+ print FN "$lines[$i]\n";
+ }
+ }
+ # add the new settings and maps
+ for my $k (@add_setting) {
+ my $v = $upd{'setting'}{$k}{'val'};
+ print FN "$k $v\n";
+ }
+ for my $m (@add_map) {
+ my $t = $upd{'maps'}{$m}{'type'};
+ my $p = ($upd{'maps'}{$m}{'status'} eq "disabled" ? "#! " : "");
+ print FN "$p$t $m\n";
+ }
+ close(FN) || warn("Cannot close file handle for $fn: $!");
+ delete $alldata->{'updmap'}{$fn}{'changed'};
+ #
+ # update lsR database
+ $updLSR->{add}($fn);
+ #
+ return 1;
+ }
+ return 0;
+}
+
+######################
+# check for correct option value
+#
+sub check_option {
+ my ($opt, $val) = @_;
+ if ((($settings{$opt}{'type'} eq "binary") &&
+ $val ne "true" && $val ne "false") ||
+ (($settings{$opt}{'type'} eq "string") &&
+ !member($val, @{$settings{$opt}{'possible'}}))) {
+ return 0;
+ }
+ return 1;
+}
+
+###############################################################################
+# setOption (conf_file, option, value)
+# sets option to value in the config file (replacing the existing setting
+# or by adding a new line to the config file).
+#
+sub setOption {
+ my ($opt, $val) = @_;
+
+ die "$prg: Unsupported option $opt." if (!defined($settings{$opt}));
+ die "$0: Invalid value $val for option $opt."
+ if (!check_option($opt, $val));
+
+ # silently accept this old option name, just in case.
+ return if $opt eq "dvipdfmDownloadBase14";
+
+ #print "Setting option $opt to $val...\n" if !$opts{'quiet'};
+ my $tc = $alldata->{'changes_config'};
+
+ die "$prg: top config file $tc has not been read."
+ if (!defined($alldata->{'updmap'}{$tc}));
+
+ if (defined($alldata->{'updmap'}{$tc}{'setting'}{$opt}{'val'})) {
+ # the value is already set, do nothing
+ if ($alldata->{'updmap'}{$tc}{'setting'}{$opt}{'val'} eq $val) {
+ return;
+ }
+ $alldata->{'updmap'}{$tc}{'setting'}{$opt}{'val'} = $val;
+ $alldata->{'updmap'}{$tc}{'changed'} = 1;
+ } else {
+ $alldata->{'updmap'}{$tc}{'setting'}{$opt}{'val'} = $val;
+ $alldata->{'updmap'}{$tc}{'setting'}{$opt}{'line'} = -1;
+ $alldata->{'updmap'}{$tc}{'changed'} = 1;
+ }
+}
+
+
+###############################################################################
+# copyFile()
+# copy file $src to $dst, sets $dst creation and mod time
+#
+sub copyFile {
+ my ($src, $dst) = @_;
+ my $dir;
+ ($dir=$dst)=~s/(.*)\/.*/$1/;
+ mkdirhier($dir);
+
+ $src eq $dst && return "can't copy $src to itself!\n";
+
+ open IN, "<$src" or die "$0: can't open source file $src for copying: $!";
+ open OUT, ">$dst";
+
+ binmode(IN);
+ binmode(OUT);
+ print OUT <IN>;
+ close(OUT);
+ close(IN);
+ my @t = stat($src);
+ utime($t[8], $t[9], $dst);
+}
+
+###############################################################################
+# files_are_identical(file_A, file_B)
+# compare two files. Same as cmp(1).
+#
+sub files_are_identical {
+ my $file_A=shift;
+ my $file_B=shift;
+ my $retval=0;
+
+ open IN, "$file_A";
+ my $A=(<IN>);
+ close IN;
+ open IN, "$file_B";
+ my $B=(<IN>);
+ close IN;
+
+ $retval=1 if ($A eq $B);
+ return $retval;
+}
+
+###############################################################################
+# files_are_different(file_A, file_B[, comment_char])
+# compare two equalized files.
+#
+sub files_are_different {
+ my $file_A=shift;
+ my $file_B=shift;
+ my $comment=shift;
+ my $retval=0;
+
+ my $A=equalize_file("$file_A", $comment);
+ my $B=equalize_file("$file_B", $comment);
+ $retval=1 unless ($A eq $B);
+ return $retval;
+}
+
+###############################################################################
+# equalize_file(filename[, comment_char])
+# read a file and return its processed content as a string.
+# look into the source code for more details.
+#
+sub equalize_file {
+ my $file=shift;
+ my $comment=shift;
+ my @temp;
+
+ open IN, "$file";
+ my @lines = (<IN>);
+ close IN;
+ chomp(@lines);
+
+ for (@lines) {
+ s/\s*${comment}.*// if (defined $comment); # remove comments
+ next if /^\s*$/; # remove empty lines
+ s/\s+/ /g; # replace multiple whitespace chars by a single one
+ push @temp, $_;
+ }
+ return join('X', sort(@temp));
+}
+
+###############################################################################
+# normalizeLines()
+# not the original function, we want it to keep comments, that are
+# anyway only the file names we are adding!
+# whitespace is exactly one space, no empty lines,
+# no whitespace at end of line, one space before and after "
+#
+sub normalizeLines {
+ my @lines = @_;
+ my %count = ();
+
+ # @lines = grep { $_ !~ m/^[*#;%]/ } @lines;
+ map {$_ =~ s/\s+/ /gx } @lines;
+ @lines = grep { $_ !~ m/^\s*$/x } @lines;
+ map { $_ =~ s/\s$//x ;
+ $_ =~ s/\s*\"\s*/ \" /gx;
+ $_ =~ s/\" ([^\"]*) \"/\"$1\"/gx;
+ } @lines;
+
+ # @lines = grep {++$count{$_} < 2 } (sort @lines);
+ @lines = grep {++$count{$_} < 2 } (@lines);
+
+ return @lines;
+}
+
+
+#################################################################
+#
+# reading updmap-cfg files and the actual map files
+#
+# the following hash saves *all* the information and is passed around
+# we do not fill everything from the very beginning to make sure that
+# we only read what is necessary (speed!)
+#
+# initialized by main
+# $alldata->{'changes_config'} = the config file where changes are saved
+#
+# initialized by read_updmap_files
+# $alldata->{'order'} = [ list of updmap in decreasing priority ]
+# $alldata->{'updmap'}{$full_path_name_of_updmap}{'lines'} = \@lines
+# $alldata->{'updmap'}{$full_path_name_of_updmap}{'setting'}{$key}{'val'} = $val
+# $alldata->{'updmap'}{$full_path_name_of_updmap}{'setting'}{$key}{'line'} = $i
+# $alldata->{'updmap'}{$full_path_name_of_updmap}{'maps'}{$mapname}{'type'}
+# = 'Map'|'MixedMap'|'KanjiMap'|'disabled'
+# $alldata->{'updmap'}{$full_path_name_of_updmap}{'maps'}{$mapname}{'status'}
+# = 'enabled'|'disabled'
+# $alldata->{'updmap'}{$full_path_name_of_updmap}{'maps'}{$mapname}{'line'} = $i
+# $alldata->{'maps'}{$m}{'origin'} = $updmap_path_name
+# $alldata->{'maps'}{$m}{'status'} = enabled | disabled
+#
+# initialized by read_map_files
+# $alldata->{'maps'}{$m}{'fonts'}{$font} = $definition
+# $alldata->{'fonts'}{$f}{'origin'} = $map
+#
+# initialized by merge_data
+# $alldata->{'merged'}{'setting'}{$key}{'val'} = $val
+# $alldata->{'merged'}{'setting'}{$key}{'origin'} = $origin_updmap_cfg
+# $alldata->{'merged'}{'allMaps'}{'fonts'}{$fontdef} = $rest
+# $alldata->{'merged'}{'noMixedMaps'}{'fonts'}{$fontdef} = $rest
+# $alldata->{'merged'}{'KanjiMaps'}{'fonts'}{$fontdef} = $rest
+#
+
+sub read_updmap_files {
+ my (@l) = @_;
+ for my $l (@l) {
+ my $updmap = read_updmap_file($l);
+ $alldata->{'updmap'}{$l}{'lines'} = $updmap->{'lines'};
+ if (defined($updmap->{'setting'})) {
+ for my $k (keys %{$updmap->{'setting'}}) {
+ $alldata->{'updmap'}{$l}{'setting'}{$k}{'val'} = $updmap->{'setting'}{$k}{'val'};
+ $alldata->{'updmap'}{$l}{'setting'}{$k}{'line'} = $updmap->{'setting'}{$k}{'line'};
+ }
+ }
+ if (defined($updmap->{'maps'})) {
+ for my $k (keys %{$updmap->{'maps'}}) {
+ $alldata->{'updmap'}{$l}{'maps'}{$k}{'type'} = $updmap->{'maps'}{$k}{'type'};
+ $alldata->{'updmap'}{$l}{'maps'}{$k}{'status'} = $updmap->{'maps'}{$k}{'status'};
+ $alldata->{'updmap'}{$l}{'maps'}{$k}{'line'} = $updmap->{'maps'}{$k}{'line'};
+ }
+ }
+ }
+ # in case the changes_config is a new one read it in and initialize it here
+ my $cc = $alldata->{'changes_config'};
+ if (! -r $cc) {
+ $alldata->{'updmap'}{$cc}{'lines'} = [ ];
+ }
+ #
+ $alldata->{'order'} = \@l;
+ #
+ # merge the settings so that we can check for kanjiEmbed
+ #
+ merge_settings();
+ #
+ my ($kanjiEmbed, $kanjiEmbed_origin) = get_cfg('kanjiEmbed');
+ my ($kanjiVariant, $kanjiVariant_origin) = get_cfg('kanjiVariant');
+ #
+ # go through all map files and check that the text is properly replaced
+ # after the replacement check that the generated map file actually
+ # exists, we do NOT want to break in this case!
+ #
+ for my $l (@l) {
+ for my $m (keys %{$alldata->{'updmap'}{$l}{'maps'}}) {
+ if ($m =~ m/\@kanjiEmbed@/ || $m =~ m/\@kanjiVariant@/) {
+ my $newm = $m;
+ $newm =~ s/\@kanjiEmbed@/$kanjiEmbed/;
+ $newm =~ s/\@kanjiVariant@/$kanjiVariant/;
+ if (locateMap($newm)) {
+ # now we have to update various linked items
+ $alldata->{'updmap'}{$l}{'maps'}{$newm}{'type'} =
+ $alldata->{'updmap'}{$l}{'maps'}{$m}{'type'};
+ $alldata->{'updmap'}{$l}{'maps'}{$newm}{'status'} =
+ $alldata->{'updmap'}{$l}{'maps'}{$m}{'status'};
+ $alldata->{'updmap'}{$l}{'maps'}{$newm}{'line'} =
+ $alldata->{'updmap'}{$l}{'maps'}{$m}{'line'};
+ $alldata->{'updmap'}{$l}{'maps'}{$newm}{'original'} = $m;
+ } else {
+ print "$prg: generated map $newm (from $m) does not exists, not activating it!\n";
+ }
+ # in any case delete the @kanji...@ entry line, such a map will
+ # never exist
+ delete $alldata->{'updmap'}{$l}{'maps'}{$m};
+ }
+ }
+ }
+ #
+ # first round determine which maps should be used and which type, as
+ # different updmap.cfg files might specify different types of maps
+ # (MixedMap or Map or KanjiMap).
+ # Again, we have to do that in reverse order
+ for my $l (reverse @l) {
+ if (defined($alldata->{'updmap'}{$l}{'maps'})) {
+ for my $m (keys %{$alldata->{'updmap'}{$l}{'maps'}}) {
+ $alldata->{'maps'}{$m}{'origin'} = $l;
+ $alldata->{'maps'}{$m}{'status'} = $alldata->{'updmap'}{$l}{'maps'}{$m}{'status'};
+ }
+ }
+ }
+}
+
+sub read_updmap_file {
+ my $fn = shift;
+ my $is_old_local = ($fn =~ m/updmap-local.cfg/ ? 1 : 0);
+ my %data;
+ if (!open(FN,"<$fn")) {
+ die ("Cannot read $fn: $!");
+ }
+ # we count lines from 0 ..!!!!
+ my $i = -1;
+ my @lines = <FN>;
+ chomp(@lines);
+ $data{'lines'} = [ @lines ];
+ close(FN) || warn("Cannot close $fn: $!");
+ for (@lines) {
+ $i++;
+ chomp;
+ if ($is_old_local) {
+ # in case we read an old updmap-local.cfg we have to make sure
+ # that the disable lines
+ # ^#!foo.map
+ # are rewritten to proper disable lines
+ # ^#! Map foo.map
+ # we are guessing here the type of the map (namely Map)
+ $_ =~ s/^#!([^ ])/#! Map $1/;
+ }
+ next if /^\s*$/;
+ next if /^\s*#$/;
+ next if /^\s*#[^!]/;
+ next if /^\s*##/;
+ next if /^#![^ ]/;
+ # allow for commands on the line itself
+ s/([^#].*)#.*$/$1/;
+ my ($a, $b, @rest) = split ' ';
+ # make sure we get empty strings as arguments
+ $b = "" if (!defined($b));
+ if ($a eq "#!") {
+ if ($b eq "Map" || $b eq "MixedMap" || $b eq "KanjiMap") {
+ my $c = shift @rest;
+ if (!defined($c)) {
+ warning("updmap: apparently not a real disable line, ignored: $_\n");
+ } else {
+ if (defined($data{'maps'}{$c})) {
+ warning("updmap: double mentioning of $c in $fn\n");
+ }
+ $data{'maps'}{$c}{'status'} = 'disabled';
+ $data{'maps'}{$c}{'type'} = $b;
+ $data{'maps'}{$c}{'line'} = $i;
+ }
+ }
+ next;
+ }
+ if (@rest) {
+ warning("updmap: line $i in $fn contains a syntax error, more than two words!\n");
+ }
+ if (defined($settings{$a})) {
+ if (check_option($a, $b)) {
+ $data{'setting'}{$a}{'val'} = $b;
+ $data{'setting'}{$a}{'line'} = $i;
+ } else {
+ warning("updmap: unknown setting for $a: $b, ignored!\n");
+ }
+ } elsif ($a eq "Map" || $a eq "MixedMap" || $a eq "KanjiMap") {
+ if (defined($data{'maps'}{$b}) && $data{'maps'}{$b}{'type'} ne $a) {
+ warning("updmap: double mentioning of $b with conflicting types in $fn\n");
+ } else {
+ $data{'maps'}{$b}{'type'} = $a;
+ $data{'maps'}{$b}{'status'} = 'enabled';
+ $data{'maps'}{$b}{'line'} = $i;
+ }
+ } else {
+ warning("updmap: unrecognized line $i in $fn: $_\n");
+ }
+ }
+ return \%data;
+}
+
+sub read_map_files {
+ if (!defined($alldata->{'updmap'})) {
+ return;
+ }
+ my @missing;
+ my @l = @{$alldata->{'order'}};
+ # first collect all the map files we are interested in
+ # and determine whether they exist, and get their full path
+ my @maps;
+ for my $f (@l) {
+ next if !defined($alldata->{'updmap'}{$f}{'maps'});
+ for my $m (keys %{$alldata->{'updmap'}{$f}{'maps'}}) {
+ # only read a map file if its final status is enabled!
+ push @maps, $m if ($alldata->{'maps'}{$m}{'status'} eq 'enabled');
+ }
+ }
+ for my $m (qw/dvips35.map pdftex35.map ps2pk35.map/) {
+ push @maps, $m;
+ $alldata->{'maps'}{$m}{'status'} = 'enabled';
+ }
+ @maps = sort_uniq(@maps);
+ my @fullpath = `kpsewhich --format=map @maps`;
+ chomp @fullpath;
+ foreach my $map (@maps) {
+ my ($ff) = grep /\/$map(\.map)?$/, @fullpath;
+ if ($ff) {
+ $alldata->{'maps'}{$map}{'fullpath'} = $ff;
+ } else {
+ # if the map file is not found, then push it onto the list of
+ # missing map files, since we know that it is enabled
+ push @missing, $map;
+ }
+ }
+
+ #
+ # read in the three basic fonts definition maps
+ for my $m (qw/dvips35.map pdftex35.map ps2pk35.map/) {
+ my $ret = read_map_file($alldata->{'maps'}{$m}{'fullpath'});
+ my @ff = ();
+ for my $font (keys %$ret) {
+ $alldata->{'fonts'}{$font}{'origin'} = $m;
+ $alldata->{'maps'}{$m}{'fonts'}{$font} = $ret->{$font};
+ }
+ }
+ # we read the updmap in reverse directions, since we
+ # replace the origin field of font definition always with the
+ # top one
+ for my $f (reverse @l) {
+ my @maps = keys %{$alldata->{'updmap'}{$f}{'maps'}};
+ for my $m (@maps) {
+ # we do not read a map file multiple times, if $alldata{'maps'}{$m} is
+ # defined we expect that it was read and do skip it
+ next if defined($alldata->{'maps'}{$m}{'fonts'});
+ # we do not read a map files content if it is disabled
+ next if ($alldata->{'maps'}{$m}{'status'} eq 'disabled');
+ if (!defined($alldata->{'maps'}{$m}{'fullpath'})) {
+ # we have already pushed these map files onto the list of missing
+ # map files, so do nothing here
+ next;
+ }
+ my $ret = read_map_file($alldata->{'maps'}{$m}{'fullpath'});
+ if (defined($ret)) {
+ for my $font (keys %$ret) {
+ if (defined($alldata->{'fonts'}{$font})) {
+ # we got another definition, warn on that
+ # if the origin is not defined by now, the font is defined
+ # multiple times in the same map file, otherwise it is
+ # defined in another map file already
+ if (defined($alldata->{'fonts'}{$font}{'origin'})) {
+ my $fontorig = $alldata->{'fonts'}{$font}{'origin'};
+ my $maporig = $alldata->{'maps'}{$fontorig}{'origin'};
+ warning("$prg: font $font is defined multiple times:\n");
+ warning("$prg: $fontorig (from $maporig)\n");
+ warning("$prg: $m (from $f) (used)\n");
+ } else {
+ warning("$prg: font $font is multiply defined in $m, using an arbitrary instance!\n");
+ }
+ }
+ $alldata->{'fonts'}{$font}{'origin'} = $m;
+ $alldata->{'maps'}{$m}{'fonts'}{$font} = $ret->{$font};
+ }
+ }
+ }
+ }
+ return (@missing);
+}
+
+sub read_map_file {
+ my $fn = shift;
+ my @lines;
+ if (!open(MF,"<$fn")) {
+ warn("cannot open $fn: $!");
+ return;
+ }
+ @lines = <MF>;
+ close(MF);
+ chomp(@lines);
+ my %data;
+ for (@lines) {
+ next if /^\s*#/;
+ next if /^\s*%/;
+ next if /^\s*$/;
+ my ($a, $b) = split(' ', $_, 2);
+ $data{$a} = $b;
+ }
+ return \%data;
+}
+
+#
+# merge and update the setting
+#
+sub merge_settings {
+ my @l = @{$alldata->{'order'}};
+ #
+ # for security clean out everything that was there
+ %{$alldata->{'merged'}} = ();
+ #
+ # first read in the settings
+ # we read it in *reverse* order and simple fill up the combined data
+ # thus if there are multiple definitions/settings, the one coming from
+ # the first in the original list will win!
+ for my $l (reverse @l) {
+ # merge settings
+ if (defined($alldata->{'updmap'}{$l}{'setting'})) {
+ for my $k (keys %{$alldata->{'updmap'}{$l}{'setting'}}) {
+ $alldata->{'merged'}{'setting'}{$k}{'val'} = $alldata->{'updmap'}{$l}{'setting'}{$k}{'val'};
+ $alldata->{'merged'}{'setting'}{$k}{'origin'} = $l;
+ }
+ }
+ }
+ #
+}
+
+#
+# merging the various font definitions
+#
+sub merge_data {
+ my @l = @{$alldata->{'order'}};
+ #
+ # now merge the data
+ #
+ for my $m (keys %{$alldata->{'maps'}}) {
+ my $origin = $alldata->{'maps'}{$m}{'origin'};
+ next if !defined($origin);
+ next if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'status'} eq "disabled");
+ for my $f (keys %{$alldata->{'maps'}{$m}{'fonts'}}) {
+ # use the font definition only for those fonts where the origin matches
+ if ($alldata->{'fonts'}{$f}{'origin'} eq $m) {
+ $alldata->{'merged'}{'allMaps'}{'fonts'}{$f} =
+ $alldata->{'maps'}{$m}{'fonts'}{$f}
+ if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'} ne "KanjiMap");
+ $alldata->{'merged'}{'noMixedMaps'}{'fonts'}{$f} =
+ $alldata->{'maps'}{$m}{'fonts'}{$f}
+ if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'} eq "Map");
+ $alldata->{'merged'}{'KanjiMap'}{'fonts'}{$f} =
+ $alldata->{'maps'}{$m}{'fonts'}{$f}
+ if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'} eq "KanjiMap");
+ }
+ }
+ }
+}
+
+sub warning {
+ print STDERR @_;
+}
+
+#
+# help, version etc etc
+#
+
+sub version {
+ my $ret = sprintf "%s (TeX Live, multi) version %s\n", $prg, $version;
+ return $ret;
+}
+
+sub help {
+ my $usage = <<"EOF";
+Usage: $prg [OPTION] ... [COMMAND]
+ or: $prg-sys [OPTION] ... [COMMAND]
+
+Update the default font map files used by pdftex, dvips, and dvipdfm(x),
+(and optionally pxdvi) as determined by all configuration files updmap.cfg
+(the ones returned by running "kpsewhich --all updmap.cfg", but see below).
+
+Among other things, these map files are used to determine which fonts
+should be used as bitmaps and which as outlines, and to determine which
+fonts are included in the output.
+
+By default, the TeX filename database (ls-R) is also updated.
+
+Options:
+ --cnffile FILE read FILE for the updmap configuration
+ (can be given multiple times, in which case
+ all the files are used)
+ --dvipdfmxoutputdir DIR specify output directory (dvipdfm syntax)
+ --dvipsoutputdir DIR specify output directory (dvips syntax)
+ --pdftexoutputdir DIR specify output directory (pdftex syntax)
+ --pxdvioutputdir DIR specify output directory (pxdvi syntax)
+ --outputdir DIR specify output directory (for all files)
+ --copy cp generic files rather than using symlinks
+ --force recreate files even if config hasn't changed
+ --nomkmap do not recreate map files
+ --nohash do not run texhash
+ -n, --dry-run only show the configuration, no output
+ --quiet, --silent reduce verbosity
+
+Commands:
+ --help show this message and exit
+ --version show version information and exit
+ --showoptions OPTION show possible settings for OPTION
+ --showoption OPTION show the current setting of OPTION
+ --setoption OPTION VALUE set OPTION to value
+ --setoption OPTION=VALUE as above, just different syntax
+ --enable MAPTYPE MAPFILE add "MAPTYPE MAPFILE" to updmap.cfg,
+ where MAPTYPE is either Map, MixedMap, KanjiMap
+ --enable Map=MAPFILE add \"Map MAPFILE\" to updmap.cfg
+ --enable MixedMap=MAPFILE add \"MixedMap MAPFILE\" to updmap.cfg
+ --enable KanjiMap=MAPFILE add \"KanjiMap MAPFILE\" to updmap.cfg
+ --disable MAPFILE disable MAPFILE, whether Map, MixedMap, or KanjiMap
+ --listmaps list all active and inactive maps
+ --listavailablemaps same as --listmaps, but without
+ unavailable map files
+ --syncwithtrees disable unavailable map files in updmap.cfg
+
+Explanation of the map types: the (only) difference between Map and
+MixedMap is that MixedMap entries are not added to psfonts_pk.map.
+KanjiMap entries are added to psfonts_t1.map and kanjix.map.
+The purpose is to help users with printers that render Type 1 outline
+fonts worse than mode-tuned Type 1 bitmap fonts. So, MixedMap is used
+for fonts that are available as both Type 1 and Metafont.
+
+Explanation of the possible OPTIONS (showoptions, showoptions, setoption):
+
+ dvipsPreferOutline true|false (default true)
+ Whether dvips uses bitmaps or outlines, when both are available.
+ dvipsDownloadBase35 true|false (default false)
+ Whether dvips includes the standard 35 PostScript fonts in its output.
+ pdftexDownloadBase14 true|false (default true)
+ Whether pdftex includes the standard 14 PDF fonts in its output.
+ pxdviUse true|false (default false)
+ Whether maps for pxdvi (Japanese-patched xdvi) is under control of updmap.
+ LW35 URWkb|URW|ADOBEkb|ADOBE (default URWkb)
+ Adapt the font and file names of the standard 35 PostScript fonts.
+ URWkb URW fonts with "berry" filenames (e.g. uhvbo8ac.pfb)
+ URW URW fonts with "vendor" filenames (e.g. n019064l.pfb)
+ ADOBEkb Adobe fonts with "berry" filenames (e.g. phvbo8an.pfb)
+ ADOBE Adobe fonts with "vendor" filenames (e.g. hvnbo___.pfb)
+ kanjiEmbed (any string)
+ kanjiVariant (any string)
+
+ These options are only read and acted on by updmap; dvips, pdftex, etc.,
+ do not know anything about them. They work by changing the default map
+ file which the programs read, so they can be overridden by specifying
+ command-line options or configuration files to the programs, as
+ explained at the beginning of updmap.cfg.
+
+ The options kanjiEmbed and kanjiVariant govern special replacements
+ in the map lines. If a map contains the string \@kanjiEmbed\@, then
+ this will be replaced by the value of the respective option. Similarly
+ for kanjiVariant. This way users of Japanese TeX can select different
+ fonts to be included in the final pdf.
+
+Explanation of trees and files normally used:
+
+ updmap reads all the updmap.cfg files found by
+ kpsewhich -all updmap.cfg
+ in the order returned by kpsewhich. There is one exception to keep
+ upgradability from earlier versions of TeX Live: If there is a file
+ TEXMFLOCAL/web2c/updmap-local.cfg (which was formerly used by tlmgr
+ to merge local fonts), then a (not necessarily existing) file
+ TEXMFLOCAL/web2c/updmap.cfg is ignored and the updmap-local.cfg is
+ used instead. In this case updmap recognizes also the syntax for
+ disabling map files in the updmap-local.cfg (this syntax was different
+ to what is used now!).
+
+ According to the actions updmap might write to one of the given files or
+ create a new updmap.cfg, see below for details.
+
+ If multiple updmap.cfg files are found, all the map files mentioned
+ in all the updmap.cfg files are merged.
+
+ CAVEATS with multiple updmap.cfg files
+ * where changes are saved
+ If config files are given on the cmd line, then the first given will
+ be used to save changes (by --setoption, --enable or --disable).
+ If the config files are taken from kpsewhich, then the algorithm is
+ more complex:
+ - if one of \$TEXMFHOME/web2c/updmap.cfg or \$TEXMFCONFIG/web2c/updmap.cfg
+ appears in the list of used files, then the one given *first* by
+ kpsewhich --all, or equivalently, the one given by kpsewhich updmap.cfg,
+ is used
+ - if none of the above two are present, a new config file is created
+ in \$TEXMFCONFIG/web2c/updmap.cfg (in case there are actual changes)
+ and used
+
+ * multiple font definitions
+ If a font is defined multiple times in different maps, then the
+ definition of the map file that comes from the highest priority
+ updmap.cfg file is used.
+ If a font is defined multiple times in the same map file, an
+ arbitrary definition is used.
+ In both cases warnings are issued.
+
+ * disabling map files
+ updmap.cfg files with higher priority can disable map files that
+ are mentioned in lower priority updmap.cfg files by disabling
+ them, i.e., writing
+ \#! Map mapname.map
+ or
+ \#! MixedMap mapname.map
+ into the higher prioprity updmap.cfg file.
+
+ As an example take a user with a copy of the commercial MTPRO fonts.
+ He wants to disable the belleek version of the fonts, that is
+ disable the map belleek.map. The user should create a updmap.cfg file
+ in \$TEXMFCONFIG/web2c/updmap.cfg with the content
+ #! Map belleek.map
+ Map mt-plus.map
+ Map mt-yy.map
+ and call $prg.
+
+ updmap writes the map files for dvips (psfonts.map) and pdftex
+ (pdftex.map) to the TEXMFVAR/fonts/map/updmap/{dvips,pdftex}/
+ directories.
+
+ The log file is written to TEXMFVAR/web2c/updmap.log.
+
+ When updmap-sys is run, TEXMFSYSCONFIG and TEXMFSYSVAR are used
+ instead. This is the only difference between updmap-sys and updmap.
+
+ Other locations can be used if overridden on the command line, or these
+ trees don't exist, or you are not using the original TeX Live.
+
+ To see the precise locations of the various files that
+ will be read and written, give the -n option (or read the man page).
+
+For step-by-step instructions on making new fonts known to TeX, read
+http://tug.org/fonts/fontinstall.html. For even more terse
+instructions, read the beginning of updmap.cfg.
+
+Report bugs to: tex-k\@tug.org
+TeX Live home page: <http://tug.org/texlive/>
+EOF
+;
+ print &version();
+ print $usage;
+ exit 0;
+}
+
+### Local Variables:
+### perl-indent-level: 2
+### tab-width: 2
+### indent-tabs-mode: nil
+### End:
+# vim:set tabstop=2 expandtab: #