#!/bin/sh

###############################################################################
# updmap: utility to maintain map files for outline fonts.
#
# Thomas Esser, (C) 2002. Public domain.
# Usage: updmap [option] ... [command]
#
# Valid options:
#   --cnffile file             specify configuration file
#   --outputdir directory      specify output directory
#   --nohash                   do not run texhash
#   --nomkmap                  do not recreate map files
#   --quiet                    reduce verbosity
#
# Valid commands:
#   --edit                     edit $cnfFileShort file
#   --help                     show this message
#   --showoptions item         show alternatives for options
#   --setoption option value   set option where option is one
#                              of dvipsPreferOutline, LW35, dvipsDownloadBase35
#                              or pdftexDownloadBase14
#   --enable maptype mapfile   add or enable a Map or MixedMap
#   --disable mapfile          disable Map or MixedMap for mapfile
#   --listmaps                 list all active and inactive maps
#
###############################################################################

###############################################################################
# program history:
#   Mon Jan 27 22:38:44 CET 2003
#      don't call a function before processOptions; we may loose our
#      argument list with some broken shells
#   Mon Jan 27 06:55:28 CET 2003
#      fix unportable egrep / sed
#   Sat Jan 18 10:10:26 CET 2003
#      use $tmp8 in dvips2dvipdfm()
#   Thu Jan  2 23:14:34 CET 2003
#      add umask 022, so generated files are always world-readable
#   Sun Oct 27 11:33:04 CET 2002
#      write output in normalized format
#      add support for dvipdfm
#   Mon Sep 22 19:18:57 CEST 2002
#      fix typo: buildin -> builtin
#   Mon Sep  2 19:18:57 CEST 2002
#      fix condensed <-> narrow mapping
#   Sun Sep  1 15:02:28 CEST 2002
#      add dvipsDownloadBase35 / pdftexDownloadBase14 options
#   Wed May 22 20:00:13 CEST 2002
#      listmaps option added by Gerben Wierda
#   Tue May 21 05:27:37 CEST 2002
#      now removing map files before rewriting them; fixes permission problems
#   Tue May 21 05:05:34 CEST 2002:
#      cli options added: showoptions, setoption, enable, disable, nomkmap
#      now even more verbose; now reporting non-existing map files
#      fixing trap for MAC OS/X compatibility
#   Fri May 17 22:38:37 CEST 2002:
#      rewritten from teTeX-1.0 version; Completely new designed.
###############################################################################

test -f /bin/sh5 && test -z "$RUNNING_SH5" \
  && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
  && { RUNNING_SH5=true; export RUNNING_SH5; exec /bin/sh5 $0 ${1+"$@"}; }
unset RUNNING_SH5

test -f /bin/bsh && test -z "$RUNNING_BSH" \
  && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
  && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
unset RUNNING_BSH

# hack around a bug in zsh:
test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'

version=2.0

###############################################################################
# help()
#   display help message and exit
###############################################################################
help()
{
  cat <<eof
Usage: updmap [option] ... [command]

Valid options:
  --cnffile file             specify configuration file
  --outputdir directory      specify output directory
  --nohash                   do not run texhash
  --nomkmap                  do not recreate map files
  --quiet                    reduce verbosity

Valid commands:
  --edit                     edit $cnfFileShort file
  --help                     show this message
  --showoptions item         show alternatives for options
  --setoption option value   set option where option is one
                             of dvipsPreferOutline, LW35, dvipsDownloadBase35
                             or pdftexDownloadBase14
  --enable maptype mapfile   add or enable a Map or MixedMap
  --disable mapfile          disable Map or MixedMap for mapfile
  --listmaps                 list all active and inactive maps
eof
  exit
}

###############################################################################
# verboseMsg(msg)
#   print `msg' to stderr is $verbose is true
###############################################################################
verboseMsg() { $verbose && echo ${1+"$@"} >&2; }

###############################################################################
# warn(msg)
#   print `msg' to stderr
###############################################################################
warn()
{
  echo "$progname: $1." >&2
}

###############################################################################
# abort(errmsg)
#   print `errmsg' to stderr and exit with error code 1
###############################################################################
abort()
{
  echo "$progname: $1." >&2
  false  # some systems need this to set nonzero $?
  cleanup
  exit 1
}

###############################################################################
# cfgval(variable)
#   read variable ($1) from config file
###############################################################################
cfgval()
{
  cat $cnfFile | sed -n 's/^'"$1"'[	 =][	 =]*//p' | tail -1
}

###############################################################################
# setupSymlinks()
#   set symlink for psfonts.map according to dvipsPreferOutline variable
###############################################################################
setupSymlinks()
{
  rm -f $outputdir/psfonts.map
  if test "x$dvipsPreferOutline" = xtrue; then
    ln -s psfonts_t1.map $outputdir/psfonts.map
  else
    ln -s psfonts_pk.map $outputdir/psfonts.map
  fi

  rm -f $outputdir/pdftex.map
  if test "x$pdftexDownloadBase14" = xtrue; then
    ln -s pdftex_dl14.map $outputdir/pdftex.map
  else
    ln -s pdftex_ndl14.map $outputdir/pdftex.map
  fi
  rm -f $outputdir/dvipdfm.map
  if test "x$dvipdfmDownloadBase14" = xtrue; then
    ln -s dvipdfm_dl14.map $outputdir/dvipdfm.map
  else
    ln -s dvipdfm_ndl14.map $outputdir/dvipdfm.map
  fi
}

###############################################################################
# transLW35(args ...)
#   transform fontname and filenames according to transformation specified
#   by mode
###############################################################################
transLW35()
{
  case $mode in
    ""|URWkb)
      cat ${1+"$@"}
      ;;
    URW)
      fileURW ${1+"$@"}
      ;;
    ADOBE|ADOBEkb)
      psADOBE ${1+"$@"} | file$mode
      ;;
  esac  
}

###############################################################################
# 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.
###############################################################################
catMaps()
{
  egrep "$1" $cnfFile \
    | sed 's@#.*@@' \
       | awk '{print $2}' \
       | sort \
       | uniq \
       | grep . > $tmp4

  while read map; do
    file=`locateMap "$map"`

    # output the file; also output a newline, because the final newline
    # might be missing in the map file; Empty lines are filtered out later,
    # so it does not really hurt do do this here.
    test -n "$file" && { cat "$file"; echo; }
  done < $tmp4
}

###############################################################################
# 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.
###############################################################################
configReplace()
{
  file=$1; pat=$2; line=$3

  if grep "$pat" "$file" >/dev/null; then
    ed "$file" >/dev/null 2>&1 <<-eof
	/$pat/
	c
	$line
	.
	w
	q
eof
  else
    echo "$line" >> $file
  fi
}

###############################################################################
# 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).
###############################################################################
setOption()
{
  opt=$1
  val=$2
  case "$opt" in
    LW35)
      case "$val" in
        URWkb|URW|ADOBE|ADOBEkb)
          ;;
        *)
          abort "invalid value $val for option $opt"
          ;;
      esac
      ;;
    dvipsPreferOutline|dvipsDownloadBase35|pdftexDownloadBase14|dvipdfmDownloadBase14)
      case "$val" in
        true|false)
          ;;
        *)
          abort "invalid value $val for option $opt"
      esac
      ;;
    *)
      abort "unsupported option $opt"
      ;;
  esac

  configReplace "$cnfFile" "^$opt[ 	]" "$opt $val"
}

###############################################################################
# enableMap (type, map)
#   enables an entry in the config file for map with a given type.
###############################################################################
enableMap()
{
  case $1 in
    Map|MixedMap)
      ;;
    *)
      abort "invalid mapType $1"
      ;;
  esac

  # a map can only have one type, so we carefully disable everything
  # about map here:
  disableMap "$2"

  # now enable with the right type:
  configReplace "$cnfFile" "^#![ 	]*$1[ 	]*$2" "$1 $2"
}

###############################################################################
# disableMap (map)
#   disables map in config file (any type)
###############################################################################
disableMap()
{
  mapType=`awk '($1 == "MixedMap" || $1 == "Map") && $2 == map { print $1 }' \
             map=$1 <"$cnfFile" | sort | uniq`
  for type in $mapType; do
    configReplace "$cnfFile" "^$type[ 	]*$1" "#! $type $1"
  done
}

###############################################################################
# psADOBE()
#   transform fontnames from URW to Adobe
###############################################################################
psADOBE()
{
  sed \
    -e 's/ URWGothicL-Demi / AvantGarde-Demi /' \
    -e 's/ URWGothicL-DemiObli / AvantGarde-DemiOblique /' \
    -e 's/ URWGothicL-Book / AvantGarde-Book /' \
    -e 's/ URWGothicL-BookObli / AvantGarde-BookOblique /' \
    -e 's/ URWBookmanL-DemiBold / Bookman-Demi /' \
    -e 's/ URWBookmanL-DemiBoldItal / Bookman-DemiItalic /' \
    -e 's/ URWBookmanL-Ligh / Bookman-Light /' \
    -e 's/ URWBookmanL-LighItal / Bookman-LightItalic /' \
    -e 's/ NimbusMonL-Bold / Courier-Bold /' \
    -e 's/ NimbusMonL-BoldObli / Courier-BoldOblique /' \
    -e 's/ NimbusMonL-Regu / Courier /' \
    -e 's/ NimbusMonL-ReguObli / Courier-Oblique /' \
    -e 's/ NimbusSanL-Bold / Helvetica-Bold /' \
    -e 's/ NimbusSanL-BoldCond / Helvetica-Narrow-Bold /' \
    -e 's/ NimbusSanL-BoldItal / Helvetica-BoldOblique /' \
    -e 's/ NimbusSanL-BoldCondItal / Helvetica-Narrow-BoldOblique /' \
    -e 's/ NimbusSanL-Regu / Helvetica /' \
    -e 's/ NimbusSanL-ReguCond / Helvetica-Narrow /' \
    -e 's/ NimbusSanL-ReguItal / Helvetica-Oblique /' \
    -e 's/ NimbusSanL-ReguCondItal / Helvetica-Narrow-Oblique /' \
    -e 's/ CenturySchL-Bold / NewCenturySchlbk-Bold /' \
    -e 's/ CenturySchL-BoldItal / NewCenturySchlbk-BoldItalic /' \
    -e 's/ CenturySchL-Roma / NewCenturySchlbk-Roman /' \
    -e 's/ CenturySchL-Ital / NewCenturySchlbk-Italic /' \
    -e 's/ URWPalladioL-Bold / Palatino-Bold /' \
    -e 's/ URWPalladioL-BoldItal / Palatino-BoldItalic /' \
    -e 's/ URWPalladioL-Roma / Palatino-Roman /' \
    -e 's/ URWPalladioL-Ital / Palatino-Italic /' \
    -e 's/ StandardSymL / Symbol /' \
    -e 's/ NimbusRomNo9L-Medi / Times-Bold /' \
    -e 's/ NimbusRomNo9L-MediItal / Times-BoldItalic /' \
    -e 's/ NimbusRomNo9L-Regu / Times-Roman /' \
    -e 's/ NimbusRomNo9L-ReguItal / Times-Italic /' \
    -e 's/ URWChanceryL-MediItal / ZapfChancery-MediumItalic /' \
    -e 's/ Dingbats / ZapfDingbats /' \
    ${1+"$@"}
}

###############################################################################
# fileADOBEkb()
#   transform filenames from URW to ADOBE (both berry names)
###############################################################################
fileADOBEkb()
{
  sed \
    -e 's/\([^A-Za-z]\)uagd8a.pfb/\1pagd8a.pfb/' \
    -e 's/\([^A-Za-z]\)uagdo8a.pfb/\1pagdo8a.pfb/' \
    -e 's/\([^A-Za-z]\)uagk8a.pfb/\1pagk8a.pfb/' \
    -e 's/\([^A-Za-z]\)uagko8a.pfb/\1pagko8a.pfb/' \
    -e 's/\([^A-Za-z]\)ubkd8a.pfb/\1pbkd8a.pfb/' \
    -e 's/\([^A-Za-z]\)ubkdi8a.pfb/\1pbkdi8a.pfb/' \
    -e 's/\([^A-Za-z]\)ubkl8a.pfb/\1pbkl8a.pfb/' \
    -e 's/\([^A-Za-z]\)ubkli8a.pfb/\1pbkli8a.pfb/' \
    -e 's/\([^A-Za-z]\)ucrb8a.pfb/\1pcrb8a.pfb/' \
    -e 's/\([^A-Za-z]\)ucrbo8a.pfb/\1pcrbo8a.pfb/' \
    -e 's/\([^A-Za-z]\)ucrr8a.pfb/\1pcrr8a.pfb/' \
    -e 's/\([^A-Za-z]\)ucrro8a.pfb/\1pcrro8a.pfb/' \
    -e 's/\([^A-Za-z]\)uhvb8a.pfb/\1phvb8a.pfb/' \
    -e 's/\([^A-Za-z]\)uhvb8ac.pfb/\1phvb8an.pfb/' \
    -e 's/\([^A-Za-z]\)uhvbo8a.pfb/\1phvbo8a.pfb/' \
    -e 's/\([^A-Za-z]\)uhvbo8ac.pfb/\1phvbo8an.pfb/' \
    -e 's/\([^A-Za-z]\)uhvr8a.pfb/\1phvr8a.pfb/' \
    -e 's/\([^A-Za-z]\)uhvr8ac.pfb/\1phvr8an.pfb/' \
    -e 's/\([^A-Za-z]\)uhvro8a.pfb/\1phvro8a.pfb/' \
    -e 's/\([^A-Za-z]\)uhvro8ac.pfb/\1phvro8an.pfb/' \
    -e 's/\([^A-Za-z]\)uncb8a.pfb/\1pncb8a.pfb/' \
    -e 's/\([^A-Za-z]\)uncbi8a.pfb/\1pncbi8a.pfb/' \
    -e 's/\([^A-Za-z]\)uncr8a.pfb/\1pncr8a.pfb/' \
    -e 's/\([^A-Za-z]\)uncri8a.pfb/\1pncri8a.pfb/' \
    -e 's/\([^A-Za-z]\)uplb8a.pfb/\1pplb8a.pfb/' \
    -e 's/\([^A-Za-z]\)uplbi8a.pfb/\1pplbi8a.pfb/' \
    -e 's/\([^A-Za-z]\)uplr8a.pfb/\1pplr8a.pfb/' \
    -e 's/\([^A-Za-z]\)uplri8a.pfb/\1pplri8a.pfb/' \
    -e 's/\([^A-Za-z]\)usyr.pfb/\1psyr.pfb/' \
    -e 's/\([^A-Za-z]\)utmb8a.pfb/\1ptmb8a.pfb/' \
    -e 's/\([^A-Za-z]\)utmbi8a.pfb/\1ptmbi8a.pfb/' \
    -e 's/\([^A-Za-z]\)utmr8a.pfb/\1ptmr8a.pfb/' \
    -e 's/\([^A-Za-z]\)utmri8a.pfb/\1ptmri8a.pfb/' \
    -e 's/\([^A-Za-z]\)uzcmi8a.pfb/\1pzcmi8a.pfb/' \
    -e 's/\([^A-Za-z]\)uzdr.pfb/\1pzdr.pfb/' \
    ${1+"$@"}
}

###############################################################################
# fileURW()
#   transform filenames from URWkb (berry names) to URW (vendor names)
###############################################################################
fileURW()
{
  sed \
    -e 's/\([^A-Za-z]\)uagd8a.pfb/\1a010015l.pfb/' \
    -e 's/\([^A-Za-z]\)uagdo8a.pfb/\1a010035l.pfb/' \
    -e 's/\([^A-Za-z]\)uagk8a.pfb/\1a010013l.pfb/' \
    -e 's/\([^A-Za-z]\)uagko8a.pfb/\1a010033l.pfb/' \
    -e 's/\([^A-Za-z]\)ubkd8a.pfb/\1b018015l.pfb/' \
    -e 's/\([^A-Za-z]\)ubkdi8a.pfb/\1b018035l.pfb/' \
    -e 's/\([^A-Za-z]\)ubkl8a.pfb/\1b018012l.pfb/' \
    -e 's/\([^A-Za-z]\)ubkli8a.pfb/\1b018032l.pfb/' \
    -e 's/\([^A-Za-z]\)ucrb8a.pfb/\1n022004l.pfb/' \
    -e 's/\([^A-Za-z]\)ucrbo8a.pfb/\1n022024l.pfb/' \
    -e 's/\([^A-Za-z]\)ucrr8a.pfb/\1n022003l.pfb/' \
    -e 's/\([^A-Za-z]\)ucrro8a.pfb/\1n022023l.pfb/' \
    -e 's/\([^A-Za-z]\)uhvb8a.pfb/\1n019004l.pfb/' \
    -e 's/\([^A-Za-z]\)uhvb8ac.pfb/\1n019044l.pfb/' \
    -e 's/\([^A-Za-z]\)uhvbo8a.pfb/\1n019024l.pfb/' \
    -e 's/\([^A-Za-z]\)uhvbo8ac.pfb/\1n019064l.pfb/' \
    -e 's/\([^A-Za-z]\)uhvr8a.pfb/\1n019003l.pfb/' \
    -e 's/\([^A-Za-z]\)uhvr8ac.pfb/\1n019043l.pfb/' \
    -e 's/\([^A-Za-z]\)uhvro8a.pfb/\1n019023l.pfb/' \
    -e 's/\([^A-Za-z]\)uhvro8ac.pfb/\1n019063l.pfb/' \
    -e 's/\([^A-Za-z]\)uncb8a.pfb/\1c059016l.pfb/' \
    -e 's/\([^A-Za-z]\)uncbi8a.pfb/\1c059036l.pfb/' \
    -e 's/\([^A-Za-z]\)uncr8a.pfb/\1c059013l.pfb/' \
    -e 's/\([^A-Za-z]\)uncri8a.pfb/\1c059033l.pfb/' \
    -e 's/\([^A-Za-z]\)uplb8a.pfb/\1p052004l.pfb/' \
    -e 's/\([^A-Za-z]\)uplbi8a.pfb/\1p052024l.pfb/' \
    -e 's/\([^A-Za-z]\)uplr8a.pfb/\1p052003l.pfb/' \
    -e 's/\([^A-Za-z]\)uplri8a.pfb/\1p052023l.pfb/' \
    -e 's/\([^A-Za-z]\)usyr.pfb/\1s050000l.pfb/' \
    -e 's/\([^A-Za-z]\)utmb8a.pfb/\1n021004l.pfb/' \
    -e 's/\([^A-Za-z]\)utmbi8a.pfb/\1n021024l.pfb/' \
    -e 's/\([^A-Za-z]\)utmr8a.pfb/\1n021003l.pfb/' \
    -e 's/\([^A-Za-z]\)utmri8a.pfb/\1n021023l.pfb/' \
    -e 's/\([^A-Za-z]\)uzcmi8a.pfb/\1z003034l.pfb/' \
    -e 's/\([^A-Za-z]\)uzdr.pfb/\1d050000l.pfb/' \
    ${1+"$@"}
}

###############################################################################
# fileADOBE()
#   transform filenames from URWkb (berry names) to ADOBE (vendor names)
###############################################################################
fileADOBE()
{
  sed \
    -e 's/\([^A-Za-z]\)uagd8a.pfb/\1agd_____.pfb/' \
    -e 's/\([^A-Za-z]\)uagdo8a.pfb/\1agdo____.pfb/' \
    -e 's/\([^A-Za-z]\)uagk8a.pfb/\1agw_____.pfb/' \
    -e 's/\([^A-Za-z]\)uagko8a.pfb/\1agwo____.pfb/' \
    -e 's/\([^A-Za-z]\)ubkd8a.pfb/\1bkd_____.pfb/' \
    -e 's/\([^A-Za-z]\)ubkdi8a.pfb/\1bkdi____.pfb/' \
    -e 's/\([^A-Za-z]\)ubkl8a.pfb/\1bkl_____.pfb/' \
    -e 's/\([^A-Za-z]\)ubkli8a.pfb/\1bkli____.pfb/' \
    -e 's/\([^A-Za-z]\)ucrb8a.pfb/\1cob_____.pfb/' \
    -e 's/\([^A-Za-z]\)ucrbo8a.pfb/\1cobo____.pfb/' \
    -e 's/\([^A-Za-z]\)ucrr8a.pfb/\1com_____.pfb/' \
    -e 's/\([^A-Za-z]\)ucrro8a.pfb/\1coo_____.pfb/' \
    -e 's/\([^A-Za-z]\)uhvb8a.pfb/\1hvb_____.pfb/' \
    -e 's/\([^A-Za-z]\)uhvb8ac.pfb/\1hvnb____.pfb/' \
    -e 's/\([^A-Za-z]\)uhvbo8a.pfb/\1hvbo____.pfb/' \
    -e 's/\([^A-Za-z]\)uhvbo8ac.pfb/\1hvnbo___.pfb/' \
    -e 's/\([^A-Za-z]\)uhvr8a.pfb/\1hv______.pfb/' \
    -e 's/\([^A-Za-z]\)uhvr8ac.pfb/\1hvn_____.pfb/' \
    -e 's/\([^A-Za-z]\)uhvro8a.pfb/\1hvo_____.pfb/' \
    -e 's/\([^A-Za-z]\)uhvro8ac.pfb/\1hvno____.pfb/' \
    -e 's/\([^A-Za-z]\)uncb8a.pfb/\1ncb_____.pfb/' \
    -e 's/\([^A-Za-z]\)uncbi8a.pfb/\1ncbi____.pfb/' \
    -e 's/\([^A-Za-z]\)uncr8a.pfb/\1ncr_____.pfb/' \
    -e 's/\([^A-Za-z]\)uncri8a.pfb/\1nci_____.pfb/' \
    -e 's/\([^A-Za-z]\)uplb8a.pfb/\1pob_____.pfb/' \
    -e 's/\([^A-Za-z]\)uplbi8a.pfb/\1pobi____.pfb/' \
    -e 's/\([^A-Za-z]\)uplr8a.pfb/\1por_____.pfb/' \
    -e 's/\([^A-Za-z]\)uplri8a.pfb/\1poi_____.pfb/' \
    -e 's/\([^A-Za-z]\)usyr.pfb/\1sy______.pfb/' \
    -e 's/\([^A-Za-z]\)utmb8a.pfb/\1tib_____.pfb/' \
    -e 's/\([^A-Za-z]\)utmbi8a.pfb/\1tibi____.pfb/' \
    -e 's/\([^A-Za-z]\)utmr8a.pfb/\1tir_____.pfb/' \
    -e 's/\([^A-Za-z]\)utmri8a.pfb/\1tii_____.pfb/' \
    -e 's/\([^A-Za-z]\)uzcmi8a.pfb/\1zcmi____.pfb/' \
    -e 's/\([^A-Za-z]\)uzdr.pfb/\1zd______.pfb/' \
    ${1+"$@"}
}

base14RemovePSName()
{
  sed \
    -e '/^[^ 	]*[ 	]Courier[ 	]/s/[ 	][^ 	]*//' \
    -e '/^[^ 	]*[ 	]Courier-Bold[ 	]/s/[ 	][^ 	]*//' \
    -e '/^[^ 	]*[ 	]Courier-Oblique[ 	]/s/[ 	][^ 	]*//' \
    -e '/^[^ 	]*[ 	]Courier-BoldOblique[ 	]/s/[ 	][^ 	]*//' \
    -e '/^[^ 	]*[ 	]Helvetica[ 	]/s/[ 	][^ 	]*//' \
    -e '/^[^ 	]*[ 	]Helvetica-Bold[ 	]/s/[ 	][^ 	]*//' \
    -e '/^[^ 	]*[ 	]Helvetica-Oblique[ 	]/s/[ 	][^ 	]*//' \
    -e '/^[^ 	]*[ 	]Helvetica-BoldOblique[ 	]/s/[ 	][^ 	]*//' \
    -e '/^[^ 	]*[ 	]Symbol[ 	]/s/[ 	][^ 	]*//' \
    -e '/^[^ 	]*[ 	]Times-Roman[ 	]/s/[ 	][^ 	]*//' \
    -e '/^[^ 	]*[ 	]Times-Bold[ 	]/s/[ 	][^ 	]*//' \
    -e '/^[^ 	]*[ 	]Times-Italic[ 	]/s/[ 	][^ 	]*//' \
    -e '/^[^ 	]*[ 	]Times-BoldItalic[ 	]/s/[ 	][^ 	]*//' \
    -e '/^[^ 	]*[ 	]ZapfDingbats[ 	]/s/[ 	][^ 	]*//'
}

###############################################################################
# locateWeb2c (file ...)
#   apply kpsewhich with format 'web2c files'
###############################################################################
locateWeb2c()
{
  kpsewhich --format='web2c files' ${1+"$@"}
}

###############################################################################
# locateMap (file ...)
#   apply kpsewhich with format 'dvips config'
###############################################################################
locateMap()
{
  for map
  do
    file=`kpsewhich --format='dvips config' "$map"`
    if test -f "$file"; then
      verboseMsg "using map file \`$file'"
      echo "$file"
    else
      warn "map file \`$map' not found"
    fi
  done
}

###############################################################################
# cleanup()
#   clean up the temp area and exit with proper exit status
###############################################################################
cleanup()
{
  rc=$?
  $needsCleanup && test -n "$tmpdir" && test -d "$tmpdir" \
    && { rm -f "$tmpdir"/*; cd /; rmdir "$tmpdir"; }
  exit $rc
}

###############################################################################
# setupTmpDir()
#   set up a temp directory and a trap to remove it
###############################################################################
setupTmpDir()
{
  $needsCleanup && return

  trap 'cleanup' 1 2 3 7 13 15
  needsCleanup=true
  mkdir "$tmpdir" || abort "could not create directory \`$tmpdir'"
}

###############################################################################
# showOptions(item)
#   show Options for an item
###############################################################################
showOptions()
{
  item=$1

  case "$item" in
    LW35)
      echo "URWkb URW ADOBE ADOBEkb"
      ;;
    dvipsPreferOutline|pdftexDownloadBase14|dvipdfmDownloadBase14|dvipsDownloadBase35)
      echo "true false"
      ;;
    *)
      abort "Unknown item \"$item\". Choose one of LW35, dvipsPreferOutline, dvipsDownloadBase35, pdftexDownloadBase14 or dvipdfmDownloadBase14"
      ;;
  esac

  exit 0
}


###############################################################################
# setupDestDir()
#   find an output directory if none specified on cmd line. First choice is
#   $VARTEXMF/dvips/config (if VARTEXMF is set), next is relative to config
#   file location. Fallback is $TEXMFMAIN/dvips/config.
###############################################################################
setupDestDir()
{
  if test -z "$outputdir"; then

    # Try VARTEXMF tree. Use it if variable is set and dvips/config can
    # be written. Copy config file if it does not exist there.
    tf=`kpsewhich -expand-var='$VARTEXMF'`
    if test -n "$tf"; then
      $TEXMFMAIN/web2c/mktexdir "$tf/dvips/config" >/dev/null
      if test ! -d "$tf/dvips/config" || test ! -w "$tf/dvips/config"; then
        # forget about VARTEXMF tree...
        tf=
      fi
    fi
      
    # Try something relative to config file, fall back to $TEXMFMAIN.
    if test -z "$tf"; then
      tf=`echo $cnfFile | sed -n 's@/web2c/[^/]*$@@p'`
      test -z "$tf" && tf=$TEXMFMAIN
    fi

    outputdir=$tf/dvips/config
  fi

  $TEXMFMAIN/web2c/mktexdir "$outputdir"
  test -d "$outputdir" || abort "output directory \`$outputdir' does not exist"
  test -w "$outputdir" || abort "output directory \`$outputdir' is not writable"
  verboseMsg "using output directory $outputdir"
}

###############################################################################
# setupCfgFile()
#   find config file if none specified on cmd line.
###############################################################################
setupCfgFile()
{

  if test -z "$cnfFile"; then

    tf=`kpsewhich -expand-var='$VARTEXMF'`
    if test -n "$tf" && test ! -f "$tf/web2c/$cnfFileShort"; then
      test -d "$tf/web2c" || $TEXMFMAIN/web2c/mktexdir "$tf/web2c" 2>/dev/null
      if test -d "$tf/web2c" && test -w "$tf/web2c"; then
        rm -f "$tf/web2c/$cnfFileShort"
        cp $TEXMFMAIN/web2c/$cnfFileShort "$tf/web2c/$cnfFileShort"
        $TEXMFMAIN/web2c/mktexupd "$tf/web2c" "$cnfFileShort"
      fi
    fi

    cnfFile=`locateWeb2c $cnfFileShort`
    if test -n "$cnfFile"; then
      verboseMsg "using config file $cnfFile"
    else
      abort "config file $cnfFileShort not found"
    fi
  fi
}

###############################################################################
# processOptions()
#   process cmd line options
###############################################################################
processOptions()
{
  while
    case $1 in
      --quiet|-q)
          verbose=false;;
      --cnffile)
          cfgparam=1; cnfFile=$2; shift;;
      --cnffile=*)
          cfgparam=1; cnfFile=`echo "$1" | sed 's/--cnffile=//'`;;
      --outputdir)
          outputdirparam=1; outputdir=$2; shift;;
      --outputdir=*)
          outputdirparam=1; outputdir=`echo "$1" | sed 's/--outputdir=//'`;;
      --setoption)
          test $# -ge 3 || { abort "--setoption needs two parameters: option value"; }
          cmd=setoption; setoptionOpt=$2; setoptionVal=$3; shift; shift
          ;;
      --enable)
          test $# -ge 3 || { abort "--enable needs two parameters: mapType mapFile"; }
          cmd=enable; enableMapType=$2; enableMapFile=$3; shift; shift
          ;;
      --disable)
          cmd=disable; disableMapFile=$2; shift
          ;;
      --edit|-e)
          cmd=edit;;
      --listmaps|-l)
          cmd=listmaps;;
      --showoptions)
          cmd=showoptions; showoptionsItem=$2; shift;;
      --showoptions=*)
          cmd=showoptions; showoptionsItem=`echo "$1" | sed 's/--showoptions=//'`;;
      --nohash)
          texhashEnabled=false;;
      --nomkmap)
          mkmapEnabled=false;;
      --help|-help|-h)
          help;;
      "") break;;
      *) echo "$progname: unknown option \`$1' ignored." >&2;;
    esac
  do test $# -gt 0 && shift; done

  if test -n "$cfgparam"; then
    if test -z "$cnfFile" || test ! -f "$cnfFile"; then
      abort "config file \`$cnfFileShort' not found"
    fi
  fi

  if test -n "$outputdirparam"; then
    if test -z "$outputdir" || test ! -d "$outputdir"; then
      abort "output directory \`$1' not found"
    fi
  fi
}



###############################################################################
# listMaps()
#   list all maps mentioned in the config file
###############################################################################
listMaps()
{
  egrep '^(#! *)?(Mixed)?Map' $cnfFile
}

###############################################################################
# normalizeLines()
#   remove comments, whitespace is exactly one space, no empty lines,
#   no whitespace at end of line, one space before and after "
###############################################################################
normalizeLines()
{
  sed \
      -e '/^%/d' \
      -e 's@[ 	][ 	]*@ @g' \
      -e '/^ *$/d' \
      -e 's@ $@@' \
      -e 's@ *" *@ " @g' | sort | uniq
}

dvips2dvipdfm()
{
  sed -e 's@$@ %@' \
      -e 's@^\(\([^ ]*\).*\)@\1\2@' \
      -e 's@\(.*<\[* *\([^ ]*\)\.enc\(.*\)\)@\1 \2@' \
      -e '/%[^ ]*$/s@$@ default@' \
      -e 's@\(.*<<* *\([^ ]*\)\.pf[ab].*\)@\1 \2@' \
      -e '/%[^ ]* [^ ]*$/s@\( \([^ ]*\).*\)$@\1 \2@' \
      -e 's@\(.* \([.0-9-][.0-9-]*\) *ExtendFont.*\)@\1 -e \2@' \
      -e 's@\(.* \([.0-9-][.0-9-]*\) *SlantFont.*\)@\1 -s \2@' \
      -e 's@.*%@@' |
  awk '$1 == $3 && $2 == "default" {$2=""; $3=""} {print}' > $tmp8
 
  egrep '^(cm|eu|la|lc|line|msam|xy)' $tmp8 | sed 's@$@ -r@'
  egrep -v '^(cm|eu|la|lc|line|msam|xy)' $tmp8
}


###############################################################################
# mkMaps()
#   the main task of this script: create the output files
###############################################################################
mkMaps()
{
  mode=`cfgval LW35`
  dvipsPreferOutline=`cfgval dvipsPreferOutline`
  dvipsDownloadBase35=`cfgval dvipsDownloadBase35`
  pdftexDownloadBase14=`cfgval pdftexDownloadBase14`
  dvipdfmDownloadBase14=`cfgval dvipdfmDownloadBase14`

  # defaults
  test -z "$mode" && mode=URWkb
  test -z "$dvipsPreferOutline" && dvipsPreferOutline=true
  test -z "$dvipsDownloadBase35" && dvipsDownloadBase35=false
  test -z "$pdftexDownloadBase14" && pdftexDownloadBase14=false
  test -z "$dvipdfmDownloadBase14" && dvipdfmDownloadBase14=false

  $verbose && cat >&2 <<-eof

	updmap is creating new map files using the following configuration:
	  prefer outlines: $dvipsPreferOutline
	  texhash enabled: $texhashEnabled
	  download standard fonts (dvips): $dvipsDownloadBase35
	  download standard fonts (pdftex): $pdftexDownloadBase14
	  download standard fonts (dvipdfm): $dvipdfmDownloadBase14
eof

  verboseMsg
  verboseMsg "Scanning for LW35 support files"
  dvips35=`locateMap dvips35.map`
  pdftex35=`locateMap pdftex35.map`
  dvipdfm35=`locateMap dvipdfm35.map`
  ps2pk35=`locateMap ps2pk35.map`

  verboseMsg
  verboseMsg "Scanning for MixedMap entries:"
  catMaps '^MixedMap' > $tmp1

  verboseMsg
  verboseMsg "Scanning for Map entries:"
  catMaps '^Map' > $tmp2
  verboseMsg

  # files should be work-readable
  umask 022

  # Create psfonts_t1.map, psfonts_pk.map, ps2pk.map, pdftex.map and dvipdfm.map:
  for file in download35.map builtin35.map psfonts_t1.map psfonts_pk.map pdftex_dl14.map pdftex_ndl14.map dvipdfm_dl14.map dvipdfm_ndl14.map ps2pk.map; do
    rm -f "$outputdir/$file"
    cat > $outputdir/$file <<-eof
	% $file: maintained by the script updmap.
	%   Don't change this file directly. Edit texmf/web2c/$cnfFileShort
	%   and run updmap to recreate this file.
eof
  done

  { transLW35 $ps2pk35; cat $tmp1 $tmp2; } \
    | normalizeLines >> $outputdir/ps2pk.map

  { transLW35 $ps2pk35; } \
    | normalizeLines >> $outputdir/download35.map
  { transLW35 $dvips35; } \
    | normalizeLines >> $outputdir/builtin35.map

  if test "x$dvipsDownloadBase35" = xtrue; then
    dftdvips=$ps2pk35
  else
    dftdvips=$dvips35
  fi
  { transLW35 $dftdvips; cat $tmp1 $tmp2; } \
    | normalizeLines >> $outputdir/psfonts_t1.map
  { transLW35 $dftdvips; cat $tmp2; } \
    | normalizeLines >> $outputdir/psfonts_pk.map

  # remove PaintType due to Sebastian's request
  { transLW35 $pdftex35; cat $tmp1 $tmp2; } \
    | egrep -v '(^%|PaintType)' | grep . > $tmp3
  { transLW35 $dvipdfm35; cat $tmp1 $tmp2; } \
    | egrep -v '(^%|PaintType)' | grep . > $tmp6
  { transLW35 $ps2pk35; cat $tmp1 $tmp2; } \
    | egrep -v '(^%|PaintType)' | grep . > $tmp7

  # remove PS-Fontname from ExtendFont / SlantFont lines (works around a
  # pdftex bug)
  { <$tmp3 egrep '".*[^A-Za-z](Slant|Extend)Font([^A-Za-z].*"|")' | sed 's@[ 	][^ 	]*@@'
    <$tmp3 egrep -v '".*[^A-Za-z](Slant|Extend)Font([^A-Za-z].*"|")'
  } | normalizeLines >> $outputdir/pdftex_ndl14.map
  { <$tmp7 egrep '".*[^A-Za-z](Slant|Extend)Font([^A-Za-z].*"|")' | sed 's@[ 	][^ 	]*@@'
    <$tmp7 egrep -v '".*[^A-Za-z](Slant|Extend)Font([^A-Za-z].*"|")'
  } | base14RemovePSName | normalizeLines >> $outputdir/pdftex_dl14.map
  <$tmp7 normalizeLines | dvips2dvipdfm | normalizeLines >> $outputdir/dvipdfm_dl14.map
  <$tmp6 normalizeLines | dvips2dvipdfm | normalizeLines >> $outputdir/dvipdfm_ndl14.map
  setupSymlinks
  $texhashEnabled && { $verbose && texhash || texhash >/dev/null 2>&1; }

  verboseMsg
  verboseMsg "Files generated in $outputdir:"
  $verbose && (cd $outputdir; ls -l dvipdfm.map dvipdfm_dl14.map dvipdfm_ndl14.map pdftex.map pdftex_dl14.map pdftex_ndl14.map ps2pk.map psfonts.map psfonts_pk.map psfonts_t1.map builtin35.map download35.map) >&2
  verboseMsg
}

###############################################################################
# main()
#   execution starts here
###############################################################################
main()
{
  # initialize global variables
  progname=updmap
  cmd=

  cfgparam=
  outputdirparam=
  texhashEnabled=true
  mkmapEnabled=true
  verbose=true
  needsCleanup=false

  cnfFileShort=updmap.cfg
  cnfFile=
  outputdir=
  TEXMFMAIN=`kpsewhich --expand-var='$TEXMFMAIN'`

  tmpdir=${TMP-/tmp}/$progname.$$
  tmp1=$tmpdir/a
  tmp2=$tmpdir/b
  tmp3=$tmpdir/c
  tmp4=$tmpdir/d
  tmp5=$tmpdir/e
  tmp6=$tmpdir/f
  tmp7=$tmpdir/g
  tmp8=$tmpdir/h

  processOptions ${1+"$@"}

  case "$cmd" in
    showoptions) showOptions "$showoptionsItem"; exit;;
    help)        help; exit;;
  esac

  setupCfgFile
  case "$cmd" in
    listmaps) listMaps; exit;;
  esac

  # keep a copy of config file, so that we can see if the file was modified
  setupTmpDir
  cp $cnfFile $tmp5

  case "$cmd" in
    edit)
      ${VISUAL-${EDITOR-vi}} $cnfFile;;
    setoption)
      setOption "$setoptionOpt" "$setoptionVal";;
    enable)
      enableMap "$enableMapType" "$enableMapFile";;
    disable)
      disableMap "$disableMapFile";;
  esac

  if test -n "$cmd" && cmp $cnfFile $tmp5 >/dev/null 2>&1; then
    verboseMsg "$cnfFile unchanged. Map files not recreated."
    return
  fi

  $mkmapEnabled || return
  setupDestDir
  mkMaps
}

main ${1+"$@"}
true
cleanup
