(defvar me-quotes-toggle nil "*me-mode quotes toggle")
(defvar me-italics-toggle nil "*me-mode italics toggle")
(defvar me-bold-toggle nil "*me-mode bold toggle")
(defvar me-bold-italics-toggle nil "*me-mode bold italics toggle")
(defvar me-courier-toggle nil "*me-mode courier toggle")
(defvar me-courier-italic-toggle nil "*me-mode courier italic toggle")
(defvar me-courier-bold-toggle nil "*me-mode courier bold toggle")
(defvar me-helvetica-toggle nil "*me-mode helvetica toggle")
(defvar me-helvetica-italic-toggle nil "*me-mode helvetica italic toggle")
(defvar me-helvetica-bold-toggle nil "*me-mode helvetica bold toggle")
(defvar me-ref-toggle nil "*me-mode ref toggle")
(defvar me-subscript-toggle nil "*me-mode subscript toggle")
(defvar me-superscript-toggle nil "*me-mode superscript toggle")
(defvar me-alltt-toggle nil "*me-mode alltt toggle")

(defvar enuming nil "*Are we enuming or listing?")
(defvar in-me-list-toggle nil "*")
(defvar in-me-enum-toggle nil "*")

(defun dot () (point))

(defun 
    begin/end-me-quotes () (interactive)
	(if (toggle-var 'me-quotes-toggle)
	    (insert-string "``")
	    (insert-string "''")
	)
)

(defun 
    begin/end-me-italics () (interactive)
	(if (toggle-var 'me-italics-toggle)
	    (insert-string (concat "\\fI"))
	    (insert-string (concat "\\fP"))
	)
)

(defun 
    begin/end-me-bold-italics () (interactive)
	(if (toggle-var 'me-italics-toggle)
	    (insert-string (concat "\\f[BI]"))
	    (insert-string (concat "\\fP"))
	)
)

(defun
    begin/end-me-bold () (interactive)
	(if (toggle-var 'me-bold-toggle)
	    (insert-string "\\fB")
	    (insert-string "\\fP")
	)
)

(defun
    begin/end-me-courier () (interactive)
	(if (toggle-var 'me-courier-toggle)
	    (insert-string "\\fC")
	    (insert-string "\\fP")
	)
)

(defun
    begin/end-me-courier-italic () (interactive)
	(if (toggle-var 'me-courier-italic-toggle)
	    (insert-string "\\f[CI]")
	    (insert-string "\\fP")
	)
)

(defun
    begin/end-me-courier-bold () (interactive)
	(if (toggle-var 'me-courier-bold-toggle)
	    (insert-string "\\f[CB]")
	    (insert-string "\\fP")
	)
)

(defun
    begin/end-me-helvetica () (interactive)
	(if (toggle-var 'me-helvetica-toggle)
	    (insert-string "\\fH")
	    (insert-string "\\fP")
	)
)

(defun
    begin/end-me-helvetica-italic () (interactive)
	(if (toggle-var 'me-helvetica-italic-toggle)
	    (insert-string "\\f[HI]")
	    (insert-string "\\fP")
	)
)

(defun
    begin/end-me-helvetica-bold () (interactive)
	(if (toggle-var 'me-helvetica-bold-toggle)
	    (insert-string "\\f[HB]")
	    (insert-string "\\fP")
	)
)

(defun
    begin/end-me-ref () (interactive)
	(if (toggle-var 'me-ref-toggle)
	    (insert-string ".[ [\n")
	    (insert-string ".]]\n")
	)
)

(defun 
    begin/end-me-subscript () (interactive)
	(if (toggle-var 'me-subscript-toggle)
	    (insert-string "\\*<")
	    (insert-string "\\*>")
	)
)

(defun 
    begin/end-me-superscript () (interactive)
	(if (toggle-var 'me-superscript-toggle)
	    (insert-string "\\*{")
	    (insert-string "\\*}")
	)
)

(defun
    insert-bullet-item  () (interactive)
	(insert-string
	    (concat (int-to-string enum-item-spacing)
		    "\\.ee\n"
	    )
	)
	(previous-line 1)
)

(defun check-match-of-me-font-changes ()
"Superceded by ./match-troff-font-changes.el, q.v."
    (message "Superceded by ./match-troff-font-changes.el, q.v.")
)

(defvar list-item-spacing 3 "*")
(defvar enum-item-spacing 3 "*")
(defvar list-item ".le\n" "*")
(defvar enum-item ".ee\n" "*")

(defun set-list-item-spacing (a1 item-suffix)

"If A1 (a prefix arg) is < 0, use old-style item spacing with explicit .sp
commands separating list item commands, with spacing set to 0.1 * abs(A1).  If
arg is >= 0, use new-style item spacing, with no explicit .sp commands.  With
the new-style spacing, the troff macros handle the spacing commands.  See def
of .(L and .le macros ~/nroff/stdhdr.me."

    (interactive "nlist item spacing: 
sitem suffix: ")
    (setq list-item-spacing a1)
    (setq enum-item-spacing list-item-spacing)
    (if (< a1 0)
	(progn
	  (setq list-item
		(concat ".sp ."
			(int-to-string (- list-item-spacing)) "v\n.le\n"))
	  (setq enum-item
		(concat ".sp ."
			(int-to-string (- enum-item-spacing)) "v\n.ee\n"))
	)
	(progn
	  (setq list-item (concat ".le" item-suffix "\n"))
	  (setq enum-item (concat ".ee" item-suffix "\n"))
	)
    )
)

(defun 
    insert-list-item (sp) (interactive "P")
        (if (not (null sp))
	    (set-list-item-spacing sp "")
	)
	(insert-string
	    (if enuming
		enum-item
		list-item
	    )
	)
)

	    

(defun 
    Es (sp) (interactive "P")
       (setq enuming t)
       (if (not (null sp))
	   (set-list-item-spacing sp "")
       )
       (insert-string
	   (concat ".(i\n.(E\n"
		   enum-item
	   )
       )
)
(defun 
    Ee () (interactive)
       (insert-string (concat \ "EndEnum\n"))
       (local-unset-ket "")
)

;DEFUNCT:
(defun 
    Ls (sp) (interactive "P")
       (setq enuming nil)			;i.e., we're listing now
       (if (not (null sp))
	   (if (< sp 0)
	       (set-list-item-spacing (- sp) "")
	       (set-list-item-spacing 0 "")
	   )
       ) 
       (insert-string
	   (concat ".(i\n.(L 1\n"
		   list-item
	   )
       )
)
(defun 
    Le () (interactive)
       (insert-string ".)L 1\n.)i\n")
)

(defun 
    begin/end-me-list () (interactive)
	(if (toggle-var 'in-me-list-toggle)
	    (Ls)
	    (Le)
	)
)

(defun 
    begin/end-me-enum () (interactive)
	(if (toggle-var "in-me-enum-toggle")
	    (Es)
	    (Ee)
	)
)

(defun
  insert-me-list-template (sp)
  (interactive "p")
	(setq enuming nil)			;i.e., we`re listing now
	(if (eq sp 1)
	  (progn
	     (insert-me-list-template-1 "1" list-item-spacing)
	  )
	  (progn
	     (setq x sp)
	     (set-list-item-spacing sp "")
	     (call-interactively 'insert-me-list-template-1 '("1" sp))
	  )
	)
)

(defun
    insert-me-list-template-1 (af sp)
    (interactive
       "sType of list (I, A, 1, a, i): 
pSpacing"
    )
        (if (string= af "") (setq af 1))
	(setq x sp)
	(if (> sp 0)
	    (progn
	      (insert-string 
		  ".(L " af " ." sp "v" "\n"
		  list-item
		  "\n"
		  ".)L " af "\n"
	      )
	     )
	     (progn
	      (insert-string 
		  ".(L " af "\n"
		  list-item
		  "\n"
		  ".)L " af "\n"
	      )
	     )
	)
	(previous-line 2)
)

;The following doesnt work currently due to some misunderstanding of and/or
;bug in gosmacs lisp parm passing.
;(defun 
;    (insert-indented-me-list-template-bogus af
;	(insert-string ".(i\n")
;	(if prefix-argument-provided
;	    (provide-prefix-argument prefix-argument
;		(insert-me-list-template af))
;	    (insert-me-list-template af)
;	)
;	(next-line) (next-line)
;	(insert-string ".)i\n")
;	(previous-line) (previous-line) (previous-line)
;    )
;)

(defun 
    insert-indented-me-list-template () (interactive)
	(call-interactively 'insert-me-list-template)
	(previous-line 2)
	(end-of-line)
	(insert-string " 4n")
	(next-line 3)
;	(insert-string " 4n")
	(previous-line 1)
)

(defun 
    insert-indented-me-list-template-old () (interactive)
	(insert-string ".(i\n")
	(call-interactively 'insert-me-list-template)
	(next-line 2)
	(insert-string ".)i\n")
	(previous-line 3)
)


(defun  insert-me-enum-template (sp)
    (interactive "P")
    (insert-me-enum-template1 sp "")
)

(defun
    insert-me-enum-template1 (sp item-suffix) (interactive "P")
	(setq enuming t)
	(if (null sp)
	  (progn
	    (insert-string 
		".(E ." list-item-spacing "v\n"
		enum-item
		"\n"
		".)E\n"
	    )
	  )
	  (if (>= sp 0)
	    (progn
	      (set-list-item-spacing sp item-suffix)
	      (insert-string 
		  ".(E" " ." sp "v" "\n"
		  enum-item
		  "\n"
		  ".)E\n"
	      )
	    )
	    (progn
	      (set-list-item-spacing sp item-suffix)
	      (insert-string 
		  ".(E\n"
		  enum-item
		  "\n"
		  ".)E\n"
	      )
	    )
	  )
	)
	(previous-line 2)
)

; Hmm, how clever I am.  We don't need to call with 25 cause the current non-
; specialized version remembers the spacing if it's not in the interactive arg.
(defun insert-specialized-me-enum-template (sp)
    (interactive "P")
    (insert-me-enum-template1 sp "c")
)

(defun 
    insert-indented-me-enum-template () (interactive)
	(call-interactively 'insert-me-enum-template)
	(previous-line 2)
	(end-of-line)
	(insert-string " 4n")
	(next-line 3)
;	(insert-string " 4n")
	(previous-line 1)
)

(defun 
    insert-indented-me-enum-template-old () (interactive)
	(insert-string ".(i\n")
	(call-interactively 'insert-me-enum-template)
	(next-line 2)
	(insert-string ".)i\n")
	(previous-line 3)
)

(defun 
    insert-me-alltt-template () (interactive)
	(insert-string 
	    ".(i\n"
	    "\n"
	    ".)i\n"
	)
	(previous-line 2)
)

(defun 
    insert-me-section (s)
      (interactive "NSection depth: ")
	(if (= s 1)
	    (insert-string ".sh 1 \"\"")
	    (if (= s 2)
		(insert-string ".sh 2 \"\"")
		(if (= s 3)
		    (insert-string ".sh 3 \"\"")
		    (if (= s 4)
			(insert-string ".sh 4 \"\"")
		        (error "Section depth must be between 1 and 5")
		    )
		)
	    )
	)
;	(insert-string "\\indent")
	(backward-char 1)
)

(defun 
    insert-me-center-template () (interactive)
	(insert-string 
	    ".(C\n"
	    "\n"
	    ".)C\n"
	)
	(previous-line 2)
)

(defun 
    insert-me-verbatim-template () (interactive)
	(insert-string 
	    ".nf\n.na\n"
	    "\n"
	    ".fi\n.ad\n"
	)
	(previous-line 3)
)

(defun insert-me-title (title)

"Insert a combined me and html with the .(TI ... .)TI command, q.v. in
~/nroff/html.me"

  (interactive "sTitle: ")
  (insert-string (concat
		    ".(TI \"" title "\"\n"
		    ".(S +2\n"
		    "\\fB" title "\\fP\n"
		    ".)S\n"
		    ".)TI\n"
		 )
  )
)

(defun insert-me-section-ref ()
"Insert a section ref template of the form
    .(Ah ``href''
    Section \*[vref]
    .)Ah
where href is the local url and vref is the corresponding var name.  The
insertion is made at the current point of the current buffer.  The href and
vref strings are derived from the line at which point is set in the next
buffer, i.e., the buffer entered via (other-window 1).  In that buffer, point
is assumed to be at the beginning of a line containing a troff section heading
of the standard format."

  (interactive)
  (let ((file-name nil) (section-name nil) (d nil))

    ; Goto the next buffer, get the stuff, and come back.
    (other-window 1)
    (setq file-name (buffer-name))
    (beginning-of-line)
    (search-forward "\"")
    (setq d (dot))
    (end-of-line)
    (backward-char 1)
    (setq section-name (buffer-substring d (dot)))
    (other-window -1)

    ; Insert the stuff and groom it as necessary.
    (insert-me-href-template
        (concat
	    (substring file-name 0 -3) ".html#" section-name))
    (backward-char 1)
    (insert section-name)
    (beginning-of-line)
    (insert "Section ")
    (end-of-line)
    (setq d (dot))
    (search-backward "[")
    (narrow-to-region (dot) d)
    (replace-string " " "_")
    (widen)
    (previous-line 1)
    (end-of-line)
    (setq d (dot))
    (search-backward "#")
    (narrow-to-region (dot) d)
    (replace-string " " "\\ ")
    (widen)
  )
)

(defun insert-me-figure-ref ()
"Insert a figure ref template of the form
    .(Ah ``href''
    Figure \*[fref]
    .)Ah
where href is the local url and fref is the corresponding var name.  The
insertion is made at the current point of the current buffer.  The href and
fref strings are derived from the line at which point is set in the next
buffer, i.e., the buffer entered via (other-window 1).  In that buffer, point
is assumed to be at the beginning of a line containing a troff figure caption
of the standard format."

  (interactive)
  (let ((file-name nil) (figure-caption nil) (d nil))

    ; Goto the next buffer, get the stuff, and come back.
    (other-window 1)
    (setq file-name (buffer-name))
    (beginning-of-line)
    (search-forward "\"")
    (setq d (dot))
    (end-of-line)
    (backward-char 1)
    (setq figure-caption (buffer-substring d (dot)))
    (other-window -1)

    ; Insert the stuff and groom it as necessary.
    (insert-me-href-template
        (concat
	    (substring file-name 0 -3) ".html#Figure " figure-caption))
    (backward-char 1)
    (insert (concat "Figure " figure-caption))
    (beginning-of-line)
    (insert "Figure ")
    (end-of-line)
    (setq d (dot))
    (search-backward "[")
    (narrow-to-region (dot) d)
    (replace-string " " "_")
    (widen)
    (previous-line 1)
    (end-of-line)
    (setq d (dot))
    (search-backward "#")
    (narrow-to-region (dot) d)
    (replace-string " " "\\ ")
    (widen)
  )
)

(defun insert-me-href-template (url)
"Insert html href template .(Ah "" ... .)Ah."
    (interactive "sURL: ")
    (insert
       (concat
	   ".(Ah \"" url "\"\n"
	   "\\*[]\n"
	   ".)Ah"
       )
    )
    (previous-line 1)
)

(defun my-nroff-mode ()
    (interactive)
    (read-abbrev-file "~gfisher/emacs/lib/text-mode-abbrev-table")
    (setq nroff-mode-abbrev-table text-mode-abbrev-table)
    (nroff-mode)
    (abbrev-mode 1)
    ;Remove some of gnu's funky nroff-mode bindings:
    (local-unset-key "p")
    (local-unset-key "n")
    (local-unset-key "s")

    ;My bindings:
	(local-set-key "'" 'begin/end-me-italics)
;	(local-set-key "`'" 'begin/end-me-italics)
	(local-set-key "\"" 'begin/end-me-bold-italics)
;	(local-set-key "`\"" 'begin/end-me-quotes)
	(local-set-key "_" 'begin/end-me-bold)
;	(local-set-key "`_" 'begin/end-me-bold)
	(local-set-key ";" 'begin/end-me-courier)
;	(local-set-key "`;" 'begin/end-me-courier)
;	(local-set-key ":" 'begin/end-me-helvetica)
	;(local-set-key "=" 'begin/end-me-courier-bold)
	(local-set-key "+" 'begin/end-me-helvetica-bold)

	(local-set-key "[" 'begin/end-me-ref)
;	(local-set-key "`[" 'begin/end-me-ref)
	(local-set-key ";" 'begin/end-me-subscript)
	(local-set-key ":" 'begin/end-me-superscript)
	(local-set-key "i" 'insert-list-item)
;	(local-set-key "`i" 'insert-list-item)
	(local-set-key " " 'set-list-item-spacing)
;	(local-set-key "` " 'set-list-item-spacing)
	;(local-set-key "begin/end-me-list" "\^xL")
	;(local-set-key "begin/end-me-enum" "\^xE")
	(local-set-key "L" 'insert-me-list-template)
	(local-set-key "E" 'insert-me-enum-template)
	(local-set-key "I" 'insert-indented-me-enum-template)
	(local-set-key "K" 'insert-indented-me-list-template)
	(local-set-key "a"
	    '(keymap (?f . insert-me-figure-ref)
		     (?h . insert-me-href-template)
		     (?n . insert-me-name-template)
		     (?s . insert-me-section-ref)
		     (?t . insert-me-alltt-template)
	     )
	)
	(local-set-key "S" 'insert-me-section)
	(local-set-key "C" 'insert-me-center-template)
	(local-set-key "T" 'insert-me-title)
	(local-set-key "V" 'insert-me-verbatim-template)
	(local-set-key "(" 'backward-sexp)
	(local-set-key ")" 'forward-sexp)
	(local-set-key "ve" 'vc-ediff-buffer)
;	(Remove-local-binding "\e/")
 	(setq fill-prefix nil)
	(setq fill-column 79)
	(auto-fill-mode 1)
	(setq case-fold-search nil)
	(setq truncate-lines nil)

        ; (set-line-spacing)  ; Turned off for now.  See comments in .emacs.

	(setq mode-name "my-nroff-me")
)

(defun make-me-outline ()
    (interactive)
    (while (search-forward "\n.sh" nil t)
      (beginning-of-line)
      (setq d (dot))
      (next-line 1)
      (beginning-of-line)
      (append-to-buffer (concat (buffer-name) ".outln") d (dot))
    )
)

(defun courierize-words ()
"Surround a sequencw of uppercase words with \&'\fC ... \fP."
    (interactive)
    (insert "\\&'\\fC")
    (forward-word 1)
    (forward-char 1)
    (while (is-upper (char-to-string (following-char)))
        (forward-word 1)
        (forward-char 1)
    )
    (backward-char 1)
    (insert "\\fP'")
)

(defun is-upper (char)
"Return t if the given single-char string is upper case."
    (interactive "sEnter a single char: ")
    (and (>= (string-to-char char) ?A) (<= (string-to-char char) ?Z))
)

(defun bulletize-region ()
"Put make region into a .(E .ee ... .)E block."
    (interactive)
    (setq d (dot))
    (exchange-dot-and-mark)
    (narrow-to-region (dot) d)
    (beginning-of-buffer)
    (insert ".(E\n")
    (while (not (eobp))
        (insert ".ee\n")
	(next-line 1)
    )
    (insert ".)E\n")
    (widen)
)