Revision | 7d171c6a7406d25f4e732cb045f4b0400e5db988 (tree) |
---|---|
Time | 2010-12-02 01:10:40 |
Author | lorenzo |
Commiter | lorenzo |
I added a file which should help emacs to deal with non-English spelling in
latex documents.
@@ -0,0 +1,482 @@ | ||
1 | +;; flyspell-babel.el -- Switch flyspell language according to LaTeX | |
2 | +;; Babel commands | |
3 | +;; | |
4 | +;; Copyright (C) 2004 P J Heslin | |
5 | +;; | |
6 | +;; Author: Peter Heslin <p.j.heslin@dur.ac.uk> | |
7 | +;; URL: http://www.dur.ac.uk/p.j.heslin/Software/Emacs/Download/flyspell-babel.el | |
8 | +;; Version: 3.2 | |
9 | +;; | |
10 | +;; This program is free software; you can redistribute it and/or modify | |
11 | +;; it under the terms of the GNU General Public License as published by | |
12 | +;; the Free Software Foundation; either version 2, or (at your option) | |
13 | +;; any later version. | |
14 | +;; | |
15 | +;; This program is distributed in the hope that it will be useful, | |
16 | +;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | +;; GNU General Public License for more details. | |
19 | +;; | |
20 | +;; If you do not have a copy of the GNU General Public License, you | |
21 | +;; can obtain one by writing to the Free Software Foundation, Inc., 59 | |
22 | +;; Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
23 | + | |
24 | +;;; Installation: | |
25 | +;; | |
26 | +;; Flyspell is an Emacs package that highlights misspelled words as | |
27 | +;; you type; Babel is the standard mechanism for switching languages | |
28 | +;; in LaTeX. There are a number of Emacs packages available that will | |
29 | +;; try to guess the current language of a buffer or part of a buffer, | |
30 | +;; and make flyspell switch to a different dictionary; but I didn't | |
31 | +;; find one that used the explicit language-switching commands | |
32 | +;; available in a LaTeX file for this purpose. This package makes | |
33 | +;; flyspell use the correct dictionary for the language used in each | |
34 | +;; part of a LaTeX file. There are some restrictions on the usage of | |
35 | +;; Babel commands, on which see below. | |
36 | +;; | |
37 | +;; flyspell-babel requires ispell-multi to be installed; it may be | |
38 | +;; found in the same directory indicated by the URL above. It also | |
39 | +;; needs flyspell to be installed (version 1.7f or better) and | |
40 | +;; flyspell-mode to be active. If you are using Emacs 21.3 or | |
41 | +;; earlier, you will need to upgrade to ispell.el version 3.6, | |
42 | +;; available from http://www.kdstevens.com/~stevens/ispell-page.html. | |
43 | +;; | |
44 | +;; To use this file, put it somewhere in your load-path, and add this | |
45 | +;; to your .emacs file: | |
46 | +;; | |
47 | +;; (autoload 'flyspell-babel-setup "flyspell-babel") | |
48 | +;; (add-hook 'latex-mode-hook 'flyspell-babel-setup) | |
49 | +;; | |
50 | +;; You will need to reload flyspell-babel.el if you install any new | |
51 | +;; ispell languages or language aliases. | |
52 | +;; | |
53 | +;; I have only tested this with GNU Emacs. | |
54 | + | |
55 | +;;; Commentary: | |
56 | +;; | |
57 | +;; This package examines the LaTeX code around point to discover the | |
58 | +;; language of the current text, and then it caches that value in a | |
59 | +;; text-property. This means that, if you modify or add a Babel | |
60 | +;; command to change the language of some text, the current language | |
61 | +;; may be out of sync with the cached value. In this case, you can | |
62 | +;; just stop typing for a bit, and the surrounding text will be | |
63 | +;; re-parsed, and the new, correct language should be determined. The | |
64 | +;; length of time that Emacs is idle before this re-parsing happens is | |
65 | +;; configurable via the variable flyspell-babel-delay (default is 5 | |
66 | +;; seconds). | |
67 | +;; | |
68 | +;; The parsing done by this package has its limits limited, and so it | |
69 | +;; will not work with arbitrary LaTeX code. I hope that these | |
70 | +;; restrictions will not in practice impinge on the typical usage of | |
71 | +;; most people. The first language declaration is usually determined | |
72 | +;; by the final language option passed to the babel \usepackage | |
73 | +;; command, which takes effect after \begin{document}. Thereafter, | |
74 | +;; you can switch the declared language with \selectlanguage | |
75 | +;; statements, otherlanguage environments, and \foreignlanguage | |
76 | +;; commands. You can also define your own language-switching | |
77 | +;; commands, and register these with flyspell-babel. | |
78 | +;; | |
79 | +;; This package does not understand complex LaTeX constructs, such as | |
80 | +;; \input. If you want to set the default language for a particular | |
81 | +;; file (for example, one that has no Babel declaration, but is going | |
82 | +;; to be \input into a file that does), you can just put a redundant | |
83 | +;; \selectlanguage declaration at the start of the file. You can | |
84 | +;; limit the scope of a \selectlanguage declaration by putting an | |
85 | +;; opening brace immediately before it, and flyspell-babel will | |
86 | +;; respect that scoping, but not otherwise, since that would make the | |
87 | +;; task of parsing too complex. | |
88 | +;; | |
89 | +;; By default, an ispell dictionary is invoked with the same name as | |
90 | +;; the current Babel language or dialect, which works in many cases. | |
91 | +;; If your ispell has a different name for that language, you have two | |
92 | +;; options. You can make ispell recognize the Babel name by adding | |
93 | +;; symlinks under that name in your Ispell directory. Alternatively, | |
94 | +;; you can customize flyspell-babel-to-ispell-alist, which maps Babel | |
95 | +;; languages and dialects to Ispell language names. If you map a | |
96 | +;; language to 'nil, that means not to spell-check that language, | |
97 | +;; which can be useful for languages without an ispell dictionary. | |
98 | + | |
99 | +;;; Customization: | |
100 | +;; | |
101 | +;; The code that follows is an example of my customization of this | |
102 | +;; package. The first form tells the package to turn on debugging | |
103 | +;; messages to see when we switch dictionaries as we move from place | |
104 | +;; to place. The second tells it not to spell-check the languages | |
105 | +;; "latin" and "ibycus" (an encoding for ancient Greek), since I don't | |
106 | +;; have ispell dictionaries for them; it also tells it to translate | |
107 | +;; the Babel language "french" to the ispell dictionary "francais". | |
108 | +;; The third form defines some language-switching shortcut commands, | |
109 | +;; so that I can more easily say \fr{merci} and \itl{grazie}. The | |
110 | +;; fourth defines some short-cut environments, since \begin{german} is | |
111 | +;; a lot easier to write than \begin{otherlanguage}{german}. The last | |
112 | +;; form defines some shortcut declarations for switching between | |
113 | +;; American and British spelling. | |
114 | +;; | |
115 | +;; (setq flyspell-babel-verbose t) | |
116 | +;; | |
117 | +;; (setq flyspell-babel-to-ispell-alist | |
118 | +;; '(("latin" nil) | |
119 | +;; ("ibycus" nil) | |
120 | +;; ("french" "francais"))) | |
121 | +;; | |
122 | +;; (setq flyspell-babel-command-alist | |
123 | +;; '(("lat" "latin") | |
124 | +;; ("gk" "ibycus") | |
125 | +;; ("fr" "french") | |
126 | +;; ("ger" "german") | |
127 | +;; ("itl" "italian"))) | |
128 | +;; | |
129 | +;; (setq flyspell-babel-environment-alist | |
130 | +;; '(("latin" "latin") | |
131 | +;; ("greek" "ibycus") | |
132 | +;; ("french" "french") | |
133 | +;; ("german" "german") | |
134 | +;; ("italian" "italian"))) | |
135 | +;; | |
136 | +;; (setq flyspell-babel-declaration-alist | |
137 | +;; '(("yank" "american") | |
138 | +;; ("brit" "british"))) | |
139 | +;; | |
140 | +;; Here is the LaTeX code that defines these short-cuts: | |
141 | +;; | |
142 | +;; \usepackage[ibycus,latin,french,german,italian,british,american]{babel} | |
143 | +;; | |
144 | +;; \newcommand{\lat}[1]{\foreignlanguage{latin}{\emph{#1}}} | |
145 | +;; \newenvironment{latin}{\begin{otherlanguage}{latin}}{\end{otherlanguage}} | |
146 | +;; | |
147 | +;; \newcommand{\fr}[1]{\foreignlanguage{french}{\emph{#1}}} | |
148 | +;; \newenvironment{french}{\begin{otherlanguage}{french}}{\end{otherlanguage}} | |
149 | +;; | |
150 | +;; \newcommand{\ger}[1]{\foreignlanguage{german}{\emph{#1}}} | |
151 | +;; \newenvironment{german}{\begin{otherlanguage}{german}}{\end{otherlanguage}} | |
152 | +;; | |
153 | +;; \newcommand{\itl}[1]{\foreignlanguage{italian}{\emph{#1}}} | |
154 | +;; \newenvironment{italian}{\begin{otherlanguage}{italian}}{\end{otherlanguage}} | |
155 | +;; | |
156 | +;; \newcommand{\yank}{\selectlanguage{american}} | |
157 | +;; \newcommand{\brit}{\selectlanguage{british}} | |
158 | + | |
159 | +;;; Bugs: | |
160 | +;; | |
161 | +;; If a word comes to be erroneously highlighted as misspelled because | |
162 | +;; you have recently changed a Babel command, then the normal thing to | |
163 | +;; do is to wait a few seconds until the idle-timer runs the code to | |
164 | +;; re-parse the text. This works, except when the new Babel language | |
165 | +;; is mapped to 'nil, meaning that it shouldn't be spell-checked at | |
166 | +;; all. When this is the case, the spell-checking mechanism is | |
167 | +;; by-passed completely, so the erroneous highlighting will not be | |
168 | +;; removed, since those words will not be re-recognized as "correctly" | |
169 | +;; spelled. The best thing to do in this case is to switch | |
170 | +;; flyspell-mode off and on again, which will remove all flyspell | |
171 | +;; highlighting. | |
172 | + | |
173 | +;;; Changes | |
174 | +;; | |
175 | +;; 3.2 Made flyspell-babel-parse-block non-recursive to avoid blowing | |
176 | +;; max-lisp-eval-depth in long files | |
177 | +;; 3.1 Fixed bug when \usepackage[foo]{babel} was commented out | |
178 | +;; 3.0 Re-factored to use new ispell-multi.el. | |
179 | +;; 2.0 Major re-write. Instead of partially-parsing every time a word | |
180 | +;; is spell-checked, we now cache the language in a text property, | |
181 | +;; and use an idle timer to re-parse in case the language has | |
182 | +;; changed. | |
183 | +;; 1.3 Only use ispell-valid-dictionary-list if it's available | |
184 | +;; 1.2 Removed dependency on AUCTeX and newcomment and fixed bug when | |
185 | +;; disabling flyspell-large-region | |
186 | +;; 1.1 Removed error report when \usepackage{babel} not present | |
187 | +;; 1.0 Initial public release | |
188 | + | |
189 | +(require 'ispell-multi) | |
190 | +(require 'flyspell) | |
191 | + | |
192 | +(defgroup flyspell-babel nil | |
193 | + "Switch flyspell language according to LaTeX babel commands" | |
194 | + :tag "Switch flyspell language according to Babel commands" | |
195 | + :group 'tex | |
196 | + :prefix "flyspell-babel-") | |
197 | + | |
198 | +(defcustom flyspell-babel-to-ispell-alist () | |
199 | + "Maps LaTeX babel language or dialect names to ispell | |
200 | + dictionaries" | |
201 | + :type 'alist | |
202 | + :group 'flyspell-babel) | |
203 | + | |
204 | +(defcustom flyspell-babel-declaration-alist () | |
205 | + "Maps LaTeX language-switching declarations (other than the | |
206 | + built-in babel \\selectlanguage declaration) to babel | |
207 | + languages" | |
208 | + :type 'alist | |
209 | + :group 'flyspell-babel) | |
210 | + | |
211 | +(defcustom flyspell-babel-environment-alist () | |
212 | + "Maps LaTeX language-switching environments (other than the | |
213 | + built-in babel \"otherlanguage\" environment) to babel languages" | |
214 | + :type 'alist | |
215 | + :group 'flyspell-babel) | |
216 | + | |
217 | +(defcustom flyspell-babel-command-alist () | |
218 | + "Maps LaTeX language-switching commands (other than the | |
219 | + built-in babel \\foreignlanguage command) to babel languages" | |
220 | + :type 'alist | |
221 | + :group 'flyspell-babel) | |
222 | + | |
223 | +(defcustom flyspell-babel-verbose nil | |
224 | + "Whether routinely to report changing from one language to another" | |
225 | + :type 'boolean | |
226 | + :group 'flyspell-babel) | |
227 | + | |
228 | +(defcustom flyspell-babel-delay 5 | |
229 | + "Seconds of idleness before current Babel block is re-parsed." | |
230 | + :type 'integer | |
231 | + :group 'flyspell-babel) | |
232 | + | |
233 | + | |
234 | +(defvar flyspell-babel-declaration-alist-all nil) | |
235 | +(defvar flyspell-babel-decl-regexp nil) | |
236 | +(defvar flyspell-babel-environment-alist-all nil) | |
237 | +(defvar flyspell-babel-env-regexp nil) | |
238 | +(defvar flyspell-babel-command-alist-all nil) | |
239 | +(defvar flyspell-babel-com-regexp nil) | |
240 | +(defvar flyspell-babel-decl-env-com-regexp nil) | |
241 | + | |
242 | +(setq flyspell-babel-declaration-alist-all | |
243 | + (append '(("selectlanguage" "selectlanguage")) | |
244 | + flyspell-babel-declaration-alist)) | |
245 | + | |
246 | +(setq flyspell-babel-decl-regexp | |
247 | + (concat "\\\\begin[ \t\n]*{document}" "\\|" | |
248 | + (mapconcat (lambda (pair) (concat "\\\\" (car pair) "[ \t\n{]")) | |
249 | + flyspell-babel-declaration-alist-all "\\|"))) | |
250 | + | |
251 | +(setq flyspell-babel-environment-alist-all | |
252 | + (append '(("otherlanguage" "otherlanguage")) | |
253 | + flyspell-babel-environment-alist)) | |
254 | + | |
255 | +(setq flyspell-babel-env-regexp | |
256 | + (mapconcat (lambda (pair) (concat "\\\\begin{" (car pair) "}")) | |
257 | + flyspell-babel-environment-alist-all "\\|")) | |
258 | + | |
259 | +(setq flyspell-babel-command-alist-all | |
260 | + (append '(("foreignlanguage" "foreignlanguage")) | |
261 | + flyspell-babel-command-alist)) | |
262 | + | |
263 | +(setq flyspell-babel-com-regexp | |
264 | + (mapconcat (lambda (pair) (concat "\\\\" (car pair) "[ \t\n{]")) | |
265 | + flyspell-babel-command-alist-all "\\|")) | |
266 | + | |
267 | +(setq flyspell-babel-decl-env-com-regexp | |
268 | + (mapconcat 'identity (list flyspell-babel-decl-regexp | |
269 | + flyspell-babel-env-regexp | |
270 | + flyspell-babel-com-regexp) "\\|")) | |
271 | + | |
272 | + | |
273 | +(defun flyspell-babel-parse-buffer () | |
274 | + (save-excursion | |
275 | + (goto-char (point-max)) | |
276 | + (flyspell-babel-parse))) | |
277 | + | |
278 | +(defun flyspell-babel-parse () | |
279 | + "Parse backward from point until containing element or bob is | |
280 | +found; then run forward and flag regions found." | |
281 | + (let ((current-position (point)) | |
282 | + beg end lang macro-begin tag-list finished) | |
283 | + (while (and (not finished) | |
284 | + (not (input-pending-p)) | |
285 | + (flyspell-babel-find-previous-macro nil)) | |
286 | + ;; We standardize on having the language switch happening | |
287 | + ;; just *after* regexp-match, since re-search-backward | |
288 | + ;; will fail to match when we are in the middle of a macro. | |
289 | + (setq beg (match-end 0)) | |
290 | + (setq macro-begin (point)) | |
291 | + (if (looking-at flyspell-babel-com-regexp) | |
292 | + (flyspell-babel-check-com) | |
293 | + (if (looking-at flyspell-babel-env-regexp) | |
294 | + (flyspell-babel-check-env) | |
295 | + (if (looking-at flyspell-babel-decl-regexp) | |
296 | + (flyspell-babel-check-decl) | |
297 | + (flyspell-babel-message "internal error 1")))) | |
298 | + (setq end (point)) | |
299 | + (when (< current-position end) | |
300 | + ;; Got it | |
301 | + (setq finished t) | |
302 | + ;; As an optimization, we flag the text after point | |
303 | + ;; as far as the start of the next Babel command. | |
304 | + (goto-char current-position) | |
305 | + (when (and (flyspell-babel-find-next-macro end) | |
306 | + (< current-position (point)) | |
307 | + (< (point) end)) | |
308 | + (setq end (1+ (point))))) | |
309 | + (setq tag-list (cons (list beg end lang) tag-list)) | |
310 | + (goto-char macro-begin)) | |
311 | + ;; Background is default lang | |
312 | + (setq tag-list (cons (list (point-min) current-position "no-command-found") tag-list)) | |
313 | + ;; We now run through in a forward direction | |
314 | + (while tag-list | |
315 | + (apply 'flyspell-babel-flag-region (car tag-list)) | |
316 | + (setq tag-list (cdr tag-list))))) | |
317 | + | |
318 | + | |
319 | + | |
320 | +(defun flyspell-babel-find-previous-macro (end) | |
321 | + (let ((found)) | |
322 | + (while (and (not found) | |
323 | + (re-search-backward flyspell-babel-decl-env-com-regexp end t)) | |
324 | + (setq found (not (flyspell-babel-in-comment-p)))) | |
325 | + found)) | |
326 | + | |
327 | +(defun flyspell-babel-find-next-macro (end) | |
328 | + (let ((found)) | |
329 | + (while (and (not found) | |
330 | + (re-search-forward flyspell-babel-decl-env-com-regexp end t)) | |
331 | + (setq found (not (flyspell-babel-in-comment-p)))) | |
332 | + found)) | |
333 | + | |
334 | +(defun flyspell-babel-check-com () | |
335 | + (if (re-search-forward | |
336 | + "\\=\\\\foreignlanguage[ \t\n]*{\\([^}]+\\)}[ \t\n]*{" nil t) | |
337 | + (setq lang (match-string 1)) | |
338 | + (if (re-search-forward "\\=\\\\\\([^{ \t\n]+\\)[ \t\n]*{" nil t) | |
339 | + (setq lang (cadr | |
340 | + (assoc (match-string 1) | |
341 | + flyspell-babel-command-alist-all))) | |
342 | + (flyspell-babel-message "internal error 2"))) | |
343 | + (backward-char) | |
344 | + (flyspell-babel-forward-sexp)) | |
345 | + | |
346 | +(defun flyspell-babel-check-env () | |
347 | + (let ((env)) | |
348 | + (if (looking-at "\\=\\\\begin{otherlanguage}[ \t\n]*{\\([^}]+\\)}") | |
349 | + (setq env "otherlanguage" lang (match-string 1)) | |
350 | + (if (looking-at "\\=\\\\begin[ \t\n]*{\\([^}]+\\)}") | |
351 | + (setq env (match-string 1) | |
352 | + lang (cadr | |
353 | + (assoc env flyspell-babel-environment-alist-all))) | |
354 | + (flyspell-babel-message "internal error 3"))) | |
355 | + (flyspell-babel-find-matching-end env) | |
356 | +; (backward-char))) | |
357 | + )) | |
358 | + | |
359 | +(defun flyspell-babel-check-decl () | |
360 | + (if (looking-at "\\\\begin[ \t\n]*{document}") | |
361 | + (progn | |
362 | + (if (save-excursion | |
363 | + (re-search-backward | |
364 | + ;; To exclude commented lines, only allow spaces before | |
365 | + "^[ \t\n]*\\\\usepackage.*[[,]\\([^]]+\\)\\]{babel}" nil t)) | |
366 | + (setq lang (match-string 1)) | |
367 | + (setq lang "no-command-found")) | |
368 | + (goto-char (point-max))) | |
369 | + (if (looking-at "\\\\selectlanguage[ \t\n]*{\\([^}]+\\)}") | |
370 | + (setq lang (match-string 1)) | |
371 | + (if (and (looking-at "\\\\\\([^{ \t\n]+\\)") | |
372 | + (cadr (assoc (match-string 1) | |
373 | + flyspell-babel-declaration-alist-all))) | |
374 | + (setq lang | |
375 | + (cadr (assoc (match-string 1) | |
376 | + flyspell-babel-declaration-alist-all))) | |
377 | + (flyspell-babel-message "internal error 4"))) | |
378 | + (unless (bobp) | |
379 | + (backward-char)) | |
380 | + (if (looking-at "{") | |
381 | + (flyspell-babel-forward-sexp) | |
382 | + (goto-char (point-max))))) | |
383 | + | |
384 | +(defun flyspell-babel-flag-region (beg end lang) | |
385 | + (let ((trans (assoc lang flyspell-babel-to-ispell-alist)) | |
386 | + (buffer-modified-before (buffer-modified-p)) | |
387 | + (after-change-functions nil)) | |
388 | + (when trans | |
389 | + ;; We have a translation of a Babel language name to ispell | |
390 | + ;; nomenclature | |
391 | + (setq lang (cadr trans))) | |
392 | + (cond | |
393 | + ((not lang) | |
394 | + ;; A parsed region with a nil dict -- don't spell-check. | |
395 | + (setq lang "void")) | |
396 | + ((equal lang "no-command-found") | |
397 | + (setq lang "default")) | |
398 | + ((and ispell-multi-valid-dictionary-list | |
399 | + (not (member lang ispell-multi-valid-dictionary-list))) | |
400 | + ;; A parsed region with an uninstalled dict | |
401 | + (message "Flyspell-babel warning: no dictionary installed for %s" lang) | |
402 | + (setq lang "void"))) | |
403 | + (put-text-property beg end 'ispell-multi-lang lang) | |
404 | + (set-buffer-modified-p buffer-modified-before))) | |
405 | + | |
406 | + | |
407 | +(defun flyspell-babel-forward-sexp (&optional arg) | |
408 | + "Makes sure to ignore comments when using forward-sexp, and | |
409 | + trap errors for unbalanced braces." | |
410 | + (interactive "p") | |
411 | + (let ((parse-sexp-ignore-comments t)) | |
412 | + (condition-case nil | |
413 | + (forward-sexp arg) | |
414 | + (error (goto-char (point-max)))))) | |
415 | + | |
416 | +(defun flyspell-babel-find-matching-end (env) | |
417 | + "Find end of current environment, or end of file when there is | |
418 | + no matching \end." | |
419 | + (interactive) | |
420 | + (let ((regexp (concat "\\\\\\(begin\\|end\\)[ \t\n]*{" env "}")) | |
421 | + (level 0) | |
422 | + (proceed t)) | |
423 | + (while proceed | |
424 | + (if (re-search-forward regexp nil t) | |
425 | + (let ((match (match-string 1))) | |
426 | + (unless (flyspell-babel-in-comment-p) | |
427 | + (if (string= match "begin") | |
428 | + (setq level (1+ level)) | |
429 | + (if (string= match "end") | |
430 | + (setq level (1- level)) | |
431 | + (flyspell-babel-message "internal error 5"))))) | |
432 | + (goto-char (point-max)) | |
433 | + (setq proceed nil)) | |
434 | + (when (= 0 level) | |
435 | + (setq proceed nil))))) | |
436 | + | |
437 | +(defun flyspell-babel-in-comment-p () | |
438 | + "Are we in a Latex comment? (Stolen from auctex tex.el)" | |
439 | + (save-match-data | |
440 | + (if (or (bolp) | |
441 | + (null comment-start-skip) | |
442 | + (eq (preceding-char) ?\r)) | |
443 | + nil | |
444 | + (save-excursion | |
445 | + (let ((pos (point))) | |
446 | + (re-search-backward "^\\|\r" nil t) | |
447 | + (or (looking-at comment-start-skip) | |
448 | + (re-search-forward comment-start-skip pos t))))))) | |
449 | + | |
450 | +(defun flyspell-babel-message (mess &optional force) | |
451 | + (when (or flyspell-babel-verbose force) | |
452 | + (message "Flyspell-babel -- %s" mess))) | |
453 | + | |
454 | +(defun flyspell-babel-start () | |
455 | + (flyspell-babel-parse-buffer) | |
456 | + (setq ispell-multi-nil-callback 'flyspell-babel-parse) | |
457 | + (make-local-variable 'flyspell-large-region) | |
458 | + (setq flyspell-large-region 'nil) | |
459 | + (flyspell-mode 1) | |
460 | + (setq flyspell-generic-check-word-p 'ispell-multi-verify) | |
461 | + (setq ispell-multi-idler-callback 'flyspell-babel-parse-buffer) | |
462 | + (ispell-multi-idler-setup flyspell-babel-delay) | |
463 | + (ispell-multi-hack-flyspell-modeline)) | |
464 | + | |
465 | +(defun flyspell-babel-stop () | |
466 | +; (ispell-multi-idler-cancel) | |
467 | + (setq flyspell-generic-check-word-p nil) | |
468 | + (ispell-multi-unhack-flyspell-modeline) | |
469 | + (flyspell-mode -1)) | |
470 | + | |
471 | +(define-minor-mode flyspell-babel-mode | |
472 | + "Mode to make flyspell language selection obey LaTeX Babel commands" nil | |
473 | + :group 'flyspell-babel | |
474 | + (if flyspell-babel-mode | |
475 | + (flyspell-babel-start) | |
476 | + (flyspell-babel-stop))) | |
477 | + | |
478 | +(defun flyspell-babel-setup () | |
479 | + (flyspell-babel-mode 1)) | |
480 | + | |
481 | +(provide 'flyspell-babel) | |
482 | + |