#!/usr/Tcl/bin/wish -f

# RCS Id:
#	tktex,v 2.1 1995/07/18 06:50:14 ndanger Alpha
#

###     TkTeX:  Tk-based GUI for TeX and related tools.
###     Copyright (C) 1995  Norman Danner
### 
###     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.
### 
###     You should have received a copy of the GNU General Public License
###     along with this program; if not, write to the Free Software
###     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

###      e-mail:	ndanner@indiana.edu
###      WWW:		http://nickel.ucs.indiana.edu/~ndanner

# Set TKTEX(lib_dir) to the directory in which you have put TkTeX's support
# files.

set TKTEX(lib_dir) /usr/local/lib/tk/tktex
set auto_path [linsert $auto_path 0 $TKTEX(lib_dir)]

if {[lindex [split $tk_version "."] 0] == "3"} {
  set TKTEX(tk3) 1
  set TKTEX(tk4) 0
} else {
  set TKTEX(tk3) 0
  set TKTEX(tk4) 1
}

# ################
# Utility routines
# ################

# tktex:get_option {w o} -- Get the value of the option o of the widget
#  w.

proc tktex:get_option {w o} {
  
  global TKTEX
  
  if {$TKTEX(tk3)} {
    return [lindex [$w configure $o] 4]
  } else {
    return [$w cget $o]
  }
  
}


# ########
# Defaults
# ########

proc tktex:var-defaults {} {

	global TKTEX
	global env

	set TKTEX(view_cmd) "xdvi"
	set TKTEX(print_cmd) "dvips"
	set TKTEX(edit_cmd) "emacs"
	set TKTEX(show_dir) 0
	set TKTEX(show_cmds) 1
	set TKTEX(clear_new) 1
	set TKTEX(printers) "lp"
	set TKTEX(update) 100
	set TKTEX(interactive) 0

	set TKTEX(font) [tktex:get_option $TKTEX(text_widget) -font]
	set TKTEX(background) [tktex:get_option $TKTEX(text_widget) -background]
	set TKTEX(input_fg) [tktex:get_option $TKTEX(text_widget) -foreground]
	set TKTEX(output_fg) $TKTEX(input_fg)
	
	if {[string first "TEXEDIT" [array names env]] == -1} \
	  {set env(TEXEDIT) "xterm -e vi %d %s"}
	
	set TKTEX(dvips,print_dest) "lpr"
	set TKTEX(dvips,pages) "allpages"
	set TKTEX(dvips,pgtype) "texpage"
	set TKTEX(dvips,mfeed) 0
	set TKTEX(dvips,reverse) 0
	set TKTEX(dvips,burst_page) 0
	set TKTEX(dvips,xops) ""
	
	AddFormat TeX "Plain TeX" tex {tex_hook}
	set TKTEX(tex_fmt) ""

	AddProcess "BiBTeX" {tktex:io "bibtex -verbose $TKTEX(src_file)" passive}

}


# ###############
# Variable traces
# ###############

trace variable TKTEX w tktex:var-traces

proc tktex:var-traces {name1 name2 op} {

    global TKTEX
        
    if {$name2 == "src_file"} {
      if {$TKTEX(src_file) == ""} {set s "disabled"} {set s "normal"}
      .compile configure -state $s
      .proc configure -state $s
      .vp configure -state $s
    }
    
}


# ##########
# Procedures
# ##########

# Formats are stored as lists of the form {lbl cmd hook}. lbl is the label
# of the format; this is used the describe the format in the Formats menu
# (e.g., "Plain TeX").  cmd is the unix command that is executed to run TeX
# with this format (e.g., "tex").  hook is the name of a proc to be executed
# any time the format is set to the one corresponding to this list (e.g.,
# "tex_hook").  The lists are stored as the variables TKTEX(fmts,$fmt), where
# $fmt is the (internal) name of the format, the one that is supplied as an
# argument to SetFormat.

proc AddFormat {fmt lbl cmd hook} {

    global TKTEX
    
#   If this format already exists, assume we are redefining it.  So delete
#   the current definition, and remove its entry from the Formats menus.
    if {[string first "fmts,$fmt" [array names TKTEX]] != -1} {
      unset TKTEX(fmts,$fmt)
      .compile.m delete "$lbl"
    }
    
#   Define the format and add its entry to the Formats menu.
    set TKTEX(fmts,$fmt) [list $lbl $cmd $hook]
    .compile.m add command -label "$lbl" -command "SetFormat $fmt"
    
}


proc ListFormats {} {

    global TKTEX
    
    set ret {}
    foreach n [array names TKTEX] {
    	if {[string first "fmts" $n] == 0} \
    	  {lappend ret [lindex [split $n ","] 1]}
    }
    
    return $ret
    
}


proc SetFormat {f} {

    global TKTEX
    
#   If the format doesn't exist, return an error.
    if {[string first "fmts,$f" [array names TKTEX]] == -1} {return -1}
    
#   Set the format, update the label of the Formats menu button, set tex_cmd
#   to the unix command appropriate for this format, and execute the hook, if
#   one is specified and it exists as a proc.

    set TKTEX(tex_fmt) $f
    .compile configure -text "Format <[lindex $TKTEX(fmts,$f) 0]>"
    set TKTEX(tex_cmd) [lindex $TKTEX(fmts,$f) 1]
    if {[lindex $TKTEX(fmts,$f) 2] != "" && [info procs [lindex $TKTEX(fmts,$f) 2]] != ""} {eval [lindex $TKTEX(fmts,$f) 2]}
    
}


# AddProcess {lbl proc}:  Add the entry $lbl to the Processing menu, and
# execute the proc $proc when this entry is selected.  This allows users
# (or admins) to add procs for site-specific and local programs that are
# related to TeX; see the docs for more detail about how to use this.

proc AddProcess {lbl proc} {

    global TKTEX
    
    catch {.proc.m delete "$lbl"}
    .proc.m add command -label "$lbl" -command $proc
    
}


proc tktex:update {msec} {
    
  update idletasks
  after $msec tktex:update $msec
  
}


# tktex:io {cmd type} -- Start an i/o session for some command cmd.  "type"
# must be either 'interactive' or 'passive', indicating whether or not the
# command might expect user input (e.g., 'tex file.tex' is interactive,
# and 'xdvi file.dvi' is not).

proc tktex:io {cmd type} {
  
  global TKTEX
  
# Check usage of the command.
  if {"$type" != "passive" && "$type" != "interactive"} {
    error "usage:  tktex:io <cmd> <passive|interactive>"
  }

# Make sure we aren't trying to start up an interactive i/o session when there
# is already one in progress.
  if {"$type" == "interactive" && $TKTEX(interactive)} {
    error "tktex:io:  Interactive process currently running"
  }
  
# Show the working directory and the command if so desired by the user.  Make
# sure that this text is marked readonly.
  set tmp [$TKTEX(text_widget) index insert]
  if {$TKTEX(show_dir)} \
    {$TKTEX(text_widget) insert insert "Working in directory [pwd]\n"}
  if {$TKTEX(show_cmds)} \
      {$TKTEX(text_widget) insert insert "$cmd\n"}
  $TKTEX(text_widget) tag add readonly $tmp insert

# Start the command.
  set pid [open "|$cmd 2>@ stdout" r+]

# Some bookkeeping; keep track of whether this process is interactive; if it
# is, then also set TKTEX(interactive) to make sure that another interactive
# process is not started before this one finishes.

  if {"$type" == "interactive"} {
    set TKTEX($pid,interactive) 1
    set TKTEX(interactive) 1
    set TKTEX(interactive_pid) $pid
  } else {
    set TKTEX($pid,interactive) 0
    if {$TKTEX(interactive)} {tkwait variable TKTEX(interactive)}
  }
#   if {"$type" == "interactive"} {set TKTEX(interactive) 1}

# Catch the output, using 'addinput' if this is tk3.6, 'fileevent' if tk4.x.
  if {$TKTEX(tk3)} {
    addinput -read $pid "tktex:display-output $pid"
  } else {
    fileevent $pid readable "tktex:display-output $pid"
  }
  
}

# tktex:display-output:  Display the output of a command, one byte at a time.
#   We pretty much are forced to do it one byte at a time, because if we try
#   more and there is an error in a TeX file, we are likely to hang waiting for
#   output while TeX is waiting for input.

proc tktex:display-output {pid} {
  
  global TKTEX
  
  if {$TKTEX($pid,interactive) || !$TKTEX(interactive)} {
    if {![eof $pid]} {
      set c [read $pid 1]
#       if {![$TKTEX(text_widget) compare insert == end]} \
#         {$TKTEX(text_widget) mark set insert end}
      $TKTEX(text_widget) insert insert $c
      $TKTEX(text_widget) tag add readonly insert-1char
      $TKTEX(text_widget) yview -pickplace insert
    } {
      if {$TKTEX(tk3)} {removeinput $pid}
      catch "close $pid"
      unset TKTEX($pid,interactive)
      if {$TKTEX(interactive)} {set TKTEX(interactive) 0}
    }  
  }
  
}


#
# help_file:  View a help file, if it exists.
#

proc tktex:help-file {suff} {

    global TKTEX
    
    set file $TKTEX(lib_dir)/tktex-$suff
    if {[file exists $file.dvi]} {tktex:io "$TKTEX(view_cmd) $file" passive}

}


#
# about_window:  Display an info window
#

proc tktex:about {} {
  
  tktex:popup .about "About TkTeX"
  
  label .about.l -text {TkTeX v2.1} -font "*-helvetica-bold-r-normal--24-*"
  message .about.desc -aspect 600 \
    -text {TkTeX:  Tk-based GUI for TeX and related tools.}
  message .about.disc -aspect 600 -text {\
TkTeX, Copyright (C) 1995 Norman Danner.\
TkTeX comes with ABSOLUTELY NO WARRANTY.\
This is free software, and you are welcome to redistribute it\
under the conditions of the GNU Public License Version 2.\
  }
  message .about.address -aspect 1000 -font "8x13" -text {\
ndanner@indiana.edu
http://nickel.ucs.indiana.edu/~ndanner\
  }
  button .about.b -text "Dismiss" -command {destroy .about}
  
  pack .about.l .about.desc .about.disc .about.address .about.b -in .about
}


# tktex:popup {w t}:  This creates a toplevel window $w with title $t, or, if it
#   already exists, raises it.  Useful for things like Options windows,
#   which people sometimes leave open, but get obscured by other windows.

proc tktex:popup {w t} {

    if {[winfo exists $w]} {
    	raise $w
    	return 1
    } {
    	toplevel $w
    	wm title $w "$t"
    	return 0
    }
    
}

# tktex:new-file {f} -- Open a new source file.  If $f == "", prompt for
# a file.
#	base_file:	The full pathname of the selected file.
#	src_file:	The rootname of the the selected file (i.e., base_file
#			with the path and extension deleted).
#	tex_file:	The name of the file selected (i.e., base_file with the
#			path deleted).  We don't assume TeX files necessarily
#			use the extension .tex, since some people like .ltx,
#			.dtx, etc.
#	dvi_file:	src_file.dvi.

proc tktex:new-file {f} {

    global TKTEX
      
    set tmp $TKTEX(base_file)
    if {($f == "") || ![file exists $f]} {
      set TKTEX(base_file) \
        [FileSelect .fileSelect $TKTEX(tex_dir) "Select Input File" OK]
    } else {
      set f [glob $f]
      if {[string first "/" $f] == 0} {
        set TKTEX(base_file) $f
      } else {
        if {[string first "./" $f] == 0} {
          set TKTEX(base_file) "[pwd]/[string range $f 2 end]"
        } else {
          set TKTEX(base_file) "[pwd]/$f"
        }
      }
    }
    if {$TKTEX(base_file) != ""} {
      set TKTEX(tex_dir) [file dir $TKTEX(base_file)]
      set TKTEX(src_file) [file rootname [file tail $TKTEX(base_file)]]
      set TKTEX(tex_file) [file tail $TKTEX(base_file)]
      set TKTEX(dvi_file) "$TKTEX(src_file).dvi"
      tktex:build-edit-menu "$TKTEX(tex_dir)/$TKTEX(tex_file)"
      set TKTEX(file_lbl) "File <$TKTEX(tex_file)>"
      cd $TKTEX(tex_dir)
      if {$TKTEX(clear_new)} {$TKTEX(text_widget) delete 1.0 end}
      set TKTEX(dvips,file_name) "$TKTEX(src_file).ps"
    } {
      set TKTEX(base_file) tmp
    }

}


#
# tktex:build-edit-menu:  Given a base file, find all the files \include'd in
# it, and put them in the edit menu.
#
proc tktex:build-edit-menu {f} {
  
  global TKTEX

#  Don't delete the "New File" entry.  The "perforation"
#  counts as a menu item in tk4.x.  The separator entry seems to get deleted
#  and immediately added because when this menu is empty, the separator
#  doesn't seem to count as an item; in particular, if we just leave it
#  alone, the first time a file is selected, it will get deleted, and then
#  not added back.
  if {$TKTEX(tk3)} {.file.m delete 1 last} {.file.m delete 2 last}
  .file.m add separator
  
# Visually isolate the main (galley) file.
  set dir [file dir $f]
  set main [file tail $f]
  .file.m add command -label "$main" -command \
    "eval \"exec \$TKTEX(edit_cmd) $f &\""
  .file.m add separator
  
  set fId [open $f r]
  
# flist becomes a list of filenames that occur inside \include statements
# (have to make sure we aren't looking at an \includeonly for this) and
# \input statements.
  set flist {}
  while {[gets $fId line] >= 0} {
    if {[string first "\\include" $line] != -1 && \
	[string first "\\includeonly" $line] == -1} {
	    lappend flist "[lindex [split $line "\{\}"] 1]"
    }
    if {[string first "\\input" $line] == 0} {
    	lappend flist "[lindex [split $line " "] 1]"
    }
  }
  close $fId
  
# Create the menu consisting of files in flist.  If a file doesn't have an
# extension, assume it is ".tex".  Add the file to the menu only if it exists
# in the same directory as the main file.  This makes the assumption that files
# that are included but in different directories are macro files or some such,
# and hence not something we would want to both with finding and editing very
# often.
  foreach f $flist {
    if {[file extension $f] == ""} {set f "$f.tex"}
    if {![file exists $dir/$f]} continue
    .file.m add command -label $f -command \
      "eval \"exec \$TKTEX(edit_cmd) $dir/$f &\""
  }
  
}


#
# tktex:build-dvips-cmd:  Creates the command to be executed when DVIPS is the
#   selected DVI printing program and "Print" is selected.
#

proc tktex:build-dvips-cmd {f} {

  global TKTEX
  
  set cmd "$TKTEX(print_cmd)"
  
  if {$TKTEX(dvips,print_dest) == "lpr"} {
    if {$TKTEX(dvips,burst_page)} \
      {append cmd " -o \"\\!lpr -P$TKTEX(printer_name)\""} \
      {append cmd " -o \"\\!lpr -P$TKTEX(printer_name) -h\""}
  } {
    append cmd " -o $TKTEX(dvips,file_name)"
  }
  
  if {$TKTEX(dvips,pages) == "somepages"} {
    if {$TKTEX(dvips,spage) != ""} {
      if {$TKTEX(dvips,pgtype) == "abspage"} \
        {append cmd " -p \"=$TKTEX(dvips,spage)\""} \
	{append cmd " -p $TKTEX(dvips,spage)"}
    }
    if {$TKTEX(dvips,epage) != ""} {
      if {$TKTEX(dvips,pgtype) == "abspage"} \
        {append cmd " -l \"=$TKTEX(dvips,epage)\""} \
      	{append cmd " -l $TKTEX(dvips,epage)"}
    }
  }
  
  if {$TKTEX(dvips,mfeed)} {append cmd " -m"}
  if {$TKTEX(dvips,reverse)} {append cmd " -r"}
  if {$TKTEX(dvips,xops) != ""} {append cmd " $TKTEX(dvips,xops)"}
  
  append cmd " $f"
  return $cmd
  
}


#
# tktex:dvips-options:  Options panel for dvips.  The theory is that there could
# also be a 'dvi2ps_options', 'dvi2im72_options', or whatever, depending on
# what printing program is being used.
#
proc tktex:dvips-options {} {
    global TKTEX
    
    if {[tktex:popup .dvips_ops "DVIPS Options"]} {return}
    set f .dvips_ops
        
    frame $f.dest -relief raised -bd 1
    frame $f.dest.f1
    frame $f.dest.l
    frame $f.dest.r
    
    label $f.dest.lbl -text "Printer Options"
    
    radiobutton $f.dest.file -text "File" -variable TKTEX(dvips,print_dest) \
      -value "file"
    LabelEntryH $f.dest.file_name "File Name:" {-textvar TKTEX(dvips,file_name)}
    radiobutton $f.dest.lpr -text "Printer" -variable TKTEX(dvips,print_dest) \
      -value "lpr"
    MButtonEntryH $f.dest.lpr_name "Printer name:" {-textvar TKTEX(printer_name)}
    if {$TKTEX(tk4)} {[$f.dest.lpr_name menu] configure -tearoff 0}
    foreach p $TKTEX(printers) {
      [$f.dest.lpr_name menu] add command -label $p -command "set TKTEX(printer_name) $p"
    }
    
    pack $f.dest.file $f.dest.lpr -in $f.dest.l -fill x
    pack $f.dest.file_name $f.dest.lpr_name -in $f.dest.r -fill x -expand 1
    pack $f.dest.l $f.dest.r -in $f.dest.f1 -side left
    pack configure $f.dest.r -expand 1
    pack $f.dest.lbl $f.dest.f1 -fill x
    
#     ComboWin $f.dest \
#       $f.dest.lbl \
#       "$f.dest.file $f.dest.file_name" \
#       "$f.dest.lpr $f.dest.lpr_name"
    
    frame $f.pg -relief raised -bd 1
    frame $f.pg.f1
    frame $f.pg.r
    frame $f.pg.l
    
    label $f.pg.lbl -text "Page Range"
    
    radiobutton $f.pg.allpages -text "All pages" -variable TKTEX(dvips,pages) \
      -value "allpages" -command "
      $f.pg.abspage configure -state disabled
      $f.pg.texpage configure -state disabled
    "
    radiobutton $f.pg.somepages -text "Some pages" \
      -variable TKTEX(dvips,pages) -value "somepages" -command "
      $f.pg.abspage configure -state normal
      $f.pg.texpage configure -state normal
    "

   radiobutton $f.pg.abspage -text "Absolute" -variable TKTEX(dvips,pgtype) \
     -value "abspage"
   radiobutton $f.pg.texpage -text "TeX pages" -variable TKTEX(dvips,pgtype) \
     -value "texpage"
   
   if {$TKTEX(dvips,pages) == "allpages"} "$f.pg.allpages invoke"

   LabelEntryH $f.pg.spage "Start:" {-textvar TKTEX(dvips,spage)}
   LabelEntryH $f.pg.epage "End:" {-textvar TKTEX(dvips,epage)}
    
    pack $f.pg.allpages $f.pg.abspage $f.pg.spage -in $f.pg.l -fill x
    pack $f.pg.somepages $f.pg.texpage $f.pg.epage -in $f.pg.r -fill x
    pack $f.pg.l $f.pg.r -in $f.pg.f1 -side left
    pack $f.pg.lbl $f.pg.f1
    
#     ComboWin $f.pg \
#       $f.pg.lbl \
#       "$f.pg.allpages $f.pg.somepages" \
#       "$f.pg.abspage $f.pg.texpage" \
#       "$f.pg.spage $f.pg.epage"
    
    frame $f.misc -relief raised -bd 1
    label $f.misc.lbl -text "Miscellaneous Options"
    
    checkbutton $f.misc.mfeed -text "Manual feed" -variable TKTEX(dvips,mfeed)
    checkbutton $f.misc.rev -text "Reverse pages" -variable TKTEX(dvips,reverse)
    checkbutton $f.misc.burst -text "Burst page" -variable TKTEX(dvips,burst_page)
    
    LabelEntryH $f.misc.xops "Other options:" {-textvar TKTEX(dvips,xops) -width 35}
    
    ComboWin $f.misc \
      $f.misc.lbl \
      "$f.misc.mfeed $f.misc.rev $f.misc.burst" \
      $f.misc.xops
    
    button $f.dis -text "Dismiss" -command "destroy $f"
        
    ComboWin $f \
      $f.dest \
      $f.pg \
      $f.misc \
      $f.dis
}


#
# tktex:set-options:  Helper applications, environment.
#
proc tktex:set-options {} {

    global TKTEX
    
    if {[tktex:popup .optionset "TkTeX Options"]} {return}
        
    frame .optionset.f1 -relief flat
    frame .optionset.f2 -relief flat
    
    frame .optionset.f1v1 -relief raised -bd 1
    label .optionset.helpers -text "Helper Applications"
    LabelEntryH .optionset.viewer "DVI previewer:" {-textvar TKTEX(view_cmd)}
    LabelEntryH .optionset.editor "Editor:" {-textvar TKTEX(edit_cmd)}
    pack .optionset.helpers .optionset.viewer .optionset.editor -in .optionset.f1v1 -side top -fill x
    
    frame .optionset.f1v2 -relief raised -bd 1
    label .optionset.misc -text "Miscellaneous"
    checkbutton .optionset.show_dir -text "Show working directory" \
      -variable TKTEX(show_dir)
    checkbutton .optionset.show_cmds -text "Show commands" \
      -variable TKTEX(show_cmds)
    checkbutton .optionset.clear_on_new -text "Clear on new file" \
      -variable TKTEX(clear_new)
    pack .optionset.misc .optionset.show_dir .optionset.show_cmds .optionset.clear_on_new -in .optionset.f1v2 -side top -fill x

    pack .optionset.f1v1 .optionset.f1v2 -in .optionset.f1 -side top -fill both
    
    frame .optionset.f2v1 -relief raised -bd 1
    label .optionset.env -text "Environment"
    LabelEntryH .optionset.texinputs "TEXINPUTS:" {-textvar env(TEXINPUTS) -width 30}
    LabelEntryH .optionset.bibinputs "BIBINPUTS:" {-textvar env(BIBINPUTS) -width 30}
    LabelEntryH .optionset.texedit "TEXEDIT:" {-textvar env(TEXEDIT) -width 30}
    LabelEntryH .optionset.display "DISPLAY:" {-textvar env(DISPLAY) -width 30}
    pack .optionset.env .optionset.texinputs .optionset.bibinputs .optionset.texedit .optionset.display \
      -in .optionset.f2v1 -side top -fill x
    
    pack .optionset.f2v1 -in .optionset.f2 -side top -fill both
   
    button .optionset.dis -text "Dismiss" -command {destroy .optionset}
    pack .optionset.dis -side bottom -fill x
    pack .optionset.f1 .optionset.f2 -side left -fill both -expand yes
    
}


# ############################################################
# Make all the buttons, to be packed into the frame ".buttons"
# ############################################################

#
# tktex:mbdefault:  Clicking mouse button 3 over menubutton $mb will invoke
#	      index $index of $menu.
#
proc tktex:mbdefault {mb menu index} {
    bind $mb <ButtonRelease-3> "
     if {\"\[tktex:get_option %W -state\]\" == \"disabled\"} {return} ;
     $menu invoke \"$index\"
    "
}


# tktex:make-menus:  Make the various menu-type buttons.

proc tktex:make-menus {mbar} {

  global TKTEX

# .file:  Select a base file and build the File menu.  Here's what all the
#    variables are:
#
  menubutton .file -textvar TKTEX(file_lbl) -menu .file.m
  set TKTEX(file_lbl) "File <>"
  menu .file.m
  tktex:mbdefault .file .file.m "New File"
  .file.m add command -label "New File" -command {tktex:new-file ""}
  .file.m add separator

# .compile:  Select and run a TeX format.
  menubutton .compile -menu .compile.m
  menu .compile.m
  tktex:mbdefault .compile .compile.m "Run TeX"
  .compile.m add command -label "Run TeX" -command {
    tktex:io "$TKTEX(tex_cmd) $TKTEX(src_file)" interactive
  }
  .compile.m add separator

# .vp:  View and print.
  menubutton .vp -menu .vp.m -text "View/Print"
  menu .vp.m
  tktex:mbdefault .vp .vp.m "View"
  .vp.m add command -label "View" -command {
    tktex:io "$TKTEX(view_cmd) $TKTEX(src_file)" passive
  }
  .vp.m add command -label "Print" -command {
    tktex:io [tktex:build-$TKTEX(print_cmd)-cmd $TKTEX(src_file)] passive
  }
  .vp.m add separator
  .vp.m add command -label "Print options" \
    -command {tktex:$TKTEX(print_cmd)-options}

# .proc:  Miscellaneous (site-dependent) processing (e.g., bibtex, makeindex)
  menubutton .proc -menu .proc.m -text "Processing"
  menu .proc.m

# .help:  Show help files, available format information.
  menubutton .help -menu .help.m -text "Help"
  menu .help.m
  .help.m add command -label "About" -command {tktex:about}
  .help.m add separator
  .help.m add command -label "General" -command {tktex:help-file gen}
  .help.m add command -label "Variables" -command {tktex:help-file vars}
  .help.m add command -label "Show Formats" -command {
      set TKTEX(tmp) [$TKTEX(text_widget) index insert]
      $TKTEX(text_widget) insert end "---------------------------------------\n"
      $TKTEX(text_widget) insert end "           AVAILABLE FORMATS           \n"
      $TKTEX(text_widget) insert end "---------------------------------------\n"
      foreach f [ListFormats] {
  	$TKTEX(text_widget) insert end "$f:\n"
  	$TKTEX(text_widget) insert end "\tLabel:  [lindex $TKTEX(fmts,$f) 0]\n\tCommand:  [lindex $TKTEX(fmts,$f) 1]\n\tHook:  [lindex $TKTEX(fmts,$f) 2]\n"
      }
      $TKTEX(text_widget) tag add readonly $TKTEX(tmp) insert
      $TKTEX(text_widget) yview -pickplace insert
  }
  pack .file .compile .vp .proc .help -in $mbar -side left -padx 5

}


# tktex:make-buttons {mbar}:  Make button-type objects and pack into mbar

proc tktex:make-buttons {mbar} {
  
  global TKTEX
  
  button .options -text "Options" -command {tktex:set-options}
  
  button .clear -text "Clear" -command {
      $TKTEX(text_widget) delete 1.0 end
      update
  }
  
  button .quit -text "Quit" -command {exit}
  
  pack .options .clear .quit \
    -in $mbar -side left -fill x -expand yes
  
}


# tktex:make-text:  Make the text widget.

proc tktex:make-text {t} {
  
  global TKTEX
  
  ScrollText $t {-setgrid 1}
  
}


# tktex:bind-text:  Bindings for the text widget.

proc tktex:bind-text {} {
  
  global TKTEX
  
  if {$TKTEX(tk3)} {
    bind $TKTEX(text_widget) <Return> {
      if {!$TKTEX(interactive)} {return}
      puts $TKTEX(interactive_pid) \
        [$TKTEX(text_widget) get [ROtextPrevReadOnly %W insert]+1c insert]
      flush $TKTEX(interactive_pid)
      if {[ROtextReadOnlyTag %W insert]} return
      %W insert insert \n; %W yview -pickplace insert
    }
  } else {
    bind $TKTEX(text_widget) <Return> {
      if {!$TKTEX(interactive)} {return}
      puts $TKTEX(interactive_pid) \
        [$TKTEX(text_widget) get [ROtextPrevReadOnly %W insert]+1c insert]
      flush $TKTEX(interactive_pid)
    }
  }
  
}


# tktex:bind-entry:  Bindings for entries.  This is only necessary for tk3.x,
#   since tk4.x has reasonable defaults for entry widgets.

proc tktex:bind-entry {} {
  
  global TKTEX
  
# Get arrow keys in Entry widgets to do something useful--scrolling with
# the middle mousebutton doesn't seem to occur naturally in nature.

  if {$TKTEX(tk3)} {
    bind Entry <Left> {
      %W icursor [expr [%W index insert]-1]
      %W view [expr "[%W index insert]-([lindex [%W configure -width] 4]/2)"]
    }
    bind Entry <Right> {
      %W icursor [expr [%W index insert]+1]
      %W view [expr "[%W index insert]-([lindex [%W configure -width] 4]/2)"]
    }
  }
  
}

# #####################
# Build the main window
# #####################

frame .menubar
tktex:make-menus .menubar
tktex:make-buttons .menubar
tktex:make-text .text
set TKTEX(text_widget) [.text text]
tktex:bind-text
tktex:bind-entry

pack .menubar .text -side top -fill both -expand yes
focus $TKTEX(text_widget)
update


# #######################
# Set a bunch of defaults
# #######################

# Widget set
CWinit
set CW(fileSelect,modal) 1

# Read-only tags for text
ROinit

set TKTEX(tex_pid) ""
set TKTEX(base_file) ""
set TKTEX(src_file) ""
set TKTEX(tex_dir) "$env(HOME)"
tktex:var-defaults

# Read in .rc file, if it exists
if {[file exists $TKTEX(lib_dir)/tktex.rc]} {source $TKTEX(lib_dir)/tktex.rc}
if {[file exists $env(HOME)/.tktexrc]} {source $env(HOME)/.tktexrc}

if {$TKTEX(tex_fmt) == ""} {SetFormat TeX}
set TKTEX(printer_name) [lindex $TKTEX(printers) 0]
$TKTEX(text_widget) configure -background $TKTEX(background)
$TKTEX(text_widget) configure -foreground $TKTEX(input_fg)
$TKTEX(text_widget) tag configure readonly -foreground $TKTEX(output_fg)
$TKTEX(text_widget) configure -insertbackground $TKTEX(input_fg)
$TKTEX(text_widget) configure -font $TKTEX(font)

# ########################################
# Parse the argument list, if there is any
# ########################################

for {set i 0} {$i < $argc} {incr i 2} {
  set val [lindex $argv [expr $i+1]]
  
  switch -- [lindex $argv $i] \
    -dir	"set TKTEX(tex_dir) $val" \
    -file	"tktex:new-file $val" \
    default	"puts \"Ignoring unknown option [lindex $argv $i]\""

}

wm title . {TkTeX v2.1}
