;;; l2latexinfo.el

;;; Latexinfo mode utilities to convert LaTeX files to latexinfo.

;;; Written for Latexinfo by Mike Clarkson
;;; Please send bug reports to:  mike@apl.ists.ca

;;; Copyleft  (C) 1991 Michael E. Clarkson
;; It's not perfect, but there's not much to do.

(require 'latexinfo)
(require 'latexnfo-upd)

(defun latex-to-latexinfo (arg)
  (interactive "FNew File Name: ")
  (let ((case-fold-search nil)
	(input-buffer (current-buffer)))
    (find-file arg)
    (erase-buffer)
    (insert-buffer-substring input-buffer)
    (set-syntax-table latexinfo-format-syntax-table)
    (goto-char (point-min))
    ;; Input the \input files
    (l2l-input-files)
    (goto-char (point-min))
    (re-search-forward "^\\\\documentstyle" nil nil)
    (if (looking-at "\\[")
	(progn (search-forward "]" nil nil)
	       (forward-char -1)
	       (insert ",latexinfo"))
      (insert "[latexinfo]"))
    (re-search-forward "^\\\\begin{document}" nil nil)
    (forward-line 1)
    (insert "\\alwaysrefill\n" 
	    "\\setfilename{" arg ".info}\n"
	    "\\node top, ,(dir), (dir)\n")
    (l2l-format-scan-noverbatim)
    (goto-char (point-min))
    (set-mark-command)
    (goto-char (point-max))
    (latexinfo-sequential-node-update t)
    )
  )

(defun l2l-input-files ()
  (if (and (save-excursion (re-search-forward "^\\\\input" nil t))
	   (yes-or-no-p
	    "Would you like to do the \\\\input files now, to do it all at once?"))
      (while (re-search-forward "^\\\\input" nil t)
	(save-excursion
	  (skip-chars-forward " 	{")
	  (let ((file-name
		 (buffer-substring 
		  (point)
		  (progn
		    (skip-chars-forward "^ 	\n")
		    (point)))))
	    (setq file-name
		  (expand-file-name
		   (if (file-readable-p (expand-file-name file-name))
		       file-name
		     (concat file-name ".tex"))))
	    (beginning-of-line 1)
	    (if (file-readable-p file-name)
		(progn
		  (delete-region (point) (progn (forward-line 1) (point)))
		  (message "Inserting file %s..." file-name) (sit-for 1)
		  (insert-file file-name)
		  (message "Inserting file %s...done" file-name))
	      (error "I can't find the file %s" file-name))
	    )))))

(defun l2l-format-scan-noverbatim ()
  (if (re-search-forward latexinfo-special-regexp nil t)
      (let ((start (point-min))
	    (end nil)
	    str)
	(goto-char start)
	(while (re-search-forward l2l-special-regexp nil t)
	  (setq str (buffer-substring (match-beginning 0) (match-end 0)))
	  ;; Handle LaTeX \input{filename} commands by inserting them now.
	  ;; Only look at the beginning of the line to avoid \c \input{foo}
	  (cond 
	   ((string-equal str "\\input{")
	    (latexinfo-insert-input-files)
	    )
	   ((string-equal str "\\begin{verbatim}")
	    (setq end (point))
	    (l2l-do-global-substitutions start end)
	    (re-search-forward "\\\\end{verbatim}" nil nil) 
	    (setq start (point))
	    )
	   ((string-equal str "\\verb")
	    (setq end (point))
	    (l2l-do-global-substitutions start end)
	    (setq str (buffer-substring (point) (1+ (point))))
	    (forward-char 1)
	    (search-forward str nil nil) 
	    (forward-char 1)
	    (setq start (point))
	    )
	   )
	  )
	(if end (l2l-do-global-substitutions start (point-max)))
	)
    (l2l-do-global-substitutions (point-min) (point-max))
    )
  (l2l-format-scan))

(defun l2l-format-scan ()
  (goto-char (point-min))
  (latexinfo-insert-node-lines (point-min) (point-max) t)
  (latexinfo-master-menu 8)
  )

(defun l2l-do-global-substitutions (min max)
  (save-excursion
    (narrow-to-region min max)
    ;; LaTeX sometimes uses \\ to force a new-line
    (let ((case-fold-search nil)
	  (alist l2l-global-alist))
      (while alist
	(goto-char (point-min))
	(quietly-replace-regexp (car (car alist)) (cdr (car alist)) nil)
	(message "%s" (car (car alist)))
	(setq alist (cdr alist)))
      )))

(defvar l2l-global-alist '(
			   ;; Fonts
			   ("{\\\\tt " . "\\\\t{")
			   ("{\\\\bf " . "\\\\r{")
			   ("{\\\\it " . "\\\\t{")
			   ("{\\\\sl " . "\\\\i{")
			   ("{\\\\em " . "\\\\emph{")
			   ("^[%]+" . "\\c")
			   ;; this breaks on \~
			   ("~" . "\\\\tie")
			   ("$\\\\ldots\\$" . "\\\\dots{}")
			   ;; This is a wild guess
			   ("$\\([a-zA-Z]+\\)\\$" . "\\\\var{\\1}")
			   ))


