Pergunta

I use Emacs for writing most of my writings. I write using reStructuredText, and then transform them to LaTeX after some preprocessing since I write my citations á-la LaTeX. This is an excerpt of one of my texts (in Spanish):

En \cite[pp.~XXVIII--XXIX]{Crnkovic2002} se brindan algunos riesgos
que se pueden asumir con el desarrollo basado en componentes, los

This text is processed by some custom scripts that deals with the \cite part so rst2latex can do its job.

When I activate flyspell-mode it signals most of the citation keys as spelling errors.

How can I tell flyspell not to spellcheck things within \cite commands.

Furthermore, how can I combine rst-mode and flyspell, so that rst-mode would keep flyspell from spellchecking the following?

  • reST comments
  • reST code literal
  • reST directive parameters and arguments
  • reST raw directive contents

Any ideas?

Foi útil?

Solução

You can set the variable ispell-parser to the value 'tex so that flyspell will ignore (la)tex sequences. To do so, you can either set it manually in each buffer like so:

M-: (setq 'ispell-parser 'tex)

or you write a little function that will do that for you. Put the following in your .emacs file:

(defun flyspell-ignore-tex ()
  (interactive)
  (set (make-variable-buffer-local 'ispell-parser) 'tex))

Then you can still invoke it manually, using

M-x flyspell-ignore-tex

or you could add a hook that calls that function automatically whenever you edit a file of a certain type. You would do the latter by adding the newly defined function to your auto-mode-alist. Say your filenames typically end with ".rst", then add this line to your .emacs file:

(add-to-list 'auto-mode-alist '("\\.rst$" . flyspell-ignore-tex))

As for the second part of your question: making flyspell-mode ignore larger regions, such as, e.g., reST comments, is not easily achievable. It becomes clear when you think about the way flyspell works: it checks text on a word-by-word basis. For that, flyspell-word only looks at one word at a time which it sends to an ispell process running in the background. The ispell process does the dictionary lookup and returns whether or not the current word is correct. If flyspell-word had to check every single time whether or not the current word is part of a comment or other region that should not be checked, it would be rather slow, because that would include quite a bit of searching through the buffer.

Now of course, one could approach this a little bit smarter and first find the non-comment regions etc. and then do the word-by-word checking only in those parts that are outside of those regions - but unfortunately, that's not the way flyspell is implemented.

If you can do without the "fly" part, however, ispell-mode has a mechanism to customize which regions of a buffer can be skipped. This is done via the variable ispell-skip-region-alist. But although flyspell-mode works off ispell-mode, for the reasons outlined above that variable is not used by flyspell-mode.

Outras dicas

You can also use flyspell-generic-check-word-predicate as I explained in this question at Super User.

(aspell's tex filter may do exactly what you want - but if you want a more general solution)

Although I am using the code below to persuade flyspell to not flag certain words with numbers in them, you can use this sort of hook to match certain context.

looking-at starts at the position you want - so you may want to search backwards for start/end of whatever context you care about.

(when "another attempt to accept certain words flyspell/ispell/aspell flags as incorrect"
  (defun flyspell-ignore-WordNumber99-stuff/ag (beg end info)
    (save-excursion
      (goto-char beg)
      (cond
    ((or
       (looking-at "\\bWord1\\b")
       (looking-at "\\bWord99Foo\\b")
       )
      t)
    (t nil)
    )
      )
    )
  )

(add-hook 'flyspell-incorrect-hook 'flyspell-ignore-WordNumber99-stuff/ag)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top