#!/usr/local/bin/wish8.6

# Name:  xtexsh
#
# Author: Gerald Teschl
#
# Version: 1.4-2
#

wm title . "xTeX Shell"

#
# Set some default values
#

set userconf "~/.xtexshrc"
set allconf "/usr/local/etc/xtexshrc"

set programs {tex editor dviviewer psviewer pdfviewer spell makeindex bibtex xterm print dvips ps2pdf psnup}
set auxfiles {aux bbl blg dvi glo idx ilg ind log lof lot out ps pdf toc}
set printopts {abspagenumbers printtofile twoup}
# Helper apps
set tex "tex"
set editor "emacs"
set dviviewer "xdvi"
set psviewer "gv"
set pdfviewer "gv"
set spell "ispell -t"
set makeindex "makeindex"
set bibtex "bibtex"
set xterm "xterm"
set print "lpr"
set dvips "dvips"
set ps2pdf "ps2pdf"
# if you have psnup
set psnup "psnup -q -2"
# if you have pstops
#set psnup "pstops -q \"2:0L@.7(21cm,0)+1L@.7(21cm,14.85cm)\""
# autotex
set watchfile "n"
set watchdelay "20"
# stuff
set geometry ""
set interminal "y"
set defaultview "dvi"
set thisview $defaultview
# Are the page numbers specified for dvips absolute (y=yes, n=no)?
set abspagenumbers n
# Should it be printed twoup?
set twoup n
# Should a ps file be written instead (y=yes, n=no)?
set printtofile n

# At startup open: f(iledialog) l(ast documenat)
set startup l
set n_recent 5
set defaultdir ""
set searchpath "."

# Which aux files shall be marked for removal (y=yes, n=no)?
set bak y
set aux y
set bbl y
set blg y
set dvi n
set idx y
set ilg y
set ind y
set glo y
set log y
set lof y
set lot y
set out y
set ps y
set pdf y
set toc y
set rminclf y

# Read environment variables
foreach i $programs {
          set ui [string toupper $i]
	  if [info exists env($ui)] {set $i $env($ui)}
	  }

#
# End of default settings
#

set help_msg "
The present program is a simple TeX interface for the X Window
System based on \"wish\", respectively Tcl/Tk. It allows you to
process a given TeX file by choosing operations from a menu
or by pressing buttons, rather than typing the corresponding
commands.

I assume that tex, latex, pdftex, pdflatex, xdvi, dvips, makeindex, bibtex,
etc. are installed on your system and that you are familiar with TeX.

(1) STARTING xTeX Shell

It can be invoked from the command line using

            xtexsh \[wish options\]\[file\[.tex\]\]

Here \"wish options\" refers to any option understood by \"wish\"
(e.g., -geometry or -display, see \"man wish\" for more info).
You can also use \"file\" or \"file.\" instead of \"file.tex\"
and specify a search path in the preferences.
If no file is given, depending on the preferences set, a file
dialog appears, your last file will be opened, or nothing happens.
In addition, xtexsh -r\[n\] will open your n-th recent file (n=0
being the most recent).

If a directory is given instead of a file (or if a default directory
is set), the file dialog begins in that directory.

(2) USING xTeX Shell

Once you have chosen a file, its name will be displayed inside
the window. All operations are performed with respect to this
file (lets call it file.tex).
The file will be typeset using tex unless it contains the strings
\"\\documentclass\" or \"\\documentstyle\" in which case latex will
be used. In addition, the command for typesetting can be changed
using \"File->TeX command->Choose custom\" from the menu.

Here is a short description of the possible operations:

File->Open: Pops up a file dialog in order to change the current
	base file.
File->Open recent: Lets you open an recent file.
File->Edit: Opens file.tex with your favorite editor.
File->Ispell: Opens file.tex with ispell (or any other spell
	checker).
File->Print: Prints the typeset version of file.tex. You will
	be presented a dialog which asks for the first, last
	page to print. Absolute page numbers correspond to the
	page number when counting sheets, rather then to the
	numbers tex puts on each page. You can also print the
	document \"2up\" (provided you have \"psnup\" or
	\"pstops\" (which are part of the psutils package)
	installed.
File->Remove aux files: This pops up a window which allows you to
	select and remove auxiliary files (produced by TeX).
File->View aux file: Select an aux file and open it with your
	favorite editor.
File->Execute command: Lets you execute a command.
File->Open Shell: Opens a terminal window.
File->Preferences: Set your personal preferences.
File->Quit: Quits the program.

Typeset->TeX: Compiles file.tex using the chosen TeX command.
Typeset->TeX command->tex: Sets the current TeX command to \"tex\".
Typeset->TeX command->latex: Sets the current TeX command to
	\"latex\"
Typeset->TeX command->pdftex: Sets the current TeX command to
	\"pdftex\".
Typeset->TeX command->pdflatex: Sets the current TeX command to
	\"pdflatex\"
Typeset->TeX command->Choose custom: Chose a custom TeX command
	in the preferences (e.g., provide some options for tex).
Typeset->AutoTeX: Automatically invoke TeX whenever the
	main file changes on disk.
Typeset->Bibtex: Runs bibtex with the present file.
Typeset->Makeindex: Runs makeindex with the present file.
Typeset->Create PS: Create postscript file from dvi file.
Typeset->Create PDF: Create pdf file from ps file (requires a
         revent version of ghostscript).
Typeset->View: Allows you to view the present file.
Typeset->Default View: Set the default viewing method.
Typeset->Default View->dvi: View dvi file.
Typeset->Default View->ps: View ps file.
Typeset->Default View->pdf: View pdf file.
Typeset->View DVI: Allows you to view the present dvi file.
Typeset->View PS: Allows you to view the present ps file.
Typeset->View PDF: Allows you to view the present pdf file.


Help->About: Some general info about xTeX Shell.
Help->Help: Displays the present help.
Help->License: License information.

The button bar provides shortcuts for the main operations
for the corresponding menu items.

(3) CUSTOMIZING xTeX Shell

xTeX Shell can be easily customized using the menu item
\"File->Preferences\".

The programs invoked by xTeX Shell can be changed by choosing
\"File->Preferences\" from the menu or by setting environment
variables according to the following table:

Program		Environment variable	Original setting
TeX			\$TEX			tex / latex / pdftex /pdflatex
Editor		\$EDITOR      	xedit
DVI viewer	\$DVIVIEWER		xdvi
PS viewer	\$PSVIEWER		gv
PS viewer	\$PDFVIEWER		gv
Spelling	\$SPELL			ispell -t
Makeindex	\$MAKEINDEX		makeindex
Bibtex		\$BIBTEX     	bibtex
Xterm		\$XTERM			xterm
Print		\$PRINT			lpr
Dvips		\$DVIPS			dvips
Ps2pdf		\$PS2PDF 		ps2pdf
Ps-n-up		\$PSNUP			psnup -q -2

Note that you can also specify options in addition to the
command (e.g., \"xdvi -s 12\"). Printing will be done by
using dvips (and psnup) and pipeing the resulting output
to the print command. An alternative filter for producing
the 2up version can be specified.

In addition, you can change the startup behavior / geometry
of xTeX Shell, the auxiliary files which are selected for
removal, and the printing options.

All preferences are stored in \"\~/.xtexshrc\".
System wide preferences can be set in \"/usr/local/etc/xtexshrc\".
All recent files are stored in \"\~/.xtexsh_recent\".


If this still is not enough for you, note that the script is a
plain text file. So you can easily edit it to meet your own
needs! (Always keep a copy of the original version, in case
something goes wrong...)

(4) ICON

An icon \"xtexsh.xpm\" is included. If you used the
rpm version it should be in the documentation
directory (usually /usr/share/doc/xtexsh-1.4).

(5) UPDATES

The recent version can be found at

<http://www.mat.univie.ac.at/~gerald/ftp/xtexsh/>


Have fun,
Gerald Teschl
<Gerald.Teschl@univie.ac.at>
<http://www.mat.univie.ac.at/~gerald/>"


set license_msg "
Copyright (C) 1997  Gerald Teschl
<Gerald.Teschl@univie.ac.at>
<http://www.mat.univie.ac.at/~gerald/>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

Please see the included file LICENSE for a copy of the GNU
General Public License. If you used the rpm version it should
be in the documentation directory (usually /usr/share/doc/xtexsh-1.4).
If this file is missing, check out
	http://www.gnu.ai.mit.edu/copyleft/gpl.html
or write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA."


#
# Procedures
#

proc message {msg name {w .message}} {
    catch {destroy $w}
    toplevel $w
    wm title $w $name
    bind $w <Control-q> "destroy ."
    bind $w <Control-c> "destroy $w"
    bind $w <Return> "destroy $w"

    frame $w.buttons
    pack $w.buttons -side bottom -fill x
    button $w.buttons.ok -text OK -command "destroy $w"
    pack $w.buttons.ok -expand 1

    text $w.text -yscrollcommand "$w.scroll set" -setgrid true \
	-width 65 -height 26 -wrap word
    scrollbar $w.scroll -command "$w.text yview"
    pack $w.scroll -side right -fill y
    pack $w.text -expand yes -fill both

    $w.text tag configure big -font -*-Courier-Bold-R-Normal--*-140-*-*-*-*-*-*
    $w.text insert end "xTeX Shell\n" big
    $w.text insert end $msg
}

proc edit { file } {
    global editor
    eval "exec $editor $file &"
}

proc view {} {
	global thisview
	switch $thisview {
	"ps" viewps
	"pdf" viewpdf
	default viewdvi
	}
}

proc viewdvi {} {
    global dviviewer fileroot
    if [file isfile $fileroot.dvi] {
	eval "exec $dviviewer $fileroot.dvi &" }\
    else { tk_messageBox -icon info -title "Warning"\
	 -message "Please create $fileroot.dvi first." }
}

proc viewps {} {
    global psviewer fileroot
    if [file isfile $fileroot.ps] {
	eval "exec $psviewer $fileroot.ps &"}\
    else { tk_messageBox -icon info -title "Warning"\
	 -message "Please create $fileroot.ps first." }
}

proc viewpdf {} {
    global pdfviewer fileroot
    if [file isfile $fileroot.pdf] {
	eval "exec $pdfviewer $fileroot.pdf &"}\
    else { tk_messageBox -icon info -title "Warning"\
	 -message "Please create $fileroot.pdf first." }
}

proc texit {} {
    global xterm file tex
    if [file isfile $file] {
	eval "exec $xterm -e $tex $file &" }\
    else { tk_messageBox -icon info -title "Warning"\
	 -message "Please create $file first." }
}

proc watchit {} {
    global xterm tex file includefiles fileroot watchdelay watchfile
    if { $watchfile == "n" } {
	.tex configure -relief raised
	return
    }
    if [file isfile $file] {
        if [file isfile $fileroot.dvi] {
		set changed "n"
	    if [expr [file mtime $file] > [file mtime $fileroot.dvi]] {
		set changed "y" }
		foreach i $includefiles {
			if { [file isfile $i] == 0 } {set i $i.tex }
			if [expr [file mtime $i] > [file mtime $fileroot.dvi]] {
			set changed "y" }
		}
	    if { $changed == "y" } {
		exec touch -r $file $fileroot.dvi
		texit
		after [expr $watchdelay * 1000] watchit
	    } else {
		after [expr $watchdelay * 1000] watchit
	    }
	} else {
	    exec touch $fileroot.dvi
	    texit
	    after [expr $watchdelay * 1000] watchit
	}
    } else {
	tk_messageBox -icon info -title "Warning"\
		-message "Please create $file first." 
	.tex configure -relief raised
    }
}   

proc texpress {} {
    global file watchfile
    if {$watchfile == "y"} {
	if {[.tex cget -relief] == "raised"} {
	    .tex configure -relief sunken 
	    watchit
	} else {
	    .tex configure -relief raised
	    after cancel watchit
	}
    } else {
	texit
    }
}   

proc makeindex {} {
    global xterm makeindex fileroot
    if [file isfile $fileroot.idx] {
	eval "exec $xterm -e $makeindex $fileroot.idx &" }\
    else { tk_messageBox -icon info -title "Warning"\
	 -message "Please create $fileroot.idx first." }
}

proc bibtex {} {
    global xterm bibtex fileroot
    if [file isfile $fileroot.aux] {
	eval "exec $xterm -e $bibtex $fileroot &"}\
    else { tk_messageBox -icon info -title "Warning"\
	 -message "Please create $fileroot.aux first." }
}

proc dvips {} {
    global xterm dvips fileroot
    if [file isfile $fileroot.dvi] {
	eval "exec $xterm -e $dvips -o $fileroot.ps $fileroot.dvi &"}\
    else { tk_messageBox -icon info -title "Warning"\
	 -message "Please create $fileroot.dvi first." }
}

proc ps2pdf {} {
    global xterm ps2pdf fileroot
    if [file isfile $fileroot.ps] {
	eval "exec $xterm -e $ps2pdf $fileroot.ps &"}\
    else { tk_messageBox -icon info -title "Warning"\
	 -message "Please create $fileroot.ps first." }
}

proc spell { file } {
    global xterm spell
    if [file isfile $file] {
	eval "exec $xterm -e $spell $file &" }\
    else { tk_messageBox -icon info -title "Warning"\
	 -message "Please create $file first." }
}

proc detect {} {
   global file tex defaultview thisview
   set tex tex
   set thisview $defaultview
   if [file isfile $file] {
	set line ""
	set dummy ""
	set match ""
	set myfile [open $file r]
	gets $myfile line
	close $myfile
	if [ regexp {^%&(.+)$} $line dummy match ] {
		set tex $match
		if [ regexp {pdf(la)?tex} $match ] {
			set thisview "pdf" 
		}
	} else {
		if  [exec sh -c "echo `grep -c \\documentclass $file`"] { set tex latex }
		if  [exec sh -c "echo `grep -c \\documentstyle $file`"] { set tex latex }
		if  [exec sh -c "echo `grep -c \"\\input amstex\" $file`"] { set tex tex }
		if { $thisview == "pdf" } { set tex "pdf$tex" }
	}
   }
}

proc labelentry {path text length default} {
    frame $path
    label $path.label -text $text
    entry $path.entry -width $length -relief sunken
    $path.entry insert end $default
    pack $path.label -side left -expand y
    pack $path.entry -side right -expand y
}

proc filebox {} {
    set types {
	{"TeX  files"		{.tex}	}
	{"All  files"		*}
    }
    setfile [tk_getOpenFile -filetypes $types -parent .]
}

proc findfile { } {
    global file searchpath

    set oldpath [pwd]
	if { $file == "" } { return 0 }
    foreach path $searchpath {
	if [file isdirectory $path] {
		cd $path
		if [file isfile $file] { return 1}
		if [file isfile ${file}tex] { set file ${file}tex; return 1 }
		if [file isfile $file.tex] { set file $file.tex; return 1 }
	} else { puts stdout "xtexsh: $path: No such directory" }
   }
   cd $oldpath
   return 0
}

proc setfile { newfile } {
    global recent n_recent m_recent includefiles file fileroot

    if { $newfile == "" && $file == "" } { set newfile $recent(0) }
    if { $newfile != "" } {
    	if [file isdirectory [file dirname $newfile] ] { cd [file dirname $newfile]
			set newfile [file tail $newfile] }
	set file "[pwd]/$newfile"
	set rcfile [open ~/.xtexsh_recent w]
	set i 0
	puts $rcfile $file
	if { $n_recent >= 1 } {
		if {$m_recent >= $n_recent} {set n [expr $n_recent-1]}\
		else {set n $m_recent}
		while {$i <= $n} {
			if {$recent($i) != $file} { puts $rcfile $recent($i) }\
			else { if {$n < $m_recent} { set n [expr $n+1] } }
			set i [expr $i+1] }
	}
	close $rcfile
	if { $m_recent >= 1 } { readrecentfiles }

	if { [file extension $newfile ] == ".tex" } {
		set fileroot [file rootname $newfile] }\
	else {
	    	set fileroot $newfile }
	set file $newfile
	wm title . "xTeX: $file"
	detect
	if [file isfile $file] {
		set cline  "grep \"^ *\\\\\\include\{.*\}\" $file | sed -e 'y/\{\}/@@/' | awk 'BEGIN\{FS=\"@\"\} \{print \$2\}'"
		set includefiles [exec sh -c "$cline; exit 0" ] }\
	else { set includefiles "" }
	menufile
    }
}

proc execute {{w .execute}} {
    catch {destroy $w}
    toplevel $w
    wm title $w "Execute command"
    bind $w <Control-q> "destroy ."
    bind $w <Control-c> "destroy $w"
    bind $w <Return> "executeit $w"

    label $w.pwd -text "Current directory: [pwd]"
    labelentry $w.command "Command:" 50 ""
    checkbutton $w.interminal -text "Execute in xterminal" \
	    -onvalue "y" -offvalue "n" -relief flat

    frame $w.buttons
    button $w.buttons.cancel -text "Cancel" -underline 0 -command "destroy $w"
    button $w.buttons.ok -text "OK" -underline 0 -command "executeit $w"
    pack $w.buttons.cancel -side left
    pack $w.buttons.ok -side right

    pack $w.pwd $w.command $w.interminal $w.buttons -side top -anchor w
}

proc executeit { path } {
    global interminal xterm
    set command [$path.command.entry get]
    if {$command != ""} {
	if {$interminal == "y"} { eval "exec $xterm -e $command &" }\
	else { eval "exec $command &" }
	}
    destroy $path
}

proc prefs {{w .prefs}} {
    catch {destroy $w}
    toplevel $w
    wm title $w "Set Preferences"
    global file bak auxfiles programs printopts geometry startup n_recent defaultdir searchpath env watchdelay defaultview userconf
    eval "global $programs"
    eval "global $auxfiles"
    eval "global $printopts"
    bind $w <Control-q> "destroy ."
    bind $w <Control-c> "destroy $w"
    bind $w <Control-o> "setprefs $w; destroy $w"
    bind $w <Return> "setprefs $w; destroy $w"
    bind $w <Control-r> "readprefs $userconf; destroy $w"
    bind $w <Control-s> "setprefs $w; saveprefs $w"

    labelentry $w.file "Current file  :" 63 $file
    labelentry $w.searchpath "File search path:" 60 $searchpath
    label $w.pwd -text "Current directory: [pwd]"
    label $w.sp -text ""

    frame $w.page
    frame $w.page.aux
    label $w.page.aux.label -text "Aux files:"
    pack $w.page.aux.label -side top -anchor w
    checkbutton $w.page.aux.bak -text "bak,~" \
	    -onvalue "y" -offvalue "n" -variable bak -relief flat
    pack $w.page.aux.bak -side top -anchor w
    foreach i $auxfiles {
       checkbutton $w.page.aux.$i -text $i \
	    -onvalue "y" -offvalue "n" -variable $i -relief flat
       pack $w.page.aux.$i -side top -anchor w}
    checkbutton $w.page.aux.rminclf -text "aux include files" \
	    -onvalue "y" -offvalue "n" -variable rminclf -relief flat
    pack $w.page.aux.rminclf -side top -anchor w

    frame $w.page.print
    label $w.page.print.label1 -text "Print options:"
    pack $w.page.print.label1 -side top -anchor w
    foreach i $printopts {
       checkbutton $w.page.print.$i -text $i \
	    -onvalue "y" -offvalue "n" -relief flat
       pack $w.page.print.$i -side top -anchor w}
    label $w.page.print.label2 -text "At startup"
    labelentry $w.page.print.defaultdir "cd into:" 22 $defaultdir
    label $w.page.print.label3 -text "and open:"
    radiobutton $w.page.print.startf -text "file dialog" -variable startup -value f
    radiobutton $w.page.print.startl -text "last file" -variable startup -value l
    labelentry $w.page.print.nrecent "Number of recent files:" 2 $n_recent
    checkbutton $w.page.print.interminal -text "Execute commands in xterminal" \
	    -onvalue "y" -offvalue "n" -relief flat
    checkbutton $w.page.print.watchfile -text "AutoTeX" \
	    -onvalue "y" -offvalue "n" -relief flat
    labelentry $w.page.print.watchdelay "Delay in seconds between checks:" \
	    3 $watchdelay
    label $w.page.print.label4 -text "Default view mode:"
    radiobutton $w.page.print.dvi -text "dvi" -variable defaultview -value dvi
    radiobutton $w.page.print.ps -text "ps" -variable defaultview -value ps
    radiobutton $w.page.print.pdf -text "pdf" -variable defaultview -value pdf

    pack $w.page.print.label2 $w.page.print.defaultdir $w.page.print.label3\
	$w.page.print.startf $w.page.print.startl\
	$w.page.print.nrecent $w.page.print.interminal\
    $w.page.print.watchfile $w.page.print.watchdelay \
	$w.page.print.label4 $w.page.print.dvi $w.page.print.ps $w.page.print.pdf\
       -side top -anchor w

    button $w.page.print.getdefaultdir -text "Set current directory as default" -command "
	$w.page.print.defaultdir.entry delete 0 end
	$w.page.print.defaultdir.entry insert end [pwd]"
	pack $w.page.print.getdefaultdir -side top -anchor e

    frame $w.page.prog
    label $w.page.prog.label -text "Programs:"
    pack $w.page.prog.label -side top -anchor w
    foreach i $programs {
	labelentry $w.page.prog.$i "$i:" 20 [eval "format %s $$i"]
	pack $w.page.prog.$i -side top -anchor e}
        labelentry $w.page.prog.geometry "geometry:" 20 $geometry
	pack $w.page.prog.geometry -side top -anchor e
    button $w.page.prog.getgeometry -text "Get current window geometry" -command "
	$w.page.prog.geometry.entry delete 0 end
	$w.page.prog.geometry.entry insert end [wm geometry .]"
	pack $w.page.prog.getgeometry -side top -anchor e

    pack $w.page.prog $w.page.aux $w.page.print -pady 6 -side left -anchor n -padx 8

    frame $w.buttons
    button $w.buttons.cancel -text "Cancel" -underline 0 -command "destroy $w"
    button $w.buttons.ok -text "OK" -underline 0 -command "setprefs $w; destroy $w"
    button $w.buttons.save -text "Read" -underline 0 -command "readprefs $userconf; destroy $w"
    button $w.buttons.read -text "Save" -underline 0 -command "setprefs $w; saveprefs $w"
    pack $w.buttons.save $w.buttons.cancel -side left
    pack $w.buttons.ok $w.buttons.read -side right

    pack $w.file $w.searchpath $w.pwd $w.sp -side top -anchor w
    pack $w.page $w.buttons -side top -fill x
}

proc readprefs { cfgfile } {
    global bak auxfiles rminclf programs printopts geometry startup n_recent\
	 defaultdir searchpath interminal watchfile watchdelay defaultview env 
    eval "global $programs"
    eval "global $auxfiles"
    eval "global $printopts"

    if [file readable $cfgfile] {
	set rcfile [open $cfgfile r]
	while {[eof $rcfile] != 1} {
	  gets $rcfile dummy
	  set dummy [string trim $dummy]
	  if { $dummy != "" } {
		if {[string index $dummy 0] != "#"} {eval "set $dummy" }
		}
	  }
	close $rcfile
     }
   if {$geometry != ""} { wm geometry . $geometry }
}

proc setprefs { path } {
    global file programs geometry n_recent m_recent defaultdir searchpath watchdelay
    eval "global $programs"

    if {$file != [$path.file.entry get]} {
	set file [$path.file.entry get]
	findfile
	setfile $file}
    set searchpath [$path.searchpath.entry get]
    set geometry [$path.page.prog.geometry.entry get]
    if {$n_recent != [$path.page.print.nrecent.entry get]} {
	set n_recent [$path.page.print.nrecent.entry get]
	if {$n_recent < 0} { set n_recent 0 }
	if {$m_recent > $n_recent} { set m_recent $n_recent }
	menufile }
    set watchdelay [$path.page.print.watchdelay.entry get]
    if {$watchdelay < 1} { set watchdelay 1 }
    set defaultdir [$path.page.print.defaultdir.entry get]
    if {$geometry != ""} { wm geometry . $geometry }
    foreach i $programs {
	set $i [$path.page.prog.$i.entry get]
	}
}

proc saveprefs { path } {
    global bak auxfiles rminclf printopts programs geometry startup n_recent defaultdir searchpath interminal watchfile watchdelay defaultview userconf
    eval "global $programs"
    eval "global $auxfiles"
    eval "global $printopts"

    set rcfile [open $userconf w]
    puts $rcfile "geometry $geometry"
    puts $rcfile "# File stuff"
    puts $rcfile "startup $startup"
    puts $rcfile "n_recent $n_recent"
    puts $rcfile "defaultdir $defaultdir"
    puts $rcfile "searchpath \{$searchpath\}"

    puts $rcfile "# Which aux files shall be marked for removal (y=yes, n=no)?"
    puts $rcfile "bak $bak"
    foreach i $auxfiles {
	puts $rcfile "$i [eval "format %s $$i"]"
	}
    puts $rcfile "rminclf $rminclf"
	puts $rcfile "# Stuff"
    puts $rcfile "defaultview $defaultview"
    puts $rcfile "interminal $interminal"
    puts $rcfile "# AutoTeX"
    puts $rcfile "watchfile $watchfile"
    puts $rcfile "watchdelay $watchdelay"
    puts $rcfile "# Printing options"
    foreach i $printopts {
	puts $rcfile "$i [eval "format %s $$i"]"
	}
    puts $rcfile "# Programs"
    foreach i $programs {
	puts $rcfile "$i \"[eval "format %s $$i"]\""
	}
    close $rcfile
    destroy $path
}

proc print {{w .printdialog}} {
    catch {destroy $w}
    toplevel $w
    wm title $w "Print"
    bind $w <Control-q> {destroy .}
    bind $w <Control-c> "destroy $w"
    bind $w <Control-p> "printit $w"
    bind $w <Return> "printit $w"

    frame $w.page
    labelentry $w.page.fpage "First page:" 6 ""
    labelentry $w.page.lpage "Last  page:" 6 ""
    frame $w.flag
    checkbutton $w.flag.abspagenumbers -text "page numbers are absolute" \
	    -onvalue "y" -offvalue "n" -relief flat
    checkbutton $w.flag.twoup -text "2up" \
	    -onvalue "y" -offvalue "n" -relief flat
    checkbutton $w.flag.printtofile -text "print to file" \
	    -onvalue "y" -offvalue "n" -relief flat
    frame $w.buttons
    button $w.buttons.cancel -text "Cancel" -underline 0 -command "destroy $w"
    button $w.buttons.print -text "Print" -underline 0 -command "printit $w"

    pack $w.page.fpage $w.page.lpage -side left -padx 5
    pack $w.flag.abspagenumbers $w.flag.twoup $w.flag.printtofile -side left
    pack $w.buttons.print -side right
    pack $w.buttons.cancel -side left

    pack $w.page $w.flag $w.buttons -side top -fill x
}

proc printit { path } {
    global printopts psnup print dvips fileroot
    eval "global $printopts"

    if [file isfile $fileroot.dvi] {
	set fpflag "-p"; set lpflag "-l"; set tuflag ""
	if {$abspagenumbers == "y"} {set fpflag "-p ="; set lpflag "-l ="}
	set fpage [$path.page.fpage.entry get]
	if {$fpage != ""} {set fpage "$fpflag$fpage"}
	set lpage [$path.page.lpage.entry get]
	if {$lpage != ""} {set lpage "$lpflag$lpage"}
	if {$printtofile == "y"} {
		if {$twoup == "y"} {exec sh -c "$dvips -o -q $fpage $lpage -f $fileroot.dvi | $psnup > $fileroot.ps" }\
		else { exec sh -c "$dvips -o -q $fpage $lpage $fileroot.dvi" } }\
	else {
		if {$twoup == "y"} {exec sh -c "$dvips -o -q $fpage $lpage -f $fileroot.dvi | $psnup | $print" }\
		else { exec sh -c "$dvips -o -q $fpage $lpage -f $fileroot.dvi | $print" } }
    }\
    else { tk_messageBox -icon info -title "Warning"\
	 -message "Please create $fileroot.dvi first." }
    destroy $path
}

proc rmaux {{w .rmaux}} {
    catch {destroy $w}
    toplevel $w
    wm title $w "Remove"
    bind $w <Control-q> {destroy .}
    bind $w <Control-c> "destroy $w"
    bind $w <Return> "rmit $w"
    global bak auxfiles includefiles rminclf file fileroot
    eval "global $auxfiles"

    frame $w.page
    if {[file isfile $file.bak] || [file isfile $file~]} {
	checkbutton $w.page.bak -onvalue "y" -offvalue "n" -relief flat\
	-text "[if [file isfile $file~] {format "%s~" $file}] \
	[if [file isfile $file.bak] {format "%s.bak" $file}]"

	pack $w.page.bak -side top -anchor w
	}
    foreach i $auxfiles {
	if [file isfile $fileroot.$i] {
		checkbutton $w.page.$i -text $fileroot.$i \
	    		-onvalue "y" -offvalue "n" -relief flat
		pack $w.page.$i -side top -anchor w }
    }
    if { $includefiles != "" } {
	checkbutton $w.page.rminclf -text "Remove aux include files" \
	    -onvalue "y" -offvalue "n" -relief flat
    	pack $w.page.rminclf -side top -anchor w
    }
    frame $w.buttons
    button $w.buttons.cancel -text "Cancel" -underline 0 -command "destroy $w"
    button $w.buttons.rm -text "Remove files" -borderwidth 3 -command "rmit $w"
    pack $w.buttons.rm -side right
    pack $w.buttons.cancel -side left

    pack $w.page $w.buttons -side top -fill x
}

proc rmit {w} {
    global file fileroot auxfiles bak includefiles rminclf
    eval "global $auxfiles"

    if {$bak == "y"} { file delete $file~; file delete $file.bak }
    foreach i $auxfiles {
      if { [eval "format %s $$i"] == "y" } {
	file delete $fileroot.$i }
    }
    if { $rminclf == "y" } {
	foreach i $includefiles {
		if { $aux == "y" } { file delete $i.aux }
		if { $bak == "y" } { file delete $i~; file delete $i.bak }
	}
    }
    destroy $w
}

proc viewaux {{w .viewaux}} {
    catch {destroy $w}
    toplevel $w
    wm title $w "View aux file"
    bind $w <Control-q> {destroy .}
    bind $w <Control-c> "destroy $w"
    global auxfiles fileroot
    eval "global $auxfiles"

    foreach i $auxfiles {
	if {[file isfile $fileroot.$i] && [expr {$i != "dvi"}]} {
	    button $w.$i -text "Edit $fileroot.$i" \
	    -command "edit $fileroot.$i; destroy $w"
	pack $w.$i -side top -fill x -anchor w}
	}

    button $w.cancel -text "Cancel" -underline 0 -command "destroy $w"
    pack $w.cancel -side top
}


proc readrecentfiles {} {
   global recent m_recent n_recent

   set m_recent -1
   set recent(0) ""
   if [file readable ~/.xtexsh_recent] {
	set rcfile [open ~/.xtexsh_recent r]
	while {[eof $rcfile] != 1 && $m_recent <= $n_recent } {
	  gets $rcfile dummy
	  set dummy [string trim $dummy]
	  if { [file isfile $dummy] } {
		set m_recent [expr $m_recent+1]
		set recent($m_recent) $dummy
		}
	  }
	close $rcfile
   }
}


proc menufile {} {
   global startup recent m_recent file fileroot includefiles

   set m .menu.file.m
   $m delete 0 end
	$m add command -label "Open" -underline 0 -accelerator <Ctrl-o> -command { filebox }
	if { $m_recent >= 1 } {
		$m add cascade -label "Open recent" -underline 7 -menu $m.recent
		$m.recent delete 0 end
		set i 1
		while { $i <= $m_recent } {
			$m.recent add command -label [file tail $recent($i) ] -command "setfile $recent($i)"
			set i [expr $i+1]
		}
	}
	$m add command -label "Edit" -underline 0 -accelerator <Ctrl-e> -command { edit $file }
	if { $includefiles != "" } {
		$m add cascade -label "Edit include files" -underline 6 -menu $m.include
		$m.include delete 0 end
		$m add cascade -label "Ispell" -underline 0 -menu $m.spell
		$m.spell delete 0 end
                $m.spell add command -label $fileroot -command "spell $file"
		$m.spell add separator
		foreach i $includefiles {
			if [file isfile $i ] { set ii $i }\
			else { set ii $i.tex }
			$m.include add command -label [file tail $i] -command "edit $ii"
			$m.spell add command -label [file tail $i] -command "spell $ii"  }
	} else {\
		$m add command -label "Ispell" -underline 0 -accelerator <Ctrl-i> -command { spell $file }
	}
	$m add command -label "Print" -underline 0 -accelerator <Ctrl-p> -command { print }
	$m add command -label "Remove aux files" -underline 0 -accelerator <Ctrl-r> -command { rmaux }
	$m add command -label "View aux file" -underline 0 -command { viewaux }
	$m add command -label "Execute command" -underline 1 -accelerator <Ctrl-x> -command { execute }
	$m add command -label "Open Shell" -underline 5 -accelerator <Ctrl-s> -command { eval "exec $xterm &" }
	$m add separator
	$m add command -label "Preferences" -underline 3 -accelerator <Ctrl-f> -command { prefs }
	$m add separator
	$m add command -label "Quit" -underline 0 -accelerator <Ctrl-q> -command "destroy ."
}

#
# Main program
#

bind . <Control-q> {destroy .}
bind . <Control-e> {edit $file}
bind . <Control-t> {texit}
bind . <Control-i> {spell $file}
bind . <Control-o> {filebox}
bind . <Control-f> {prefs}
bind . <Control-h> {message $help_msg Help}
bind . <F1> {message $help_msg Help}
bind . <Control-b> {bibtex}
bind . <Control-m> {makeindex}
bind . <Control-b> {bibtex}
bind . <Control-p> {print}
bind . <Control-r> {rmaux}
bind . <Control-v> {view}
bind . <Control-x> {execute}
bind . <Control-s> {eval "exec $xterm &"}

# Read the preferences and recent files
readprefs $allconf
readprefs $userconf
if { $n_recent < 0 } { set n_recent 0 }
readrecentfiles

# Create main frame

frame .menu -relief raised -bd 2

# Process the arguments and create the file menu

menubutton .menu.file -text "File" -underline 0 -menu .menu.file.m
menu .menu.file.m
menu .menu.file.m.recent
menu .menu.file.m.include
menu .menu.file.m.spell

# Create some default entries

set m .menu.file.m
	$m add command -label "Open" -underline 0 -accelerator <Ctrl-o> -command { filebox }
	$m add command -label "Execute command" -underline 1 -accelerator <Ctrl-x> -command { execute }
	$m add command -label "Open Shell" -underline 5 -accelerator <Ctrl-s> -command { eval "exec $xterm &" }
	$m add separator
	$m add command -label "Preferences" -underline 3 -accelerator <Ctrl-f> -command { prefs }
	$m add separator
	$m add command -label "Quit" -underline 0 -accelerator <Ctrl-q> -command "destroy ."

if $argc>0 {set file [lindex $argv 0]} else {set file ""}

if {[string range $file 0 1] == "-r"} {
   if {[catch {set i [expr [string range $file 2 end]]}] ==1} {set i 0}
   if {$i > $m_recent} {set i 0}
   set file $recent($i)
   }

set path [file dirname $file]
if [file isdirectory $path] {
	cd $path
	set file [file tail $file]
	} else { puts stdout "xtexsh: [pwd]/$path: No such directory" }
if [file isdirectory $file ] {cd $file; set file ""}

set ext [file extension $file ]
foreach i $auxfiles {
	if { ".$i" == $ext } {
	    set file [file rootname $file] } }

if {[findfile] == 0 } {
	if {$file != ""} {tk_messageBox -icon info -title "Warning"\
	 -message "New file [pwd]/$file" }
	}

if {$file != "" } { setfile $file }\
else {
	if { $startup == "l" && $m_recent >= 0 } { setfile $recent(0) }\
	else {
		if {$defaultdir != ""} {cd $defaultdir}
		filebox
		}
}

# Typeset menu

set m .menu.typeset.m
menubutton .menu.typeset -text "Typeset" -underline 0 -menu $m
menu $m
	$m add command -label "TeX" -underline 0 -accelerator <Ctrl-t> -command { texit }
	$m add cascade -label "TeX command" -underline 4 -menu $m.radiotex
	$m add checkbutton -label "AutoTeX" -onvalue "y" -offvalue "n" -variable watchfile
	$m add separator
	$m add command -label "Bibtex" -underline 0 -accelerator <Ctrl-b> -command { bibtex }
	$m add command -label "Makeindex" -underline 0 -accelerator <Ctrl-m> -command { makeindex }
	$m add separator
	$m add command -label "Create PS" -underline 0 -command { dvips }
	$m add command -label "PS2PDF" -underline 2 -command { ps2pdf }
	$m add separator
	$m add command -label "View" -underline 0 -accelerator <Ctrl-v> -command { view }
	$m add cascade -label "Default view" -underline 11 -menu $m.radioview
	$m add command -label "View DVI" -underline 5 -command { viewdvi }
	$m add command -label "View PS" -underline 5 -command { viewps }
	$m add command -label "View PDF" -underline 7 -command { viewpdf }
set mm $m.radiotex
menu $mm
	$mm add radio -label "tex" -variable tex -value tex
	$mm add radio -label "latex" -variable tex -value latex
	$mm add radio -label "pdftex" -variable tex -value pdftex
	$mm add radio -label "pdflatex" -variable tex -value pdflatex
	$mm add separator
	$mm add command -label "Choose custom" -command { prefs }
	$mm add separator
set mm $m.radioview
menu $mm
	$mm add radio -label "dvi" -variable thisview -value dvi
	$mm add radio -label "ps" -variable thisview -value ps
	$mm add radio -label "pdf" -variable thisview -value pdf
	


# Help menue

set m .menu.help.m
menubutton .menu.help -text "Help" -menu $m -underline 0
menu $m
$m add command -label "About" -underline 0 -command { tk_messageBox -icon info -title "About TeX Shell"\
	 -message "xTeX Shell - Version: 1.4-2

by Gerald Teschl" -type ok -parent . }
$m add command -label "Help" -underline 0 -accelerator <F1> -command { message $help_msg Help }
$m add command -label "License" -underline 0 -command { message $license_msg License }

# Pack the menus

pack .menu.help -side right
pack .menu.file .menu.typeset -side left


button .edit -text "Edit" -underline 0 -command { edit $file }
button .tex -text "TeX" -underline 0 -command { texpress }
button .dvi -text "View" -underline 0 -command { view }
button .print -text "Print" -underline 0 -command { print }
button .quit -text "Quit" -underline 0 -command { destroy . }


pack .menu -side top -fill x
pack .edit -side left
pack .tex -side left
pack .dvi -side left
pack .print -side left
pack .quit -side right


