;;                    -*- emacs-lisp -*-
;;
;; tex-dk-mode.el -- Easy acces to danish macros in tex.
;;
;; $Id: tex-dk.el,v 5.1 1992/03/31 03:19:14 krab Exp $
;;
;;
;; This file is distributed with the AUC TeX package as a sample of
;; native language support.
;;
;; Added minor maps and ugly code by,
;; Per Abrahamsen at University of Aalborg, Denmark 18 sep 87.
;; mail amanda@iesd.uucp (supporting of this version)
;;
;; Most code originally by
;; Kurt N{\o}rmark at University of Aalborg, Denmark SomeDay.
;; mail normark@iesd.uucp

;; This file contain no copyright message.

(require 'min-map)

(make-variable-buffer-local 'tex-dk-double-mode)
(setq-default tex-dk-double-mode nil)

(setq minor-mode-alist (cons '(tex-dk-double-mode " {\\DK}") 
			     minor-mode-alist))

(defun tex-dk-double-mode (arg) "\
Toggle tex-dk-double-mode.
With arg, turn tex-dk-double-mode on iff arg is positive.

This mode allow users to get the TeX macros for danish chars directly
from the keyboard, and the corresponding english chars by pressing a
key twice.

If tex-dk-keymap is nil, I will use the following keymap:

[	{\\AE}
\\	{\\O}
]	{\\AA}
{	{\\ae}
|	{\\o}
}	{\\aa}

Otherwise this keymap will be used:

:	{\\AE}
\"	{\\O}
{	{\\AA}
;	{\\ae}
'	{\\o}
[	{\\aa}

Always:

^B	Move backward danish or english char."

  (interactive "P")
  (if (or (and (null arg) tex-dk-double-mode)
	  (<= (prefix-numeric-value arg) 0))
      (if tex-dk-double-mode
	  (progn			;Turn it off
	    (unbind-minor-mode 'tex-dk-double-mode)
	    (setq tex-dk-double-mode nil)))
    (if tex-dk-double-mode		;Turn it on
	()
      (minor-set-key "[" 'dk-square-left 'tex-dk-double-mode)
      (minor-set-key "{" 'dk-curly-left 'tex-dk-double-mode)
      (minor-set-key "]" 'dk-square-right 'tex-dk-double-mode)
      (minor-set-key "}" 'dk-curly-right 'tex-dk-double-mode)
      (minor-set-key "\\" 'dk-back-slash 'tex-dk-double-mode)
      (minor-set-key "|" 'dk-bar 'tex-dk-double-mode)
      (minor-set-key "\"" 'dk-quote 'tex-dk-double-mode)
      (minor-set-key "'" 'dk-single-quote 'tex-dk-double-mode)
      (minor-set-key ":" 'dk-colon 'tex-dk-double-mode)
      (minor-set-key ";" 'dk-semicolon 'tex-dk-double-mode)
      (minor-set-key "" 'dk-backward-char 'tex-dk-double-mode)
      (minor-set-key "\177" 'delete-previous-danish-char 'tex-dk-double-mode)
      (setq tex-dk-double-mode t)))
  (set-buffer-modified-p (buffer-modified-p)))

(defun dk-curly-left (arg) "\
Insert danish char at first call, change to english char in later
calls. With ARG, insert that many english chars."
  (interactive "P")
  (if arg
      (insert-char ?{ (prefix-numeric-value arg))
    (double-insert "{" (if tex-dk-keyboard
			   "{\\AA}"
			 "{\\ae}"))))

(defun dk-curly-right (arg) "\
Insert danish char at first call, change to english char in later
calls. With ARG, insert that many english chars."
  (interactive "P")
  (if (or arg tex-dk-keyboard)
      (insert-char ?} (prefix-numeric-value arg))
    (double-insert "}" "{\\aa}")))

(defun dk-square-left (arg) "\
Insert danish char at first call, change to english char in later
calls. With ARG, insert that many english chars."
  (interactive "P")
  (if arg
      (insert-char ?[ (prefix-numeric-value arg))
    (double-insert "[" (if tex-dk-keyboard
			   "{\\aa}"
			 "{\\AE}"))))

(defun dk-square-right (arg) "\
Insert danish char at first call, change to english char in later
calls. With ARG, insert that many english chars."
  (interactive "P")
  (if (or arg tex-dk-keyboard)
      (insert-char ?] (prefix-numeric-value arg))
    (double-insert "]" "{\\AA}")))

(defun dk-back-slash (arg) "\
Insert danish char at first call, change to english char in later
calls. With ARG, insert that many english chars."
  (interactive "P")
  (if (or arg tex-dk-keyboard)
      (insert-char ?\\ (prefix-numeric-value arg))
    (double-insert "\\" "{\\O}")))

(defun dk-bar (arg) "\
Insert danish char at first call, change to english char in later
calls. With ARG, insert that many english chars."
  (interactive "P")
  (if (or arg tex-dk-keyboard)
      (insert-char ?\| (prefix-numeric-value arg))
    (double-insert "|" "{\\o}")))

(defun dk-quote (arg) "\
Insert danish char at first call, change to english char in later
calls. With ARG, insert that many english chars."
  (interactive "P")
  (if (or arg (not tex-dk-keyboard))
      (TeX-insert-quote arg)
    (cond ((save-excursion (search-backward "{\\O}" (- (point) 4) t))
	   (progn (delete-previous-danish-char)
		  (TeX-insert-quote nil)))
	  ((eq (preceding-char) ?\\)
	   (TeX-insert-quote nil))
	  (t (insert "{\\O}")))))

(defun dk-single-quote (arg) "\
Insert danish char at first call, change to english char in later
calls. With ARG, insert that many english chars."
  (interactive "P")
  (if (or arg (not tex-dk-keyboard))
      (insert-char ?\' (prefix-numeric-value arg))
    (double-insert "'" "{\\o}")))

(defun dk-colon (arg) "\
Insert danish char at first call, change to english char in later
calls. With ARG, insert that many english chars."
  (interactive "P")
  (if (or arg (not tex-dk-keyboard))
      (insert-char ?\: (prefix-numeric-value arg))
    (double-insert ":" "{\\AE}")))

(defun dk-semicolon (arg) "\
Insert danish char at first call, change to english char in later
calls. With ARG, insert that many english chars."
  (interactive "P")
  (if (or arg (not tex-dk-keyboard))
      (insert-char ?\; (prefix-numeric-value arg))
    (double-insert ";" "{\\ae}")))

(defun dk-backward-char (n)
  "Go back ARG characters, tex macros for danish chars counting as one char"
  (interactive "p")
  (if (null n) (setq n 1))
  (let ((count n))
    (while (> count 0)
      (if (previous-danish-charp)
	  (search-backward "{\\" (- (point) 5))
	(goto-char (1- (point))))
      (setq count (1- count)))))

(defun previous-danish-charp ()
  "Return t if point is at the end of a tex macro for a danish char."
  (save-excursion
    (and (eq (preceding-char) ?})
	 (search-backward "{\\" (- (point) 5) t)
	 (looking-at "{\\\\\\(ae\\|o\\|aa\\|\\|AE\\|O\\|AA\\)}"))))

(defun delete-previous-danish-char ()
  "Delete previous char, including danish macros."
  (interactive)
  (let ((beg-point (point)))
    (if (not (previous-danish-charp))
	(delete-char -1)
      (search-backward "{\\" (- (point) 5))
      (delete-region (point) beg-point))))

(defun double-insert (char danish)
  "Takes arguments CHAR and DANISH.
First activation: Insert DANISH.
Following activations just after the first: Insert CHAR."
  (cond
   ((save-excursion (search-backward danish (- (point) (length danish)) t))
    (progn (delete-previous-danish-char)
	   (insert char)))
   ((eq (preceding-char) ?\\)
    (insert char))
   (t (insert danish))))
