Hi all,

I sometimes happen to try to compile documents with a wrong engine
(above all example documents found on the Internet and the culprits
are fontspec and polyglossia, which require LuaTeX or XeTeX).  I'd
like to be warned by AUCTeX that I'm going to get an error, then I
wrote the attached patch.

Style authors should specify the engines required by the package (e.g.
LuaTeX and XeTeX for fontspec and polyglossia), then if the option
`TeX-check-engine' is non-nil the user will be warned before running
LaTeX command that a wrong engine has been selected, for example when
`TeX-engine' is set to `default'.

If you know other packages requiring a specific engine please tell us.

Comments?

Bye,
Mosè
diff --git a/style/fontspec.el b/style/fontspec.el
index 144b976..5ec7bb4 100644
--- a/style/fontspec.el
+++ b/style/fontspec.el
@@ -166,6 +166,7 @@ to retrieve the list of fonts."
 (TeX-add-style-hook
  "fontspec"
  (lambda ()
+   (TeX-check-engine-add-engines 'luatex 'xetex)
    (TeX-run-style-hooks "expl3" "xparse")
    (TeX-add-symbols
     ;; Font selection
diff --git a/tex-buf.el b/tex-buf.el
index b5ed365..dc7e3c6 100644
--- a/tex-buf.el
+++ b/tex-buf.el
@@ -332,6 +332,91 @@ This works only with TeX commands and if the
 (defconst TeX-error-overview-buffer-name "*TeX errors*"
   "Name of the buffer in which to show error list.")
 
+(defcustom TeX-check-engine t
+  "Whether AUCTeX should check the correct engine has been set before running LaTeX commands."
+  :group 'TeX-command
+  :type 'boolean)
+
+(defvar TeX-check-engine-list '(default luatex omega xetex)
+  "List of engines required by the loaded TeX packages.
+
+Do not set this variable directly, use
+`TeX-check-engine-add-engines' to specify required engines.")
+(make-variable-buffer-local 'TeX-check-engine-list)
+
+(defun TeX-check-engine-add-engines (&rest engines)
+  "Add ENGINES to list of required engines.
+
+This function calculates the intersection between
+`TeX-check-engine-list' and the list of provided engines.
+
+See for example style/fontspec.el"
+  (let ((list TeX-check-engine-list)
+	(res nil))
+    (setq TeX-check-engine-list
+	  ;; The following is based on the definition of `cl-intersection' of
+	  ;; GNU Emacs.
+	  (and list engines
+	       (if (equal list engines) list
+		 (or (>= (length list) (length engines))
+		     (setq list (prog1 engines (setq engines list))))
+		 (while engines
+		   (if (memq (car engines) list)
+		       (push (car engines) res))
+		   (pop engines))
+		 res)))))
+
+(defun TeX-check-engine ()
+  "Check the correct engine has been set.
+
+Look into `TeX-check-engine-list' for the required engines."
+  (and TeX-check-engine-list
+       (null (memq TeX-engine TeX-check-engine-list))
+       (memq TeX-engine '(default luatex omega xetex))
+       ;; The engine set is not listed in `TeX-check-engine-list'.  We check
+       ;; only builtin engines because we can't take care of custom ones.  Do
+       ;; nothing if there is no allowed engine, we don't know what to do in
+       ;; that case.
+       (let ((length (length TeX-check-engine-list))
+	     (name-alist '((default . "TeX")
+			   (luatex  . "LuaTeX")
+			   (omega   . "Omega")
+			   (xetex   . "XeTeX")))
+	     (completion-ignore-case t)
+	     (engine nil))
+	 (cond
+	  ;; There is exactly one allowed engine.
+	  ((= length 1)
+	   (if (y-or-n-p (format "%s is required to build this document.
+Do you want to use this engine?" (cdr (assoc (car TeX-check-engine-list)
+					     name-alist))))
+	       (setq engine (car TeX-check-engine-list))))
+	  ;; More than one engine is allowed.
+	  ((> length 1)
+	   (if (y-or-n-p (format "%s are required to build this document.
+Do you want to select one of these engines?"
+				 (mapconcat
+				  (lambda (elt) (cdr (assoc elt name-alist)))
+				  TeX-check-engine-list ", ")))
+	       (setq engine
+		     (car (rassoc
+			   (completing-read
+			    (format
+			     "Choose between %s: "
+			     (mapconcat
+			      (lambda (elt) (cdr (assoc elt name-alist)))
+			      TeX-check-engine-list ", "))
+			    (mapcar
+			     (lambda (elt) (cdr (assoc elt name-alist)))
+			     TeX-check-engine-list))
+			   name-alist))))))
+	 (when engine
+	   (TeX-engine-set engine)
+	   (when (and (fboundp 'add-file-local-variable)
+		      (y-or-n-p "Do you want to remember the choice?"))
+	     (add-file-local-variable 'TeX-engine engine)
+	     (save-buffer))))))
+
 (defun TeX-command (name file &optional override-confirm)
   "Run command NAME on the file returned by calling FILE.
 
@@ -343,7 +428,13 @@ Use the information in `TeX-command-list' to determine how to run
 the command.
 
 If OVERRIDE-CONFIRM is a prefix argument, confirmation will be
-asked if it is positive, and suppressed if it is not."
+asked if it is positive, and suppressed if it is not.
+
+When `TeX-check-engine' is non-nil, check the correct engine has
+been set before running LaTeX commands."
+  (and (string= name "LaTeX") TeX-check-engine
+       (TeX-check-engine))
+
   (cond ((eq file 'TeX-region-file)
 	 (setq TeX-current-process-region-p t))
 	((eq file 'TeX-master-file)
_______________________________________________
auctex-devel mailing list
auctex-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/auctex-devel

Reply via email to