summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <n.goaziou@gmail.com>2012-10-29 20:36:03 +0100
committerNicolas Goaziou <n.goaziou@gmail.com>2012-10-29 20:36:03 +0100
commit8fb5987e562a447a520179df438b1970a4a7e5bd (patch)
treed88e239526581d17155d9d55011bbb4b38803d9a
parentc7f4a9ebad99fd065155e12d53807b1dbd7170dc (diff)
downloadorg-mode-8fb5987e562a447a520179df438b1970a4a7e5bd.tar.gz
org-export: Fix smart quotes with isolated quotes
* contrib/lisp/org-export.el (org-export-activate-smart-quotes): Fix smart quotes in some corner-cases. Refactor code. * testing/lisp/test-org-export.el: Add test.
-rw-r--r--contrib/lisp/org-export.el154
-rw-r--r--testing/lisp/test-org-export.el11
2 files changed, 81 insertions, 84 deletions
diff --git a/contrib/lisp/org-export.el b/contrib/lisp/org-export.el
index e9122f6..dc601d4 100644
--- a/contrib/lisp/org-export.el
+++ b/contrib/lisp/org-export.el
@@ -4291,107 +4291,95 @@ original string.
Return the new string."
(if (equal s "") ""
- (let ((quotes-alist (cdr (assoc (plist-get info :language)
- org-export-smart-quotes-alist))))
- ;; 1. Replace quote character at the beginning of S.
- (let* ((prev (org-export-get-previous-element (or original s) info))
- (pre-blank (and prev (org-element-property :post-blank prev))))
+ (let* ((prev (org-export-get-previous-element (or original s) info))
+ (pre-blank (and prev (org-element-property :post-blank prev)))
+ (next (org-export-get-next-element (or original s) info))
+ (get-smart-quote
+ (lambda (q type)
+ ;; Return smart quote associated to a give quote Q, as
+ ;; a string. TYPE is a symbol among `open', `close' and
+ ;; `apostrophe'.
+ (let ((key (case type
+ (apostrophe 'apostrophe)
+ (open (if (equal "'" q) 'opening-single-quote
+ 'opening-double-quote))
+ (otherwise (if (equal "'" q) 'closing-single-quote
+ 'closing-double-quote)))))
+ (or (plist-get
+ (cdr (assq key
+ (cdr (assoc (plist-get info :language)
+ org-export-smart-quotes-alist))))
+ encoding)
+ q)))))
+ (if (or (equal "\"" s) (equal "'" s))
+ ;; Only a quote: no regexp can match. We have to check both
+ ;; sides and decide what to do.
+ (cond ((and (not prev) (not next)) s)
+ ((not prev) (funcall get-smart-quote s 'open))
+ ((and (not next) (zerop pre-blank))
+ (funcall get-smart-quote s 'close))
+ ((not next) s)
+ ((zerop pre-blank) (funcall get-smart-quote s 'apostrophe))
+ (t (funcall get-smart-quote 'open)))
+ ;; 1. Replace quote character at the beginning of S.
(cond
;; Apostrophe?
((and prev (zerop pre-blank)
(string-match (nth 2 org-export-smart-quotes-regexps) s))
- (let ((smart-quote
- (plist-get (cdr (assq 'apostrophe quotes-alist)) encoding)))
- (when smart-quote
- (setq s (replace-match smart-quote nil t s 1)))))
+ (setq s (replace-match
+ (funcall get-smart-quote (match-string 1 s) 'apostrophe)
+ nil t s 1)))
;; Closing quote?
((and prev (zerop pre-blank)
(string-match (nth 1 org-export-smart-quotes-regexps) s))
- (let ((smart-quote
- (plist-get (cdr (assq (if (equal (match-string 1 s) "'")
- 'closing-single-quote
- 'closing-double-quote)
- quotes-alist))
- encoding)))
- (when smart-quote
- (setq s (replace-match smart-quote nil t s 1)))))
+ (setq s (replace-match
+ (funcall get-smart-quote (match-string 1 s) 'close)
+ nil t s 1)))
;; Opening quote?
((and (or (not prev) (> pre-blank 0))
(string-match (nth 0 org-export-smart-quotes-regexps) s))
- (let ((smart-quote
- (plist-get (cdr (assq (if (equal (match-string 1 s) "'")
- 'opening-single-quote
- 'opening-double-quote)
- quotes-alist))
- encoding)))
- (when smart-quote
- (setq s (replace-match smart-quote nil t s 1)))))))
- ;; 2. Replace quotes in the middle of the string.
- (setq s
- ;; Opening quotes.
- (replace-regexp-in-string
- (nth 3 org-export-smart-quotes-regexps)
- (lambda (text)
- (or (plist-get
- (cdr (assq (if (equal (match-string 1 text) "'")
- 'opening-single-quote
- 'opening-double-quote)
- quotes-alist))
- encoding)
- (match-string 1 text)))
- s nil t 1))
- (setq s
- (replace-regexp-in-string
- ;; Closing quotes.
- (nth 4 org-export-smart-quotes-regexps)
- (lambda (text)
- (or (plist-get
- (cdr (assq (if (equal (match-string 1 text) "'")
- 'closing-single-quote
- 'closing-double-quote)
- quotes-alist))
- encoding)
- (match-string 1 text)))
- s nil t 1))
- (setq s
- (replace-regexp-in-string
- ;; Apostrophes.
- (nth 5 org-export-smart-quotes-regexps)
- (lambda (text)
- (or (plist-get (cdr (assq 'apostrophe quotes-alist)) encoding)
- (match-string 1 text)))
- s nil t 1))
- ;; 3. Replace quote character at the end of S.
- (let ((next (org-export-get-next-element (or original s) info)))
+ (setq s (replace-match
+ (funcall get-smart-quote (match-string 1 s) 'open)
+ nil t s 1))))
+ ;; 2. Replace quotes in the middle of the string.
+ (setq s (replace-regexp-in-string
+ ;; Opening quotes.
+ (nth 3 org-export-smart-quotes-regexps)
+ (lambda (text)
+ (funcall get-smart-quote (match-string 1 text) 'open))
+ s nil t 1))
+ (setq s (replace-regexp-in-string
+ ;; Closing quotes.
+ (nth 4 org-export-smart-quotes-regexps)
+ (lambda (text)
+ (funcall get-smart-quote (match-string 1 text) 'close))
+ s nil t 1))
+ (setq s (replace-regexp-in-string
+ ;; Apostrophes.
+ (nth 5 org-export-smart-quotes-regexps)
+ (lambda (text)
+ (funcall get-smart-quote (match-string 1 text) 'apostrophe))
+ s nil t 1))
+ ;; 3. Replace quote character at the end of S.
(cond
;; Apostrophe?
((and next (string-match (nth 8 org-export-smart-quotes-regexps) s))
- (let ((smart-quote
- (plist-get (cdr (assq 'apostrophe quotes-alist)) encoding)))
- (when smart-quote (setq s (replace-match smart-quote nil t s 1)))))
+ (setq s (replace-match
+ (funcall get-smart-quote (match-string 1 s) 'apostrophe)
+ nil t s 1)))
;; Closing quote?
((and (not next)
(string-match (nth 7 org-export-smart-quotes-regexps) s))
- (let ((smart-quote
- (plist-get (cdr (assq (if (equal (match-string 1 s) "'")
- 'closing-single-quote
- 'closing-double-quote)
- quotes-alist))
- encoding)))
- (when smart-quote (setq s (replace-match smart-quote nil t s 1)))))
+ (setq s (replace-match
+ (funcall get-smart-quote (match-string 1 s) 'close)
+ nil t s 1)))
;; Opening quote?
((and next (string-match (nth 6 org-export-smart-quotes-regexps) s))
- (let ((smart-quote
- (plist-get (cdr (assq (if (equal (match-string 1 s) "'")
- 'opening-single-quote
- 'opening-double-quote)
- quotes-alist))
- encoding)))
- (when smart-quote
- (setq s (replace-match smart-quote nil t s 1)))))))
- ;; Return string with smart quotes.
- s)))
-
+ (setq s (replace-match
+ (funcall get-smart-quote (match-string 1 s) 'open)
+ nil t s 1))))
+ ;; Return string with smart quotes.
+ s))))
;;;; Topology
;;
diff --git a/testing/lisp/test-org-export.el b/testing/lisp/test-org-export.el
index 6fca839..92f7ea1 100644
--- a/testing/lisp/test-org-export.el
+++ b/testing/lisp/test-org-export.el
@@ -1234,7 +1234,16 @@ Another text. (ref:text)
(org-element-map
tree 'plain-text
(lambda (s) (org-export-activate-smart-quotes s :html info))
- info))))))
+ info)))))
+ ;; Special case: isolated quotes.
+ (should
+ (equal '("&ldquo;" "&rdquo;")
+ (let ((org-export-default-language "en"))
+ (org-test-with-parsed-data "\"$x$\""
+ (org-element-map
+ tree 'plain-text
+ (lambda (s) (org-export-activate-smart-quotes s :html info))
+ info))))))