[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/org 33503445e6: org-export: Do not treat unpaired ' and
From: |
ELPA Syncer |
Subject: |
[elpa] externals/org 33503445e6: org-export: Do not treat unpaired ' and " as smart quotes |
Date: |
Sun, 24 Mar 2024 06:58:43 -0400 (EDT) |
branch: externals/org
commit 33503445e60a76c83c73d71141568fb6e3fd3526
Author: Ihor Radchenko <yantar92@posteo.net>
Commit: Ihor Radchenko <yantar92@posteo.net>
org-export: Do not treat unpaired ' and " as smart quotes
* lisp/ox.el (org-export--smart-quote-status): When quotes are not
balanced, treat " literally and ' as apostrophes.
* testing/lisp/test-ox.el (test-org-export/activate-smart-quotes): Fix
test with unbalanced " and add new tests for unbalanced quotes.
Reported-by: Juan Manuel Macías <maciaschain@posteo.net>
Link: https://list.orgmode.org/orgmode/875xxfqdpt.fsf@posteo.net/
---
lisp/ox.el | 50 +++++++++++++++++++++++++++++++++++++++++++++++++
testing/lisp/test-ox.el | 37 ++++++++++++++++++++++++++++++++++--
2 files changed, 85 insertions(+), 2 deletions(-)
diff --git a/lisp/ox.el b/lisp/ox.el
index 929b306dc4..9ca19db43c 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -5942,6 +5942,56 @@ INFO is the current export state, as a plist."
(when current-status
(push (cons text (nreverse current-status)) full-status))))
info nil org-element-recursive-objects)
+ ;; When quotes are not balanced, treat them as apostrophes.
+ (setq full-status (nreverse full-status))
+ (let (primary-openings secondary-openings)
+ (dolist (substatus full-status)
+ (let ((status (cdr substatus)))
+ (while status
+ (pcase (car status)
+ (`apostrophe nil)
+ (`primary-opening
+ (push status primary-openings))
+ (`secondary-opening
+ (push status secondary-openings))
+ (`secondary-closing
+ (if secondary-openings
+ ;; Remove matched opening.
+ (pop secondary-openings)
+ ;; No matching openings for a given closing. Replace
+ ;; it with apostrophe.
+ (setcar status 'apostrophe)))
+ (`primary-closing
+ (when secondary-openings
+ ;; Some secondary opening quotes are not closed
+ ;; within "...". Replace them all with apostrophes.
+ (dolist (opening secondary-openings)
+ (setcar opening 'apostrophe))
+ (setq secondary-openings nil))
+ (if primary-openings
+ ;; Remove matched opening.
+ (pop primary-openings)
+ ;; No matching openings for a given closing.
+ (error "This should no happen"))))
+ (setq status (cdr status)))))
+ (when primary-openings
+ ;; Trailing unclosed "
+ (unless (= 1 (length primary-openings))
+ (error "This should not happen"))
+ ;; Mark for not replacing.
+ (setcar (car primary-openings) nil)
+ ;; Mark all the secondary openings and closings after
+ ;; trailing unclosed " as apostrophes.
+ (let ((after-unbalanced-primary nil))
+ (dolist (substatus full-status)
+ (let ((status (cdr substatus)))
+ (while status
+ (when (eq status (car primary-openings))
+ (setq after-unbalanced-primary t))
+ (when after-unbalanced-primary
+ (when (memq (car status) '(secondary-opening
secondary-closing))
+ (setcar status 'apostrophe)))
+ (setq status (cdr status))))))))
(puthash (cons parent (org-element-secondary-p s)) full-status cache)
(cdr (assq s full-status))))))
diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el
index 01e082c9bf..cc14b4fe8f 100644
--- a/testing/lisp/test-ox.el
+++ b/testing/lisp/test-ox.el
@@ -4134,9 +4134,9 @@ This test does not cover listings and custom
environments."
;; Opening quotes: at the beginning of a paragraph.
(should
(equal
- '("“begin")
+ '("“begin”")
(let ((org-export-default-language "en"))
- (org-test-with-parsed-data "\"begin"
+ (org-test-with-parsed-data "\"begin\""
(org-element-map tree 'plain-text
(lambda (s) (org-export-activate-smart-quotes s :html info))
info)))))
@@ -4267,6 +4267,39 @@ This test does not cover listings and custom
environments."
(org-test-with-parsed-data "*\"foo\"*"
(org-element-map tree 'plain-text
(lambda (s) (org-export-activate-smart-quotes s :html info))
+ info nil nil t)))))
+ ;; Unmatched quotes.
+ (should
+ (equal '("\\guillemotleft{}my friends' party and the students'
papers\\guillemotright{} \\guillemotleft{}``mothers''\\guillemotright{}")
+ (let ((org-export-default-language "es"))
+ (org-test-with-parsed-data
+ "\"my friends' party and the students' papers\" \"'mothers'\""
+ (org-element-map tree 'plain-text
+ (lambda (s) (org-export-activate-smart-quotes s :latex info))
+ info nil nil t)))))
+ (should
+ (equal '("\"'mothers'")
+ (let ((org-export-default-language "es"))
+ (org-test-with-parsed-data
+ "\"'mothers'"
+ (org-element-map tree 'plain-text
+ (lambda (s) (org-export-activate-smart-quotes s :latex info))
+ info nil nil t)))))
+ (should
+ (equal '("\"'mothers " "end'")
+ (let ((org-export-default-language "es"))
+ (org-test-with-parsed-data
+ "\"'mothers =verbatim= end'"
+ (org-element-map tree 'plain-text
+ (lambda (s) (org-export-activate-smart-quotes s :latex info))
+ info nil nil t)))))
+ (should
+ (equal '("\\guillemotleft{}να 'ρθώ το βράδυ\\guillemotright{}")
+ (let ((org-export-default-language "el"))
+ (org-test-with-parsed-data
+ "\"να 'ρθώ το βράδυ\""
+ (org-element-map tree 'plain-text
+ (lambda (s) (org-export-activate-smart-quotes s :latex info))
info nil nil t))))))
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [elpa] externals/org 33503445e6: org-export: Do not treat unpaired ' and " as smart quotes,
ELPA Syncer <=