From becff06c71d277647eda4378203d03ab36e141eb Mon Sep 17 00:00:00 2001 From: mattkae Date: Tue, 17 May 2022 07:07:37 -0400 Subject: Evil mode and latex support --- elpa/auctex-13.1.3/texmathp.el | 438 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 438 insertions(+) create mode 100644 elpa/auctex-13.1.3/texmathp.el (limited to 'elpa/auctex-13.1.3/texmathp.el') diff --git a/elpa/auctex-13.1.3/texmathp.el b/elpa/auctex-13.1.3/texmathp.el new file mode 100644 index 0000000..f02824c --- /dev/null +++ b/elpa/auctex-13.1.3/texmathp.el @@ -0,0 +1,438 @@ +;;; texmathp.el -- Code to check if point is inside LaTeX math environment -*- lexical-binding: t; -*- + +;; Copyright (C) 1998-2021 Free Software Foundation, Inc. + +;; Author: Carsten Dominik +;; Maintainer: auctex-devel@gnu.org +;; Keywords: tex + +;; This file is part of AUCTeX. + +;; AUCTeX is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; AUCTeX is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with AUCTeX; see the file COPYING. If not, write to the Free +;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +;; 02110-1301, USA. + +;;; Commentary: +;; +;; This code provides a function to determine if point in a buffer is +;; inside a (La)TeX math environment. This is not trivial since many +;; different ways are used to switch between the two. Examples: +;; +;; \begin{equation} ... \end{equation} +;; $ ... $ +;; $$ ... $$ +;; \[ ... \] +;; \ensuremath{...} +;; \mbox{...} +;; +;; To install, put this file on your load-path and compile it. +;; +;; To use this in a Lisp program, do +;; +;; (require 'texmathp) +;; +;; You can then write code like this: +;; +;; (if (texmathp) ...) +;; +;; The call to `texmathp' leaves some extra information in the +;; variable `texmathp-why'. It's value is a cons cell (MATCH . POSITION), +;; specifying which command at what position is responsible for math +;; mode being on or off. +;; +;; To configure which macros and environments influence LaTeX math +;; mode, customize the variable `texmathp-tex-commands'. By default +;; it recognizes the plain TeX and LaTeX core as well as AMS-LaTeX +;; and packages mathtools, empheq and breqn (see the variable +;; `texmathp-tex-commands-default', also as an example). +;; +;; To try out the code interactively, use `M-x texmathp RET'. +;; +;; Of course, in order to work this function has to assume that the +;; LaTeX above point is syntactically correct. In particular: +;; +;; o The different math delimiters are paired correctly. Thus if +;; you do things like "\begin{equation} $" or "\[ ... \)" +;; the result of (texmathp) is undefined. It is in fact possible +;; in LaTeX to pair \[ with $$ and \( with $, but this will confuse +;; texmathp (and human readers as well). +;; +;; o However, texmathp will correctly work with nested delimiters. +;; Something like the following will be parsed correctly at any point: +;; +;; \begin{equation} +;; x = y \mbox{abc \ensuremath{\alpha} cba $2^3$} +;; \end{equation} +;; +;; o texmathp is somewhat forgiving if you have an empty line inside +;; the current math environment, which is not legal in TeX but may +;; easily happen during editing. Depending upon the variable +;; `texmathp-search-n-paragraphs' several paragraphs are checked +;; backwards, by default 2. Paragraph here means something limited +;; by an empty line. +;;-------------------------------------------------------------------------- +;; +;; BUGS: +;; +;; If any of the the special macros like \mbox or \ensuremath has optional +;; arguments, math mode inside these optional arguments is *not* influenced +;; by the macro. +;; +;; Nested \(\) and \[\] can confuse texmathp. It returns nil at AAA +;; in the following examples: +;; \[ x=y \mbox{abc \(\alpha\) cba} AAA \] +;; \[ x=y \begin{minipage}{3cm} abc \[\alpha\] cba \end{minipage} AAA \] +;;-------------------------------------------------------------------------- + +;;; Code: + +(defgroup texmathp nil + "Testing TeX and LaTeX documents for math mode." + :tag "Test For TeX and LaTeX Math Mode" + :prefix "texmathp-" + :group 'tex) + +;; Some internal variables which are computed from `texmathp-tex-commands' +;; and `texmathp-tex-commands-default'. +(defvar texmathp-environments nil) +(defvar texmathp-macros nil) +(defvar texmathp-onoff-regexp nil) +(defvar texmathp-toggle-regexp nil) +(defvar texmathp-tex-commands1 nil) +(defvar texmathp-memory nil) + +(defvar texmathp-tex-commands) ; silence the compiler + +(defvar texmathp-tex-commands-default + '(;; Plain TeX + ("$$" sw-toggle) ("$" sw-toggle) + ("\\hbox" arg-off) + ("\\vbox" arg-off) + ("\\vtop" arg-off) + ("\\vcenter" arg-off) + + ;; Standard LaTeX + ("equation" env-on) + ("eqnarray" env-on) ("eqnarray*" env-on) + ("math" env-on) + ("displaymath" env-on) + ("minipage" env-off) + ("\\fbox" arg-off) + ("\\mbox" arg-off) + ("\\framebox" arg-off) + ("\\label" arg-off) + ("\\textrm" arg-off) + ("\\(" sw-on) ("\\)" sw-off) + ("\\[" sw-on) ("\\]" sw-off) + ("\\ensuremath" arg-on) + + ;; AMS-LaTeX + ("equation*" env-on) + ("align" env-on) ("align*" env-on) + ("gather" env-on) ("gather*" env-on) + ("multline" env-on) ("multline*" env-on) + ("flalign" env-on) ("flalign*" env-on) + ("alignat" env-on) ("alignat*" env-on) + ("xalignat" env-on) ("xalignat*" env-on) + ("xxalignat" env-on) ("\\boxed" arg-on) + ("\\text" arg-off) ("\\intertext" arg-off) + ("\\tag" arg-off) ("\\tag*" arg-off) + + ;; mathtools + ("\\shortintertext" arg-off) + + ;; empheq + ("empheq" env-on) + ("AmSequation" env-on) ("AmSequation*" env-on) + ("AmSalign" env-on) ("AmSalign*" env-on) + ("AmSgather" env-on) ("AmSgather*" env-on) + ("AmSmultline" env-on) ("AmSmultline*" env-on) + ("AmSflalign" env-on) ("AmSflalign*" env-on) + ("AmSalignat" env-on) ("AmSalignat*" env-on) + + ;; breqn + ("dmath" env-on) ("dmath*" env-on) + ("dseries" env-on) ("dseries*" env-on) + ("dgroup" env-on) ("dgroup*" env-on) + ("darray" env-on) ("darray*" env-on) + ("dsuspend" env-off)) + "The default entries for `texmathp-tex-commands', which see.") + +(defun texmathp-compile () + "Compile the value of `texmathp-tex-commands' into the internal lists. +Call this when you have changed the value of that variable without using +customize (customize calls it when setting the variable)." + (interactive) + ;; Extract lists and regexp. + (setq texmathp-macros nil texmathp-environments nil) + (setq texmathp-memory + (cons texmathp-tex-commands texmathp-tex-commands-default)) + (setq texmathp-tex-commands1 (append texmathp-tex-commands + texmathp-tex-commands-default)) + (let ((list (reverse texmathp-tex-commands1)) + entry type switches togglers) + (while (setq entry (car list)) + (setq type (nth 1 entry) + list (cdr list)) + (cond ((memq type '(env-on env-off)) (push (car entry) texmathp-environments)) + ((memq type '(arg-on arg-off)) (push (car entry) texmathp-macros)) + ((memq type '(sw-on sw-off)) (push (car entry) switches)) + ((memq type '(sw-toggle)) (push (car entry) togglers)))) + (setq texmathp-onoff-regexp + (concat "\\(?:[^\\]\\|\\`\\)" + (regexp-opt switches t)) + texmathp-toggle-regexp + (concat "\\([^\\$]\\|\\`\\)" + (regexp-opt togglers t))))) + +(defcustom texmathp-tex-commands nil + "List of environments and macros influencing (La)TeX math mode. +This user-defined list is used in addition to LaTeX and AMSLaTeX defaults. +The structure of each entry is (NAME TYPE) + +- The first item in each entry is the name of an environment or macro. + If it's a macro, include the backslash. + +- The second item is a symbol indicating how the command works: + `env-on' Environment: turns math mode for its body on + `env-off' Environment: turns math mode for its body off + `arg-on' Command: turns math mode for its arguments on + `arg-off' Command: turns math mode for its arguments off + `sw-on' Switch: turns math-mode of following text on + `sw-off' Switch: turns math-mode of following text off + `sw-toggle' Switch: toggles math mode of following text" + :set (lambda (symbol value) (set-default symbol value) (texmathp-compile)) + :type + '(repeat + (list :value ("" env-on) + (string :tag "Name") + (choice :tag "Type" + (const :tag "Environment: turns math mode for its body on" env-on) + (const :tag "Environment: turns math mode for its body off" env-off) + (const :tag "Command: turns math mode for its argument on" arg-on) + (const :tag "Command: turns math-mode for its argument off" arg-off) + (const :tag "Switch: turns math-mode of following text on" sw-on) + (const :tag "Switch: turns math-mode of following text off" sw-off) + (const :tag "Switch: toggles math mode of following text" sw-toggle))))) + +(defcustom texmathp-search-n-paragraphs 2 + "Number of paragraphs to check before point. +Normally, you cannot have an empty line in a math environment in (La)TeX. +The fastest method to test for math mode is then limiting the search +backward to the nearest empty line. +However, during editing it happens that such lines exist temporarily. +Therefore we look a little further. This variable determines how many +empty lines we go back to fix the search limit." + :type 'number) + +(defcustom texmathp-allow-detached-args nil + "Non-nil means, allow arguments of macros to be detached by whitespace. +When this is t, `aaa' will be interpreted as an argument of \\bbb in the +following construct: \\bbb [xxx] {aaa} +This is legal in TeX. The disadvantage is that any number of braces expressions +will be considered arguments of the macro independent of its definition." + :type 'boolean) + +(defvar texmathp-why nil + "After a call to `texmathp' this variable shows why math-mode is on or off. +The value is a cons cell (MATCH . POSITION). +MATCH is a string like a car of an entry in `texmathp-tex-commands', for +example \"equation\" or \"\\ensuremath\" or \"\\=\\[\" or \"$\". +POSITION is the buffer position of the match. If there was no match, +it points to the limit used for searches, usually two paragraphs up.") + +;; We need our own syntax table to play with the syntax of () [] and {} +;; For speed reasons we define it statically instead of copying it each time. +(defvar texmathp-syntax-table + (let ((table (make-syntax-table))) + (mapc (lambda (x) (modify-syntax-entry (car x) (cdr x) table)) + '((?\\ . "\\") (?\f .">") (?\n . ">") (?% . "<") + (?\[ . ".") (?\] . ".") (?\{ . "(}") (?\} . "){") + (?\( . ".") (?\) . ".") (?\" . ".") (?& . ".") (?_ . ".") + (?@ . "_") (?~ . " ") (?$ . "$") (?' . "w"))) + table) + "Syntax table used while texmathp is parsing.") + +;;;###autoload +(defun texmathp () + "Determine if point is inside (La)TeX math mode. +Returns t or nil. Additional info is placed into `texmathp-why'. +The functions assumes that you have (almost) syntactically correct (La)TeX in +the buffer. +See the variable `texmathp-tex-commands' about which commands are checked." + (interactive) + (let* ((pos (point)) math-on sw-match + (bound (save-excursion + (if (re-search-backward + (if (eq major-mode 'doctex-mode) + "[\n\r]%*[ \t]*[\n\r]" + "[\n\r][ \t]*[\n\r]") + nil 1 texmathp-search-n-paragraphs) + (match-beginning 0) + (point-min)))) + (mac-match (texmathp-match-macro bound)) + (env-match (texmathp-match-environment + (if (and mac-match (> (cdr mac-match) bound)) + (cdr mac-match) + bound))) + (match (cons nil bound))) + + ;; Select the nearer match + (and env-match (setq match env-match)) + ;; Use `>=' instead of `>' in case called inside \ensuremath{..} + ;; beginning just at (point-min). + (and mac-match (>= (cdr mac-match) (cdr match)) (setq match mac-match)) + (setq math-on (memq (nth 1 (assoc (car match) texmathp-tex-commands1)) + '(env-on arg-on))) + + ;; Check for switches + (and (not math-on) + (setq sw-match (texmathp-match-switch bound)) + ;; Use `>=' instead of `>' by similar reason as above. (bug#41559) + (>= (cdr sw-match) (cdr match)) + (eq (nth 1 (assoc (car sw-match) texmathp-tex-commands1)) 'sw-on) + (setq match sw-match math-on t)) + + ;; Check for togglers + (if (not math-on) + (save-excursion + (goto-char (cdr match)) + (while (re-search-forward texmathp-toggle-regexp pos t) + (if (setq math-on (not math-on)) + (setq sw-match (cons (match-string-no-properties 2) (match-beginning 2))) + (setq sw-match nil))) + (and math-on sw-match (setq match sw-match)))) + + ;; Store info, show as message when interactive, and return + (setq texmathp-why match) + (and (called-interactively-p 'any) + (message "math-mode is %s: %s begins at buffer position %d" + (if math-on "on" "off") + (or (car match) "new paragraph") + (cdr match))) + (and math-on t))) + +(defun texmathp-match-environment (bound) + "Find out if point is inside any of the math environments. +Limit searched to BOUND. The return value is like (\"equation\" . (point))." + (catch 'exit + (save-excursion + (and (null texmathp-environments) (throw 'exit nil)) + ;; Check if the line we are starting with is a commented one. + (let ((orig-comment-flag + ;; Could be replaced by `TeX-in-commented-line'. + (progn + (save-excursion + (beginning-of-line) + (skip-chars-forward " \t") + (string= (buffer-substring-no-properties + (point) (min (point-max) + (+ (point) (length comment-start)))) + comment-start)))) + end-list env) + (while (re-search-backward "\\\\\\(begin\\|end\\)[ \t]*{\\([^}]+\\)}" + bound t) + ;; Check if the match found is inside of a comment. + (let ((current-comment-flag + ;; Could be replaced by `TeX-in-comment'. + (when (save-match-data + (re-search-backward comment-start-skip + (line-beginning-position) t)) + ;; We need a t for comparison with `orig-comment-flag', + ;; not a number. + t))) + ;; Only consider matching alternatives with respect to + ;; "in-commentness", i.e. if we started with a comment + ;; only consider matches which are in comments as well and + ;; vice versa. + (when (eq orig-comment-flag current-comment-flag) + (setq env (buffer-substring-no-properties + (match-beginning 2) (match-end 2))) + (cond ((string= (match-string-no-properties 1) "end") + (setq end-list (cons env end-list))) + ((equal env (car end-list)) + (setq end-list (cdr end-list))) + ((member env texmathp-environments) + (throw 'exit (cons env (point)))))))) + nil)))) + +(defun texmathp-match-macro (bound) + "Find out if point is within the arguments of any of the Math macros. +Limit searches to BOUND. The return value is like (\"\\macro\" . (point))." + (catch 'exit + (and (null texmathp-macros) (throw 'exit nil)) + (let (pos cmd (syntax-table (syntax-table))) + (unwind-protect + (save-restriction + (save-excursion + (set-syntax-table texmathp-syntax-table) + (narrow-to-region (max 1 bound) (point)) + ;; Move back out of the current parenthesis + (while (condition-case nil (progn (up-list -1) t) (error nil)) + ;; Move back over any touching sexps (in fact also non-touching) + (while + (and + (cond + ((memq (preceding-char) '(?\] ?\}))) + ((and + texmathp-allow-detached-args + (re-search-backward + "[]}][ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*\\=" + bound t)) + (goto-char (1+ (match-beginning 0))) t)) + (if (eq (preceding-char) ?\}) + ;; Jump back over {} + (condition-case nil + (progn (backward-sexp) t) + (error nil)) + ;; Jump back over []. Modify syntax temporarily for this. + (unwind-protect + (progn + (modify-syntax-entry ?\{ ".") + (modify-syntax-entry ?\} ".") + (modify-syntax-entry ?\[ "(]") + (modify-syntax-entry ?\] ")[") + (condition-case nil + (progn (backward-sexp) t) + (error nil))) + (modify-syntax-entry ?\{ "(}") + (modify-syntax-entry ?\} "){") + (modify-syntax-entry ?\[ ".") + (modify-syntax-entry ?\] ".") + nil)))) + (setq pos (point)) + (and (memq (following-char) '(?\[ ?\{)) + (re-search-backward "\\\\[*a-zA-Z]+\\=" nil t) + (setq cmd (buffer-substring-no-properties + (match-beginning 0) (match-end 0))) + (member cmd texmathp-macros) + (throw 'exit (cons cmd (point)))) + (goto-char pos)) + (throw 'exit nil))) + (set-syntax-table syntax-table))))) + +;;;###autoload +(defun texmathp-match-switch (bound) + "Search backward for any of the math switches. +Limit searched to BOUND." + ;; The return value is like ("\\(" . (point)). + (save-excursion + (if (re-search-backward texmathp-onoff-regexp bound t) + (cons (buffer-substring-no-properties (match-beginning 1) (match-end 1)) + (match-beginning 1)) + nil))) + +(provide 'texmathp) + +;;; texmathp.el ends here -- cgit v1.2.1