#!/bin/sh
SAVE_ARGS="$*"

# TeX-Config version 0.4. I hope, you will love this script :-)

# More comments, more verbose messages, and better error handling are needed.
# It sould give more help (e.g on ls-R and localfont) and ask a bit more
# for confirmations.

# Any comments, improvements, ... please via Email to:
# Thomas Esser, te@informatik.uni-hannover.de
# Copyright: Thomas Esser, 1994, 1995, 1996

# You may override DIALOG_TERMINFO and DIALOG_TERM in your environment.

# These are setup in $TETEXDIR/texmf.cnf.
progname=`basename $0`
tmpdir=${TMP-/tmp}/texconf$$
std_pager=more
xdvi_shrink_scale=75
std_editor=vi

envvars="
BIBINPUTS BSTINPUTS DVIPSHEADERS GFFONTS GLYPHFONTS MFBASES MFINPUTS
MFPOOL MPMEMS MPINPUTS MPPOOL MPSUPPORT PKFONTS TEXCONFIG TEXFONTS
TEXFORMATS TEXINPUTS TEXMFCNF TEXPICTS TEXPKS TEXPOOL TFMFONTS VFFONTS
DVIPSFONTS XDVIVFS XDVIFONTS DVILJFONTS TRFONTS"

umask 022

PATH=$PATH:`pwd`; export PATH
log=$tmpdir/logfile
unset mode

echo_a()
{
	echo -n "$@"
}

echo_b()
{
	echo "$@\c"
}

echo_c()
{
	echo -e "$@\c"
}

echo_d()
{
	/bin/echo -n "$@"
}

echo_e()
{
	/bin/echo "$@\c"
}

echo_f()
{
	/bin/echo -e "$@\c"
}


find_echo()
{
	for i in a b c d e f; do
		test "`echo_$i c``echo_$i a`"  = ca &&
			echon=echo_$i && return
	done
	echon=echo
}

find_echo

find_fmt()
{
  FMT=fmt
  test ! -x /bin/fmt && test ! -f /usr/bin/fmt &&
    { test -x /bin/adjust || test -x /usr/bin/adjust; } && FMT=adjust
}

find_fmt

cls()
{
  test -z "$NO_CLEAR" && clear
}

# Some systems have their own dialog. Use it then and do not use
# faked TERM and TERMINFO variables when calling that dialog.
find_dialogtype()
{
  own_dialog=false
  { u=`uname -s`; } 2>/dev/null
  case "$u" in
    FreeBSD)
      DIALOG_PROG=/usr/bin/dialog
      test -x "$DIALOG_PROG" && own_dialog=true;;
  esac
}
 
find_dialogtype
 
run_dialog()
{
  test -z "$NO_CLEAR" && clear
  if $own_dialog; then
    $DIALOG_PROG --title "teTeX setup utility" "$@"
  else
    TERM=$DIALOG_TERM TERMINFO=$DIALOG_TERMINFO dialog --title "teTeX setup utility" "$@"
  fi
}

check_environ()
{
	found=
	for i in $envvars; do
		eval var=\"\$$i\"
		if [ ! -z "$var" ]; then
			case $var in
				:*|*:|*::*)	;;
				*)	found="$found $i"
					;;
			esac
		fi
	done
	test -z "$found" && return
	clear
	cat <<-eof
		$progname has found the folloving environment variables set:

	eof
	for i in $found; do
		eval echo \"	\$i = \$$i\"
	done
	cat <<-eof

		Please make sure, their values are ok, and otherwise change or unset them.
		If you continue with wrong values for the above variables, $progname
		might run into trouble when locating files on the disk.

		Note that you can refer to the default path by giving an "empty" path
		component (i.e. a colon in front or in the end, or a doubled colon
		somewhere in the middle).

		If you set TEXINPUTS, e.g. to :~/TeX/macros, (La)TeX will search along
		the default path and then in ~/TeX/macros.

		For more information, see the Kpathsea and the teTeX manual.

	eof
	
	$echon "Press RETURN to continue (or Control-C to abort)... "
	read dummy
}

fonts_ro()
{
  clear
  echo "Removing global write permissions in fonts tree:" >&2
  find $TEXMF/fonts -perm -2 -type d -exec sh -c '
		chmod -t $1 || exit;
		chmod go-w $1 || exit;
		echo $1 >&2;
	' sh '{}' \;
  chmod go-w $TEXMF/ls-R && echo $TEXMF/ls-R >&2
  echo "Done." >&2
}

fonts_rw()
{
  clear
  echo "Adding global write permissions in fonts tree:" >&2
  find $TEXMF/fonts/tfm $TEXMF/fonts/pk $TEXMF/fonts/source/jknappen \
	-type d -exec sh -c '
		case $1 in
		*/adobe*|*/bitstrea*)	exit;;
		esac
		chmod 1777 $1 || exit;
		echo $1 >&2;
	' sh '{}' \;
  chmod 666 $TEXMF/ls-R && echo $TEXMF/ls-R >&2
  echo "Done." >&2
}

check_terminal()
{
	terminfo=${DIALOG_TERMINFO-/usr/lib/terminfo}

	test -f $terminfo/`echo $DIALOG_TERM | sed 's/\(.\).*/\1/'`/$DIALOG_TERM && return
	cat >&2 <<-eof
		TERM=$DIALOG_TERM is not supported by your terminfo system.
		See terminfo(5), tic(1m) and term(5) for help.

		$progname failed. Program aborted.
	eof
	exit 1
}

fix_pager_more()
{
	case "$PAGER" in
		less*)	: ;;
		*)	$echon 'Press return to continue... ' >&2
			read foo;;
	esac
}

exist_test()
{
	type=$1 ; name=$2
	if [ ! "$type" "$name" ] && [ -z "$name" ]; then
            run_dialog --msgbox \
                "'$name' does not exist.\\n\\nThe programm will show you the error-log and then exit." 23 80
	    clear
	    <$log eval $PAGER
	    fix_pager_more
	    exit 1
	fi
}

choose_editor()
{
	run_dialog --inputbox \
		"Your editor for changing config-files currently\\nis set to $EDIT.\\n\\nPress RETURN to accept this default or enter\\nthe name of the editor of your choice.\\n\\n" \
		23 80 2>/tmp/menu$$ || return
	x=`cat /tmp/menu$$`
	test -z "$x" || EDIT=$x
}

choose_pager()
{
        run_dialog --inputbox \
                "Your pager to view the logfile currently\\nis set to $PAGER.\\n\\nPress RETURN to accept this default or enter\\nthe name of the pager of your choice.\\n\\n" \
                23 80 2>/tmp/menu$$ || return
        x=`cat /tmp/menu$$`
        test -z "$x" || PAGER=$x
}


setup_preferences()
{
    while true ; do
        run_dialog \
                --menu "\\n\\nSet up your editor and pager for this texconfig session.\\n\\n" \
                23 80 4 \
		RETURN 'back to main menu' \
                EDITOR 'set up editor for changing config-files' \
                PAGER 'set up pager to view the logfile' \
		"LOG"	'view logfile' \
                2>/tmp/menu$$ || return
        ans=`cat /tmp/menu$$`
        test -z "$ans" && return
        case "$ans" in
            EDITOR)       choose_editor ;;
            PAGER)      choose_pager ;;
	    LOG)	clear; <$log eval $PAGER; fix_pager_more ;;
            RETURN)     return ;;
        esac
    done
}

run_config_tex()
{
  case "$1" in
  tex*)
    echo "Running initex to create plain format..."
      (
        cd $formats
        rm -f $formats/tex.fmt $formats/plain.fmt $formats/tex.log
	require_binary tex
        TEXINPUTS=`kpsepath -n tex tex` initex tex.ini || return
        ln -s tex.fmt $formats/plain.fmt
        append_db $formats plain.fmt
        append_db $formats tex.fmt
      ) </dev/null
    echo "Done."; echo;;
  eplain*)
    echo "Running initex to create eplain format..."
      (
        cd $formats
        rm -f $formats/eplain.fmt $formats/eplain.log
	require_binary eplain
        TEXINPUTS=`kpsepath -n eplain tex` initex eplain.ini
        append_db $formats eplain.fmt
      ) </dev/null
    echo "Done."; echo;;
  latex209*)
    echo "Running initex to create latex209 format..."
      (
        cd $formats
        rm -f $formats/latex209.fmt $formats/latex209.log
	require_binary latex209
	TEXINPUTS=`kpsepath -n latex209 tex` initex latex209.ini
        append_db $formats latex209.fmt
      ) </dev/null
    echo "Done."; echo;;
  amstex*)
    echo "Running initex to create amstex format..."
      (
        cd $formats
        rm -f $formats/amstex.fmt $formats/amstex.log
	require_binary amstex
        TEXINPUTS=`kpsepath -n amstex tex` initex amstex.ini
        append_db $formats amstex.fmt
      ) </dev/null
    echo "Done."; echo;;
  *)
    echo "Running initex to create LaTeX format..."
      (
        cd $formats
        rm -f $formats/latex.fmt $formats/latex.log
	require_binary latex
        TEXINPUTS=`kpsepath -n latex tex` initex '\scrollmode\input latex.ltx'
        append_db $formats latex.fmt
      )
    echo "Done."; echo;;
  esac
}

config_tex()
{
	exist_test -d $formats
	exist_test -f $language

	clear
	$EDIT $language
	clear; run_config_tex tex.ini 2>&1 | tee -a $log
	clear; test -d $TEXMF/tex/latex && run_config_tex latex.ltx 2>&1 | tee -a $log
	clear; test -d $TEXMF/tex/amstex && run_config_tex amstex.ini 2>&1 | tee -a $log
	# clear; test -d $TEXMF/tex/eplain && run_config_tex eplain.ini 2>&1 | tee -a $log
	# clear; test -d $TEXMF/tex/latex209 && run_config_tex latex209.ini 2>&1 | tee -a $log
}

choose_mode()
{
	out=$1
	choose_mode_msg="$2"
	mode=$default_mode
	exist_test -f $modes
	if [ ! -z "$mode" ] ; then
		if yesno "\\n\\nUse mode $mode as default $3?\\n\\n" 23 80 ; then
			: # nothing
		else
			mode=""
		fi
	fi
	if [ -z "$mode" ] ; then
		#--title \"teTeX-Config: MetaFont mode\" \
	    eval run_dialog \
		--menu \"\$choose_mode_msg\" \
		23 80 14 `list_mf_modes $modes` \
		2>$out
	else
		echo $mode >$out
	fi
}

get_default_mode()
{
	choose_mode /tmp/ans$$ 'Choose a default mode for xdvi, dvips and metafont. As a rule\nof thumb, choose the most commonly mode used for printing at your site.'
	default_mode=`cat /tmp/ans$$`
	test -z "$default_mode" && return

	clear
	do_set_default_mode "$default_mode" 2>&1 | tee -a $log

}

do_set_default_mode()
{
	mode=$1
	res=`find_res $mode`
	dvips_conf=$dvips_conf_dir/config.ps

	run_setup_mf_mode $mode
	run_dvips_setup_mode $mode $res
	run_xdvi_setup_mode $mode $res
	config_replace $maketex_site '^: ..MT_DEF_MODE' ": \${MT_DEF_MODE=$mode}"
	config_replace $maketex_site '^: ..MT_DEF_BDPI' ": \${MT_DEF_BDPI=$res}"

	run_config_mf

}

run_config_mf()
{
	exist_test -d $bases
	exist_test -f $modes

	echo "Running inimf to create plain base ..."
	run_create_mf_base
	echo "Done."; echo
}

run_setup_mf_mode()
{
	mode="$1"
	ed $modes >/dev/null 2>&1 <<-eof
		/^localfont :=/
		c
		localfont := $mode;
		.
		w
		q
	eof
}

run_create_mf_base()
{
    (
	cd $bases
	rm -f mf.base plain.base mf.log
	inimf mf.ini </dev/null || return
	ln -s mf.base plain.base
	append_db $bases mf.base 2>/dev/null
	append_db $bases plain.base 2>/dev/null
    )
}

run_config_mp()
{
	exist_test -d $mems

	echo "Running inimp to create plain mem ..."
	run_create_mp_mem
	echo "Done."; echo
}

run_create_mp_mem()
{
    (
	cd $mems
	rm -f mp.mem plain.mem mp.log
	inimp mp.ini </dev/null || return
	ln -s mp.mem plain.mem
	append_db $mems plain.mem
	append_db $mems mp.mem
    )
}

config_dvips_paper()
{
		#--title \"teTeX-Config: dvips default paper\" \
	eval run_dialog \
		--menu \'\\n\\nChoose the default papersize definition for dvips.\\n\\n\' \
		23 80 8 `list_dvips_papers $dvips_conf` \
		2>/tmp/menu$$ || return
	paper=`cat /tmp/menu$$`
	test -z "$paper" && return ;
	setup_dvips_paper "$paper" 2>&1 | tee -a $log
}

dvips_choose_printcmd()
{
        run_dialog --inputbox \
                "\\n\\nEnter the command to print to the printer '$printer'.\\nIn general, you need a command like 'lpr' or 'lpr -Pfoo'.\\n\\nNOTE: If you just press return, printing will be disabled\\nand the output saved to a file by default.\\n\\n" \
                23 80 2>/tmp/menu$$ || return
        x=`cat /tmp/menu$$`
        if [ -z "$x" ] ; then
		echo save-to-file >&2
	else
		echo $x >&2
	fi

}

has_latex()
{
	test -d $TEXMF/tex/latex && return 0
	run_dialog --msgbox \
		"This funtion needs LaTeX to be installed." 23 80
	return 1
}

dvips_test_print()
{
	has_latex || return
	cd $tmpdir					
	clear
	latex testpage					2>&1 | tee -a $log
	case $printer in
	    default)	dvips testpage ;;
	    *)		dvips -P$printer testpage ;;
	esac						2>&1 | tee -a $log
	
}

yesno()
{
	run_dialog --yesno "$@"
}

dvips_setup_mode()
{
        choose_mode /tmp/ans$$ "Choose the metafont mode for printer '$printer'" "for printer $printer"
        mode=`cat /tmp/ans$$`
        test -z "$mode" && return
	run_dvips_setup_mode "$mode" 2>&1 | tee -a $log
}

run_dvips_setup_mode()
{
	mode="$1"
        res=${2-`find_res $mode`}
        config_replace $dvips_conf '^M' "M $mode"
        config_replace $dvips_conf '^D' "D $res"
}

dvips_setup_printcmd()
{
        dvips_choose_printcmd 2>/tmp/ans$$
        printcmd=`cat /tmp/ans$$`
        test -z "$printcmd" && return
	do_dvips_setup_printcmd "$printcmd" 2>&1 | tee -a $log
}

do_dvips_setup_printcmd()
{
	printcmd="$@"
	if test "$printcmd" = save-to-file; then
		config_replace $dvips_conf '^o' 'o'
	else
		config_replace $dvips_conf '^o' "o |$printcmd"
	fi
}

dvips_setup_offset()
{
        run_dialog --inputbox \
                "

Enter a dimension pair (A rightwards offset and a downwards
offset), e.g. 2mm,-0.5in (right 2mm and up .5in):

" \
                23 80 2>/tmp/menu$$ || return
        x=`cat /tmp/menu$$`
	test -z "$x" || run_dvips_setup_offset "$x" 2>&1 | tee -a $log
}

do_dvips_setup_offset()
{
	x="$1"
	if test -z "$x"; then
		echo "Error: no offset given to do_dvips_setup_offset. Skipped." >&2
		return
	fi
	run_dvips_setup_offset "$x"
}

run_dvips_setup_offset()
{
	x="$1"
	config_replace $dvips_conf '^O' "O $x"
}

dvips_config_local()
{
    exist_test -d $dvips_conf_dir

    while true ; do
        run_dialog \
                --menu "\\n\\nteTeX: set up printer '$printer' for dvips\\n\\n" \
                23 80 5 \
                RETURN 'Back to dvips main menu' \
                MODE 'Set up mf mode (resolution will be calculated as well)' \
                CMD 'Set up the command to print on this printer' \
                OFFSETS 'Set up offsets for printing' \
                TEST 'Print a testpage' \
                2>/tmp/menu$$ || return
        ans=`cat /tmp/menu$$`
        test -z "$ans" && return
        case "$ans" in
	    MODE)	dvips_setup_mode ;;
	    CMD)	dvips_setup_printcmd ;;
	    OFFSETS)	dvips_setup_offset ;;
	    TEST)	dvips_test_print ;;
	    RETURN)	return ;;
	esac
    done
}

dvips_config_global()
{
	config_dvips_paper
	printer=default
	dvips_config_local
}

dvips_get_printername()
{
	run_dialog --inputbox \
		"Printer name" \
		23 80 2>/tmp/menu$$ || return
	x=`cat /tmp/menu$$`
	test -z "$x" || echo $x >&2
}

config_dvips()
{
    while true ; do
	run_dialog \
		--menu '
dvips section: If you only have no more than one printer, you
only need to go through the GLOBAL menu. You can use dvips for non
PostScript printers, if you can setup your printing system to convert
PostScript to a format that your printer can handle. Maybe, you can
use GhostScript to do the conversation (if you printer is supported).

A definition for a printer PRINTER directly corresponds to a
configuration file config.PRINTER in the $TEXMF/dvips directory.

' \
		23 80 6 \
		RETURN 'back to main menu' \
		GLOBAL 'global settings' \
		ADD 'add a printer configuration (to be used via -P flag)' \
		DEL 'remove a printer definition' \
		CHANGE 'change an existing printer definition' \
		"LOG"	'view logfile' \
		2>/tmp/menu$$ || return
	ans=`cat /tmp/menu$$`
	test -z "$ans" && return
	case "$ans" in
		ADD|DEL|CHANGE)
			dvips_get_printername 2>/tmp/ans$$
			printer=`cat /tmp/ans$$`
			test -z "$printer" && continue
			dvips_conf=$dvips_conf_dir/config.$printer
			;;
	esac
	case "$ans" in
	    GLOBAL) 	dvips_conf=$dvips_conf_dir/config.ps
			dvips_config_global ;;
	    ADD)	if [ -f $dvips_conf_dir/config.$printer ] ; then
				run_dialog --msgbox \
					"Configuration for $printer already exists." 23 80
				continue
			fi
			touch $dvips_conf_dir/config.$printer
			append_db $dvips_conf_dir config.$printer
			dvips_config_local ;;
	    DEL)	rm -f $dvips_conf_dir/config.$printer $dvips_conf_dir/config.$printer.orig ;;
	    CHANGE)	if [ ! -f $dvips_conf_dir/config.$printer ] ; then
				run_dialog --msgbox \
					"Configuration for $printer not found." 23 80
				continue
			fi
			dvips_config_local ;;
	    LOG)	clear; <$log eval $PAGER; fix_pager_more;;
	    RETURN)	return ;;
	esac
    done
}

do_dvips_setup_paper()
{
	paper="$1"
	list=`list_dvips_papers $dvips_conf | awk '{print $1}'`
	if test_in_list "$paper" $list; then
		setup_dvips_paper "$paper"
	fi
}

do_xdvi_setup_paper()
{
	paper="$1"
	list=`list_xdvi_papers | awk '{print $1}'`
	if test_in_list "$paper" $list; then
		run_xdvi_setup_paper "$paper"
	fi
}

run_xdvi_setup_paper()
{
	paper="$1"
	config_replace $xdvi_conf 'paper:' "XDvi*paper: $paper"
}

xdvi_setup_paper()
{
                #--title \"TeX-Config: xdvi default paper\" \
        eval run_dialog \
                --menu \"Choose the default papersize definition for xdvi.\" \
                23 80 15 `list_xdvi_papers` \
                2>/tmp/menu$$ || return
        paper=`cat /tmp/menu$$`
        test -z "$paper" && return
        run_xdvi_setup_paper "$paper" 2>&1 | tee -a $log
}

do_dvips_setup_mode()
{
	mode="$1"
	if test -z "$mode"; then
		echo "Error: no mode given to do_dvips_setup_mode. Skipped.">&2
		return 1
	fi
	list=`list_mf_modes $modes | awk '{print $1}'`
	if test_in_list "$mode" $list; then
		run_dvips_setup_mode "$mode"
	fi
}

cmd_mode_maketex()
{
	case "$1" in
		vardir)
			if test -z "$2"; then
				echo "Usage: texconfig font vardir DIR" >&2
				return 1
			else
				do_setup_mt_vardir "$2"
			fi
			;;
                ro)
			fonts_ro;;
                rw)	fonts_rw;;
		options)
			shift
			if test $# = 0; then
				echo "Usage: texconfig options OPTIONS ..." >&2
				return 1
			fi
			if test "$*" = -; then
				set_mt_options
			else
				set_mt_options "$@"
			fi
			;;
		*)
			echo "Usage: texconfig font vardir DIR" >&2
			echo "       texconfig font ro" >&2
			echo "       texconfig font rw" >&2
			echo "       texconfig font options OPTIONS ..." >&2
			echo >&2
			echo "       valid OPTIONS: $all_mt_features -" >&2
			echo "       the special OPTION '-' can be used to disable all OPTIONS" >&2
			return 1
			;;
	esac
}

cmd_mode_set_default_mode()
{
	mode="$1"
	case "$mode" in
		"") echo "Usage: texconfig mode MODE" >&2
		    echo "       Valid modes:" >&2
		    echo >&2
		    list_mf_modes $modes | awk '{print $1}' | $FMT >&2
		    echo >&2
		    echo "See file $modes" >&2
		    echo "for more information about these modes." >&2
		    return 1;;
	esac
	list=`list_mf_modes $modes | awk '{print $1}'`
	if test_in_list "$mode" $list; then
		do_set_default_mode "$mode"
	fi
}

run_xdvi_setup_mode()
{
	mode="$1"
        res=${2-`find_res $mode 2>>$log`}
        shrink=`expr $res / $xdvi_shrink_scale`
        config_replace $xdvi_conf 'mfmode:' "XDvi*mfmode: $mode"                    2>&1 | tee -a $log
        config_replace $xdvi_conf 'pixelsPerInch:' "XDvi*pixelsPerInch: $res"       2>&1 | tee -a $log
        config_replace $xdvi_conf 'shrinkFactor:' "XDvi*shrinkFactor: $shrink"      2>&1 | tee -a $log
}

xdvi_make_test()
{
	if [ -z "$DISPLAY" ] ; then
		:
	fi
	cd $tmpdir 2>&1 | tee -a $log
	clear
	tex '\input story\end' 2>&1 | tee -a $log
	clear
	xdvi story 2>&1 | tee -a $log
}


config_xdvi()
{
    test -d $xdvi_app || MakeTeXmkdir $xdvi_app
    test -f $xdvi_conf || touch $xdvi_conf
    exist_test -f $xdvi_conf

    while true ; do
        run_dialog \
                --menu '\n\nSet up xdvi via application ressources.\n\nNote 1: set the mode from the main menu.\nNote 2: a symbolic Link for the app-default file is no longer necessary.\n\n' \
                23 80 4 \
                RETURN 'back to main menu' \
                PAPER 'default papertype' \
                TEST 'view a testfile' \
		"LOG"	'view logfile' \
                2>/tmp/menu$$ || return
        ans=`cat /tmp/menu$$`
        test -z "$ans" && return
        case "$ans" in
            PAPER)        xdvi_setup_paper ;;
            TEST)       xdvi_make_test ;;
	    LOG)	clear; <$log eval $PAGER; fix_pager_more;;
            RETURN)     return ;;
        esac
    done
}

keep_mode()
{
  yesno "\\n\\nUse mode $mode\\n\\n" 23 80
}

config_replace()
{
	config=$1
	pattern=$2
	replacement=$3

	require_binary ed

	test -f "$config" > /dev/null 2>&1
	if [ $? != 0 ]; then
		echo "config_replace: file '$config' not found." >&2
		return
	fi

	test -w "$config" > /dev/null 2>&1
	if [ $? != 0 ]; then
		echo "config_replace: cannot write to file '$config'." >&2
		return
	fi

	egrep -e "$pattern" "$config" > /dev/null 2>&1 
	if [ $? != 0 ]; then
		echo "$replacement" >> "$config"
	else
		ed $config >/dev/null 2>&1 <<-eof
			/$pattern/c
			$replacement
			.
			w
			q
		eof
		error=$?
		if [ $error != 0 ]; then
			echo "config_replace: ed returned error code '$error'." >&2
			return
		fi
	fi
}

find_res()
{
  mf '\mode='"$1"';  \input mode2dpi' </dev/null | awk '$1 == "DPI" {print $3}'
}

mode_name()
{
  mf '\mode='"$1"';  \input modename' | sed -n '/^MODENAME/!d; s/.*= //; s/_.*//; p'
}

list_dvips_papers()
{
  grep '@ ' $1 | sed "s/..//;s/ / '/;s/\$/' /"
}

list_mf_modes()
{
  grep mode_def $1 |
  sed -e 's/mode_def //' \
      -e 's/ .*%[ \[]*/ '\'/ \
      -e s/\$/\'\ / |
  egrep -v "^(help|%)" | sort
}

list_xdvi_papers()
{
	cat <<-'eof'
		us           "8.5x11"
		usr          "11x8.5"
		legal        "8.5x14"
		foolscap     "13.5x17.0"
		a1           "59.4x84.0cm"
		a2           "42.0x59.4cm"
		a3           "29.7x42.0cm"
		a4           "21.0x29.7cm"
		a5           "14.85x21.0cm"
		a6           "10.5x14.85cm"
		a7           "7.42x10.5cm"
		a1r          "84.0x59.4cm"
		a2r          "59.4x42.0cm"
		a3r          "42.0x29.7cm"
		a4r          "29.7x21.0cm"
		a5r          "21.0x14.85cm"
		a6r          "14.85x10.5cm"
		a7r          "10.5x7.42cm"
		b1           "70.6x100.0cm"
		b2           "50.0x70.6cm"
		b3           "35.3x50.0cm"
		b4           "25.0x35.3cm"
		b5           "17.6x25.0cm"
		b6           "13.5x17.6cm"
		b7           "8.8x13.5cm"
		b1r          "100.0x70.6cm"
		b2r          "70.6x50.0cm"
		b3r          "50.0x35.3cm"
		b4r          "35.3x25.0cm"
		b5r          "25.0x17.6cm"
		b6r          "17.6x13.5cm"
		b7r          "13.5x8.8cm"
		c1           "64.8x91.6cm"
		c2           "45.8x64.8cm"
		c3           "32.4x45.8cm"
		c4           "22.9x32.4cm"
		c5           "16.2x22.9cm"
		c6           "11.46x16.2cm"
		c7           "8.1x11.46cm"
		c1r          "91.6x64.8cm"
		c2r          "64.8x45.8cm"
		c3r          "45.8x32.4cm"
		c4r          "32.4x22.9cm"
		c5r          "22.9x16.2cm"
		c6r          "16.2x11.46cm"
		c7r          "11.46x8.1cm"
	eof
}

setup_dvips_paper()
{
	config=$dvips_conf
	paper=$1

	test -f "$config" > /dev/null 2>&1
	if [ $? != 0 ]; then
		echo "setup_dvips_paper: global dvips config file '$config' not found." >&2
		return
	fi

	test -w "$config" > /dev/null 2>&1
	if [ $? != 0 ]; then
		echo "setup_dvips_paper: cannot write to file '$config'." >&2
		return
	fi

	grep "@ $paper" "$config" > /dev/null 2>&1 
	if [ $? != 0 ]; then
		echo "setup_dvips_paper: paper '$paper' not found in file '$config'." >&2
		return
	fi

	ed $config > /dev/null 2>&1 <<-eof
		/@ /ka
		\$a
		@ 
		.
		/@ $paper/;/@ /-1m'a-1
		\$d
		w
		q
	eof

	error=$?

	if [ $error != 0 ]; then
		echo "setup_dvips_paper: ed returned error code '$error'." >&2
	fi
}

cmd_mode()
{
	case "$1" in
		faq)	clear; test -f $FAQ && <$FAQ eval $PAGER; fix_pager_more;;
		conf)	do_print_setup;;
		rehash)	eval $texhash_done || { texhash; locate_files; };;
		hyphen)	edit_hyphen;;
		mode)	shift; cmd_mode_set_default_mode ${1+"$@"} ;;
		xdvi)	shift; cmd_mode_xdvi ${1+"$@"};;
		dvips)	shift; cmd_mode_dvips ${1+"$@"};;
		font) shift; cmd_mode_maketex ${1+"$@"};;
		confall) do_print_all_setup;;
		init)	init_all;;
		*)	echo "Usage: texconfig conf" >&2
			echo "       texconfig confall" >&2
			echo "       texconfig rehash" >&2
			echo "       texconfig hyphen" >&2
			echo "       texconfig mode    [options]" >&2
			echo "       texconfig xdvi    [options] ..." >&2
			echo "       texconfig dvips   [options] ..." >&2
			echo "       texconfig font    [options] ..." >&2
			echo "       texconfig faq" >&2
			echo "       texconfig init" >&2
			echo >&2
			echo "Get help with:" >&2
			echo "       texconfig help" >&2
			echo "       texconfig mode" >&2
			echo "       texconfig xdvi" >&2
			echo "       texconfig dvips" >&2
			echo "       texconfig font" >&2
			exit 1;;
	esac
	exit
}

cmd_mode_dvips()
{
	printer=""
	dvips_conf="$dvips_conf_dir/config.ps"
	case "$1" in
		-P)	printer=$2; shift; shift;;
		-P*)	printer=`echo $2 | sed 's/..//'`; shift;;
	esac
	test -z "$printer" || dvips_conf="$dvips_conf_dir/config.$printer"
	case "$1" in
		add)	if test -z "$2"; then
				echo "Usage: texconfig dvips add PRINTER" >&2
			else
				touch "$dvips_conf_dir/config.$2"
				append_db "$dvips_conf_dir" "config.$2"
			fi;;
		del)	if test -z "$2"; then
				echo "Usage: texconfig dvips del PRINTER" >&2
			else
				rm -f "$dvips_conf_dir/config.$2"
			fi;;
		mode)
			if test -z "$2"; then
			  echo "Usage: texconfig dvips [-P PRINTER] mode MODE" >&2
			  echo "       Valid modes:" >&2                                 
			  echo >&2
			  list_mf_modes $modes | awk '{print $1}' | $FMT >&2       
			  echo >&2
			  echo "See file $modes" >&2                 
			  echo "for more information about these modes." >&2
			else
			  do_dvips_setup_mode "$2"
			fi;;

		printcmd)
			case "$2" in
				"")	echo "Usage: dvips [-P PRINTER] printcmd CMD" >&2
					echo "       For printing, the output will be piped to the CMD" >&2
					echo "       Typically, CMD is set to 'lpr' or 'lpr -P SOME-NAME'." >&2
					echo >&2
					echo "       Use - as CMD to disable direct drinting." >&2;;
				-)	do_dvips_setup_printcmd save-to-file;;
				*)	shift; do_dvips_setup_printcmd ${1+"$@"};;
			esac;;
		offset)	if test -z "$2"; then
				echo "Usage: dvips [-P PRINTER] offset OFFSET" >&2
				echo "       For OFFSET choose a dimension pair, such as '0.4in,-2in'." >&2
			else
			  do_dvips_setup_offset "$2"
			fi;;
		paper)
			if test -z "$2"; then
			  echo "Usage: texconfig dvips paper PAPER" >&2
			  echo "       Valid papertypes:" >&2
			  echo >&2
			  list_dvips_papers $dvips_conf | awk '{print $1}' | $FMT >&2
			else
			  dvips_conf="$dvips_conf_dir/config.ps"
			  do_dvips_setup_paper "$2"
			fi;;
		*)	cat<<-'eof'
			Usage: texconfig dvips add PRINTER
			       texconfig dvips del PRINTER
			       texconfig dvips paper PAPER
			       texconfig dvips [-P PRINTER] mode MODE
			       texconfig dvips [-P PRINTER] offset OFFSET
			       texconfig dvips [-P PRINTER] printcmd CMD
			eof
	esac
}

cmd_mode_xdvi()
{
	case $# in
	    1)	do_xdvi_setup_paper "$1";;
	    *)	{ echo 'Usage: texconfig xdvi PAPER'
		  echo "       recognised papersizes are:"; echo
		  echo "`list_xdvi_papers | awk '{print $1}' | $FMT`"; } >&2
	esac
}

test_in_list()
{
	obj="$1"; shift
	test -z "$obj" && return 1
	for i
	do
		test "$obj" = "$i" && return 0
	done
	echo "Error: value '$obj' not in list '$@'." >&2
	return 1
}
	

init_tex_formats()
{
	run_config_tex tex.ini
	test -d $TEXMF/tex/latex && run_config_tex latex.ltx
	test -d $TEXMF/tex/amstex && run_config_tex amstex.ini
	# test -d $TEXMF/tex/eplain && run_config_tex eplain.ini
	# test -d $TEXMF/tex/latex209 && run_config_tex latex209.ini
}

init_all()
{
	init_tex_formats
	run_config_mf
	check_for_binary inimp >/dev/null && run_config_mp
}


edit_hyphen()
{
	$EDIT $language
	init_tex_formats
}

check_for_binary()
{
  testbin=$1
  set x `echo "$PATH" | sed 's/^:/.:/; s/:$/:./; s/::/:.:/g; s/:/ /g'`; shift
  for i
  do
    if [ -x "$i/$testbin" ]; then
      echo "$i/$testbin"
      return 0
    fi
  done
  return 1
}

require_binary()
{
	for this_binary
	do
		check_for_binary $this_binary >/dev/null
		if [ $? != 0 ]; then
			echo "texconfig: binary $this_binary not found. Please set up your PATH correctly" >&2
			exit 1
		fi
	done
}

echo_locate_binary()
{
	for locate_this_bin
	do
		location=`check_for_binary $locate_this_bin`
		if [ $? = 0 ]; then
			echo "$locate_this_bin:	$location"
		else
			echo "$locate_this_bin not found."
		fi
	done
}

echo_show_variable()
{
	for this_var
	do
		var=$this_var
		eval val=\"\${$var+=}\${$var- is unset}\"
		echo "$var$val"
	done | grep -v 'is unset$'
}

echo_file_location()
{
	if [ -f "$2" ]; then
		echo "$1: $2"
	else
		echo "$1 not found."
	fi
}

do_print_setup()
{
	echo '==================== binaries found by searching $PATH ==================='
	echo_locate_binary tex initex virtex mf inimf virmf dialog dvips xdvi kpsetool kpsewhich MakeTeXPK MakeTeXTFM
	if check_for_binary inimp >/dev/null; then
	  echo_locate_binary mp inimp virmp
	fi
	echo
	echo '=========================== Kpathsea variables ==========================='
	echo_show_variable TETEXDIR TEXMF TEXMFS TEXMFL
	echo
	echo '=============== environment variables (ok if no output here) ============='
	echo_show_variable $envvars WEB2CDIR FONTDIR FONTNAME pkdir
}

do_print_all_setup()
{
  do_print_setup
}

print_setup()
{
	do_print_setup | eval $PAGER; fix_pager_more
}

all_mt_features='stickydir dosnames stripsupplier striptypeface varfonts'
get_mt_options()
{
	MT_FEATURES=`grep '^:.*MT_FEATURES' $maketex_site | sed 's/.*=//;s/}.*//'`
	for feature in $all_mt_features; do
		case "$MT_FEATURES" in
		  *${feature}*)
			eval $feature=on;;
		  *)
			eval $feature=off;;
		esac
	done
}

set_mt_options()
{
	args="$*"
	exist_test -f $texmfcnf

	for feature in $all_mt_features; do
		eval $feature=off
	done

        set x $args; shift
	reslist=
	for i
	do
		test_in_list "$i" $all_mt_features || continue
		reslist="$reslist $i"
	done

	set x $reslist; shift

	MT_FEATURES=$1; test $# -ge 1 && shift
	for i
	do
		MT_FEATURES="$MT_FEATURES:$i"
	done
	config_replace $maketex_site '^: ..MT_FEATURES' ": \${MT_FEATURES=$MT_FEATURES}"
}

setup_mt_options()
{
	get_mt_options
	run_dialog --checklist '\nSelect options for MakeTeX scripts. Use the spacebar for enable/disable.\n\n' \
		23 80 6 \
		dosnames "dpiNNN/NAME.pk instead of NAME.NNNpk" $dosnames \
		stripsupplier "leave out SUPPLIER (e.g. ams)" $stripsupplier \
		striptypeface "leave out TYPEFACE (e.g. euler)" $striptypeface \
		varfonts "use \$VARFONTS instead of \$TEXMF/fonts" $varfonts \
		stickydir "set stick bit on new directories (recommended)" \
		   $stickydir 2>/tmp/menu$$ || return
		eval set_mt_options `cat /tmp/menu$$`
}

setup_query_mkdir()
{
	dir=$1
	if yesno "\\n\\nCreate directory $1?\\n\\n" 23 80; then
		{ mkdir $dir && chmod 1777 $dir; }  2>&1 | tee -a $log
	else
		return 1
	fi
}

setup_mt_vardir()
{
	VARFONTS=`kpsetool -v '$VARFONTS'`
	run_dialog --inputbox \
	"Your \$VARFONTS directory currently\\nis set to $VARFONTS.\\n\\nPress RETURN to accept this default or enter\\nthe name of an other directory.\\n\\n" \
	23 80 2>/tmp/menu$$ || return
	x=`cat /tmp/menu$$`
	test -z "$x" && return
	test -d "$x" || setup_query_mkdir "$x" || return
	do_setup_mt_vardir "$x" 2>&1 | tee -a $log
}

do_setup_mt_vardir()
{
	vardir=$1
	test -d "$vardir" ||
		{ mkdir "$vardir" && chmod 755 "$vardir"; } || return 1
	test -d "$vardir/pk" ||
		{ mkdir "$vardir/pk" && chmod 1777 "$vardir/pk"; } || return 1
	test -d "$vardir/tfm" ||
		{ mkdir "$vardir/tfm" && chmod 1777 "$vardir/tfm"; } || return 1
	test -d "$vardir/source" ||
		{ mkdir "$vardir/source" && chmod 1777 "$vardir/source"; } || return 1

	config_replace $texmfcnf '^VARFONTS' "VARFONTS  = $vardir"
}


setup_mt()
{
    while true; do
	ex=eufm10
	set x `MakeTeXnames $ex`
	pk=$2 tfm=$3
	run_dialog \
		--menu "\nSet up target directories for font creation.\n\nExample: current settings for font $ex with default mode\\n         are (tfm resp. pk):\\n\\n $tfm\\n $pk\n\n" \
		23 80 7 \
		RETURN 'back to main menu' \
		FONTRO 'remove global write permissions from standard fonts tree' \
		FONTRW 'add global write permissions to standard fonts tree' \
		OPTIONS 'set up options for MakeTeX scripts' \
		VARDIR 'directory for new fonts (if varfonts option active)' \
		LOG   'view logfile' \
		2>/tmp/menu$$ || return
	ans=`cat /tmp/menu$$`
	test -z "$ans" && return
	case "$ans" in
		VARDIR)      setup_mt_vardir ;;
		OPTIONS)      setup_mt_options ;;
		FONTRO)
			get_mt_options
			: ${VARFONTS=`kpsetool -v '$VARFONTS'`}
			if test "$varfonts" != on; then
				run_dialog --msgbox \
					'\n\n\nPlease enable the varfonts feature (OPTIONS menue) first.' \
					23 80
				continue
			fi
			if test ! -d "$VARFONTS"; then
				run_dialog --msgbox \
					'\n\n\nPlease make sure that the VARFONTS directory exists and try again.' \
					23 80
				continue
			fi
			if test -z "$VARFONTS"; then
				run_dialog --msgbox \
					'\n\n\nPlease set up a non-empty VARFONTS directory (VARDIR menue) first.' \
					23 80
				continue
			fi
			fonts_ro;;
		FONTRW) fonts_rw;;
		LOG)      clear; <$log eval $PAGER; fix_pager_more;;
		RETURN)   return ;;
	esac
    done
}

locate_files()
{
	language=`kpsetool -w tex language.dat`
	modes=`kpsetool -w mf modes.mf`
	texmfcnf=`kpsetool -w cnf texmf.cnf`
}

# This function rebuilds the html index to the local documentation
# By Ottavio G. Rizzo
rebuild_doc()
{
	run_dialog --inputbox \
		"I assume the local TeX documentation is in\\n$doc\\n\\nPress RETURN if this is true or enter the name of the directory.\\n\\n" \
		23 80 2>/tmp/menu$$ || return
	x=`cat /tmp/menu$$`
	test -z "$x" || doc=$x
	if  test -d $doc 
	# Did I get a meaningful directory?
	then
	   (
		cd $doc 
		helpindex=`\ls -l helpindex.html 2>/dev/null | awk '{print $NF}'`
		case $helpindex in
		  "") helpindex=$doc/helpindex.html;;
		  /*) ;;
		  *)  helpindex=$doc/$helpindex;;
		esac
		mv -f $helpindex $helpindex.BAK
		# Warn the user it's going to take a while
		run_dialog --infobox \
			"This could take some time, please wait." \
			3 80
		./mkhtml > $helpindex  2>> $log
	   )
	else
		clear
		echo -e '\n\n\n\n'
		echo "$doc doesn't exist!" | tee -a $log
		echo "Press a key to continue"
		read foo
	fi
}

#------------------ begin: initialisation -----------------------------------
check_environ

require_binary kpsetool pwd
: ${TETEXDIR=`kpsetool -v '$TETEXDIR'`}
: ${TEXMF=`kpsetool -v '$TEXMF'`}
: ${MAKETEXDIR=$TEXMF/maketex}
export TEXMF MAKETEXDIR

: ${DIALOG_TERMINFO=$TEXMF/texconfig}
: ${DIALOG_TERM=generic}
: ${KPSE_DOT=`pwd`}; export KPSE_DOT

texhash_done=false
if [ ! -r $TEXMF/ls-R ]; then
	require_binary texhash
	texhash
	texhash_done=true
fi
locate_files

dvips=$TEXMF/dvips
formats=$TEXMF/web2c
bases=$TEXMF/web2c
mems=$TEXMF/web2c
xdvi_app=$TEXMF/xdvi
xdvi_conf=$xdvi_app/XDvi
dvips_conf_dir=$TEXMF/dvips/config
maketex_site=$MAKETEXDIR/maketex.site
doc=$TEXMF/doc
FAQ=$doc/tetex/teTeX-FAQ

exist_test -d $tmpdir

EDIT=${VISUAL-${EDITOR-$std_editor}}
PAGER=${PAGER-$std_pager}

check_for_binary dialog >/dev/null
dialogok=$?
set x $SAVE_ARGS
shift
if [ $dialogok != 0 ] && [ $# = 0 ]; then
        set help
fi

#------------------ end: initialisation -----------------------------------

if test $# -ge 1; then
	test -d $tmpdir || mkdir $tmpdir
	cd $tmpdir
	trap 'cd / ; rm -rf $tmpdir /tmp/menu$$ /tmp/ans$$; trap '' 0; exit 0' 0 1 2 6 13 15
	cmd_mode ${1+"$@"}
fi

{ test -f $bases/mf.base  && test -f $bases/plain.base; } ||
	run_config_mf

{ test -f $formats/tex.fmt  && test -f $formats/plain.fmt; } ||
	run_config_tex tex.ini

test -f $formats/latex.fmt ||
	{ test -d $TEXMF/tex/latex && run_config_tex latex.ltx; }

test -f $formats/amstex.fmt ||
	{ test -d $TEXMF/tex/amstex && run_config_tex amstex.ini; }

# test -f $formats/eplain.fmt ||
# 	{ test -d $TEXMF/tex/eplain && run_config_tex eplain.ini; }

# test -f $formats/latex209.fmt ||
# 	{ test -d $TEXMF/tex/latex209 && run_config_tex latex209.ini; }

check_terminal
cat <<'eof'

The interactive texconfig utility will be started now. Make sure, your
screen has at least 24 rows and 80 columns. If texconfig crashes now,
you can still set up your teTeX system using the batch mode of texconfig.
Try 'texconfig help' to get a list of options.

eof
$echon "Starting dialog utility... "

# The steps below will clear the screen. Make sure, all error messages
# can be read. The sleep may be annoying, but I think, it is useful if
# something goes wrong.
sleep 4

trap 'cd /; rm -rf $tmpdir /tmp/menu$$ /tmp/ans$$; trap 0; exit 0' 0 1 2 6 13 15
test -d $tmpdir || mkdir $tmpdir
cd $tmpdir
echo "TeX-Config. Start on `date`" >$log

while true ; do
		#--title "TeX-Config main menu" \
	run_dialog \
		--menu "
Hint: all output of external commands (e.g. initex) is logged into
a file. You can look at this file using "LOG". If cursor keys make
trouble, you may have more luck with +/- and TAB.

" 23 80 12 \
		"EXIT"	'exit' \
		"PREF"	'personal preferences' \
		"CONF"	'show configuration' \
		"REHASH"	'rebuild ls-R database' \
		"HYPHEN"	'hyphenation table (tex/latex)' \
		"MODE"	'default mode (xdvi/dvips/mf)' \
		"XDVI"	'xdvi configuration' \
		"DVIPS"	'dvips configuration' \
		"FONT"	'directories for font creation' \
		"DOC"	'rebuild html documentation' \
                "FAQ"   'frequently asked questions + answers' \
		"LOG"	'view logfile' \
		2>/tmp/menu$$

	
	case "`cat /tmp/menu$$`" in
	FAQ)	clear; test -f $FAQ && <$FAQ eval $PAGER; fix_pager_more;;
	CONF)	clear; print_setup;;
	PREF)	setup_preferences ;;
	REHASH)	clear; texhash; locate_files ;;
	HYPHEN)	config_tex;;
	MODE)	get_default_mode;;
	XDVI)	config_xdvi ;;
	DVIPS)	config_dvips ;;
	FONT)	setup_mt;;
	DOC)	rebuild_doc;;
	LOG)	clear; <$log eval $PAGER; fix_pager_more;;
	*)	reset 2>/dev/null; stty sane 2>/dev/null; clear; exit 0;;
	esac
done
