aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/textmodes
diff options
context:
space:
mode:
authorStefan Monnier2003-05-15 01:29:53 +0000
committerStefan Monnier2003-05-15 01:29:53 +0000
commit75035a8056a15f5d52ff52744844ef79446e3746 (patch)
tree6cd22c56a07f03648fa6205a19902dd055b13363 /lisp/textmodes
parent588c9a7153d7164bb7d8673a775c424943a944d5 (diff)
downloademacs-75035a8056a15f5d52ff52744844ef79446e3746.tar.gz
emacs-75035a8056a15f5d52ff52744844ef79446e3746.zip
(tex-compile-history, tex-input-files-re)
(tex-use-reftex, tex-compile-commands): New vars. (tex-summarize-command, tex-uptodate-p, tex-executable-exists-p) (tex-command-executable, tex-command-active-p, tex-compile-default) New functions. (tex-compile): New command. (tex-mode-map): Bind it to C-c C-c.
Diffstat (limited to 'lisp/textmodes')
-rw-r--r--lisp/textmodes/tex-mode.el207
1 files changed, 207 insertions, 0 deletions
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el
index 34bd13e146a..c0e606e744c 100644
--- a/lisp/textmodes/tex-mode.el
+++ b/lisp/textmodes/tex-mode.el
@@ -693,6 +693,7 @@ An alternative value is \" . \", if you use a font with a narrow period."
693 (define-key map "\C-c\C-r" 'tex-region) 693 (define-key map "\C-c\C-r" 'tex-region)
694 (define-key map "\C-c\C-b" 'tex-buffer) 694 (define-key map "\C-c\C-b" 'tex-buffer)
695 (define-key map "\C-c\C-f" 'tex-file) 695 (define-key map "\C-c\C-f" 'tex-file)
696 (define-key map "\C-c\C-c" 'tex-compile)
696 (define-key map "\C-c\C-i" 'tex-bibtex-file) 697 (define-key map "\C-c\C-i" 'tex-bibtex-file)
697 (define-key map "\C-c\C-o" 'latex-insert-block) 698 (define-key map "\C-c\C-o" 'latex-insert-block)
698 (define-key map "\C-c\C-e" 'latex-close-block) 699 (define-key map "\C-c\C-e" 'latex-close-block)
@@ -1524,6 +1525,53 @@ If NOT-ALL is non-nil, save the `.dvi' file."
1524 1525
1525(add-hook 'kill-emacs-hook 'tex-delete-last-temp-files) 1526(add-hook 'kill-emacs-hook 'tex-delete-last-temp-files)
1526 1527
1528;;
1529;; Machinery to guess the command that the user wants to execute.
1530;;
1531
1532(defvar tex-compile-history nil)
1533
1534(defvar tex-input-files-re
1535 (eval-when-compile
1536 (concat "\\." (regexp-opt '("tex" "texi" "texinfo"
1537 "bbl" "ind" "sty" "cls") t)
1538 ;; Include files with no dots (for directories).
1539 "\\'\\|\\`[^.]+\\'")))
1540
1541(defcustom tex-use-reftex t
1542 "If non-nil, use RefTeX's list of files to determine what command to use."
1543 :type 'boolean)
1544
1545(defvar tex-compile-commands
1546 '(((concat "pdf" tex-command
1547 " " (shell-quote-argument tex-start-commands) " %f")
1548 t "%r.pdf")
1549 ((concat tex-command
1550 " " (shell-quote-argument tex-start-commands) " %f")
1551 t "%r.dvi")
1552 ("xdvi %r &" "%r.dvi")
1553 ("advi %r &" "%r.dvi")
1554 ("bibtex %r" "%r.aux" "%r.bbl")
1555 ("makeindex %r" "%r.idx" "%r.ind")
1556 ("texindex %r.??")
1557 ("dvipdfm %r" "%r.dvi" "%r.pdf")
1558 ("dvipdf %r" "%r.dvi" "%r.pdf")
1559 ("dvips %r" "%r.dvi" "%r.ps")
1560 ("gv %r.ps &" "%r.ps")
1561 ("gv %r.pdf &" "%r.pdf")
1562 ("xpdf %r.pdf &" "%r.pdf")
1563 ("lpr %r.ps" "%r.ps"))
1564 "List of commands for `tex-compile'.
1565Each element should be of the form (FORMAT IN OUT) where
1566FORMAT is an expression that evaluates to a string that can contain
1567 - `%r' the main file name without extension.
1568 - `%f' the main file name.
1569IN can be either a string (with the same % escapes in it) indicating
1570 the name of the input file, or t to indicate that the input is all
1571 the TeX files of the document, or nil if we don't know.
1572OUT describes the output file and is either a %-escaped string
1573 or nil to indicate that there is no output file.")
1574
1527(defun tex-guess-main-file (&optional all) 1575(defun tex-guess-main-file (&optional all)
1528 "Find a likely `tex-main-file'. 1576 "Find a likely `tex-main-file'.
1529Looks for hints in other buffers in the same directory or in 1577Looks for hints in other buffers in the same directory or in
@@ -1574,6 +1622,165 @@ ALL other buffers."
1574 buffer-file-name))))))) 1622 buffer-file-name)))))))
1575 (if (file-exists-p file) file (concat file ".tex")))) 1623 (if (file-exists-p file) file (concat file ".tex"))))
1576 1624
1625(defun tex-summarize-command (cmd)
1626 (if (not (stringp cmd)) ""
1627 (mapconcat 'identity
1628 (mapcar (lambda (s) (car (split-string s)))
1629 (split-string cmd "\\s-*\\(?:;\\|&&\\)\\s-*"))
1630 "&")))
1631
1632(defun tex-uptodate-p (file)
1633 "Return non-nil if FILE is not uptodate w.r.t the document source files.
1634FILE is typically the output DVI or PDF file."
1635 ;; We should check all the files included !!!
1636 (and
1637 ;; Clearly, the target must exist.
1638 (file-exists-p file)
1639 ;; And the last run must not have asked for a rerun.
1640 ;; FIXME: this should check that the last run was done on the same file.
1641 (let ((buf (condition-case nil (tex-shell-buf) (error nil))))
1642 (when buf
1643 (with-current-buffer buf
1644 (save-excursion
1645 (goto-char (point-max))
1646 (and (re-search-backward
1647 "(see the transcript file for additional information)" nil t)
1648 (> (save-excursion
1649 (or (re-search-backward "\\[[0-9]+\\]" nil t)
1650 (point-min)))
1651 (save-excursion
1652 (or (re-search-backward "Rerun" nil t)
1653 (point-min)))))))))
1654 ;; And the input files must not have been changed in the meantime.
1655 (let ((files (if (and tex-use-reftex
1656 (fboundp 'reftex-scanning-info-available-p)
1657 (reftex-scanning-info-available-p))
1658 (reftex-all-document-files)
1659 (list (file-name-directory (expand-file-name file)))))
1660 (ignored-dirs-re
1661 (concat
1662 (regexp-opt
1663 (delq nil (mapcar (lambda (s) (if (eq (aref s (1- (length s))) ?/)
1664 (substring s 0 (1- (length s)))))
1665 completion-ignored-extensions))
1666 t) "\\'"))
1667 (uptodate t))
1668 (while (and files uptodate)
1669 (let ((f (pop files)))
1670 (if (file-directory-p f)
1671 (unless (string-match ignored-dirs-re f)
1672 (setq files (nconc
1673 (directory-files f t tex-input-files-re)
1674 files)))
1675 (when (file-newer-than-file-p f file)
1676 (setq uptodate nil)))))
1677 uptodate)))
1678
1679
1680(autoload 'format-spec "format-spec")
1681
1682(defvar tex-executable-cache nil)
1683(defun tex-executable-exists-p (name)
1684 "Like `executable-find' but with a cache."
1685 (let ((cache (assoc name tex-executable-cache)))
1686 (if cache (cdr cache)
1687 (let ((executable (executable-find name)))
1688 (push (cons name executable) tex-executable-cache)
1689 executable))))
1690
1691(defun tex-command-executable (cmd)
1692 (let ((s (if (stringp cmd) cmd (eval (car cmd)))))
1693 (substring s 0 (string-match "[ \t]\\|\\'" s))))
1694
1695(defun tex-command-active-p (cmd fspec)
1696 "Return non-nil if the CMD spec might need to be run."
1697 (let ((in (nth 1 cmd))
1698 (out (nth 2 cmd)))
1699 (if (stringp in)
1700 (let ((file (format-spec in fspec)))
1701 (when (file-exists-p file)
1702 (or (not out)
1703 (file-newer-than-file-p
1704 file (format-spec out fspec)))))
1705 (when (and (eq in t) (stringp out))
1706 (not (tex-uptodate-p (format-spec out fspec)))))))
1707
1708(defun tex-compile-default (dir fspec)
1709 "Guess a default command in DIR given the format-spec FSPEC."
1710 ;; TODO: Learn to do latex+dvips!
1711 (let ((cmds nil)
1712 (unchanged-in nil))
1713 ;; Only consider active commands.
1714 (dolist (cmd tex-compile-commands)
1715 (when (tex-executable-exists-p (tex-command-executable cmd))
1716 (if (tex-command-active-p cmd fspec)
1717 (push cmd cmds)
1718 (push (nth 1 cmd) unchanged-in))))
1719 ;; Remove those commands whose input was considered stable for
1720 ;; some other command (typically if (t . "%.pdf") is inactive
1721 ;; then we're using pdflatex and the fact that the dvi file
1722 ;; is inexistent doesn't matter).
1723 (let ((tmp nil))
1724 (dolist (cmd cmds)
1725 (unless (member (nth 1 cmd) unchanged-in)
1726 (push cmd tmp)))
1727 (if tmp (setq cmds tmp)))
1728 ;; remove commands whose input is not uptodate either.
1729 (let ((outs (delq nil (mapcar (lambda (x) (nth 2 x)) cmds))))
1730 (dolist (cmd (prog1 cmds (setq cmds nil)))
1731 (unless (member (nth 1 cmd) outs)
1732 (push cmd cmds))))
1733 ;; Select which file we're going to operate on (the latest).
1734 (let ((latest (nth 1 (car cmds))))
1735 (dolist (cmd (prog1 (cdr cmds) (setq cmds (list (car cmds)))))
1736 (if (equal latest (nth 1 cmd))
1737 (push cmd cmds)
1738 (unless (eq latest t) ;Can't beat that!
1739 (if (or (not (stringp latest))
1740 (eq (nth 1 cmd) t)
1741 (and (stringp (nth 1 cmd))
1742 (file-newer-than-file-p
1743 (format-spec (nth 1 cmd) fspec)
1744 (format-spec latest fspec))))
1745 (setq latest (nth 1 cmd) cmds (list cmd)))))))
1746 ;; Expand the command spec into the actual text.
1747 (dolist (cmd (prog1 cmds (setq cmds nil)))
1748 (push (cons (eval (car cmd)) (cdr cmd)) cmds))
1749 ;; Select the favorite command from the history.
1750 (let ((hist tex-compile-history)
1751 re)
1752 (while hist
1753 (setq re (concat "\\`"
1754 (regexp-quote (tex-command-executable (pop hist)))
1755 "\\([ \t]\\|\\'\\)"))
1756 (dolist (cmd cmds)
1757 (if (string-match re (car cmd))
1758 (setq hist nil cmds (list cmd))))))
1759 ;; Substitute and return.
1760 (format-spec (caar cmds) fspec)))
1761
1762(defun tex-compile (dir cmd)
1763 "Run a command CMD on current TeX buffer's file in DIR."
1764 ;; FIXME: Use time-stamps on files to decide the next op.
1765 (interactive
1766 (let* ((file (tex-main-file))
1767 (root (file-name-sans-extension file))
1768 (dir (file-name-directory (expand-file-name file)))
1769 (fspec (list (cons ?r (comint-quote-filename root))
1770 (cons ?f (comint-quote-filename file))))
1771 (default (tex-compile-default dir fspec)))
1772 (list dir
1773 (completing-read
1774 (format "Command [%s]: " (tex-summarize-command default))
1775 (mapcar (lambda (x)
1776 (list (format-spec (eval (car x)) fspec)))
1777 tex-compile-commands)
1778 nil nil nil 'tex-compile-history default))))
1779 (save-some-buffers (not compilation-ask-about-save) nil)
1780 (if (tex-shell-running)
1781 (tex-kill-job)
1782 (tex-start-shell))
1783 (tex-send-tex-command cmd dir))
1577 1784
1578(defun tex-start-tex (command file &optional dir) 1785(defun tex-start-tex (command file &optional dir)
1579 "Start a TeX run, using COMMAND on FILE." 1786 "Start a TeX run, using COMMAND on FILE."