Hello, "Feng Shu" <tuma...@163.com> writes:
> I suggest to add (:generator my-generator-function) style configure > to `org-latex-pdf-process', it is simple and powerful feature, we > can use this feature to switch latex commands dynamicially, for example: > > (defun my-latex-pdf-process-generator (texfile snippet extra-info) > (cond > ((<a>) (<org-latex-pdf-process-style-command1>) > ((<b>) (<org-latex-pdf-process-style-command2>))))) > > although we can set org-latex-pdf-process to a function to do the same work, > but this function is hard to write as org-latex-compile, it may only > useful for developer instead of user.... > > caller-info argument is for the above feature. I understand the need to extend `org-latex-pdf-process'. However this isn't a good way to look at it. In fact, it makes little sense to load the whole export framework when you're only after displaying a LaTeX snippet in the current buffer. I think a better approach would be to create a generic tool to compile a file to another format, e.g. `org-compile-file'. It would take a command (as a list of strings or a function) and apply it to the source file name. Then it would check if the output file was produced. Optionally, it would allow to create a buffer so as to retrieve error messages. Then, e.g., `org-latex-compile' or `org-preview-generate-image', could extend this function, i.e., handle specific variables (e.g., `org-latex-pdf-process') and call it with appropriate arguments. As example, here's a proof of concept for `org-compile-file' and `org-latex-compile'. (defun org-compile-file (source process extension &optional spec log-buffer) "Compile a SOURCE file using PROCESS. PROCESS is either a function or a list of shell commands, as strings. If PROCESS is a function, it is called with a single argument: SOURCE file. It must create a file with the same base name and directory as SOURCE, but using extension. If it is a list of commands, each of them is called using `shell-command'. By default, in each command, %b, %f and %o are replaced, respectively, with SOURCE base name, SOURCE full name and SOURCE directory. It is possible, however, to use different place-holders by specifying them in optional argument SPEC. In this case, SPEC should be an alist (CHARACTER REPLACEMENT-STRING). When PROCESS is a list of commands, optional argument LOG-BUFFER can be set to a buffer or a buffer name. `shell-command' then uses it as an output buffer, which may be used for collecting errors. `default-directory' is set to SOURCE directory during the whole process. Return output file or raise an error if it wasn't generated upon executing PROCESS." (let* ((base-name (file-name-sans-extension (file-name-nondirectory source))) (full-name (file-truename source)) (out-dir (file-name-directory source)) ;; Properly set working directory for compilation. (default-directory (if (file-name-absolute-p source) (file-name-directory full-name) default-directory)) (time (current-time))) (save-window-excursion (pcase process ((pred functionp) (funcall process (shell-quote-argument source))) ((pred consp) (let ((log (and log-buffer (get-buffer-create log-buffer))) (spec (or spec `((?b ,(shell-quote-argument base-name)) (?f ,(shell-quote-argument full-name)) (?o ,(shell-quote-argument out-dir)))))) (dolist (command process) (shell-command (format-spec command spec) log)))) (t (error "No valid command to process %S" source))) ;; Check for process failure. (let ((output (concat out-dire base-name extension))) (when (or (not (file-exists-p output)) ;; Only compare times up to whole seconds as some ;; file-systems (e.g. HFS+) do not retain any finer ;; granularity. (time-less-p (cl-subseq (nth 5 (file-attributes output)) 0 2) (cl-subseq time 0 2))) (error (format "File %S wasn't produced" output))) output)))) (defun org-latex-compile (texfile) "Compile a TeX file. TEXFILE is the name of the file being compiled. Processing is done through the command specified in `org-latex-pdf-process'. Return PDF file name or an error if it couldn't be produced." (message "Processing LaTeX file %s..." texfile) (let* ((base-name (file-name-sans-extension (file-name-nondirectory texfile))) (full-name (file-truename texfile)) (compiler (or (with-temp-buffer (save-excursion (insert-file-contents full-name)) (when (and (search-forward-regexp (regexp-opt org-latex-compilers) (line-end-position 2) t) (progn (beginning-of-line) (looking-at-p "%"))) (match-string 0))) "pdflatex")) (out-dir (file-name-directory texfile)) (spec `((?B ,(shell-quote-argument org-latex-bib-compiler)) (?L ,(shell-quote-argument compiler)) (?b ,(shell-quote-argument base-name)) (?f ,(shell-quote-argument full-name)) (?o ,(shell-quote-argument out-dir)))) (log-buffer (get-buffer-create "*Org PDF LaTeX Output*")) (outfile (org-compile-file texfile (let ((process org-latex-pdf-process)) ;; A function is provided: Apply it. (if (functionp org-latex-pdf-process) org-latex-pdf-process ;; A list is provided: replace %b, %f and %o with ;; appropriate values in each command before applying ;; it. Note that while "%latex" and "%bibtex" is used ;; in `org-latex-pdf-process', they are replaced with ;; "%L" and "%B" to adhere to format-spec. Output is ;; redirected to "*Org PDF LaTeX Output*" buffer. (mapcar (lambda (command) (replace-regexp-in-string "%\\(latex\\|bibtex\\)\\>" (lambda (str) (upcase (substring str 0 2))) command)) org-latex-pdf-process))) ".pdf" log-buffer))) (when org-latex-remove-logfiles (mapc #'delete-file (directory-files out-dir t (concat (regexp-quote base-name) "\\(?:\\.[0-9]+\\)?" "\\." (regexp-opt org-latex-logfiles-extensions))))) (let ((warnings (get-buffer-create(org-latex--collect-warnings outbuf)))) (message (concat "PDF file produced" (cond ((eq warnings 'error) " with errors.") (warnings (concat " with warnings: " warnings)) (t "."))))) ;; Return output file name. outfile)) > Remove the above two and only use the below *one* ? > > (make-obsolete-variable > 'org-latex-preview-ltxpng-directory > "Set `org-latex-preview-ltximg-directory' instead." "25.1") I think (make-obsolete-variable 'org-latex-preview-ltxpng-directory 'org-latex-preview-ltximg-directory "25.1") is sufficient. The code you wrote is not wrong either, tho. Regards, -- Nicolas Goaziou