all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Arash Esbati <arash@gnu.org>
To: Eli Zaretskii <eliz@gnu.org>
Cc: emacs-devel@gnu.org
Subject: Re: Ispell: Skipping part of text in texinfo-mode
Date: Fri, 30 Aug 2024 10:13:59 +0200	[thread overview]
Message-ID: <m2ikvia0mw.fsf@macmutant.fritz.box> (raw)
In-Reply-To: <8634mnfcag.fsf@gnu.org> (Eli Zaretskii's message of "Thu, 29 Aug 2024 20:51:03 +0300")

Eli Zaretskii <eliz@gnu.org> writes:

> Thanks.  But there be dragons...

I thought so, and I was hoping that someone could guide me through that
unknown water :-)

> There are many more, no?  @samp, @sc, @item, @itemx, to mention just a
> few.
> [...]
> Likewise here: @defmac, @defspec, and many others (see the Texinfo
> manual).

Yes, at some point, I have to go through the @-Command List section in
the Texinfo manual.

> What about @kbd in general? and @key?

See below, the first regexp approach was fragile anyway, I think I have
a better solution now.

> Why "entirely"?  They frequently include comments, not just code.

I think the environments contain more code to be ignored than comments
to check, but that's only me.

> Very simple: press 'a' once on each directive you never want to look
> at, and leave the rest for judgment calls.

Thanks, this was also my approach until now, but I didn't find it
satisfactory.

> To some degree, I guess.  I think we should take only the bare
> minimum, the ones that we want _never_ to be marked as mis-spellings,
> and leave the rest to the users.

We can discuss which macros to include and which to drop once the code
is working.  I'm currently facing the issue that when I open a .texi
file, eval (setq ispell-parser 'texinfo) and do M-x ispell RET, also
comments in the file are checked, the value of `ispell-check-comments'
is nil, though.  Do you have an idea what's going wrong?  I don't get
this in a .tex buffer.

Here the latest patch:

--8<---------------cut here---------------start------------->8---
diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el
index 99f9e10a5a8..8da5681af1c 100644
--- a/lisp/textmodes/ispell.el
+++ b/lisp/textmodes/ispell.el
@@ -1744,6 +1744,37 @@ ispell-html-skip-alists
  (e.g. \"<[tT][tT]/\" and \"<[^ \\t\\n>]\").")
 (put 'ispell-html-skip-alists 'risky-local-variable t)

+;;;###autoload
+(defvar ispell-texinfo-skip-alists
+  (let ((single-arg (regexp-opt '("acronym" "cite" "code" "command" "env"
+                                  "file" "kbd" "key" "option" "samp"
+                                  "url" "var")
+                                "@\\(?:"))
+        (skip-line (regexp-opt '("deffn" "deffnx" "defmac" "defun"
+                                 "defopt" "defspec" "defvar"
+                                 "findex" "vindex" "kindex" "cindex"
+                                 "end "
+                                 "ifclear" "ifset" "include"
+                                 "item" "itemx"
+                                 "setfilename")
+                               "^@\\(?:")))
+    `(;; Macros with a single arg
+      (,single-arg ispell-texinfo-arg-end)
+      ;; Envs to skip entirely
+      ("^@\\(?:\\(?:small\\)?example\\|lisp\\|verbatim\\)" .
+       "^@end \\(?:\\(?:small\\)?example\\|lisp\\|verbatim\\)")
+      ;; macros w/o arg
+      (,skip-line forward-line)
+      ;; This is for the first line:
+      ("\\\\input" forward-line)
+      ;; All other macros
+      ("@[a-zA-Z]+")))
+  "Lists of start and end keys to skip in texinfo buffers.
+Same format as `ispell-skip-region-alist'.
+Note - Match for general texinfo macros like @foo must come last, e.g.:
+  (\"@[a-zA-Z]+\").")
+(put 'ispell-texinfo-skip-alists 'risky-local-variable t)
+
 (defvar-local ispell-local-pdict ispell-personal-dictionary
   "A buffer local variable containing the current personal dictionary.
 If non-nil, the value must be a string, which is a file name.
@@ -1799,11 +1830,11 @@ ispell-accept-output
 and pass it the output of the last Ispell invocation."
   (if ispell-async-processp
       (if (process-live-p ispell-process)
-       (let ((timeout (if timeout-msecs
-			  (+ (or timeout-secs 0) (/ timeout-msecs 1000.0))
-		        timeout-secs)))
-	 (accept-process-output ispell-process timeout))
-       (error "No Ispell process to read output from!"))
+          (let ((timeout (if timeout-msecs
+			     (+ (or timeout-secs 0) (/ timeout-msecs 1000.0))
+		           timeout-secs)))
+	    (accept-process-output ispell-process timeout))
+        (error "No Ispell process to read output from!"))
     (if (null ispell-process)
 	(error "No Ispell process to read output from!")
       (let ((buf ispell-output-buffer)
@@ -3277,6 +3308,8 @@ ispell-begin-skip-region-regexp
           ;; tex
           (if (eq ispell-parser 'tex)
               (ispell-begin-tex-skip-regexp))
+          (if (eq ispell-parser 'texinfo)
+              (ispell-begin-skip-region ispell-texinfo-skip-alists))
           ;; html stuff
           (if ispell-skip-html
               (ispell-begin-skip-region ispell-html-skip-alists))
@@ -3341,6 +3374,9 @@ ispell-skip-region-list
 	      skip-alist (append (car ispell-tex-skip-alists)
 				 (car (cdr ispell-tex-skip-alists))
 				 skip-alist)))
+    (if (eq ispell-parser 'texinfo)
+        (setq case-fold-search nil
+              skip-alist (append ispell-texinfo-skip-alists skip-alist)))
     (if ispell-skip-html
 	(setq skip-alist (append ispell-html-skip-alists skip-alist)))
     (if (and ispell-checking-message
@@ -3360,6 +3396,30 @@ ispell-tex-arg-end
      (beep)
      (sit-for 2))))

+(defvar ispell--texinfo-arg-end-syntax-table
+  (let ((table (make-syntax-table))
+        (chars '((?\f . ">") (?\n . ">")
+                 (?\" . " ") (?\@ . "/")
+                 (?\( . " ") (?\) . " ")
+                 (?\[ . " ") (?\] . " ")
+                 (?\< . " ") (?\> . " ")
+                 (?\\ . " ")
+                 (?\{ . "(}") (?\} . "){"))))
+    (dolist (elt chars)
+      (modify-syntax-entry (car elt) (cdr elt) table))
+    table))
+
+(defun ispell-texinfo-arg-end (&optional arg)
+  "Skip across ARG number of braces."
+  (condition-case nil
+      (with-syntax-table ispell--texinfo-arg-end-syntax-table
+        (unless (= (following-char) ?\{)
+          (skip-chars-forward "^{"))
+        (forward-sexp (or arg 1)))
+    (error
+     (message "Error skipping s-expressions at point %d." (point))
+     (beep)
+     (sit-for 2))))

 (defun ispell-ignore-fcc (start end)
   "Query whether to delete Fcc header due to attachment between START and END.
--8<---------------cut here---------------end--------------->8---




  reply	other threads:[~2024-08-30  8:13 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-29 16:25 Ispell: Skipping part of text in texinfo-mode Arash Esbati
2024-08-29 17:51 ` Eli Zaretskii
2024-08-30  8:13   ` Arash Esbati [this message]
2024-08-30 10:46     ` Eli Zaretskii
2024-08-30 13:19       ` Arash Esbati

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m2ikvia0mw.fsf@macmutant.fritz.box \
    --to=arash@gnu.org \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.