;;; tex-mode.el --- TeX, LaTeX, and SliTeX mode commands -*- coding: utf-8 -*-
-;; Copyright (C) 1985-1986, 1989, 1992, 1994-1999, 2001-2014 Free
+;; Copyright (C) 1985-1986, 1989, 1992, 1994-1999, 2001-2015 Free
;; Software Foundation, Inc.
;; Maintainer: emacs-devel@gnu.org
(define-derived-mode plain-tex-mode tex-mode "TeX"
"Major mode for editing files of input for plain TeX.
Makes $ and } display the characters they match.
-Makes \" insert `` when it seems to be the beginning of a quotation,
+Makes \" insert \\=`\\=` when it seems to be the beginning of a quotation,
and '' when it appears to be the end; it inserts \" only after a \\.
Use \\[tex-region] to run TeX on the current region, plus a \"header\"
(define-derived-mode latex-mode tex-mode "LaTeX"
"Major mode for editing files of input for LaTeX.
Makes $ and } display the characters they match.
-Makes \" insert `` when it seems to be the beginning of a quotation,
+Makes \" insert \\=`\\=` when it seems to be the beginning of a quotation,
and '' when it appears to be the end; it inserts \" only after a \\.
Use \\[tex-region] to run LaTeX on the current region, plus the preamble
(define-derived-mode slitex-mode latex-mode "SliTeX"
"Major mode for editing files of input for SliTeX.
Makes $ and } display the characters they match.
-Makes \" insert `` when it seems to be the beginning of a quotation,
+Makes \" insert \\=`\\=` when it seems to be the beginning of a quotation,
and '' when it appears to be the end; it inserts \" only after a \\.
Use \\[tex-region] to run SliTeX on the current region, plus the preamble
(setq tex-command slitex-run-command)
(setq tex-start-of-header "\\\\documentstyle{slides}\\|\\\\documentclass{slides}"))
+(defvar tildify-space-string)
+(defvar tildify-foreach-region-function)
+
(defun tex-common-initialization ()
;; Regexp isearch should accept newline and formfeed as whitespace.
(setq-local search-whitespace-regexp "[ \t\r\n\f]+")
+ ;; Use tilde as hard-space character in tildify package.
+ (setq-local tildify-space-string "~")
+ ;; FIXME: Use the fact that we're parsing the document already
+ ;; rather than using regex-based filtering.
+ (setq-local tildify-foreach-region-function
+ (apply-partially
+ 'tildify-foreach-ignore-environments
+ `(("\\\\\\\\" . "") ; do not remove this
+ (,(eval-when-compile
+ (concat "\\\\begin{\\("
+ (regexp-opt '("verbatim" "math" "displaymath"
+ "equation" "eqnarray" "eqnarray*"))
+ "\\)}"))
+ . ("\\\\end{" 1 "}"))
+ ("\\\\verb\\*?\\(.\\)" . (1))
+ ("\\$\\$?" . (0))
+ ("\\\\(" . "\\\\)")
+ ("\\\\[[]" . "\\\\[]]")
+ ("\\\\[a-zA-Z]+\\( +\\|{}\\)[a-zA-Z]*" . "")
+ ("%" . "$"))))
;; A line containing just $$ is treated as a paragraph separator.
(setq-local paragraph-start "[ \t]*$\\|[\f\\\\%]\\|[ \t]*\\$\\$")
;; A line starting with $$ starts a paragraph,
(defun tex-insert-quote (arg)
"Insert the appropriate quote marks for TeX.
-Inserts the value of `tex-open-quote' (normally ``) or `tex-close-quote'
+Inserts the value of `tex-open-quote' (normally \\=`\\=`) or `tex-close-quote'
\(normally '') depending on the context. With prefix argument, always
inserts \" characters."
(interactive "*P")
+ ;; Discover if we'll be inserting normal double quotes.
+ ;;
(if (or arg (memq (char-syntax (preceding-char)) '(?/ ?\\))
- (eq (get-text-property (point) 'face) 'tex-verbatim)
- (save-excursion
- (backward-char (length tex-open-quote))
- (when (or (looking-at (regexp-quote tex-open-quote))
- (looking-at (regexp-quote tex-close-quote)))
- (delete-char (length tex-open-quote))
- t)))
+ (eq (get-text-property (point) 'face) 'tex-verbatim)
+ ;; Discover if a preceding occurrence of `tex-open-quote'
+ ;; should be morphed to a normal double quote.
+ ;;
+ (and (>= (point) (+ (point-min) (length tex-open-quote)))
+ (save-excursion
+ (backward-char (length tex-open-quote))
+ (when (or (looking-at (regexp-quote tex-open-quote))
+ (looking-at (regexp-quote tex-close-quote)))
+ (delete-char (length tex-open-quote))
+ (when (looking-at (regexp-quote tex-close-quote))
+ (delete-char (length tex-close-quote)))
+ t))))
+ ;; Insert the normal quote (eventually letting
+ ;; `electric-pair-mode' do its thing).
+ ;;
(self-insert-command (prefix-numeric-value arg))
- (insert (if (or (memq (char-syntax (preceding-char)) '(?\( ?> ?\s))
- (memq (preceding-char) '(?~)))
- tex-open-quote tex-close-quote))))
+ ;; We'll be inserting fancy TeX quotes, but consider and imitate
+ ;; `electric-pair-mode''s two behaviors: pair-insertion and
+ ;; region wrapping.
+ ;;
+ (if (and electric-pair-mode (use-region-p))
+ (let* ((saved (point-marker)))
+ (goto-char (mark))
+ (insert (if (> saved (mark)) tex-open-quote tex-close-quote))
+ (goto-char saved)
+ (insert (if (> saved (mark)) tex-close-quote tex-open-quote)))
+ (if (or (memq (char-syntax (preceding-char)) '(?\( ?> ?\s))
+ (memq (preceding-char) '(?~ ?')))
+ ;; We're in an "opening" context
+ ;;
+ (if electric-pair-mode
+ (if (looking-at (regexp-quote tex-close-quote))
+ (forward-char (length tex-close-quote))
+ (insert tex-open-quote)
+ (insert tex-close-quote)
+ (backward-char (length tex-close-quote)))
+ (insert tex-open-quote))
+ ;; We're in a "closing" context.
+ ;;
+ (if (looking-at (regexp-quote tex-close-quote))
+ (forward-char (length tex-close-quote))
+ (insert tex-close-quote))))))
(defun tex-validate-buffer ()
"Check current buffer for paragraphs containing mismatched braces or $s.
;; A better way to handle this, \( .. \) etc, is probably to
;; temporarily change the syntax of the \ in \( to punctuation.
((and latex-handle-escaped-parens
- (looking-back "\\\\[])}]"))
+ (looking-back "\\\\[])}]" (- (point) 2)))
(signal 'scan-error
(list "Containing expression ends prematurely"
(- (point) 2) (prog1 (point)
(goto-char pos)))))
((and latex-handle-escaped-parens
- (looking-back "\\\\\\([({[]\\)"))
+ (looking-back "\\\\\\([({[]\\)" (- (point) 2)))
(tex-next-unmatched-eparen (match-string 1)))
(t (goto-char newpos))))))