From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp11.migadu.com ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms9.migadu.com with LMTPS id IGiCNpOjFWQnNwAASxT56A (envelope-from ) for ; Sat, 18 Mar 2023 12:42:11 +0100 Received: from aspmx1.migadu.com ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp11.migadu.com with LMTPS id IOBuNpOjFWS9PwAA9RJhRA (envelope-from ) for ; Sat, 18 Mar 2023 12:42:11 +0100 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 8B7D0147E8 for ; Sat, 18 Mar 2023 12:42:11 +0100 (CET) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pdUvy-0002PO-Da; Sat, 18 Mar 2023 07:41:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pdUvv-0002P1-QM for emacs-orgmode@gnu.org; Sat, 18 Mar 2023 07:41:11 -0400 Received: from mout02.posteo.de ([185.67.36.66]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pdUvs-00067s-P5 for emacs-orgmode@gnu.org; Sat, 18 Mar 2023 07:41:11 -0400 Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id BF7F42405CC for ; Sat, 18 Mar 2023 12:41:06 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1679139666; bh=C5fTkzyOaRYu6tXnrQZozEmuieYxCcb5y9fetcZfhAw=; h=From:To:Cc:Subject:Date:From; b=iMt99/5DNDzlt50Qaexbk/LV32akhPFOUQ2yNgy551AvHA9gpv9gARDIvWvKiDBAH 7Mh/8zzU9zGAme7au9I8C0P7J6OCvDwkk2yJ4TGPE9OgcmNq3vSvIg+21svx5lDoFI dV1Vti3MXtWrNoyBC3ieHuzPT5t1KOo9qiJVjdgn5wgxF4RkBfJe4VNkVDha27FeZe JzEBejnz4eTEAlMaUlNEpBjBPSt8LqVtcqNSP1qzeB1fqUTqRi5YHS6SW5Je4bsSWO Zi73reCmleYdiC9LNHzqGdM/ZPR7LXmSrbQ9obCLBEmPfY17AKEz7Sl0gXD+28FC7l PYMrq8rbz39tQ== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4PdzbP6pLsz9rxD; Sat, 18 Mar 2023 12:41:05 +0100 (CET) From: Ihor Radchenko To: David Lukes Cc: emacs-orgmode@gnu.org Subject: Re: [PATCH] ox-odt: Prevent auto-formatting in export buffers In-Reply-To: <20221002035931.12191-1-dafydd.lukes@gmail.com> References: <20221002035931.12191-1-dafydd.lukes@gmail.com> Date: Sat, 18 Mar 2023 11:42:59 +0000 Message-ID: <87zg8axp30.fsf@localhost> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Received-SPF: pass client-ip=185.67.36.66; envelope-from=yantar92@posteo.net; helo=mout02.posteo.de X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: emacs-orgmode-bounces+larch=yhetil.org@gnu.org X-Migadu-Country: US X-Migadu-Flow: FLOW_IN ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=pass header.d=posteo.net header.s=2017 header.b="iMt99/5D"; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org"; dmarc=pass (policy=none) header.from=posteo.net ARC-Seal: i=1; s=key1; d=yhetil.org; t=1679139731; a=rsa-sha256; cv=none; b=naTGru7tXfXQZPo0UK9KdjVFU+nk2gzdHMxolH+wPXHTGK/3JK/fjSzcjattcqpSjw4eCq E4HEhb/RRew0wd61c+8E++7zD4MLT+HsGVcmeMHdcBeEF3yGd5NFpwOiS/Dwfq7qxaea5D Orb9uhkNUi3tw/tPuqh4o/FYseZySk0ph5G9xsBYJIQmobhkk1U2SDbl+IQWYOTpmsvGYC 5+Wxx8rRtYsw5g6y9hyQqrNQz/6UFK4IqkIPRQ5ct9swqbFsi5ZNQ5aMbFRW7Ar2WMzcSP lIf3aLV3dEnLc9529fq/Iq/Qy98V+ahHRmqFkCdN7B/gAM90KTUxV3KSbckJcA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1679139731; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=D1kc8IhI1644H+Dt+LnJl2uzx/TZ/dzeIQ4XwttVMLo=; b=un1fP20olz7Z7joM9atupGjVBdzP9gSSDMa0wFD2Ty/zT4kPQRtJujHPAr26vjoSQPvwq9 ydIhEKYdu5y4+PhmndVYwk+BRRnTVAdRJSUM1FXzUeBrGjvUC+bTRGIxdbXLrifexuXTTo OAE1YapXU129TXtRK9o0DQ0CLzPDarb6b+mh0MfjqOSzuSvaXBgiShGwuK3+m6dJynKwgX QzqNGC7IC5oypDYI/U0XjXB6JJ4bTH374grrLx/81E5ixd0iyewtgaORr2q3gTrREupRkM 4qlD0mS4zg174Ne68gWqirPuIVnvnuCFSFeI6So0EIkAoU595n1BicYJ7YyV/g== X-Migadu-Spam-Score: -6.27 X-Spam-Score: -6.27 X-Migadu-Queue-Id: 8B7D0147E8 X-Migadu-Scanner: scn1.migadu.com Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=posteo.net header.s=2017 header.b="iMt99/5D"; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org"; dmarc=pass (policy=none) header.from=posteo.net X-TUID: W79p5QteCZ7L --=-=-= Content-Type: text/plain David Lukes writes: > * lisp/ox-odt.el (org-odt-template, org-odt--export-wrap): > `write-region' instead of `save-buffer'. > > `write-file' and `save-buffer' trigger major mode changes, which leads > to various mode-related hooks being run. This is undesirable: running > these on generated files is wasted time and computation, and it can even > lead to hard to track data corruption when auto-formatting hooks are > involved. One such case is the 2006 version of the tidy program which > ships with stock macOS and can corrupt multi-byte UTF-8 codepoints in > HTML and ODT (via XML) exports. And even recent versions of tidy can > re-arrange whitespace in the exported documents in unwanted ways. See the attached patch where I applied the idea across Org, where it made sense. Note that I did not alter `org-odt--export-wrap' because `save-buffer' there is applied only when XML files are opened as buffers in Emacs, presumably manually. Interactive `save-buffer' makes sense then. (Though maybe that code is not needed at all, IDK) Please let me know if there are any objections. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-Prefer-write-region-to-save-file.patch >From 8d8884bb6be0ba7cb7f9662f067d42b53393e92e Mon Sep 17 00:00:00 2001 Message-Id: <8d8884bb6be0ba7cb7f9662f067d42b53393e92e.1679139580.git.yantar92@posteo.net> From: Ihor Radchenko Date: Sat, 18 Mar 2023 12:34:17 +0100 Subject: [PATCH] Prefer `write-region' to `save-file' * lisp/ob-haskell.el (org-babel-haskell-export-to-lhs): Use non-interactive `insert-file-contents' + `write-region' to avoid triggering various interactive hooks. Ensure that temp files are always deleted. * lisp/org-agenda.el (org-agenda-write): * lisp/org-table.el: Simplify code using `write-region'. * lisp/ox-odt.el (org-odt-template): Use `insert-file-contents' + `write-region' instead of `find-file-noselect' that may trigger various hooks. The new approach makes `revert-buffer' not necessary (and do not trigger `revert-buffer' hooks). Also, the problem with backups will no longer exists. Original idea: https://list.orgmode.org/orgmode/20221002035931.12191-1-dafydd.lukes@gmail.com/ --- lisp/ob-haskell.el | 41 ++++++++++++------------ lisp/org-agenda.el | 9 ++---- lisp/org-table.el | 10 ++---- lisp/ox-odt.el | 78 ++++++++++++++++++++-------------------------- 4 files changed, 59 insertions(+), 79 deletions(-) diff --git a/lisp/ob-haskell.el b/lisp/ob-haskell.el index 2b1441c2a..3e64c1657 100644 --- a/lisp/ob-haskell.el +++ b/lisp/ob-haskell.el @@ -255,26 +255,27 @@ (defun org-babel-haskell-export-to-lhs (&optional arg) t t) (indent-code-rigidly (match-beginning 0) (match-end 0) indentation))) (save-excursion - ;; export to latex w/org and save as .lhs - (require 'ox-latex) - (find-file tmp-org-file) - ;; Ensure we do not clutter kill ring with incomplete results. - (let (org-export-copy-to-kill-ring) - (org-export-to-file 'latex tmp-tex-file)) - (kill-buffer nil) - (delete-file tmp-org-file) - (find-file tmp-tex-file) - (goto-char (point-min)) (forward-line 2) - (insert "%include polycode.fmt\n") - ;; ensure all \begin/end{code} statements start at the first column - (while (re-search-forward "^[ \t]+\\\\begin{code}[^\000]+\\\\end{code}" nil t) - (replace-match (save-match-data (org-remove-indentation (match-string 0))) - t t)) - (setq contents (buffer-string)) - (save-buffer) (kill-buffer nil)) - (delete-file tmp-tex-file) - ;; save org exported latex to a .lhs file - (with-temp-file lhs-file (insert contents)) + (unwind-protect + (with-temp-buffer + ;; Export to latex w/org and save as .lhs + (require 'ox-latex) + (insert-file-contents tmp-org-file) + ;; Ensure we do not clutter kill ring with incomplete results. + (let (org-export-copy-to-kill-ring) + (org-export-to-file 'latex tmp-tex-file))) + (delete-file tmp-org-file)) + (unwind-protect + (with-temp-buffer + (insert-file-contents tmp-tex-file) + (goto-char (point-min)) (forward-line 2) + (insert "%include polycode.fmt\n") + ;; ensure all \begin/end{code} statements start at the first column + (while (re-search-forward "^[ \t]+\\\\begin{code}[^\000]+\\\\end{code}" nil t) + (replace-match (save-match-data (org-remove-indentation (match-string 0))) + t t)) + ;; save org exported latex to a .lhs file + (write-region nil nil lhs-file)) + (delete-file tmp-tex-file))) (if (not arg) (find-file lhs-file) ;; process .lhs file with lhs2tex diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index 3da0967f0..859a80c47 100644 --- a/lisp/org-agenda.el +++ b/lisp/org-agenda.el @@ -3667,13 +3667,8 @@ (defun org-agenda-write (file &optional open nosettings agenda-bufname) "ox-icalendar" (file)) (org-icalendar-export-current-agenda (expand-file-name file))) (t - (let ((bs (buffer-string))) - (find-file file) - (erase-buffer) - (insert bs) - (save-buffer 0) - (kill-buffer (current-buffer)) - (message "Plain text written to %s" file)))))))) + (write-region nil nil file) + (message "Plain text written to %s" file))))))) (set-buffer (or agenda-bufname ;; FIXME: I'm pretty sure called-interactively-p ;; doesn't do what we want here! diff --git a/lisp/org-table.el b/lisp/org-table.el index 5116b1127..97120fffd 100644 --- a/lisp/org-table.el +++ b/lisp/org-table.el @@ -4332,14 +4332,8 @@ (defun org-table-export (&optional file format) (table (org-table-to-lisp))) (unless (fboundp transform) (user-error "No such transformation function %s" transform)) - (let (buf) - (with-current-buffer (find-file-noselect file) - (setq buf (current-buffer)) - (erase-buffer) - (fundamental-mode) - (insert (funcall transform table params) "\n") - (save-buffer)) - (kill-buffer buf)) + (with-temp-file file + (insert (funcall transform table params) "\n")) (message "Export done.")) (user-error "TABLE_EXPORT_FORMAT invalid"))))) diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el index cf217c9e7..8fc34a749 100644 --- a/lisp/ox-odt.el +++ b/lisp/ox-odt.el @@ -1365,50 +1365,40 @@ (defun org-odt-template (contents info) ;; Ensure we have write permissions to this file. (set-file-modes (concat org-odt-zip-dir "styles.xml") #o600) - ;; FIXME: Who is opening an empty styles.xml before this point? - (with-current-buffer - (find-file-noselect (concat org-odt-zip-dir "styles.xml") t) - (revert-buffer t t) - - ;; Write custom styles for source blocks - ;; Save STYLES used for colorizing of source blocks. - ;; Update styles.xml with styles that were collected as part of - ;; `org-odt-hfy-face-to-css' callbacks. - (let ((styles (mapconcat (lambda (style) (format " %s\n" (cddr style))) - hfy-user-sheet-assoc ""))) - (when styles - (goto-char (point-min)) - (when (re-search-forward "" nil t) - (goto-char (match-beginning 0)) - (insert "\n\n" styles "\n")))) - - ;; Update styles.xml - take care of outline numbering - - ;; Don't make automatic backup of styles.xml file. This setting - ;; prevents the backed-up styles.xml file from being zipped in to - ;; odt file. This is more of a hackish fix. Better alternative - ;; would be to fix the zip command so that the output odt file - ;; includes only the needed files and excludes any auto-generated - ;; extra files like backups and auto-saves etc etc. Note that - ;; currently the zip command zips up the entire temp directory so - ;; that any auto-generated files created under the hood ends up in - ;; the resulting odt file. - (setq-local backup-inhibited t) - - ;; Outline numbering is retained only up to LEVEL. - ;; To disable outline numbering pass a LEVEL of 0. - - (goto-char (point-min)) - (let ((regex - "]*\\)text:level=\"\\([^\"]*\\)\"\\([^>]*\\)>") - (replacement - "")) - (while (re-search-forward regex nil t) - (unless (let ((sec-num (plist-get info :section-numbers)) - (level (string-to-number (match-string 2)))) - (if (wholenump sec-num) (<= level sec-num) sec-num)) - (replace-match replacement t nil)))) - (save-buffer 0))) + (let ((styles-xml (concat org-odt-zip-dir "styles.xml"))) + (with-temp-buffer + (when (file-exists-p styles-xml) + (insert-file-contents styles-xml)) + + ;; Write custom styles for source blocks + ;; Save STYLES used for colorizing of source blocks. + ;; Update styles.xml with styles that were collected as part of + ;; `org-odt-hfy-face-to-css' callbacks. + (let ((styles (mapconcat (lambda (style) (format " %s\n" (cddr style))) + hfy-user-sheet-assoc ""))) + (when styles + (goto-char (point-min)) + (when (re-search-forward "" nil t) + (goto-char (match-beginning 0)) + (insert "\n\n" styles "\n")))) + + ;; Update styles.xml - take care of outline numbering + ;; Outline numbering is retained only up to LEVEL. + ;; To disable outline numbering pass a LEVEL of 0. + + (let ((regex + "]*\\)text:level=\"\\([^\"]*\\)\"\\([^>]*\\)>") + (replacement + "")) + (goto-char (point-min)) + (while (re-search-forward regex nil t) + (unless (let ((sec-num (plist-get info :section-numbers)) + (level (string-to-number (match-string 2)))) + (if (wholenump sec-num) (<= level sec-num) sec-num)) + (replace-match replacement t nil)))) + + ;; Write back the new contents. + (write-region nil nil styles-xml)))) ;; Update content.xml. (let* ( ;; `org-display-custom-times' should be accessed right -- 2.39.1 --=-=-= Content-Type: text/plain -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at . Support Org development at , or support my work at --=-=-=--