1;;; tex-ispell.el --- AUCTeX skip additions for Ispell
2
3;; Copyright (C) 2016--2018 Free Software Foundation, Inc.
4
5;; Author: Arash Esbati <arash@gnu.org>
6;; Maintainer: auctex-devel@gnu.org
7;; Keywords: tex, wp, convenience
8
9;; This file is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 3, or (at your option)
12;; any later version.
13
14;; This file is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17;; GNU General Public License for more details.
18
19;; You should have received a copy of the GNU General Public License
20;; along with GNU Emacs; see the file COPYING.  If not, write to
21;; the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22;; Boston, MA 02110-1301, USA.
23
24;;; Commentary:
25
26;; This file provides additions to skip list of Ispell (in this
27;; context, Ispell is synonym for Ispell, Aspell and Hunspell spelling
28;; checker programs).  Macro arguments and environments skipped by
29;; Ispell are stored in the car and/or cdr of
30;; `ispell-tex-skip-alists'.  This file uses two functions
31;; `TeX-ispell-skip-setcar' and `TeX-ispell-skip-setcdr' defined in
32;; `tex.el' to add new items to this variable.
33
34;; Ispell has a lot of LaTeX macros and environments already built-in.
35;; E.g., check this link for Hunspell program:
36
37;; https://github.com/hunspell/hunspell/blob/master/src/parsers/latexparser.cxx
38
39;; Ispell does not check spelling in the preamble of a document.
40;; Hence, only document macros and environments should be added here.
41;; Currently, this file has support for the following macro packages:
42
43;; acro.sty
44;; amsmath.sty
45;; attachfile.sty
46;; booktabs.sty
47;; breqn.sty
48;; cleveref.sty
49;; empheq.sty
50;; enumitem.sty
51;; fancyref.sty
52;; fancyvrb.sty
53;; filecontents.sty
54;; fontaxes.sty
55;; fontspec.sty
56;; hyperref.sty
57;; listings.sty
58;; ltxtable.sty
59;; mdframed.sty
60;; minted.sty
61;; nameref.sty
62;; pythontex.sty
63;; siunitx.sty
64;; splitidx.sty
65;; tabularx.sty
66;; tabulary.sty
67;; tcolorbox.sty
68;; tikz.sty
69;; varioref.sty
70;; xltabular.sty
71
72;; If you have further additions, drop a line to <auctex-devel@gnu.org>.
73
74;;; Code:
75
76(require 'tex)
77
78;; Add new macros here:
79(eval-when-compile
80  (defvar TeX-ispell-skip-cmds-list
81    '(;; acro.sty
82      ("ac" . 1)
83      ("ac*" . 1)
84      ("Ac" . 1)
85      ("Ac*" . 1)
86      ("acs" . 1)
87      ("acs*" . 1)
88      ("acl" . 1)
89      ("acl*" . 1)
90      ("Acl" . 1)
91      ("Acl*" . 1)
92      ("aca" . 1)
93      ("aca*" . 1)
94      ("acf" . 1)
95      ("acf*" . 1)
96      ("Acf" . 1)
97      ("Acf*" . 1)
98      ("acp" . 1)
99      ("acp*" . 1)
100      ("Acp" . 1)
101      ("Acp*" . 1)
102      ("acsp" . 1)
103      ("acsp*" . 1)
104      ("aclp" . 1)
105      ("aclp*" . 1)
106      ("Aclp" . 1)
107      ("Aclp*" . 1)
108      ("acap" . 1)
109      ("acap*" . 1)
110      ("acfp" . 1)
111      ("acfp*" . 1)
112      ("Acfp" . 1)
113      ("Acfp*" . 1)
114      ("Iac" . 1)
115      ("iacs" . 1)
116      ("iacl" . 1)
117      ("acflike" . 1)
118      ("acflike*" . 1)
119      ("acfplike" . 1)
120      ("acfplike*" . 1)
121      ("acsingle" . 1)
122      ("acsingle*" . 1)
123      ("Acsingle" . 1)
124      ("Acsingle*" . 1)
125      ("acreset" . 1)
126      ("acuse" . 1)
127      ("acsetup" . 1)
128      ;; attachfile.sty
129      ("attachfile" . 1)
130      ("attachfilesetup" . 1)
131      ("textattachfile" . 1)
132      ;; booktabs.sty
133      ("addlinespace" . 0)
134      ("specialrule" . 3)
135      ;; cleveref.sty
136      ("cref" . 1)
137      ("Cref" . 1)
138      ("cref*" . 1)
139      ("Cref*" . 1)
140      ("cpageref" . 1)
141      ("Cpageref" . 1)
142      ("namecref" . 1)
143      ("nameCref" . 1)
144      ("lcnamecref" . 1)
145      ("labelcref" . 1)
146      ("crefrange" . 2)
147      ("Crefrange" . 2)
148      ("cpagerefrange" . 2)
149      ("Cpagerefrange" . 2)
150      ("crefrange*" . 2)
151      ("Crefrange*" . 2)
152      ;; empheq.sty
153      ("empheqset" . 1)
154      ;; fancyref.sty
155      ("fref" . 1)
156      ("Fref" . 1)
157      ;; fancyvrb.sty
158      ("fvset" . 1)
159      ("VerbatimInput" . 1)
160      ;; fontaxes.sty
161      ("figureversion" . 1)
162      ;; fontspec.sty
163      ("addfontfeatures" . 1)
164      ;; hyperref.sty
165      ("hypersetup" . 1)
166      ("href" . 1)
167      ("url" . 1)
168      ("nolinkurl" . 1)
169      ("hyperbaseurl" . 1)
170      ("hyperimage" . 1)
171      ("hyperdef" . 2)
172      ("hyperref" . 3)
173      ("hyperlink" . 1)
174      ("hypertarget" . 1)
175      ("autoref" . 1)
176      ("autoref*" . 1)
177      ("autopageref" . 1)
178      ("autopageref*" . 1)
179      ;; listings.sty
180      ("lstinputlisting" . 1)
181      ("lstset" . 1)
182      ;; ltxtable.sty
183      ("LTXtable" . 2)
184      ;; mdframed.sty
185      ("mdfsetup" . 1)
186      ("mdfapptodefinestyle" . 2)
187      ;; minted.sty
188      ("inputminted" . 2)
189      ("setminted" . 1)
190      ("setmintedinline" . 1)
191      ;; nameref.sty
192      ("nameref" . 1)
193      ("Nameref" . 1)
194      ;; pythontex.sty: Only add the macros which will be used in the
195      ;; document; others should be in the preamble
196      ("setpythontexfv" . 1)
197      ("useprintpythontex" . 1)
198      ("usestdoutpythontex" . 1)
199      ("inputpygments" . 1)
200      ("setpygmentsfv" . 1)
201      ("setpygmentspygopt" . 1)
202      ;; siunitx.sty
203      ("num" . 1)
204      ("si" . 1)
205      ("sisetup" . 1)
206      ("SI" . 2)
207      ;; splitidx.sty
208      ("sindex" . 1)
209      ;; tcolorbox.sty
210      ("tcbox" . 0)
211      ("tcbset" . 1)
212      ("tcbsetforeverylayer" . 1)
213      ;; tcolorbox.sty -- raster library
214      ("tcbitem" . 0)
215      ;; varioref.sty
216      ("vref" . 1)
217      ("Vref" . 1)
218      ("vref*" . 1)
219      ("Ref" . 1)
220      ("vpageref" . 1)
221      ("vpageref*" . 1)
222      ("fullref" . 1)
223      ("vrefrange" . 2)
224      ("vrefrange*" . 2)
225      ("vpagerefrange" . 2)
226      ("vpagerefrange*" . 2))
227    "List of commands with arguments to be skipped.
228Each element of the list is a cons cell with command name
229\(string) as car and the number of mandatory arguments to be
230skipped as cdr.  If number is 0, then only skip over the optional
231argument and spell check the mandatory one."))
232
233
234;; Add new environments with one optional argument here:
235(eval-when-compile
236  (defvar TeX-ispell-skip-envs-opt-arg-list
237    '(;; enumitem.sty
238      "description"
239      "description*"
240      "enumerate"
241      "enumerate*"
242      "itemize"
243      "itemize*"
244      ;; mdframed.sty
245      "mdframed"
246      ;; tcolorbox.sty
247      "tcolorbox"
248      ;; tcolorbox.sty -- raster library
249      "tcbraster"
250      "tcbitemize")
251    "List of LaTeX environments with an opt argument to be skipped."))
252
253
254;; Add new environments which should be skipped entirely here:
255(eval-when-compile
256  (defvar TeX-ispell-skip-envs-list
257    '(;; amsmath.sty
258      "align"
259      "align*"
260      "alignat"
261      "alignat*"
262      "flalign"
263      "flalign*"
264      "gather"
265      "gather*"
266      "multline"
267      "multline*"
268      ;; breqn.sty
269      "darray"
270      "darray*"
271      "dgroup"
272      "dgroup*"
273      "dmath"
274      "dmath*"
275      "dseries"
276      "dseries*"
277      ;; empheq.sty
278      "empheq"
279      ;; fancyvrb.sty
280      "BVerbatim"
281      "BVerbatim*"
282      "LVerbatim"
283      "LVerbatim*"
284      "SaveVerbatim"
285      "Verbatim"
286      "Verbatim*"
287      "VerbatimOut"
288      ;; listings.sty
289      "lstlisting"
290      ;; minted.sty
291      "minted"
292      ;; pythontex.sty
293      "pycode"
294      "pysub"
295      "pyverbatim"
296      "pyblock"
297      "pyconsole"
298      "pyconcode"
299      "pyconverbatim"
300      "pylabcode"
301      "pylabsub"
302      "pylabverbatim"
303      "pylabblock"
304      "pylabconsole"
305      "pylabconcode"
306      "pylabconverbatim"
307      "sympycode"
308      "sympysub"
309      "sympyverbatim"
310      "sympyblock"
311      "sympyconsole"
312      "sympyconcode"
313      "sympyconverbatim"
314      "pygments"
315      ;; tikz.sty
316      "tikzpicture")
317    "List of LaTeX environments which will be skipped entirely.
318Environments for math or verbatim text are candidates for this list."))
319
320
321;; Add others delimited here:
322(TeX-ispell-skip-setcar
323 `(;; LaTeX-base
324   ("\\\\(" . "\\\\)")
325   ("\\\\raisebox" TeX-ispell-tex-arg-end 1 2 0)
326   ;; booktabs.sty
327   ("\\\\cmidrule" . "{[-0-9]+}")
328   ;; fontspec.sty
329   ("\\\\fontspec" TeX-ispell-tex-arg-end 1 1 0)))
330
331
332;; Special setup for verbatim macros:
333(defcustom TeX-ispell-verb-delimiters "!|#~\"/+^-"
334  "String with all delimiters for verbatim macros.
335Characters special in regexps like `^' and `-' must come last and
336not be quoted.  An opening brace `{', asterisk `*' and at-sign
337`@' should not be used as they are not recognized by
338`font-latex.el' correctly."
339  :group 'TeX-misc
340  :type 'string)
341
342;; listings.sty, fancyvrb.sty, pythontex.sty: With opt. argument only
343;; before verb content:
344(TeX-ispell-skip-setcar
345 `((,(concat "\\\\" (regexp-opt '("Verb"     "lstinline"
346				  "py"       "pyc"       "pys"    "pyv" "pyb"
347				  "pycon"    "pyconc"    "pyconv"
348				  "pylab"    "pylabc"    "pylabs" "pylabv" "pylabb"
349				  "pylabcon" "pylabconc" "pylabconv"
350				  "sympy"    "sympyc"    "sympys" "sympyv" "sympyb"
351				  "sympycon" "sympyconc" "sympyconv")))
352    TeX-ispell-tex-arg-verb-end)))
353
354;; minted.sty: With opt. and mandatory argument before verb content.
355;; pythontex.sty: With one mandatory argument before verb content:
356(TeX-ispell-skip-setcar
357 `((,(concat "\\\\" (regexp-opt '("mint" "mintinline" "pygment")))
358    TeX-ispell-tex-arg-verb-end 1)))
359
360
361;; Add environments here:
362(TeX-ispell-skip-setcdr
363 '(;; filecontents.sty
364   ("filecontents\\*?" ispell-tex-arg-end)
365   ;; tabularx.sty, tabulary.sty, Standard LaTeX tabular*-env
366   ("tabular[*xy]" TeX-ispell-tex-arg-end)
367   ;; tcolorbox.sty -- raster library
368   ("tcboxed\\(raster\\|itemize\\)" ispell-tex-arg-end)
369   ;; xltabular.sty
370   ("xltabular" ispell-tex-arg-end 2)))
371
372
373;; No customization below this line
374
375(eval-when-compile
376  (defun TeX-ispell-sort-skip-cmds-list (arg)
377    "Return elements from `TeX-ispell-skip-cmds-list' acc. to ARG."
378    (when (member arg '(0 1 2 3))
379      (let (cmds)
380	(dolist (elt TeX-ispell-skip-cmds-list)
381	  (when (= (cdr elt) arg)
382	    (push (car elt) cmds)))
383	cmds))))
384
385(defvar TeX-ispell-skip-cmds-opt-arg-regexp
386  (eval-when-compile
387    (concat "\\\\"
388	    (regexp-opt (TeX-ispell-sort-skip-cmds-list 0) t)))
389  "Regexp of LaTeX commands with only optional arguments to be skipped.")
390
391(defvar TeX-ispell-skip-cmds-one-arg-regexp
392  (eval-when-compile
393    (concat "\\\\"
394	    (regexp-opt (TeX-ispell-sort-skip-cmds-list 1) t)))
395  "Regexp of LaTeX commands with one argument to be skipped.")
396
397(defvar TeX-ispell-skip-cmds-two-args-regexp
398  (eval-when-compile
399    (concat "\\\\"
400	    (regexp-opt (TeX-ispell-sort-skip-cmds-list 2) t)))
401  "Regexp of LaTeX commands with two arguments to be skipped.")
402
403(defvar TeX-ispell-skip-cmds-three-args-regexp
404  (eval-when-compile
405    (concat "\\\\"
406	    (regexp-opt (TeX-ispell-sort-skip-cmds-list 3) t)))
407  "Regexp of LaTeX commands with three arguments to be skipped.")
408
409(defvar TeX-ispell-skip-envs-opt-arg-regexp
410  (eval-when-compile
411    (regexp-opt TeX-ispell-skip-envs-opt-arg-list t))
412  "Regexp of LaTeX environments with an opt argument to be skipped.")
413
414(defvar TeX-ispell-skip-envs-regexp
415  (eval-when-compile
416    (regexp-opt TeX-ispell-skip-envs-list t))
417  "Regexp of LaTeX environments which will be skipped entirely.")
418
419;; Make them available to Ispell:
420(TeX-ispell-skip-setcar
421 `((,TeX-ispell-skip-cmds-opt-arg-regexp ispell-tex-arg-end 0)
422   (,TeX-ispell-skip-cmds-one-arg-regexp ispell-tex-arg-end)
423   (,TeX-ispell-skip-cmds-two-args-regexp ispell-tex-arg-end 2)
424   (,TeX-ispell-skip-cmds-three-args-regexp ispell-tex-arg-end 3)))
425
426(TeX-ispell-skip-setcdr
427 `((,TeX-ispell-skip-envs-opt-arg-regexp ispell-tex-arg-end 0)
428   ,(cons TeX-ispell-skip-envs-regexp
429	  (concat "\\\\end{" TeX-ispell-skip-envs-regexp "}"))))
430
431(provide 'tex-ispell)
432
433;;; tex-ispell.el ends here
434