emacs-elpa-diffs
[Top][All Lists]
Advanced

[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
-    '("&ldquo;begin")
+    '("&ldquo;begin&rdquo;")
     (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))))))
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]