diff --git a/Makefile.in b/Makefile.in --- a/Makefile.in +++ b/Makefile.in @@ -134,7 +134,7 @@ style/acronym.el style/xparse.el style/fancyvrb.el \ style/tabulary.el style/fontspec.el style/unicode-math.el \ style/luacode.el style/metalogo.el style/english.el \ - style/exercise.el + style/exercise.el style/plext.el STYLEELC = $(STYLESRC:.el=.elc) CLEANFILES = $(AUCELC) $(STYLEELC) $(MULEELC) diff --git a/doc/auctex.texi b/doc/auctex.texi --- a/doc/auctex.texi +++ b/doc/auctex.texi @@ -1033,6 +1033,7 @@ @node Tabular-like @subsection Tabular-like Environments address@hidden amsmath When inserting Tabular-like environments, that is, `tabular' `array' etc., you will be prompted for a template for that environment. @@ -1051,6 +1052,26 @@ act like the empty string is given, but don't prompt for a position. @end defopt address@hidden calculates the number of columns from the format string and +inserts the suitable number of ampersands. + +You can use @kbd{C-c @key{LFD}} (@code{LaTeX-insert-item}) to terminate +rows in these environments. It supplies line break macro @samp{\\} and +inserts the suitable number of ampersands on the next line. + address@hidden Command LaTeX-insert-item address@hidden C-c @key{LFD} +(@kbd{C-c @key{LFD}}) Close the current row with @samp{\\}, move to the +next line and insert an appropriate number of ampersands for the current +environment. address@hidden deffn + +Similar supports are provided for various amsmath environments such as address@hidden, @samp{gather}, @samp{alignat}, @samp{matrix} etc. Try +typing @kbd{C-c @key{LFD}} in these environments. It recognizes the +current environment and does the appropriate job depending on the +context. + @node Customizing Environments @subsection Customizing Environments diff --git a/doc/changes.texi b/doc/changes.texi --- a/doc/changes.texi +++ b/doc/changes.texi @@ -101,6 +101,19 @@ tex file. @item +The suitable number of ampersands are inserted when you insert array, +tabular and tabular* environments with @kbd{C-c C-e}. Similar +experience is obtained if you terminate rows in these environments with address@hidden @key{LFD}}. It supplies line break macro @samp{\\} and inserts +the suitable number of ampersands on the next line. + +Similar supports are provided for various amsmath environments. + address@hidden rawfile address@hidden , for details. address@hidden ifset + address@hidden Commands for narrowing to a group (@code{TeX-narrow-to-group}) and to @LaTeX{} environments (@code{LaTeX-narrow-to-environment}) were added. diff --git a/latex.el b/latex.el --- a/latex.el +++ b/latex.el @@ -1028,7 +1028,8 @@ (concat (unless (zerop (length pos)) (concat LaTeX-optop pos LaTeX-optcl)) - (concat TeX-grop fmt TeX-grcl))))) + (concat TeX-grop fmt TeX-grcl))) + (LaTeX-item-array t))) (defun LaTeX-env-label (environment) "Insert ENVIRONMENT and prompt for label." @@ -1076,7 +1077,8 @@ (concat TeX-grop width TeX-grcl) ;; not optional! (unless (zerop (length pos)) (concat LaTeX-optop pos LaTeX-optcl)) - (concat TeX-grop fmt TeX-grcl))))) + (concat TeX-grop fmt TeX-grcl))) + (LaTeX-item-tabular* t))) (defun LaTeX-env-picture (environment) "Insert ENVIRONMENT with width, height specifications." @@ -1154,6 +1156,126 @@ "Insert a new bibitem." (TeX-insert-macro "bibitem")) +(defvar LaTeX-array-skipping-regexp (regexp-opt '("[t]" "[b]" "")) + "Regexp matching between \\begin{xxx} and column specification. +For array and tabular environments. See `LaTeX-insert-ampersands' for +detail.") + +(defvar LaTeX-tabular*-skipping-regexp + ;; Assume width specification contains neither nested curly brace + ;; pair nor escaped "}". + (concat "{[^}]*}[ \t]*" (regexp-opt '("[t]" "[b]" ""))) + "Regexp matching between \\begin{tabular*} and column specification. +For tabular* environment only. See `LaTeX-insert-ampersands' for detail.") + +(defun LaTeX-item-array (&optional suppress) + "Insert line break macro on the last line and suitable number of &'s. +For array and tabular environments. + +If SUPPRESS is non-nil, do not insert line break macro." + (unless suppress + (save-excursion + (end-of-line 0) + (just-one-space) + (TeX-insert-macro "\\"))) + (LaTeX-insert-ampersands + LaTeX-array-skipping-regexp 'LaTeX-array-count-columns)) + +(defun LaTeX-item-tabular* (&optional suppress) + "Insert line break macro on the last line and suitable number of &'s. +For tabular* environment only. + +If SUPPRESS is non-nil, do not insert line break macro." + (unless suppress + (save-excursion + (end-of-line 0) + (just-one-space) + (TeX-insert-macro "\\"))) + (LaTeX-insert-ampersands + LaTeX-tabular*-skipping-regexp 'LaTeX-array-count-columns)) + +(defun LaTeX-insert-ampersands (regexp func) + "Insert suitable number of ampersands for the current environment. +The number is calculated from REGEXP and FUNC. + +Example 1: +Consider the case that the current environment begins with +\\begin{array}[t]{|lcr|} +. REGEXP must be chosen to match \"[t]\", i.e., the text between just +after \"\\begin{array}\" and just before \"{|lcr|}\", which encloses +the column specification. FUNC must return the number of ampersands to +be inserted, which is 2 since this example specifies three columns. +FUNC is called with two arguments START and END, which spans the column +specification (without enclosing braces.) REGEXP is used to determine +these START and END. + +Example 2: +This time the environment begins with address@hidden,}p{5ex}} +. REGEXP must match \"{1.0\\linewidth}[b]\" and FUNC must return 1 from +the text \"address@hidden,}p{5ex}\" between START and END specified two columns. + +FUNC should return nil if it cannot determine the number of ampersands." + (let* ((cur (point)) + (num + (save-excursion + (ignore-errors + (LaTeX-find-matching-begin) + ;; Skip over "\begin{xxx}" and possible whitespaces. + (forward-list 1) + (skip-chars-forward " \t") + ;; Skip over the text specified by REGEXP and whitespaces. + (when (let ((case-fold-search nil)) + (re-search-forward regexp cur)) + (skip-chars-forward " \t") + (when (eq (following-char) ?{) + ;; We have reached the target "{yyy}" part. + (forward-char 1) + ;; The next line doesn't move point, so point + ;; is left just after the opening brace. + (let ((pos (TeX-find-closing-brace))) + (if pos + ;; Calculate number of ampersands to be inserted. + (funcall func (point) (1- pos)))))))))) + (if (natnump num) + (save-excursion (insert (make-string num ?&)))))) + +(defvar LaTeX-array-column-letters "clrp" + "Column letters for array-like environments. +See `LaTeX-array-count-columns' for detail.") + +(defun LaTeX-array-count-columns (start end) + "Count number of ampersands to be inserted. +The columns are specified by the letters found in the string +`LaTeX-array-column-letters' and the number of those letters within the +text between START and END is basically considered to be the number of +columns. The arguments surrounded between braces such as p{30pt} do not +interfere the count of columns. + +Return one less number than the columns, or nil on failing to count the +right number." + (save-excursion + (let (p (cols 0)) + (goto-char start) + (while (< (setq p (point)) end) + + ;; The below block accounts for one unit of move for + ;; one column. + (setq cols (+ cols (skip-chars-forward + LaTeX-array-column-letters end))) + (skip-chars-forward (concat + "^" LaTeX-array-column-letters + TeX-grop) end) + (if (eq (following-char) ?{) (forward-list 1)) + + ;; Not sure whether this is really necessary or not, but + ;; prepare for possible infinite loop anyway. + (when (eq p (point)) + (setq cols nil) + (goto-char end))) + ;; The number of ampersands is one less than column. + (if cols (1- cols))))) + ;;; Parser (defvar LaTeX-auto-style nil) @@ -5678,7 +5800,10 @@ (make-local-variable 'LaTeX-item-list) (setq LaTeX-item-list '(("description" . LaTeX-item-argument) - ("thebibliography" . LaTeX-item-bib))) + ("thebibliography" . LaTeX-item-bib) + ("array" . LaTeX-item-array) + ("tabular" . LaTeX-item-array) + ("tabular*" . LaTeX-item-tabular*))) (setq TeX-complete-list (append '(("\\\\cite\\[[^]\n\r\\%]*\\]{\\([^{}\n\r\\%,]*\\)" diff --git a/style/amsmath.el b/style/amsmath.el --- a/style/amsmath.el +++ b/style/amsmath.el @@ -43,8 +43,8 @@ '("xalignat" LaTeX-amsmath-env-alignat) '("xalignat*" LaTeX-amsmath-env-alignat) '("xxalignat" LaTeX-amsmath-env-alignat) - '("aligned" LaTeX-amsmath-env-aligned) - '("gathered" LaTeX-amsmath-env-aligned) + '("aligned" ["Vertical position (t or b)"]) + '("gathered" ["Vertical position (t or b)"]) '("alignedat" LaTeX-amsmath-env-alignedat) "align*" "gather*" "flalign*" "multline*" "equation*" "split" @@ -104,19 +104,19 @@ (append '(("split" . LaTeX-item-equation) ("multline" . LaTeX-item-equation) ("multline*" . LaTeX-item-equation) - ("gather" . LaTeX-item-equations) + ("gather" . LaTeX-item-equation) ("gather*" . LaTeX-item-equation) ("gathered" . LaTeX-item-equation) - ("align" . LaTeX-item-equations) + ("align" . LaTeX-item-equation) ("align*" . LaTeX-item-equation) ("aligned" . LaTeX-item-equation) - ("alignat" . LaTeX-item-equations) - ("alignat*" . LaTeX-item-equation) - ("xalignat" . LaTeX-item-equations) - ("xalignat*" . LaTeX-item-equation) - ("xxalignat" . LaTeX-item-equation) - ("alignedat" . LaTeX-item-equation) - ("flalign" . LaTeX-item-equations) + ("alignat" . LaTeX-item-equation-alignat) + ("alignat*" . LaTeX-item-equation-alignat) + ("xalignat" . LaTeX-item-equation-alignat) + ("xalignat*" . LaTeX-item-equation-alignat) + ("xxalignat" . LaTeX-item-equation-alignat) + ("alignedat" . LaTeX-item-equation-alignat) + ("flalign" . LaTeX-item-equation) ("flalign*" . LaTeX-item-equation) ("matrix" . LaTeX-item-equation) ("pmatrix" . LaTeX-item-equation) @@ -136,7 +136,7 @@ (append '(("align" . LaTeX-amsmath-label) ("alignat" . LaTeX-amsmath-label) ("xalignat" . LaTeX-amsmath-label) - ("multline" . LaTeX-amsmath-label) + ("multline" . LaTeX-amsmath-label) ("flalign" . LaTeX-amsmath-label) ("gather" . LaTeX-amsmath-label)) LaTeX-label-alist)) @@ -158,40 +158,60 @@ (reftex-add-to-label-alist '(AMSTeX)))))) (defun LaTeX-amsmath-env-alignat (env) + "Insert ENV with column number specifications. +Insert suitable number of ampersands also if possible." (let ((ncols (read-string "Number of columns: "))) (LaTeX-insert-environment env (concat TeX-grop ncols TeX-grcl)) - (and (not (string= "xxalignat" env)) - (not (string= "*" (substring env -1))) - (LaTeX-label env) - (newline-and-indent)))) - -(defun LaTeX-amsmath-env-aligned (env) - (let ((where (read-string "(optional) Vertical position (t or b): "))) - (if (string= where "") - (setq where "") - (setq where (concat "[" where "]"))) - (LaTeX-insert-environment env where))) + (LaTeX-item-equation-alignat t))) (defun LaTeX-amsmath-env-alignedat (env) - (let ((where (read-string "(optional) Vertical position (t or b): ")) - (ncols (read-string "Number of columns: "))) - (if (string= where "") - (setq where "") - (setq where (concat "[" where "]"))) - (LaTeX-insert-environment env (concat where TeX-grop ncols TeX-grcl)))) + "Insert ENV with position and column number specifications. +Insert suitable number of ampersands also if possible." + (let ((where (read-string "(Optional) Vertical position (t or b): ")) + (ncols (read-string "Number of columns: "))) + (unless (string= where "") + (setq where (concat LaTeX-optop where LaTeX-optcl))) + (LaTeX-insert-environment env (concat where TeX-grop ncols TeX-grcl)) + (LaTeX-item-equation-alignat t))) -(defun LaTeX-item-equation () - (end-of-line 0) - (just-one-space) - (insert "\\\\") - (forward-line 1) - (indent-according-to-mode)) +(defun LaTeX-item-equation (&optional suppress) + "Insert contents to terminate a line in multi-line equations environment. +Put line break macro on the last line. If the current environment +wants \\label, insert it also. -(defun LaTeX-item-equations () - (LaTeX-item-equation) - (let ((environment (LaTeX-current-environment 1))) - (and (LaTeX-label environment) - (newline-and-indent)))) +If SUPPRESS is non-nil, do not insert line break macro." + (unless suppress + (end-of-line 0) + (just-one-space) + (TeX-insert-macro "\\") + (forward-line 1) + (indent-according-to-mode)) + (let ((env (LaTeX-current-environment))) + (when (and (assoc env LaTeX-label-alist) + (LaTeX-label env)) + (LaTeX-newline) + (indent-according-to-mode)))) + +(defun LaTeX-item-equation-alignat (&optional suppress) + "Insert contents to terminate a line in multi-line equations environment. +Put line break macro on the last line. Next, if the current +environment wants \\label, insert it also. And insert suitable number +of ampersands if possible. + +If SUPPRESS is non-nil, do not insert line break macro." + (LaTeX-item-equation suppress) + (LaTeX-insert-ampersands + (concat "\\(?:" + (regexp-quote LaTeX-optop) "[tb]" (regexp-quote LaTeX-optcl) + "\\)?") + 'LaTeX-amsmath-alignat-number-of-ampersands)) + +(defun LaTeX-amsmath-alignat-number-of-ampersands (start end) + "Return the number of ampersands to insert. +The number is 2N-1 where N is the number taken from the text between +START and END." + (let ((num (string-to-number (buffer-substring-no-properties start end)))) + (if (integerp num) (+ num num -1)))) (defvar LaTeX-amsmath-package-options '("intlimits" "nointlimits" "sumlimits" "nosumlimits" diff --git a/style/array.el b/style/array.el --- a/style/array.el +++ b/style/array.el @@ -40,7 +40,10 @@ ;; `array.sty' adds a couple of new lengths. They're added here, rather than ;; in the `TeX-add-symbols' block. - (LaTeX-add-lengths "extratabsurround" "extrarowheight"))) + (LaTeX-add-lengths "extratabsurround" "extrarowheight") + + ;; `array.sty' adds some new column specification letters. + (set (make-local-variable 'LaTeX-array-column-letters) "clrpmb"))) (defvar LaTeX-array-package-options nil "Package options for array.") diff --git a/style/plext.el b/style/plext.el new file mode 100644 --- /dev/null +++ b/style/plext.el @@ -0,0 +1,77 @@ +;;; plext.el --- AUCTeX style for the plext package. + +;; Copyright (C) 2014 Free Software Foundation, Inc. + +;; Author: Ikumi Keita +;; Maintainer: address@hidden +;; Created: 2014-07-05 +;; Keywords: tex, japanese + +;; 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 file adds support for the plext package. + +;;; Code: + +(TeX-add-style-hook + "plext" + (lambda () + ;; plext.sty extends some environments to accept option, e.g. , + ;; for vertical typesetting. + (LaTeX-add-environments + ;; TODO: Add support for minipage and picture + ;; environments extension. + '("array" LaTeX-plext-env-array) + '("tabular" LaTeX-plext-env-array) + '("tabular*" LaTeX-plext-env-array)) + + (set (make-local-variable 'LaTeX-array-skipping-regexp) + (concat "\\(?:<[tyz]>\\)?[ \t]*" (regexp-opt '("[t]" "[b]" "")))) + (set (make-local-variable 'LaTeX-tabular*-skipping-regexp) + (concat "\\(?:<[tyz]>\\)?[ \t]*{[^}]*}[ \t]*" + (regexp-opt '("[t]" "[b]" "")))))) + +(defun LaTeX-plext-env-array (env) + (let ((dir (read-string "(Optional) Direction (t or y or z): ")) + (width (if (string= env "tabular*") + (read-string "Width: " LaTeX-default-width))) + (pos (and LaTeX-default-position ; LaTeX-default-position can + ; be nil, i.e. do not prompt + (read-string "(Optional) Position: " LaTeX-default-position))) + (fmt (read-string "Format: " LaTeX-default-format))) + (unless (zerop (length dir)) + (setq dir (concat "<" dir ">"))) + (if (string= env "tabular*") + (setq LaTeX-default-width width)) + (setq LaTeX-default-position pos) + (setq LaTeX-default-format fmt) + (LaTeX-insert-environment env + (concat + dir + (if (string= env "tabular*") + (concat TeX-grop width TeX-grcl)) + (unless (zerop (length pos)) + (concat LaTeX-optop pos LaTeX-optcl)) + (concat TeX-grop fmt TeX-grcl))) + (if (string= env "tabular*") + (LaTeX-item-tabular* t) + (LaTeX-item-array t)))) + +;;; plext.el ends here.