;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; LATEX.CMD
;
; microEMACS for Windows macros to give LaTeX functionality
;
; MODIFICATION HISTORY:
; Feb 10 94 Took out readhook line.
; Feb 04 94 Modified for MEW 3.12
; Note that there are still some funny bugs, particularly with
; reference to file locking. If you get funny errors about
; files being in use, try deleting the "._xlk" sub-directories.
; Jan 25 93  Use dviwin as viewer
;
; MEWLaTeX Version 1.0
;
; Original release Jan 11 1993.
;
;    Michael F. Reid <[email protected]>
;    Department of Physics and Astronomy, University of Canterbury
;    Christchurch, New Zealand.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; There are three sections:
; GENERAL
; SPELL-CHECKING
; LATEX
;
; Key bindings and menu bindings are at the end of each section
;
; We begin with variables that must be setup locally by the user.
; As a debug tool we have variable %l-menus-loaded to prevent menus
; from being loaded twice if we edit the file and re-run it.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;                              VARIABLES
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;  GENERAL

set %x-rename "xrename.bat" ; delete and rename, used for backup-save
; if xrename.bat is not in your path, you won't get a backup!

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;  SPELL CHECKING

set %spell-exec "spell.pif"
; using spell.pif allows better control over the spell-checker
; amSpell likes to run full-screen, for example

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;  LaTeX

set %l-file-path "e:\bin\mewin\latex\"
                           ; finish with "\"
                           ; place to look for help and templates
set %l-latex     "latex.pif"
set %l-tex       "tex.pif"
set %l-view      "e:\tex\dviwin\dviwin"
set %l-print     "texprint.pif"
set %l-dvi2ps    "dvi2ps.pif"
set %l-psview    "gs.pif"
set %l-makeindex "makeindx.pif"
set %l-bibtex    "bibtex.pif"

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;           GENERAL COMMANDS
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

set $discmd FALSE

print "[Loading general macros...]"

store-procedure toggle-overwrite ; make Insert key behave "normally"
 set $cmode &bxor $cmode 32
!endm

store-procedure del-blanks   ; use ^Delete to delete to next non-blank
 !while TRUE
   !if &not &seq &chr $curchar " "
     !return
   !endif
   delete-next-character
 !endwhile
!endm

store-procedure insert-date
insert-string $time
!endm

store-procedure save-all-buffers
; This macro saves all the modified buffers to their respective
; files
; Modified by MFR - you could replace the version in emacs.rc
   set %tmp $cbufname
   !while TRUE
       !if &equ $cbflags 2  ;MFR don't try to save unchanged files
           !force save-file
       !endif
       !force next-buffer
       !if &seq %tmp $cbufname
           !return
       !endif
   !endwhile
!endm

store-procedure readhook-proc  ; TeX and bib get C and Wrap modes
; modified by MFR - you could replace the version in emacs.rc
   run extension
   !if &sin "|c|h|cpp|hpp|dlg|def|rc|cmd|" &cat &cat "|" %ext "|"
       add-mode cmode
   !else
       !if &sin "||me|1st|doc|txt|" &cat &cat "|" %ext "|"
           add-mode wrap
       !else
           !if &sin "||tex|bib|" &cat &cat "|" %ext "|"
               add-mode cmode
               add-mode wrap
           !endif
       !endif
   !endif
!endm
; set $readhook readhook-proc ; commented out 10 Feb 94

store-procedure file-split
; split $cfname into %f-dir %f-name %f-ext
; uses %f-tmp1, %f-tmp2, %f-tmp3
   set %f-dir  &low $cfname
   set %f-name ""
   set %f-ext  ""
   set %f-tmp1 &length %f-dir
   set %f-tmp2 &sindex %f-dir "."
   !if &not &equ %f-tmp2 0
       set %f-ext &mid %f-dir &add %f-tmp2 1   &sub %f-tmp1 %f-tmp2
       set %f-dir &mid %f-dir 1              &sub %f-tmp2 1
   !endif
   set %f-tmp1 &length %f-dir
   set %f-tmp2 &sindex %f-dir "\"
   !if &not &equ %f-tmp2 0
     set %f-tmp2 &length %f-dir
     !while &not &sequal "\" &mid %f-dir %f-tmp2 1
        set %f-tmp3 &mid %f-dir %f-tmp2 1
        set %f-tmp2 &sub %f-tmp2 1
     !endwhile
     set %f-name &mid %f-dir &add %f-tmp2 1   &sub %f-tmp1 %f-tmp2
     set %f-dir  &mid %f-dir 1              %f-tmp2
   !endif
   ; print &cat &cat &cat &cat %f-dir "+" %f-name "+" %f-ext
!endm

store-procedure query-save-all
; This macro saves all the modified buffers to their respective
; files, but asks as it goes along
; uses %f-tmp1, %f-tmp2
   set %f-tmp1 $cbufname
   !while TRUE
       !if &equ $cbflags 2
         set %f-tmp2 @&cat &cat "Save " $cbufname " (y/n)? [y]: "
         !if &not &sequal %f-tmp2 "n"
           !force save-file
         !endif
       !endif
       !force next-buffer
       !if &seq %f-tmp1 $cbufname
           !return
       !endif
   !endwhile
!endm

store-procedure backup-save
; renames then saves, like gnuemcs x.y -> x.~y
; uses %f-tmp1, %f-tmp2, %f-tmp3
; x-rename is a batch file name. Batch file contains:
; del     %2
; rename  %1 %2
 !if &not &equ $cbflags 2                          ; needs saving?
   print "[File not modified]"
 !else
   file-split
   set %f-tmp1 $cbufname                             ; old buffer
   set %f-tmp2 $cfname                               ; old filename
   set %f-tmp3 &cat &cat &cat %f-name ".~~" %f-ext   ; backup filename
   print "[Backing up...]"
   ; 1 forces it to wait for completion
   1 shell-command &cat &cat &cat &cat %x-rename " " %f-tmp2 " " %f-tmp3
   save-file
 !endif
!endm

store-procedure s-insert-file
; insert file, keeping point at same place, like gnu emacs
; uses %s-tmp
 set %s-tmp $yankflag
 set $yankflag TRUE
 !force execute-named-command insert-file
 set $yankflag %s-tmp
!endm

store-procedure force-current-directory
; make sure we are using directory of current buffer
 !if &not &seq $cfname "" ; e.g. main has no file name
   !force find-file $cfname ; force current directory
 !endif
!endm

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GENERAL MENU ADDITIONS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

bind-to-key set-mark          ^@    ; gnu binding ; Doesn't work for 3.12
  ; This is because ^@ means ^-space --- see documentation :-(

macro-to-key toggle-overwrite FNC   ; Insert key
macro-to-key del-blanks       FN^D  ; ^Delete
macro-to-key save-all-buffers M-^Z  ; bind to ESC Ctrl+Z
macro-to-key backup-save M-S        ;
macro-to-key s-insert-file ^XI      ; gnu binding
macro-to-key s-insert-file ^X^I     ; old insert-file binding

!if &not %l-menus-loaded
 ; change from insert-file to s-insert-file
 unbind-menu ">&File>&Insert..."
 macro-to-menu s-insert-file ">&File>&Insert...@2"
 ; add backup-save to File menu
 macro-to-menu backup-save ">&File>Back&up and Save@6"

 ; add insert-date to Edit menu
 macro-to-menu insert-date ">&Edit>Insert &Date@3"

 ; add clip-region to menu under Edit/Region
 bind-to-menu clip-region ">&Edit>&Region>To Clip&board@0"
 bind-to-menu    nop             "-"
!endif

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;     SPELL-CHECKING COMMANDS
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Run spell checker on current buffer and re-read the file.
; The spell-checker is a DOS program stored in %spell-exec

write-message "[Loading Spell macros...]"


store-procedure spell-buffer
; uses s-tmp1
 save-file
 run force-current-directory
 ; the 1 forces it to wait for completion
 1 execute-program &cat &cat %spell-exec " " $cfname
 set %s-tmp1 @"[Spell] (Wait until completion) Re-Read file (y/n)? [y]: "
 !if &not &sequal &lower %s-tmp1 "n"
    read-file $cfname
 !endif
!endm

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SPELL-CHECKING MENU ADDITIONS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

!if &not %l-menus-loaded
 macro-to-menu spell-buffer ">S&pell@4>&Buffer"
!endif

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;                  LaTeX COMMANDS
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


print "[Loading LaTeX macros...]"

set $fmtlead "\ %"     ; to prevent formatting of TeX stuff. Note blank!
set $paralead "\% ~t"

set %l-log-screen  "LaTeX LOG"
set %l-log-buffer  "_texlog"
set %l-fn        "?"  ; file name being processed (no extension)
set %l-prog      "?"  ; program being used
set %l-ext       "?"  ; extension for program (tex, dvi, etc.)
set %l-log       "?"  ; logfile extension

store-procedure set-latex-fn
; uses %l-fn, %l-tmp1
; set LaTeX file name
; default is current buffer - remembers from run to run.
   !if &sequ %l-fn "?"
        run file-split
        set %l-fn %f-name
   !endif
   set %l-tmp1 ""
   set %l-tmp1 @&cat &cat &cat %l-prog " Filename (^G aborts )[" %l-fn "]: "
   !if &not &equ 0 &sindex %l-tmp1  "[" ; Hack for ^G
     print [Abort]
     set %l-fn "?"
     set %l-tmp1 ""
     !return
   !endif
   !if &not &equal 0 &length %l-tmp1
     set %l-fn %l-tmp1
   !endif
   print &cat &cat %l-prog "file name: " %l-fn
!endm

store-procedure l-run
; uses %l-fn
; %l-prog and %l-ext must be set before running this
   run query-save-all
   run set-latex-fn
   run force-current-directory
   !if &seq %l-fn "?" ; no file
     !return
   !endif
   !if &not &exist &cat &cat %l-fn "." %l-ext
     print &cat &cat &cat &cat "[No file " %l-fn "." %l-ext "]"
     set %l-fn "?"
   !else
     ; kill old log
     !if &seq $scrname %l-log-screen      ; current screen is log
       !force delete-buffer %l-log-buffer ; kill buffer
       !force select-buffer %l-log-buffer
       add-mode view
     !else                                ; current screen is not log
       !force delete-screen %l-log-screen ; kill screen and buffer
       !force delete-buffer %l-log-buffer
     !endif
     print &cat &cat &cat &cat "[" %l-prog " " %l-fn "]"
     !if &seq %l-ext "ps"                 ; gs requires the ".ps"
       execute-program &cat &cat &cat %l-prog " " %l-fn ".ps"
     !else
       execute-program &cat &cat %l-prog " " %l-fn
     !endif
   !endif
!endm

store-procedure run-latex
 set %l-prog %l-latex
 set %l-ext  "tex"
 set %l-log  "log"
 run l-run
!endm

store-procedure run-tex
 set %l-prog %l-tex
 set %l-ext  "tex"
 set %l-log  "log"
 run l-run
!endm

store-procedure run-bibtex
 set %l-prog %l-bibtex
 set %l-ext  "aux"
 set %l-log  "blg"
 run l-run
!endm

store-procedure run-makeindex
 set %l-prog %l-makeindex
 set %l-ext  "aux"
 set %l-log  "ilg"
 run l-run
!endm

store-procedure print-latex
 set %l-prog %l-print
 set %l-ext  "dvi"
 set %l-log  "?"
 run l-run
!endm

store-procedure dvi2ps-latex
 set %l-prog %l-dvi2ps
 set %l-ext  "dvi"
 set %l-log  "?"
 run l-run
!endm

store-procedure psview-latex
 set %l-prog %l-psview
 set %l-ext  "ps"
 set %l-log  "?"
 run l-run
!endm

store-procedure view-latex
 set %l-prog %l-view
 set %l-ext "dvi"
 run set-latex-fn
 run force-current-directory
 !if &not &exist &cat %l-fn ".dvi"
     run file-split
     print &cat &cat "[No file " %l-fn ".dvi]"
     set %l-fn "?"
 !else
   print &cat &cat "[view " %l-fn "]"
   execute-program &cat &cat &cat %l-view " " %l-fn ".dvi"
 !endif
!endm

store-procedure view-charset  ; View LaTeX character set
 !if &not &exist &cat %l-file-path "charset.dvi"
    print &cat &cat "[No file " %l-file-path "charset.dvi]"
 !else
   print &cat &cat "[view " %l-file-path  "charset.dvi]"
   execute-program &cat &cat &cat %l-view " " %l-file-path "charset.dvi"
 !endif
!endm

store-procedure l-display-log
 run force-current-directory
 set %l-tmp1 &cat &cat %l-fn "." %l-log
 set %l-tmp2 @&cat &cat " Read Log (^G aborts )[" %l-tmp1 "]: "
 !if &not &equ 0 &sindex %l-tmp2  "[" ; Hack for ^G
   print "[Abort]"
   !return
 !endif
 !if &not &equ &len %l-tmp2 0
   set %l-tmp1 %l-tmp2
 !endif
 !if &not &exist %l-tmp1
   print &cat &cat "[No file " %l-tmp1 "]"
   !return
 !endif
 !force find-screen   %l-log-screen
 !force select-buffer %l-log-buffer
 !force read-file %l-tmp1
 add-mode view
 print "[F4 to find error]"
!endm

store-procedure l-find-error
; Modified for 3.12 by turning $discmd on and off... 4 Feb 94
; parse LaTeX log-file for errors
; %e-upto is line in log-file we are up to
; %e-line and %e-file are where the errors are
; uses %l-tmp1
 print "[Searching for LaTeX error]"
 set $discmd FALSE
 find-screen   %l-log-screen
 select-buffer %l-log-buffer
 set $discmd TRUE      ; turning it on seems essential
 !if &seq $cfname ""   ; read log if there is none
   l-display-log
   update-screen
   print "[Searching for LaTeX error]"
 !endif
 set $discmd FALSE
 !force search-forward "~nl."  ; find next error
 !if &not $status
   print "[No more errors]"
   !return
 !endif
 update-screen
 set %e-upto $curline
 set-mark
 end-of-word
 set %e-line $region
 set %e-paren 1              ; number of parentheses - count down to 0
 !force search-reverse "~!"             ; search back for file name
 !while TRUE
   !force previous-line
   !if &not $status
     print "[Cannot locate file name]"
     !return
   !endif
   beginning-of-line
   !if &seq &chr $curchar "?"       ; skip error listing
      !force search-reverse "~n!"
      !force next-line
   !else
     !if &seq &chr $curchar "."     ; TeX warnings
       !force search-reverse "~n[]"
     !else
      !if &not &seq &mid $line 1 15 "LaTeX Warning: "
        !if &not &seq &chr $curchar "\"
          !if &not &and &equ &sindex $line "(" 0 &equ &sindex $line ")" 0
          ; examine the line for brackets
            ; update-screen
            ; set %dummy @&cat &cat &cat "examining line" $line " " %e-paren

            end-of-line
            !while &not &equ $curcol 0
              backward-character
              !if &seq &chr $curchar "("
                set %e-paren &sub %e-paren 1
              !endif
              !if &seq &chr $curchar ")"
                set %e-paren &add %e-paren 1
              !endif
              !if &equ %e-paren 0
                !break
              !endif
            !endwhile
            !if &equ %e-paren 0
              !break
            !endif
          !endif ; end of examine the line for brackets
        !endif
      !endif
     !endif
   !endif
 !endwhile      ; should now be at filename
 !if &not &seq &chr $curchar "("
   print "[Cannot locate file name]"
   !return
 !endif
 forward-character
 set-mark
 end-of-line
 set %e-file $region
 set %l-tmp1 &sindex %e-file " "    ; always a blank before [n] etc.
 !if &not &equ 0 %l-tmp1
   set %e-file &mid %e-file 1 &sub %l-tmp1 1
 !endif
 goto-line %e-upto
 !force next-line
 beginning-of-line
 set $discmd TRUE
 update-screen
 print &cat &cat %e-file " " %e-line
 set %l-tmp1 @&cat &cat &cat "Enter for error: " %e-file " " %e-line
 set $discmd FALSE
 !force find-file %e-file
 set %l-tmp $cbufname       ; juggle the buffers - must be easier way!
 !force find-screen   %l-tmp
 !force select-buffer %l-tmp
 !force find-screen   %l-log-screen
 !force select-buffer %l-log-buffer
 !force find-screen   %l-tmp
 !if &not $status
   set $discmd TRUE
   print &cat &cat "[Cannot find file " %e-file "]"
   set $discmd FALSE
 !endif
 !force goto-line %e-line
 set $discmd TRUE
 print "[F4 for next error]"
!endm



store-procedure clear-latex-file
 set %l-fn "?"
!endm

; superscripts/subscripts

store-procedure superscript-b
 insert-string "^{}"
 backward-character
!endm

store-procedure subscript-b
 insert-string "_{}"
 backward-character
!endm

; useful pairs of delimiters

store-procedure curly-b
 insert-string "{}"
 backward-character
!endm

store-procedure round-b
 insert-string "()"
 backward-character
!endm

store-procedure square-b
 insert-string "[]"
 backward-character
!endm

store-procedure angle-b
 insert-string "\langle\rangle"
 7 backward-character
!endm

store-procedure vert-b
 insert-string "||"
 backward-character
!endm

store-procedure d-vert-b
 insert-string "\|\|"
 2 backward-character
!endm

store-procedure quote-b
 insert-string "``''"
 backward-character
 backward-character
!endm

store-procedure slash-curly-b
 insert-string "\{\}"
 2 backward-character
!endm

store-procedure slash-round-b
 insert-string "\(\)"
 2 backward-character
!endm

store-procedure slash-square-b
 insert-string "\[\]"
 2 backward-character
!endm

store-procedure dollar-b
 insert-string "$$"
 backward-character
!endm

store-procedure double-dollar-b
 insert-string "$$$$"
 2 backward-character
!endm

store-procedure sizable-curly-b
 insert-string "\left\{\right\}"
 8 backward-character
!endm

store-procedure sizable-square-b
 insert-string "\left[\right]"
 7 backward-character
!endm

store-procedure sizable-round-b
 insert-string "\left(\right)"
 7 backward-character
!endm

store-procedure sizable-angle-b
 insert-string "\left\langle\right\rangle"
 13 backward-character
!endm

store-procedure sizable-vert-b
 insert-string "\left|\right|"
 7 backward-character
!endm

store-procedure sizable-d-vert-b
 insert-string "\left\|\right\|"
 8 backward-character
!endm

set %p-doline FALSE   ; default is to do a "word"
set %p-gotop  TRUE    ; default is to go to top of file
                     ; other choices may be useful

; store the general motion commands for position-cursor
; in %motion-c1 and %motion-c2
; NOTE: Too long a string crashes the program !!
set %motion-c1               "!forward-character!backward-character!"
set %motion-c1 &cat %motion-c1 "next-line!previous-line!"
set %motion-c1 &cat %motion-c1 "beginning-of-line!end-of-line!"
set %motion-c2                "!beginning-of-file!end-of-file!"
set %motion-c2 &cat %motion-c2 "end-of-word!previous-word!"
set %motion-c2 &cat %motion-c2 "next-page!previous-page!"

store-procedure position-cursor
; Uses %p-tmp %p-tmp-t %p-tmp-l.
; if %p-gotop make sure we are at top of file.
; Use arrow, paging keys, mouse, or search to position cursor
; OR type into %p-tmp-t
; Enter terminates it, C-G aborts.
; %p-tmp-t is not blank, return it in %p-tmp,
; else if $curcol!=0 and $curline!=1 return blank-delimited string
; (not "word") at current point. If %p-doline get whole line.
 !if %p-gotop
   set $curcol  0
   set $curline 1
 !endif
 set %p-tmp ""
 set %p-tmp-t ""
 !while TRUE               ; break out with newline
   print &cat "[Type, or Select, then Enter (^G aborts)]: " %p-tmp-t
   update-screen
   set %p-tmp &gtcmd
   !if &equ &len %p-tmp 1               ; Then it's a printable character
     set %p-tmp-t &cat %p-tmp-t %p-tmp
   !else
     set %p-tmp &bind %p-tmp              ; translate command
     !if &seq %p-tmp "delete-previous-character" ; delete last character
       set %p-tmp-l &len %p-tmp-t
       !if &greater %p-tmp-l 0
         set %p-tmp-t &mid %p-tmp-t 1 &sub %p-tmp-l 1
       !endif
     !else
       ; print %p-tmp
       !if &seq %p-tmp newline  ; break out with newline
         !break
       !endif
       !if &seq %p-tmp abort-command  ; break out with ^G
         !break
       !endif
       !if &not &seq %p-tmp ERROR ; if valid command
         !while TRUE              ; break out if recognized motion key
                                  ; first look for general motion
           !if &not &equ 0 &sindex %motion-c1 &cat &cat "!" %p-tmp "!"
             !force %p-tmp
             !break
           !endif
           !if &not &equ 0 &sindex %motion-c2 &cat &cat "!" %p-tmp "!"
             !force %p-tmp
             !break
           !endif
           !if &seq %p-tmp [MSleft-down]      ; mouse strokes
             !force run MSleft-down
             !break
           !endif
           !if &seq %p-tmp [MSleft-up]
             !force run MSleft-up
             !break
           !endif
           !if &seq %p-tmp search-forward     ; searching
             execute-named-command search-forward
           !endif
           !if &seq %p-tmp search-reverse
             execute-named-command search-reverse
           !endif
           !break              ; break if we didnt get anything
         !endwhile             ; test for motion commands
       !endif ; not ERROR
     !endif
   !endif
   update-screen
 !endwhile             ; test for return
 !if &seq %p-tmp abort-command ; return nothing if aborted
   set %p-tmp ""
 !else
   !if &greater &len %p-tmp-t 0
     set %p-tmp %p-tmp-t
   !else
    !if &and &equ $curline 1 &equ $curcol 0
      set %p-tmp ""
    !else
      !if %p-doline  ; copy line
        beginning-of-line
        !while &and &equ &chr $curchar " " &not &equ $curcol $lwidth
          forward-character
        !endwhile
        set-mark
        end-of-line
      !else         ; copy word
        !while &and &not &seq &chr $curchar " " &not &equ $curcol 0
          backward-character
        !endwhile
        !if &seq &chr $curchar " "
          forward-character
        !endif
        set-mark
        !while &and &not &seq &chr $curchar " " &not &equ $curcol $lwidth
          forward-character
        !endwhile
      !endif
      set %p-tmp $region
    !endif
  !endif
 !endif
 ; print %p-tmp
!endm

store-procedure get-help-word
; uses %h-oldfile, %h-file, %h-buffer
; display file %h-file and return a word using position-cursor
; word is returned in %p-tmp
 set %h-oldfile $cfname
 !if &not &exist &cat %l-file-path %h-file
   print &cat &cat &cat "[No file " %l-file-path %h-file "]"
   set %p-tmp "ERROR"
   !return
 !endif
 find-file &cat %l-file-path %h-file
 add-mode VIEW
 update-screen
 run position-cursor
 set %h-buffer $cbufname
 !force find-file %h-oldfile
 !force delete-buffer %h-buffer
!endm

store-procedure l-insert-word
; Insert command from file %h-file
; If it has a {, position after the first one.
; Used by many of below command, but some have to add things, so
; do similar things themselves.
 run get-help-word
 !if &seq %p-tmp "ERROR"
   !return
 !endif
 set %l-tmp1 %p-tmp
 ; print %l-tmp1
 !if &not &equ &len %l-tmp1 0
   insert-string &cat %l-tmp1
   set %l-tmp2 &sindex %l-tmp1 "{"
   !if &not &equ %l-tmp2 0
     set %l-tmp3 &sub &len %l-tmp1 %l-tmp2
     !force %l-tmp3 backward-character
   !endif
 !endif
!endm

store-procedure l-env-pair
; uses %l-tmp1, %p-tmp
; create a LaTeX environment from user input
 set %h-file "environ.lh"
 run get-help-word
 !if &seq %p-tmp "ERROR"
   !return
 !endif
 set %l-tmp1 %p-tmp
 !if &not &equ &len %l-tmp1 0
    2 open-line
    insert-string &cat &cat "\begin{" %l-tmp1 "}"
    !if &seq %l-tmp1 "array"
      insert-string  "{lrc}"
    !endif
    !if &seq %l-tmp1 "list"
      insert-string  "{labeling}{spacing}"
    !endif
    !if &seq %l-tmp1 "minipage"
      insert-string  "[pos]{vsize}"
    !endif
    !if &seq %l-tmp1 "picture"
      insert-string  "(x,y)(xl,yl)"
    !endif
    !if &seq %l-tmp1 "tabular"
      insert-string  "{lrc}"
    !endif
    !if &seq %l-tmp1 "thebibliography"
      insert-string  "{99}"
    !endif
    2 next-line
    insert-string &cat &cat "\end{" %l-tmp1 "}"
    previous-line
 !endif
!endm

store-procedure l-heading
; uses %h-file, %l-tmp1, %p-tmp
; create a LaTeX heading from user input
 set %h-file "headings.lh"
 run get-help-word
 !if &seq %p-tmp "ERROR"
   !return
 !endif
 set %l-tmp1 %p-tmp
 ; print %l-tmp1
 !if &not &equ &len %l-tmp1 0
    insert-string &cat &cat "\" %l-tmp1 "{}"
    backward-character
 !endif
!endm

store-procedure l-template
; LaTeX templates
; uses %l-tmp1, %l-tmp2, %h-file, %p-tmp
 set %h-file "ltemp.lh"
 run get-help-word
 !if &seq %p-tmp "ERROR"
   !return
 !endif
 set %l-tmp1 %p-tmp
 !if &not &equ &len %l-tmp1 0
   set %l-tmp1 &cat &cat %l-file-path %l-tmp1 ".lt"
   !if &not &exist %l-tmp1
     print &cat &cat &cat "[No file " %l-tmp1 "]"
   !else
     set %l-tmp2 $yankflag
     set $yankflag TRUE    ; keep point at start of included file
     insert-file %l-tmp1
     set $yankflag %l-tmp2
   !endif
 !endif
!endm

store-procedure b-template
; BibTeX templates
; uses %l-tmp1, %l-tmp2, %h-file, %p-tmp
 set %h-file "btemp.lh"
 run get-help-word
 !if &seq %p-tmp "ERROR"
   !return
 !endif
 set %l-tmp1 %p-tmp
 !if &not &equ &len %l-tmp1 0
   set %l-tmp1 &cat &cat %l-file-path %l-tmp1 ".bt"
   !if &not &exist %l-tmp1
     print &cat &cat &cat "[No file " %l-file-path %l-tmp1 "]"
   !else
     set %l-tmp2 $yankflag
     set $yankflag TRUE    ; keep point at start of included file
     insert-file %l-tmp1
     set $yankflag %l-tmp2
     end-of-line
     backward-character
   !endif
 !endif
!endm

store-procedure l-misc
; Miscellaneous LaTeX commands
 set %h-file "misc.lh"
 run l-insert-word
!endm

store-procedure l-taccents
; Text accents
 set %h-file "taccents.lh"
 run l-insert-word
!endm

store-procedure l-tspecial
; special sybols
 set %h-file "tspecial.lh"
 run l-insert-word
!endm

store-procedure l-tforeign
; foreign symbols
 set %h-file "tforeign.lh"
 run l-insert-word
!endm

store-procedure l-maccents
; math accents
 set %h-file "maccents.lh"
 run l-insert-word
!endm

store-procedure l-greek
; greek letters
 set %h-file "greek.lh"
 run l-insert-word
!endm

store-procedure l-mbinops
; math binary operators
 set %h-file "mbinops.lh"
 run l-insert-word
!endm

store-procedure l-mrel
; math relations
 set %h-file "mrel.lh"
 run l-insert-word
!endm

store-procedure l-marrow
; math arrows
 set %h-file "marrow.lh"
 run l-insert-word
!endm

store-procedure l-mmisc
; math miscellaneous
 set %h-file "mmisc.lh"
 run l-insert-word
!endm

store-procedure l-mloglike
; math loglike
 set %h-file "mloglike.lh"
 run l-insert-word
!endm

store-procedure l-mdelim
; math delimiters
 set %h-file "mdelim.lh"
 run l-insert-word
!endm

store-procedure l-mvarsym
; math variable-sized symbols
 set %h-file "mvarsym.lh"
 run l-insert-word
!endm

store-procedure l-mline
; math overline/underline
 set %h-file "mline.lh"
 run l-insert-word
!endm

store-procedure latex-help
 help-engine &cat %l-file-path latex.hlp
!endm

store-procedure search-latex-help
; uses %s-tmp
; pull keyword off the current file and search help.
; only works for exact match.
 !force end-of-word
 set-mark
 !force previous-word
 set %s-tmp @&cat &cat "Search Help for [" $region "]: "
 !if &equ &len %s-tmp 0
   set %s-tmp $region
 !endif
 help-engine &cat %l-file-path latex.hlp
 help-engine &cat %l-file-path latex.hlp  %s-tmp
 ; note that there are two parameters to help engine in this case
 print &cat &cat "[Searching help file for " %s-tmp "]"
!endm

store-procedure interface-help
 help-engine &cat %l-file-path "interfac.hlp"
!endm

store-procedure installation-help
 !force find-screen "Installation Help"
 !force find-file &cat %l-file-path mewlatex.txt
 add-mode view
!endm

store-procedure tex-info
; TeX information files, e.g. FAQ
; You will want to change texinfo.lh for you local setup
 set %h-file "texinfo.lh"
 run get-help-word
 !if &seq %p-tmp "ERROR"
   !return
 !endif
 !if &not &equ &len %p-tmp 0
   !if &not &exist %p-tmp
     print &cat &cat "[No file " %p-tmp "]"
   !else
     !force find-screen &cat "Information: "%p-tmp
     !force find-file   %p-tmp
     add-mode view
   !endif
 !endif
!endm

store-procedure clean-bibitem
; get rid of pairs of quotes from bibTeX item.
; only makes sense for a .bib file.
; NOTE!: assumes the format in the template files, i.e.
; one item per line, and the closing } on an separate line.
 set $discmd FALSE
 !force search-reverse "@"
 beginning-of-line
 !if &not &sequal "@" &mid $line 1 1
   !return
 !endif
 !while TRUE
   !force next-line
   !if &not $status
     !break
   !endif
   !if &sequal "@" &mid $line 1 1
     !break
   !endif
   !if &not &equ 0 &sindex $line "~"~""
     1 kill-to-end-of-line
     !force previous-line
   !endif
 !endwhile
 !force backward-character
 !if &not $status
   !return
 !endif
 !while &or &seq &chr $curchar " " &seq &chr $curchar "~n"
   !force backward-character
   !if &not $status
     !return
   !endif
 !endwhile
 !if &not &seq &chr $curchar "}"
   !return
 !endif
 !force backward-character
 !while &or &seq &chr $curchar " " &seq &chr $curchar "~n"
   !force backward-character
   !if &not $status
     !return
   !endif
 !endwhile
 !if &seq &chr $curchar ","
   delete-next-character
 !endif
 ; clear-message-line
 set $discmd TRUE
!endm

store-procedure clean-bibfile
; run clean-bib-item on whole file
 run query-save-all
 set %l-tmp1 @"Do you really want to clean your entire bibTeX file? [n]: "
 !if &not &sequal &lower %l-tmp1 "y"
    !return
 !endif
 print "[Cleaning BibTeX file. This may take a while...]"
 set $discmd FALSE
 beginning-of-file
 !while TRUE
   !force search-forward "@"
   !if &not $status
     !break
   !endif
   run clean-bibitem
   ; update-screen
   !force next-line
   end-of-line
 !endwhile
 beginning-of-file
 open-line
 insert-string "BibFile Cleaned: "
 run insert-date
 print "[Please check this has not messed up your file!]"
 set $discmd TRUE
!endm

store-procedure get-bib-key
; get bibkey from current line, assuming "@name{key," synatax
 set %b-key ""
 !force search-forward "{"
 !if &not $status
   !return
 !endif
 set-mark
 !force end-of-word
 set %b-key $region
 ; print %b-key
!endm

store-procedure find-min-key
; return %m-key and %m-pos
 set %m-key ""
 set %m-pos 0
 !force search-forward "@"
 !if &not $status
   !return
 !endif
 run get-bib-key
 set %m-key %b-key
 set %m-pos $curline
 !while TRUE
   !force search-forward "@"
   !if &not $status
     !break
   !endif
   run get-bib-key
   !if &sless %b-key %m-key
     set %m-key %b-key
     set %m-pos $curline
   !endif
 !endwhile
 ; print &cat &cat %m-key " " %m-pos
!endm

store-procedure sort-bibfile
; sort a .bib file on the cite key
; uses %s-pos to remember the current position
; works through the file, doing an insertion sort on the  %b-key
;
 run query-save-all
 set %l-tmp1 @"Do you really want to sort your entire bibTeX file? [n]: "
 !if &not &sequal &lower %l-tmp1 "y"
    !return
 !endif
 print "[Sorting BibTeX file. This may take a while...]"
 set $discmd FALSE
 beginning-of-file
 !while TRUE
   !force search-forward "@"
   !if &not $status
     !break
   !endif
   set %s-pos $curline
   beginning-of-line
   run find-min-key
   ; update-screen
   ; set %dummy @&cat &cat &cat %s-pos " " %m-pos
   !if &greater %m-pos %s-pos
      goto-line %m-pos
      beginning-of-line
      set-mark
      end-of-line
      !force search-forward "@"
      !if &not $status
         end-of-file
      !else
         beginning-of-line
      !endif
      kill-region
      goto-line %s-pos
      yank
   !endif
   goto-line %s-pos
   end-of-line
 !endwhile
 beginning-of-file
 open-line
 insert-string "BibFile Sorted:  "
 run insert-date
 print "[Please check this has not messed up your file!]"
 set $discmd TRUE
!endm

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; LaTeX MENU ADDITIONS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; help
macro-to-key latex-help        FN1
macro-to-key search-latex-help FN2

; debug
macro-to-key l-display-log     FN3
macro-to-key l-find-error      FN4

; environment pair
macro-to-key l-env-pair        A-V

; super/subscripts
macro-to-key superscript-b     A-^   ; ^{}
macro-to-key subscript-b       A-_   ; _{}

; delimiter pairs -- you may want to personalize these key-bindings
macro-to-key curly-b           A-{   ; {}
macro-to-key round-b           A-(   ; ()
macro-to-key square-b          A-[   ; []
macro-to-key angle-b           A-<   ; \langle\rangle
macro-to-key vert-b            A-|   ; ||
macro-to-key d-vert-b          A-\   ; \|\|
macro-to-key quote-b           A-"   ; ``''
macro-to-key slash-curly-b     A-}   ; \{\}
macro-to-key slash-round-b     A-)   ; \(\)
macro-to-key slash-square-b    A-]   ; \{\}
macro-to-key dollar-b          A-$   ; $$
macro-to-key double-dollar-b   ^XA-$ ; $$$$
macro-to-key sizable-curly-b   ^XA-{ ; \left\{\right\}
macro-to-key sizable-square-b  ^XA-[ ; \left[\right]
macro-to-key sizable-round-b   ^XA-( ; \left(\right)
macro-to-key sizable-angle-b   ^XA-< ; \left\langle\right\rangle
macro-to-key sizable-vert-b    ^XA-| ; \left|\right|
macro-to-key sizable-d-vert-b  ^XA-\ ; \left\|\right\|

!if &not %l-menus-loaded
 print "[Setting up LaTeX Menus]"
 macro-to-menu l-template ">&TeX@5>LaTeX &Input>&Templates"
 macro-to-menu l-heading                       "&Headings"
 macro-to-menu l-env-pair                      "En&vironments"

 macro-to-menu dollar-b  ">&TeX>LaTeX &Input>Math E&nvironments@3>$ $"
 macro-to-menu double-dollar-b                                   "$$ $$"
 macro-to-menu slash-round-b                                     "\( \)"
 macro-to-menu slash-square-b                                    "\[ \]"


 macro-to-menu curly-b   ">&TeX>LaTeX &Input>&Brackets@4>{ }"
 macro-to-menu slash-curly-b                            "\{ \}"
 macro-to-menu round-b                                  "( )"
 macro-to-menu square-b                                 "[ ]"
 macro-to-menu angle-b                      "\langle \rangle"
 macro-to-menu vert-b                                   "| |"
 macro-to-menu d-vert-b                                 "\| \|"
 macro-to-menu quote-b                                  "`` ''"

 macro-to-menu l-taccents ">&TeX>LaTeX &Input>Te&xt@5>&Accents"
 macro-to-menu l-tspecial                    "&Special Symbols"
 macro-to-menu l-tforeign                    "&Foreign Symbols"

 macro-to-menu superscript-b ">&TeX>LaTeX &Input>&Math@6>&Super/Subscripts>^{}"
 macro-to-menu subscript-b                                          "_{}"

 macro-to-menu sizable-curly-b ">&TeX>LaTeX &Input>&Math>Variable &Brackets@1>left\{ \right\}"
 macro-to-menu sizable-round-b                "left( \right)"
 macro-to-menu sizable-square-b               "left[ \right]"
 macro-to-menu sizable-angle-b   "\left\langle \right\rangle"
 macro-to-menu sizable-vert-b                 "left| \right|"
 macro-to-menu sizable-d-vert-b             "left\| \right\|"

 macro-to-menu l-maccents  ">&TeX>LaTeX &Input>&Math>&Accents@2"
 macro-to-menu l-greek                              "&Greek"
 macro-to-menu l-mbinops                            "Binary &Operators"
 macro-to-menu l-mrel                               "&Relation Symbols"
 macro-to-menu l-marrow                             "Arro&ws"
 macro-to-menu l-mmisc                              "&Miscellanous"
 macro-to-menu l-mloglike                           "&Log Like"
 macro-to-menu l-mdelim                             "&Delimiters"
 macro-to-menu l-mvarsym                            "&Variable Symbols"
 macro-to-menu l-mline                              "Over/&Under Line"

 macro-to-menu l-misc     ">&TeX>LaTeX &Input>Mis&cellaneous@7"

 macro-to-menu b-template ">&TeX>&BibTeX Input@1>&Templates"
 macro-to-menu clean-bibitem                     "Clean Bib&Item"
 macro-to-menu clean-bibfile                     "Clean Bib&File"
 macro-to-menu sort-bibfile                      "&Sort BibFile"

 macro-to-menu run-latex ">&TeX>E&xecute@2>&LaTeX"
 macro-to-menu run-tex                    "&TeX"
 macro-to-menu view-latex                 "&View"
 macro-to-menu dvi2ps-latex               "&DVI to PostScript"
 macro-to-menu psview-latex               "Post&Script Preview"
 macro-to-menu print-latex                "&Print"
 macro-to-menu run-bibtex                 "&BibTeX"
 macro-to-menu run-makeindex              "&MakeIndex"
 macro-to-menu clear-latex-file           "&Clear Filename"

 macro-to-menu l-display-log ">&TeX>&Debug@3>&Read Logfile"
 macro-to-menu l-find-error                 "&Find Next Error"

 macro-to-menu latex-help ">&TeX>&Help@4>&LaTeX Commands"
 macro-to-menu search-latex-help        "&Search LaTeX Commands"
 macro-to-menu view-charset             "&Character Set"
 macro-to-menu tex-info                 "&TeX Information"
 macro-to-menu interface-help           "&MicroEMACS Interface"
 macro-to-menu installation-help        "MicroEMACS I&nstallation"
!endif

set %l-menus-loaded "TRUE" ; so menu commands are only done once.
print "[LaTeX Interface Loaded]"
set $discmd TRUE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;