[PATCH] ox-odt: Prevent auto-formatting in export buffers
* 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. TINYCHANGE --- lisp/ox-odt.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el index 208a39d9d..c678f22e7 100644 --- a/lisp/ox-odt.el +++ b/lisp/ox-odt.el @@ -1414,7 +1414,7 @@ original parsed data. INFO is a plist holding export options." (level (string-to-number (match-string 2 (if (wholenump sec-num) (<= level sec-num) sec-num)) (replace-match replacement t nil - (save-buffer 0))) + (write-region nil nil buffer-file-name))) ;; Update content.xml. (let* ( ;; `org-display-custom-times' should be accessed right @@ -4007,7 +4007,7 @@ contextual information." ;; Prettify output if needed. (when org-odt-prettify-xml (indent-region (point-min) (point-max))) - (save-buffer 0) + (write-region nil nil buffer-file-name) ;; Run zip. (let* ((target --out-file) (target-name (file-name-nondirectory target)) -- 2.37.1
[PATCH] ox.el: Protect export from auto-formatting hooks
* ox.el, ox-odt.el: Use `write-region' instead of `write-file' or `save-buffer' to protect generated export buffers from auto-formatting hooks. In particular, `tidy' is often configured as the auto-formatter for HTML and XML, and it can corrupt the exports. TINYCHANGE --- lisp/ox-odt.el | 4 ++-- lisp/ox.el | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el index 9d47067..ec1c360 100644 --- a/lisp/ox-odt.el +++ b/lisp/ox-odt.el @@ -1411,7 +1411,7 @@ original parsed data. INFO is a plist holding export options." (level (string-to-number (match-string 2 (if (wholenump sec-num) (<= level sec-num) sec-num)) (replace-match replacement t nil - (save-buffer 0))) + (write-region nil nil buffer-file-name))) ;; Update content.xml. (let* ( ;; `org-display-custom-times' should be accessed right @@ -4004,7 +4004,7 @@ contextual information." ;; Prettify output if needed. (when org-odt-prettify-xml (indent-region (point-min) (point-max))) - (save-buffer 0) + (write-region nil nil buffer-file-name) ;; Run zip. (let* ((target --out-file) (target-name (file-name-nondirectory target)) diff --git a/lisp/ox.el b/lisp/ox.el index c75357b..66d18c4 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -6553,14 +6553,14 @@ or FILE." (with-temp-buffer (insert output) (let ((coding-system-for-write ',encoding)) - (write-file ,file))) + (write-region nil nil ,file))) (or (ignore-errors (funcall ',post-process ,file)) ,file))) (let ((output (org-export-as backend subtreep visible-only body-only ext-plist))) (with-temp-buffer (insert output) (let ((coding-system-for-write encoding)) - (write-file file))) + (write-region nil nil file))) (when (and (org-export--copy-to-kill-ring-p) (org-string-nw-p output)) (org-kill-new output)) ;; Get proper return value. -- 2.36.1
[PATCH] oc-basic.el: Stringify year from CSL-JSON date-parts
* lisp/oc-basic.el (org-cite-basic--parse-json): Make sure year extracted from date-parts is returned as string. Raise error if original type other than number or string. The stringifiation is motivated by errors like the following on Emacs 28 with nativecomp: Error during redisplay: (jit-lock-function 544) signaled (wrong-type-argument "Argument is not a string or a secondary string: 2007") Additionally, the type check will warn users about problems in their CSL-JSON bibliographies. TINYCHANGE --- lisp/oc-basic.el | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lisp/oc-basic.el b/lisp/oc-basic.el index a937f75..f10b95b 100644 --- a/lisp/oc-basic.el +++ b/lisp/oc-basic.el @@ -189,7 +189,14 @@ Return a hash table with citation references as keys and fields alist as values. (cons 'year (cond ((consp date) -(caar date)) + (let ((year (caar date))) + (cond + ((numberp year) (number-to-string year)) + ((stringp year) year) + (t + (error + "First element of CSL-JSON date-parts should be a number or string, got %s: %S" + (type-of year) year) ((stringp date) (replace-regexp-in-string (rx -- 2.36.1
[PATCH] ox: Prevent auto-formatting in export buffers
* ox.el (org-export-to-file): `write-region' instead of `write-file'. * 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. TINYCHANGE --- lisp/ox-odt.el | 4 ++-- lisp/ox.el | 16 ++-- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el index 7f2e8ba47..6a8e75e9d 100644 --- a/lisp/ox-odt.el +++ b/lisp/ox-odt.el @@ -1427,7 +1427,7 @@ original parsed data. INFO is a plist holding export options." (level (string-to-number (match-string 2 (if (wholenump sec-num) (<= level sec-num) sec-num)) (replace-match replacement t nil - (save-buffer 0))) + (write-region nil nil buffer-file-name))) ;; Update content.xml. (let* ( ;; `org-display-custom-times' should be accessed right @@ -4018,7 +4018,7 @@ contextual information." ;; Prettify output if needed. (when org-odt-prettify-xml (indent-region (point-min) (point-max))) - (save-buffer 0) + (write-region nil nil buffer-file-name) ;; Run zip. (let* ((target --out-file) (target-name (file-name-nondirectory target)) diff --git a/lisp/ox.el b/lisp/ox.el index 2a3edaa50..8ec1e25ee 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -6459,18 +6459,14 @@ or FILE." `(let ((output (org-export-as ',backend ,subtreep ,visible-only ,body-only -',ext-plist))) - (with-temp-buffer -(insert output) -(let ((coding-system-for-write ',encoding)) - (write-file ,file))) +',ext-plist)) + (coding-system-for-write ',encoding)) + (write-region output nil ,file) (or (ignore-errors (funcall ',post-process ,file)) ,file))) (let ((output (org-export-as - backend subtreep visible-only body-only ext-plist))) - (with-temp-buffer -(insert output) -(let ((coding-system-for-write encoding)) - (write-file file))) + backend subtreep visible-only body-only ext-plist)) + (coding-system-for-write encoding)) + (write-region output nil file) (when (and (org-export--copy-to-kill-ring-p) (org-string-nw-p output)) (org-kill-new output)) ;; Get proper return value. -- 2.34.1
[PATCH] oc-basic.el: Better handling of CSL-JSON dates
* lisp/oc-basic.el (org-cite-basic--parse-json): Make date-parsing and year extraction more resilient. Provide more informative errors when it fails. A string-based date is not only indicated by the key 'raw, but also possibly by the key 'literal. String-based dates come in various formats, not necessarily -mm-dd. So extracting the first sequence of 4 digits is arguably a better heuristic for getting the publication year than splitting the string on - and getting the car of that. On error, include `value' in the message, which contains the original value with actionable information, whereas the previously included `date' is always nil in that case. TINYCHANGE --- lisp/oc-basic.el | 20 ++-- 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/lisp/oc-basic.el b/lisp/oc-basic.el index d82406aff..81b7e4471 100644 --- a/lisp/oc-basic.el +++ b/lisp/oc-basic.el @@ -178,21 +178,29 @@ Return a hash table with citation references as keys and fields alist as values. " and "))) ('issued ;; Date are expressed as an array - ;; (`date-parts') or a "string (`raw'). - ;; In both cases, extract the year and - ;; associate it to `year' field, for - ;; compatibility with BibTeX format. + ;; (`date-parts') or a "string (`raw' + ;; or `literal'). In both cases, + ;; extract the year and associate it + ;; to `year' field, for compatibility + ;; with BibTeX format. (let ((date (or (alist-get 'date-parts value) + (alist-get 'literal value) (alist-get 'raw value (cons 'year (cond ((consp date) (caar date)) ((stringp date) -(car (split-string date "-"))) +(replace-regexp-in-string + (rx +(minimal-match (zero-or-more anything)) +(group-n 1 (repeat 4 digit)) +(zero-or-more anything)) + (rx (backref 1)) + date)) (t (error "Unknown CSL-JSON date format: %S" - date)) + value)) (_ (cons field value item) -- 2.34.1
[PATCH] org-indent: Allow indentation per level to be 0
* lisp/org-indent.el (org-indent--compute-prefixes): Prefixes should only be computed when `org-indent-indentation-per-level' is greater than 0. For one thing, the current algorithm leads to an error otherwise, and for another, this makes it possible to use org-indent just to preserve indentation on continuation lines, without adding any additional indentation per level (by setting the option to 0). TINYCHANGE --- lisp/org-indent.el | 49 +++--- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/lisp/org-indent.el b/lisp/org-indent.el index ea7ea071b..b87cc4e5f 100644 --- a/lisp/org-indent.el +++ b/lisp/org-indent.el @@ -126,31 +126,32 @@ useful to make it ever so slightly different." (make-vector org-indent--deepest-level nil)) (setq org-indent--text-line-prefixes (make-vector org-indent--deepest-level nil)) - (dotimes (n org-indent--deepest-level) -(let ((indentation (if (<= n 1) 0 -(* (1- org-indent-indentation-per-level) - (1- n) - ;; Headlines line prefixes. - (let ((heading-prefix (make-string indentation ?*))) - (aset org-indent--heading-line-prefixes + (when (> org-indent-indentation-per-level 0) +(dotimes (n org-indent--deepest-level) + (let ((indentation (if (<= n 1) 0 + (* (1- org-indent-indentation-per-level) + (1- n) +;; Headlines line prefixes. +(let ((heading-prefix (make-string indentation ?*))) + (aset org-indent--heading-line-prefixes + n + (org-add-props heading-prefix nil 'face 'org-indent)) + ;; Inline tasks line prefixes + (aset org-indent--inlinetask-line-prefixes + n + (cond ((<= n 1) "") + ((bound-and-true-p org-inlinetask-show-first-star) + (concat org-indent-inlinetask-first-star + (substring heading-prefix 1))) + (t (org-add-props heading-prefix nil 'face 'org-indent) +;; Text line prefixes. +(aset org-indent--text-line-prefixes n - (org-add-props heading-prefix nil 'face 'org-indent)) - ;; Inline tasks line prefixes - (aset org-indent--inlinetask-line-prefixes - n - (cond ((<= n 1) "") - ((bound-and-true-p org-inlinetask-show-first-star) -(concat org-indent-inlinetask-first-star -(substring heading-prefix 1))) - (t (org-add-props heading-prefix nil 'face 'org-indent) - ;; Text line prefixes. - (aset org-indent--text-line-prefixes - n - (org-add-props - (concat (make-string (+ n indentation) ?\s) - (and (> n 0) -(char-to-string org-indent-boundary-char))) - nil 'face 'org-indent) + (org-add-props + (concat (make-string (+ n indentation) ?\s) + (and (> n 0) + (char-to-string org-indent-boundary-char))) + nil 'face 'org-indent)) (defsubst org-indent-remove-properties (beg end) "Remove indentations between BEG and END." -- 2.32.0