Arash Esbati <esb...@gmx.de> writes:

> I'm thinking about writing a function like this to catch this kind of
> arguments:
>
>     (defun TeX-ispell-tex-arg-end (&optional arg1 arg2)
>       (condition-case nil
>           (progn
>             (while (looking-at "[ \t\n]*\\[") (forward-sexp))
>             (forward-sexp (or arg1 1))
>             (while (looking-at "[ \t\n]*\\[") (forward-sexp))
>             (forward-sexp (or arg2 1)))
>         (error
>          (message "Error skipping s-expressions at point %d." (point))
>          (beep)
>          (sit-for 2))))
>
> and do ("tabular[*xy]" TeX-ispell-tex-arg-end).

Following up myself again, I implemented a function
`TeX-ispell-tex-arg-end' to deal with constructs like:

    \raisebox{2em}[1em][1em]{text} or
    \begin{tabularx}{300pt}{|p{3cm}|>{\raggedright}X|c|S|} etc.

I'd like to apply the attached patch.  I would appreciate any comments
before doing this.

Best, Arash

diff --git a/Makefile.in b/Makefile.in
index 23bf4a5..b79eaf4 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -84,7 +84,7 @@ MULEELC = @MULEELC@
 AUCSRC = tex.el tex-buf.el tex-style.el plain-tex.el latex.el tex-info.el \
 	texmathp.el multi-prompt.el tex-mik.el font-latex.el tex-font.el \
 	context.el context-en.el context-nl.el tex-fold.el \
-	toolbar-x.el tex-bar.el bib-cite.el
+	toolbar-x.el tex-bar.el bib-cite.el tex-ispell.el
 AUCELC = $(AUCSRC:.el=.elc)
 
 STYLESRC = style/prosper.el \
diff --git a/latex.el b/latex.el
index babcd1a..c21699d 100644
--- a/latex.el
+++ b/latex.el
@@ -30,6 +30,7 @@
 
 (require 'tex)
 (require 'tex-style)
+(require 'tex-ispell)
 (eval-when-compile (require 'cl))       ;FIXME: Use cl-lib.
 
 ;;; Syntax
diff --git a/tex-ispell.el b/tex-ispell.el
new file mode 100644
index 0000000..ada8cfe
--- /dev/null
+++ b/tex-ispell.el
@@ -0,0 +1,287 @@
+;;; tex-ispell.el --- AUCTeX skip additions for Ispell
+
+;; Copyright (C) 2016 Free Software Foundation, Inc.
+
+;; Author: Arash Esbati <arash.esbati'at'gmail.com>
+;; Maintainer: auctex-devel@gnu.org
+;; Keywords: tex, wp, convenience
+
+;; This file 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.
+
+;; This file 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 GNU Emacs; 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 provides additions to skip list of Ispell (in this
+;; context, Ispell is synonym for Ispell, Aspell and Hunspell spelling
+;; checker programs).  Macro arguments and environments skipped by
+;; Ispell are stored in the car and/or cdr of
+;; `ispell-tex-skip-alists'.  This file uses two functions
+;; `TeX-ispell-skip-setcar' and `TeX-ispell-skip-setcdr' defined in
+;; `tex.el' to add new items to this variable.
+
+;; Ispell has a lot of LaTeX macros and environments already built-in.
+;; E.g., check this link for Hunspell program:
+
+;; https://github.com/hunspell/hunspell/blob/master/src/parsers/latexparser.cxx
+
+;; Ispell does not check spelling in the preamble of a document.
+;; Hence, only document macros and environments should be added here.
+;; Currently, this file has support for the following macro packages:
+
+;; acro.sty
+;; amsmath.sty
+;; attachfile.sty
+;; booktabs.sty
+;; cleveref.sty
+;; enumitem.sty
+;; fancyref.sty
+;; fancyvrb.sty
+;; fontaxes.sty
+;; fontspec.sty
+;; listings.sty
+;; mdframed.sty
+;; nameref.sty
+;; siunitx.sty
+;; splitidx.sty
+;; tabularx.sty
+;; tabulary.sty
+;; tikz.sty
+;; varioref.sty
+
+;; If you have further additions, drop a line to <auctex-devel@gnu.org>.
+
+;;; Code:
+
+(require 'tex)
+
+;; Add new macros here:
+(eval-when-compile
+  (defvar TeX-ispell-skip-cmds-list
+    '(;; acro.sty
+      ("ac" . 1)
+      ("ac*" . 1)
+      ("Ac" . 1)
+      ("Ac*" . 1)
+      ("acs" . 1)
+      ("acs*" . 1)
+      ("acl" . 1)
+      ("acl*" . 1)
+      ("Acl" . 1)
+      ("Acl*" . 1)
+      ("aca" . 1)
+      ("aca*" . 1)
+      ("acf" . 1)
+      ("acf*" . 1)
+      ("Acf" . 1)
+      ("Acf*" . 1)
+      ("acp" . 1)
+      ("acp*" . 1)
+      ("Acp" . 1)
+      ("Acp*" . 1)
+      ("acsp" . 1)
+      ("acsp*" . 1)
+      ("aclp" . 1)
+      ("aclp*" . 1)
+      ("Aclp" . 1)
+      ("Aclp*" . 1)
+      ("acap" . 1)
+      ("acap*" . 1)
+      ("acfp" . 1)
+      ("acfp*" . 1)
+      ("Acfp" . 1)
+      ("Acfp*" . 1)
+      ("Iac" . 1)
+      ("iacs" . 1)
+      ("iacl" . 1)
+      ("acflike" . 1)
+      ("acflike*" . 1)
+      ("acfplike" . 1)
+      ("acfplike*" . 1)
+      ("acsingle" . 1)
+      ("acsingle*" . 1)
+      ("Acsingle" . 1)
+      ("Acsingle*" . 1)
+      ("acreset" . 1)
+      ("acuse" . 1)
+      ("acsetup" . 1)
+      ;; attachfile.sty
+      ("attachfile" . 1)
+      ("attachfilesetup" . 1)
+      ("textattachfile" . 1)
+      ;; booktabs.sty
+      ("specialrule" . 3)
+      ;; cleveref.sty
+      ("cref" . 1)
+      ("Cref" . 1)
+      ("cref*" . 1)
+      ("Cref*" . 1)
+      ("cpageref" . 1)
+      ("Cpageref" . 1)
+      ("namecref" . 1)
+      ("nameCref" . 1)
+      ("lcnamecref" . 1)
+      ("labelcref" . 1)
+      ("crefrange" . 1)
+      ("Crefrange" . 1)
+      ("cpagerefrange" . 1)
+      ("Cpagerefrange" . 1)
+      ("crefrange*" . 1)
+      ("Crefrange*" . 1)
+      ("crefrange" . 2)
+      ("Crefrange" . 2)
+      ("cpagerefrange" . 2)
+      ("Cpagerefrange" . 2)
+      ("crefrange*" . 2)
+      ("Crefrange*" . 2)
+      ;; fancyref.sty
+      ("fref" . 1)
+      ("Fref" . 1)
+      ;; fancyvrb.sty
+      ("fvset" . 1)
+      ("VerbatimInput" . 1)
+      ;; fontaxes.sty
+      ("figureversion" . 1)
+      ;; fontspec.sty
+      ("addfontfeatures" . 1)
+      ;; ("fontspec" . 1)
+      ;; listings.sty
+      ("lstinputlisting" . 1)
+      ("lstset" . 1)
+      ;; mdframed.sty
+      ("mdfsetup" . 1)
+      ("mdfapptodefinestyle" . 2)
+      ;; nameref.sty
+      ("nameref" . 1)
+      ("Nameref" . 1)
+      ;; siunitx.sty
+      ("num" . 1)
+      ("si" . 1)
+      ("sisetup" . 1)
+      ("SI" . 2)
+      ;; splitidx.sty
+      ("sindex" . 1)
+      ;; varioref.sty
+      ("vref" . 1)
+      ("Vref" . 1)
+      ("vref*" . 1)
+      ("Ref" . 1)
+      ("vpageref" . 1)
+      ("vpageref*" . 1)
+      ("fullref" . 1)
+      ("vrefrange" . 1)
+      ("vrefrange*" . 1)
+      ("vpagerefrange" . 1)
+      ("vpagerefrange*" . 1)
+      ("vrefrange" . 2)
+      ("vrefrange*" . 2)
+      ("vpagerefrange" . 2)
+      ("vpagerefrange*" . 2) )
+    "List of commands with arguments to be skipped.
+Each element of the list is a cons cell with command name
+\(string) as car and the number of mandatory arguments to be
+skipped as cdr."))
+
+
+;; Add new environments with optional argument here:
+(eval-when-compile
+  (defvar TeX-ispell-skip-envs-opt-arg-list
+    '(;; enumitem.sty
+      "description"
+      "description*"
+      "enumerate"
+      "enumerate*"
+      "itemize"
+      "itemize*"
+      ;; mdframed.sty
+      "mdframed")
+    "List of LaTeX environments with an opt argument to be skipped."))
+
+
+;; Add others delimited here:
+(TeX-ispell-skip-setcar
+ '(;; LaTeX-base
+   ("\\\\raisebox" TeX-ispell-tex-arg-end 1 2 0)
+   ;; booktabs.sty
+   ("\\\\cmidrule" . "\\(([^)]*)\\)?{[-0-9]+}")
+   ;; siunitx.sty
+   ("\\\\fontspec" TeX-ispell-tex-arg-end 1 1 0)))
+
+
+;; Add environments here:
+(TeX-ispell-skip-setcdr
+ '(;; amsmath.sty
+   ("\\(align\\(\\*\\|at\\*?\\)?\\|flalign\\*?\\)" .
+    "\\\\end{\\(align\\(\\*\\|at\\*?\\)?\\|flalign\\*?\\)}")
+   ("gather\\*?" . "\\\\end{gather\\*?}")
+   ("multline\\*?" . "\\\\end{multline\\*?}")
+   ;; listings.sty
+   ("lstlisting" . "\\\\end{lstlisting}")
+   ;; tabularx.sty, tabulary.sty, Standard LaTeX tabular*-env
+   ("tabular[*xy]" TeX-ispell-tex-arg-end)
+   ;; tikz.sty
+   ("tikzpicture" . "\\\\end{tikzpicture}")
+   ;; fancyvrb.sty: In practice, all verbatim environments have a *
+   ;; variant, which sets showspaces=true
+   ("\\(Save\\|[BL]\\)?Verbatim\\(\\*\\|Out\\)?" .
+    "\\\\end{\\(Save\\|[BL]\\)?Verbatim\\(\\*\\|Out\\)?}")))
+
+
+;; No customization below this line
+
+(eval-when-compile
+  (defun TeX-ispell-sort-skip-cmds-list (arg)
+    "Return elements from `TeX-ispell-skip-cmds-list' acc. to ARG."
+    (when (member arg '(1 2 3))
+      (let (cmds)
+	(dolist (elt TeX-ispell-skip-cmds-list)
+	  (when (= (cdr elt) arg)
+	    (push (car elt) cmds)))
+	(symbol-value 'cmds)))))
+
+(defvar TeX-ispell-skip-cmds-one-arg-regexp
+  (eval-when-compile
+    (concat "\\\\"
+	    (regexp-opt (TeX-ispell-sort-skip-cmds-list 1) t)))
+  "Regexp of LaTeX commands with one argument to be skipped.")
+
+(defvar TeX-ispell-skip-cmds-two-args-regexp
+  (eval-when-compile
+    (concat "\\\\"
+	    (regexp-opt (TeX-ispell-sort-skip-cmds-list 2) t)))
+  "Regexp of LaTeX commands with two arguments to be skipped.")
+
+(defvar TeX-ispell-skip-cmds-three-args-regexp
+  (eval-when-compile
+    (concat "\\\\"
+	    (regexp-opt (TeX-ispell-sort-skip-cmds-list 3) t)))
+  "Regexp of LaTeX commands with three arguments to be skipped.")
+
+(defvar TeX-ispell-skip-envs-opt-arg-regexp
+  (eval-when-compile
+    (regexp-opt TeX-ispell-skip-envs-opt-arg-list t))
+  "Regexp of LaTeX environments with an opt argument to be skipped.")
+
+;; Make them available to Ispell:
+(TeX-ispell-skip-setcar
+ `((,TeX-ispell-skip-cmds-one-arg-regexp ispell-tex-arg-end)
+   (,TeX-ispell-skip-cmds-two-args-regexp ispell-tex-arg-end 2)
+   (,TeX-ispell-skip-cmds-three-args-regexp ispell-tex-arg-end 3)))
+
+(TeX-ispell-skip-setcdr
+ `((,TeX-ispell-skip-envs-opt-arg-regexp ispell-tex-arg-end 0)))
+
+(provide 'tex-ispell)
+
+;;; tex-ispell.el ends here
diff --git a/tex.el b/tex.el
index 6c302bb..7e41113 100644
--- a/tex.el
+++ b/tex.el
@@ -6521,6 +6521,87 @@ NAME may be a package, a command, or a document."
       (append '(plain-tex-mode ams-tex-mode latex-mode doctex-mode)
 	      ispell-tex-major-modes))
 
+(defcustom TeX-ispell-extend-skip-list t
+  "Whether to extend regions selected for skipping during spell checking."
+  :group 'TeX-misc
+  :type 'boolean)
+
+;; These functions are used to add new items to
+;; `ispell-tex-skip-alists' -- see tex-ispell.el:
+(defun TeX-ispell-skip-setcar (skip)
+  "Add SKIP to car of `ispell-tex-skip-alists'.
+SKIP is an alist with the format described in
+`ispell-tex-skip-alists'.  Each element in SKIP is added on top
+of the car of `ispell-tex-skip-alists'.  This only happens if
+`TeX-ispell-extend-skip-list' is non-nil."
+  (when TeX-ispell-extend-skip-list
+    (let ((raws (car ispell-tex-skip-alists))
+	  (envs (cadr ispell-tex-skip-alists)))
+      (dolist (x skip)
+	(pushnew x raws :test #'equal))
+      (setq ispell-tex-skip-alists (list raws envs)))))
+
+(defun TeX-ispell-skip-setcdr (skip)
+  "Add SKIP to cdr of `ispell-tex-skip-alists'.
+SKIP is an alist with the format described in
+`ispell-tex-skip-alists'.  Each element in SKIP is added on top
+of the cdr of `ispell-tex-skip-alists'.  This only happens if
+`TeX-ispell-extend-skip-list' is non-nil."
+  (when TeX-ispell-extend-skip-list
+    (let ((raws (car ispell-tex-skip-alists))
+	  (envs (cadr ispell-tex-skip-alists)))
+      (dolist (x skip)
+	(pushnew x envs :test #'equal))
+      (setq ispell-tex-skip-alists (list raws envs)))))
+
+(defun TeX-ispell-tex-arg-end (&optional arg1 arg2 arg3)
+  "Skip across ARG1, ARG2 and ARG3 number of braces and brackets.
+This function is a variation of `ispell-tex-arg-end'.  It should
+be used when adding skip regions to `ispell-tex-skip-alists' for
+constructs like:
+
+  \\begin{tabularx}{300pt}[t]{lrc} ...
+    or
+  \\fontspec{font name}[font features]
+
+where optional and/or mandatory argument(s) follow(s) a mandatory
+one.  ARG1 is the number of mandatory arguments before the
+optional one, ARG2 the max. number of following optional
+arguments, ARG3 is the max. number of mandatory arguments
+following.  Omitting argument means 1.
+
+Here some examples for additions to `ispell-tex-skip-alists':
+
+  \\begin{tabularx}{300pt}[t]{lrc} ...
+		ARG  1    2   3
+  (\"tabularx\" TeX-ispell-tex-arg-end) or equivalent
+  (\"tabularx\" TeX-ispell-tex-arg-end 1 1 1)
+
+  \\fontspec{font name}[font features]
+	       ARG1         ARG2        ARG3=0
+  (\"\\\\\\\\fontspec\" TeX-ispell-tex-arg-end 1 1 0)
+
+  \\raisebox{lift}[height][depth]{contents}
+	    ARG1       ARG2       ARG3=0 (checked by Ispell)
+  (\"\\\\\\\\raisebox\" TeX-ispell-tex-arg-end 1 2 0)
+
+Optional arguments before the first mandatory one are all
+skipped."
+  (condition-case nil
+      (progn
+	(while (looking-at "[ \t\n]*\\[") (forward-sexp))
+	(forward-sexp (or arg1 1))
+	(let ((num 0))
+	  (while (and (looking-at "[ \t\n]*\\[")
+		      (< num (or arg2 1)))
+	    (setq num (1+ num))
+	    (forward-sexp)))
+	(forward-sexp (or arg3 1)))
+    (error
+     (message "Error skipping s-expressions at point %d." (point))
+     (beep)
+     (sit-for 2))))
+
 
 ;;; Abbrev mode
 
_______________________________________________
auctex-devel mailing list
auctex-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/auctex-devel

Reply via email to