; Last updated from parent file: 2006 Jul 25 

; This wants to be a self contained version of eltex 
; Lines modified from { bibliotek.eltex.el } are indicated by { ;! }

; USAGE Byte-compile this file in a full environment.  The resulting .elc file
; should be portable without need of all the macro files etc that went into its
; compilation.  That is, anyone with emacs (and the `cl' package that comes
; with it) should be able to use it.

; For more information the user should load eltex.standalone.elc and read the
; documentation for `eltex-do' etc. using the command `describe-function'

                        ; Time-stamp:<2006-Jul-25 01:15:17 17605.43237 at umoja.phy.syr.edu> 
;: Terminology
;
; In something like  (E::abs-val b) 
;  we call "abs-val" the TAG
;  we call "b" the CODA
;  we call "(E::" the OPENING
;  we call "abs-val b" the NAME (yuk)
;  we call the whole thing "(E::abs-val b)" the EQUATION-CONSTRUCT

;: Some variables used
;
;   eltex-ref-open "[R::"	; token which opens citations
;   eltex-eqn-open "(E::"       ; token which opens equation reference
;   eltex-ref-offset   1	; begins numbering references with this
;   eltex-eqn-offset   1	; begins numbering equations with this
;   eltex-footnote-indicators
;
;   *ref-dictionary*
;   *eqn-dictionary*
;   *eltex-draftmode*		; will be used to turn on/off draftmode

;: Functions defined herein ((C) means a user command) 
;
;   del-blanks-fwd  
;   del-blanks-bwd
;   stably-remove-duplicates
;
;   within-equation-p
;   within-comment-p
;   to-next-open
;
;   eltex-do (C)
;   eltex-do-draftmode (C)
;
;   ref (C)
;   eqn (C)
;   footnote (C)
;
;   eltex-number-refs 
;   eltex-number-eqs
;
;   eltex-replace-tags
;   eltex-provide-footnote-indicators
;
;   eltex-show-refs/eltex-list-refs (C)
;   eltex-show-eqs/eltex-list-eqs   (C)
;   eltex-show-dictionary

;: Preparations

;; (require 'preparations "~/lisp/preparations.el")  ;! sa
(require 'cl)					   ;! [comment IN for sa]

(provide 'eltex)

;: Global variables

(defvar eltex-ref-open "[R::"  "* token that opens reference names")

(defvar eltex-eqn-open "(E::"  "* token that opens equation names")

(defvar eltex-footnote-indicators '("$^\\star$" "$^\\dagger$" "$^\\flat$")
  "* a list of the symbols to be used cyclically to indicate footnotes")

; (setqq eltex-footnote-indicators ("$^\\star$" "$^\\dagger$" "$^\\flat$"))

(defvar *ref-dictionary* nil "\
 After a call to `eltex-number-refs' this variable holds an ``alist''
 mapping each reference-tag to its number.  To see this dictionary in 
 readable form call `eltex-list-refs' ")

(defvar *eqn-dictionary*  nil  
  "\
 After a call to `eltex-number-eqs' this variable holds an ``alist''
 mapping  each equation tag to its number.  To see the dictionary 
 in readable form say `eltex-list-eqs'  ")

(defvar *eltex-draftmode* nil)

;: The functions

(defun stably-remove-duplicates (L)
  " Remove repititions from a list scanning from the left"
  (remove-duplicates L :test 'equal :from-end t))

(defun del-blanks-fwd (max) 
  " Delete up to max blanks, newlines or carriage returns forward from point"
  (loop 
   repeat max
   while (member (following-char) (list ?\  ?\n ?\r)) 
   do (delete-char 1)))

(defun del-blanks-bwd (max)
  " Delete up to max blanks backward from point"
  (loop 
   repeat max
   while (equal (preceding-char) ?\ ) 
   do (delete-char -1)))


(deff within-comment-p (&optional override)
  "\
 Is point within a (``non-escaped'') comment?
 True iff a `%' strictly precedes point on the same line, and the line does not
 begin with the `override' escape string.   \
  "
 ;--------------------------------------------
 ;/mark beginning of line and current location
 ;--------------------------------------------
  (varbind stop (point))
  (beginning-of-line)
  (varbind start (point))  
  (setf (point) stop)
 ;---------------------------------------
 ;/look for `%' in that portion of buffer
 ;---------------------------------------
  (and 
   (find ?% (buffer-substring start stop))
   (not 
     (equal 
       override 
       (buffer-substring start (+ start (length override)))))))


(deff within-equation-p () 
  "\
 True iff point is within a displayed equation 
 (ie is preceded by an odd number of $$'s, ignoring $$ within comments).
  "
  (interactive)
  (varbind end (point))
  (save-excursion
    (setf (point) (point-min))
    (oddp
     (loop 
      while (search-forward "$$" end t)
      unless (within-comment-p)
      sum 1))))

(deff to-next-open (opening)
  "\ 
 Go to next construct-opening and leave point just after it.
 Pass over constructs within comments unless they are escaped by 
 `% eltex:' at the beginning of the line.
 (The word construct means equation number or reference etc)  \
  "
  (loop 
    while (search-forward opening nil t)
    unless (within-comment-p "% eltex:") 
    return (point)))
 ;
 ; the args to `search-forward' mean: "no bound" and "return nil if not found"


(defun eltex-show-dictionary (dict)
  " used to display dictionary of references or equations"
  (with-output-to-temp-buffer
      (princ (format "*Eltex Dictionary*"))  
    (mapcar 
     'princ
     (image 
      of (format "%s\n" $) 
      on (sort* (copy-seq dict) '< :key 'cdr)))))	;! alt for sa
;;      on (Sort (copy-seq dict) '< :key 'cdr)))))

(defun eltex-list-refs () 
  " See the documentation for `eltex-do'"
  (interactive)
  (eltex-show-dictionary *ref-dictionary*))
(defalias 'eltex-show-refs 'eltex-list-refs)

(defun eltex-list-eqs () 
  " See the documentation for `eltex-do'"
  (interactive)
  (eltex-show-dictionary *eqn-dictionary*))
(defalias 'eltex-show-eqs  'eltex-list-eqs)

(deff eltex-replace-tags (dictionary open)  
  "\
 Replaces partially processed tags by their numbers, removing up to 16 trailing
 blanks, as well as part of the opening.  The net effect can be illustrated by
                 [R::{piombino}] --> [17]
 Notice here that rather than remove the entire opening string \"[R::\",
 we have retained its first character in order to preserve the initial 
 bracket. We do the same for an initial parenthesis, but not for any other
 characters. 
 See the function itself for the klugey details.
  "
 ;-------------------------------------
 ;/decide how much of `open' to replace
 ;-------------------------------------
  (varbind head 
    (if (member 
	  (elt open 0)
	  (list 
	    (elt "[" 0)
	    (elt "(" 0)))
	(subseq open 1)
        open))
 ;--------------------
 ;/do the replacements
 ;--------------------
  (loop
   for x in dictionary do
   (save-excursion
     (while (search-forward (concat head "{" (car x) "}" ) nil t)
       (replace-match (format "%s" (cdr x)) t t)
       (del-blanks-fwd 16)))))
  ;
  ; In the `search-forward' form, the nil means not to bound the search,
  ; and the t means to return nil (rather than error) if no match is found.
  ;
  ; The args  t t  to replace-match are telling it not to modify the
  ; replacement string (they should not be needed, since the latter is just a
  ; number). 
  ;
  ; Still needs improvement, see ~/ms/eltex/developing/replace.el


(deff eltex-number-refs () 
  "\
 Processes references from point forward.  A citation should have 
 the form  
                 [R::<tag>]  or  [R::<tag> <rest>] 

 where <tag> should be either a legal name for an elisp symbol or an integer.
 We also allow <tag> to be be surrounded by a few blanks.
 (Currently <tag> must also be a ``sexp'' for tex mode.
 Thus, <tag> can contain the usual letters [A-z] and digits [0-9] as well as
 certain special characters including the hyphen [-] and, by special
 dispensation, the colon [:].  Various other special characters can 
 be ``protected'' by including {} in the tag.  For example,
 `{Minkowski^17:1903_or_1907}' would be valid as a single tag.)

 This input will turn into [n<rest>] where n is a sequential number
 beginning with *`eltex-ref-offset', which for now is an internal variable set
 to 1.    
 EXAMPLE 
             [R:: kuku b page 7]  -->  [6b page 7]

 A set of tags can be declared equivalent using the syntax

      %  (ref-equivalence:: <tag1> <tag2> <tag3> ...)

 where the entire equivalence class must go into a single declaration 
 (ie you should NOT declare ovelapping equivalences).
 EXAMPLE
               %  (ref-equivalence:: logan VisT unimod3)              
 
 The dictionary used to convert tags into reference numbers is returned and
 also put into `*ref-dictionary*'.       

 Reference constructs within comments are ignored *unless* the line begins with
 the string \"% eltex:\".  You can use this to override the numbering you would
 have got otherwise.

 ADVERTENCIA  A totally blank <tag> will cause an error  \
  "
  (varbind
   eltex-ref-offset 1			; number to give to first reference 
   ref-open eltex-ref-open		; token which opens citations
   equiv-open "(ref-equivalence::"	; token which opens equiv declarations
   equiv-close ")"			; token which closes them
   return-dictionary '*ref-dictionary*)	; what to call the resulting dictionary
  (&bind-too
   tag-start		; location in buffer where tag starts
   tag-end		; location in buffer where tag ends
   tag			; a string identifying a particular reference
   tags			; list of all the tags
   dictionary		; maps each tag to its assigned number
   msg			; used in case of error
   start		; start of an equivalence declaration
   stop			; end of an equivalence declaration
   equivalences		; a list of equivalence classes of tags
   n)
  ;; (debug "ref numberer")
 ;------------------------------------------------------------------
 ;/define auxiliary fcns (see below for description of what they do)
 ;------------------------------------------------------------------
 ;---------------------------
 ;/the function `gather-tags'
 ;---------------------------
  (fbind gather-tags ()  ; this version is for REFERENCES
   (save-excursion
    (loop 
    ;------------------------------------------------------ 
    ;/Find beginning of next tag and remove initial blanks
    ;------------------------------------------------------ 
     while (to-next-open ref-open)
     do 
      (del-blanks-fwd 16)		; remove up to 16 blanks
      (setq tag-start (point)) 
     ;----------------------------------------------------------------------
     ;/Find end of this tag (not of the whole reference-construct)
     ; Error handler is to take care of blank tag.
     ; (We temporarily change colon syntax to make it a legal part of a tag)
     ;----------------------------------------------------------------------
      (setq			  
       tag-end
       (condition-case msg 
	 ;  
	 (progn 
	   (vbind 
	      colon ?:
	      save-syntax (o string char-syntax colon))
	   (modify-syntax-entry colon "_")
	   (forward-sexp) ;[here is where it matters that tag be a sexp!]
	   (modify-syntax-entry colon save-syntax)
	   (point))
	 ;
	 (error				; name of specific error condition
	  (with-output-to-temp-buffer
	      (princ (format " *error in reference numberer*"))     
	    (princ 
	     (format
	      (concat
	       "Likely syntax error in tex file."
	       "\nProblem is near character %d in buffer %s."
	       "\n(Error message was: %s.)"
	       "\nHere is a glimpse of the offending text:"
	       "\n=======================================\n"
	       "%s"
	       "\n=======================================")
	      (point)
	      (buffer-name)
	      (cadr msg)
	      (buffer-substring (- (point) 64) (+ (point) 48)))))
	  (error "Numbering cannot continue"))))
     ;---------------------------------------------------------------- 
     ; Extract the tag, and also surround it with braces in the buffer
     ;----------------------------------------------------------------
      (setf 
        tag (buffer-substring tag-start tag-end)
	(buffer-substring tag-start tag-end) (concat "{"tag"}"))
      collect tag)))
 ;-----------------------------------
 ;/the function `gather-equivalences'
 ;-----------------------------------
  (fbind gather-equivalences ()  
    (setq 
     equivalences
     (save-excursion
       (setf (point) (point-min))	; go to beginning of buffer
       (loop 
	 with open = equiv-open
	 with close = equiv-close
	 while (search-forward open nil t)
	;--------------------------------------------------------
	; Do the following for each equivalence declaration found
	;--------------------------------------------------------
	 do
	  (setq start (point))			
	  (setq stop (search-forward close))
	 collect   
	  (image 
	   on 
	    (Read-from-string 
	     (concat "( "(buffer-substring start stop)" )" ))
	   of     
	    (cond      
	     ((symbolp $) (symbol-name $)) 
	     ((integerp $) (format "%s" $))
	     (t (error "invalid tag used for a reference"))))))))
            ; 
            ; Here is where it matters that a tag be a lisp symbol or an
	    ; integer.  Obviously it could be changed.
 ;-----------------------------
 ;/the function `canonize-tags'
 ;-----------------------------
  (fbind canonize-tags ()
     (loop 
      with c-tags = (copy-seq tags) ; protect `tags' by copying
      for fiber in equivalences do
      (loop 
       with x = (car fiber)
       for y in (cdr fiber) do
       (nsubstitute x y c-tags :test 'equal))
      finally return c-tags))
 ;-------------------------------
 ;/the function `make-dictionary'
 ;-------------------------------
  (fbind make-dictionary (tags)
    (loop for j from 0 below (length tags)
      collect (cons (nth j tags) (+ eltex-ref-offset j))))
 ;-----------------------------------
 ;/the function `complete-dictionary'
 ;-----------------------------------
  (fbind complete-dictionary () 
    (setq 
     dictionary
     (loop 
	for fiber in equivalences do
	(setq n (cdr (assoc (car fiber) dictionary))) 
	(setq dictionary
	      (append 
	       (image on (cdr fiber) of (cons $ n))
	       dictionary))
	finally return dictionary)))
 ;-------------------------------------
 ;/Begin actual program 
 ;-------------------------------------
 (save-excursion 

   (setq tags (stably-remove-duplicates (gather-tags)))
  
   (gather-equivalences)
  
   (setq 
    dictionary 
    (make-dictionary
     (stably-remove-duplicates
      (canonize-tags))))

   (complete-dictionary)  ; add the non-canonical tags to the dictionary

   (eltex-replace-tags dictionary ref-open) 

   (set return-dictionary dictionary)))
 ;
 ; Notes on `eltex-number-refs'
 ;
 ; 1. Buffer should be in tex(t) mode for `forward-sexp' to work right.
 ;    Currently `eltex-do' makes sure that it is in tex mode
 ;
 ; 2. Reason for surrounding tag with braces { } is to avoid confusion when one
 ;    tag is a substring of another, as in  `causet-2' and `causet-23'
 ;
 ; 3. What the auxiliary functions do
 ;
 ; `gather-tags' 
 ;     Gather the tags sequentially into a list.  As each one is 
 ;     encountered, remove (up to 16) preceding blanks, and surround 
 ;     the tag itself with {  }.  Return the list of tags.
 ;     (We ignore tags within comments)
 ;
 ; `gather-equivalences'
 ;    returns a list of "fibers", where a fiber is a set of equivalent tags.
 ;    Each fiber comes from a SINGLE equivalence declaration.
 ;    Such a declaration is a substring of the buffer, We put () around it
 ;    to make it look like a list, we "read" it, and then we convert
 ;    each elt of the resulting list to a string.
 ;    It's in this fcn that it matters that a tag be *both* a valid lisp symbol
 ;    and a sexp in the mode we are using (so far tex).
 ;
 ; `canonize-tags'  
 ;   Returns a list of tags in which each tag belonging to a equivalence-fiber
 ;   is replaced by a canonical member of that fiber
 ; 
 ; `make-dictionary'
 ;   "Creates a dictionary from the set of tags"
 ;
 ; ` complete-dictionary'
 ;    "Completes the dictionary, by consing on the non-canonical pairs taken
 ;    from fibers" 


(deff eltex-number-eqs () 
  "\
 Processes equations from point forward.  An equation number should have   
 the form  
           (E::<tag> <rest>) 

 where <tag> should be either a legal name for an elisp symbol or an integer,
 and should ALSO be a sexp in tex mode.  (It can be surrounded by a few
 blanks.)  This input will turn into (n<rest>) where n is a sequential number
 beginning with *`eltex-eqn-offset', which for now is an internal variable set to 1.   
 Example:
	      (E::kuku b)  -->  (6b)
 WARNINGS
   1. ``Forward references'' to equations may fail if `$$' are
         embedded within comments.
   2. Using ``(E::??)'' as an eq. number will cause an error (``??'' is not a
      sexp in tex mode!) 
   3. A totally blank tag will cause an error
   4. Only tags that actually number equations get processed.  A stray
      equation number in the text will not be processed if it corresponds to 
      no actual equation
   5. Commented out equations once confused it, but are supposed to be ok now.

 The dictionary that governs the conversion of tags into equation numbers
 is returned and also put into `*eqn-dictionary*'.   \
  "
  (varbind 
   eltex-eqn-offset 1				; number to give to first equation
   eqn-open eltex-eqn-open		; token which opens equation reference
   return-dictionary '*eqn-dictionary*) 
  (&bind-too 
   tag-start				; location in buffer where tag starts
   tag-end				; location in buffer where tag ends
   tag					; string identifying a particular eqn
   tags					; list of all the tags
   dictionary				; maps each tag to its assigned number
   msg					; used in case of error
   )
 ;------------------------------------------------------------------
 ;/define auxiliary fcns (seee for description of what they do)
 ;------------------------------------------------------------------
 ;---------------------------
 ;/the function `gather-tags'
 ;---------------------------
  (fbind gather-tags ()    ; this version is for EQUATIONS
   (save-excursion
    (loop 
    ;------------------------------------------------------ 
    ;/Find beginning of next tag and remove initial blanks
    ;------------------------------------------------------ 
     while (to-next-open eqn-open)
     do
      (del-blanks-fwd 16)		; remove up to 16 blanks
      (setq tag-start (point))
    ;------------------------------------------------------------
    ;/Find end of this tag (not of the whole equation reference)
    ;/Error handler is to take care of blank tag.
    ;------------------------------------------------------------
      (setq			  
       tag-end
       (condition-case msg 
	 ;
	 (progn 
	   (forward-sexp) ; here is where it matters that tag be a sexp!
	   (point))
	 ;
	 (error				; name of specific error condition
	  (with-output-to-temp-buffer
	      (princ (format " *error in equation numberer*"))     
	    (princ 
	     (format
	      (concat
		"Likely syntax error in tex file."
		"\nProblem is near character %d in buffer %s."
		"\n(Error message was: %s.)"
		"\nHere is a glimpse of the offending text:"
		"\n=======================================\n"
		"%s"
		"\n=======================================") 
	      (point)
	      (buffer-name)
	      (cadr msg)
	      (buffer-substring (- (point) 64) (+ (point) 48)))))
	  (error "Numbering cannot continue"))))
  ;;; Here should position the cursor to show where error was if possible
     ;---------------------------------------------------------------- 
     ;/Extract the tag, and also surround it with braces in the buffer
     ;----------------------------------------------------------------
      (setf 
       tag (buffer-substring tag-start tag-end)
       (buffer-substring tag-start tag-end) (concat "{" tag "}"))
    ;------------------------------------------------------------------------
    ;/collect the tag iff it is within an equation 
    ; (double-checking it's not within a comment, which it should never be)
    ;------------------------------------------------------------------------
     when 
      (and
       (within-equation-p)
       (not(within-comment-p)))
      collect tag)))
 ;-------------------------------
 ;/the function `make-dictionary'
 ;-------------------------------
  (fbind make-dictionary (tags)
    (loop 
      for tag in tags
      for j from eltex-eqn-offset
      collect (cons tag j)))
 ;----------------------------------------
 ;/Begin actual program 
 ;----------------------------------------
  (save-excursion 

    (setq tags (stably-remove-duplicates (gather-tags)))
    
    (setq dictionary (make-dictionary tags))

    (eltex-replace-tags dictionary eqn-open)
    
    (set return-dictionary dictionary)))
 ;
 ; Note: In order to make forward references work properly, we only collect
 ; tags which are within eqs.  
 ;
 ; What some of the internal functions do
 ;
 ; `gather-tags'
 ;   Gather the tags sequentially into a list.  As each one is 
 ;   encountered, remove initial blanks (up to 16), and surround the tag
 ;   itself with braces {  }.  Collect it if it's within an equation.
 ;   Ignore all tags that are within comments


(deff eltex-provide-footnote-indicators ()
  "\
 Provides footnote labels for footnotes that begin: \\footnote{},
 choosing them cyclically from the list `eltex-footnote-indicators', 
 which normally is (asterisk dagger flat).
 If the footnote begins any other way than \\footnote{}, it will be ignored.
 This can be convenient if you want to label certain footnotes by hand, or for
 latex files.   
 If you need an extra indicator try \\ddagger or \\otimes.  \
  "
 (save-excursion
  (loop 
   with inds = eltex-footnote-indicators
  ;------------------------ 
  ;/Find the next footnote
  ;------------------------ 
   while (search-forward "\\footnote{}" nil t) do
   (backward-char 1)
   (insert (car inds))
   (setq inds (append (cdr inds) (o list car inds))))))


(deff eltex-do (&optional no-suspend) 
  "\
 Numbers the equations and references in a TeX buffer, also provides symbols
 for the footnotes.  Then writes the processed text out to the file `tmp.tex'.
 Equation and reference numbers should have the respective forms

    (E::<tag> <rest>)  and   [R::<tag> <rest>], 

 and a footnote should begin as:  \\footnote{}  if you want eltex to process
 it. For further details, see the documentation for the functions
 eltex-number-eqs, eltex-number-refs, and eltex-provide-footnote-indicators.

 Unless dissuaded by a prefix argument, we also suspend emacs so you can tex 
 the file tmp.tex from shell level.
 (NOT WORKING FOR NOW: Your directory is also changed after the suspension to
  that where tmp.tex resides.)

 To see the respective dictionaries use `eltex-list-refs' or `eltex-list-eqs'.
 (See the documentation for the global variables *ref-dictionary* 
  and *eqn-dictionary*.)

 The interactive commands `eqn' and `ref' aid in writing the TeX file 
 (and they do name completion).

 Normally the keystrokes ^C^C will invoke `eltex-do'   \
  "
  (interactive "P")
  (save-excursion
   ;----------------------------------------
   ;/bind ^C^C to `eltex-do' for convenience
   ;----------------------------------------
    (local-set-key [?\C-c ?\C-c] 'eltex-do) 
   ;----------------
   ;/prepare buffers
   ;----------------
    (varbind
      in-buff (current-buffer)
      temp-buff (generate-new-buffer "tmp.tex"))
    (setf (current-buffer) temp-buff)	; makes "tmp.tex" be the current buffer
    (insert-buffer in-buff)
   ;----------------------------------
   ;/put the temp buffer into tex mode
   ;----------------------------------
    (tex-mode)
   ;----------------------------------------------------------------------
   ;/the next 3 lines are to undo the effect of outline hiding on the text
   ;----------------------------------------------------------------------
    (outline-minor-mode 1)
    (show-all)
    (outline-minor-mode 0)	
   ;--------------------------------------------------
   ;/process the references, equations, and footnotes
   ;--------------------------------------------------
    (message "Starting on references")
    (eltex-number-refs)
    (message "Starting on equations")
    (eltex-number-eqs)
    (message "Starting on footnotes")
    (eltex-provide-footnote-indicators)
   ;-----------------------------------------
   ;/write out the buffer to a file "tmp.tex"
   ;-----------------------------------------
    (write-file "tmp.tex")
    (kill-buffer temp-buff))
 ;--------------------------------
 ;/suspend emacs unless overridden
 ;--------------------------------
  (unless no-suspend
    (suspend-emacs (concat "cd " default-directory)))) 
   ;
   ; FOR SOME REASON THE SECOND ARG SUDEENLY SEEMS TO BE IGNORED:
   ; GNU Emacs 20.7.1 (alpha-redhat-linux-gnu, X toolkit) of Tue Oct 10 2000 on
   ; george.devel.redhat.com 

(deff eltex-do-draftmode (&optional no-suspend) 
  (interactive "P")
  (let ((*eltex-draftmode* nil)) (eltex-do no-suspend))
  (setq *eltex-draftmode* nil))
 ;
 ; So far draft mode does nothing (defined for future reference)!
 ; This is completely untested.


(deff ref () 
  "\
 Takes <name> from user and inserts ``[R::<name>]'' into the text.
 Will do completion on <name>.   \
  " 
  (interactive)
  (varbind tag (completing-read "reference name? " *ref-dictionary*))
  (insert (concat "[R::" tag "]"))
  (eltex-do 'no-suspend)
  (message "%s" (assoc tag *ref-dictionary*)))
  ;
  ; We run `eltex-do' so that it will know the new ref immediately.
  ; Probably only really need a subset of `eltex-number-refs' for this.
 
(deff eqn () 
  "\
 Takes <name> from user and inserts ``(E::<name>)'' into the text
 Will do completion on <name>.   \
  " 
  (interactive)
  (varbind tag (completing-read "equation name? " *eqn-dictionary*))
  (insert (concat "(E::" tag ")"))
  (eltex-do 'no-suspend)
  (message "%s" (assoc tag *eqn-dictionary*))) 
 ;
 ; We run `eltex-do' so that it will know the new equation immediately.
 ; (Only really need a subset of `eltex-number-eqs' for this purpose.)


(deff footnote ()          
  " Insert template for an eltex sytle footnote"
  (interactive)
  (insert "\\footnote{}\n%\n{\n}\n%")
  (previous-line 2))



;: e n d
