[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#31006: [PATCH] Handle quotation marks and apostrophes in ‘sgml-quote
From: |
Michal Nazarewicz |
Subject: |
bug#31006: [PATCH] Handle quotation marks and apostrophes in ‘sgml-quote’ |
Date: |
Sat, 31 Mar 2018 18:00:35 +0100 |
To be able to use text in an HTML argument, quotation marks need
to be replaced with an appropriate character reference. Make
‘sgml-quote’ do that.
While at it, fix entiteis not being unquoted if they lack closing
semicolon (e.g. ‘&’) occuring at the very end of a region.
Even though unlikely, make ‘sgml-quote’ handle this scenario.
* lisp/textmodes/sgml-mode.el (sgml-quote): Handle quotation marks and
apostrophes. Match entities lacking semicolon at the end of regions.
* test/lisp/textmodes/sgml-mode-tests.el (sgml-quote-works): New test
case for ‘sgml-quote’ function.
---
etc/NEWS | 6 ++++++
lisp/textmodes/sgml-mode.el | 26 +++++++++++++++++++-------
test/lisp/textmodes/sgml-mode-tests.el | 30 ++++++++++++++++++++++++++++++
3 files changed, 55 insertions(+), 7 deletions(-)
If everyone is fine with this I’m gonna push it in a few days.
diff --git a/etc/NEWS b/etc/NEWS
index 07f6d04a74..2da16e53fe 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -168,6 +168,12 @@ Can be controlled via the new variable
'footnote-align-to-fn-text'.
formats (e.g. "black" => "#000000" => "rgb(0, 0, 0)") has been added,
bound to 'C-c C-f'.
+** SGML mode
+
+*** 'sgml-quote' now handles double quotes and apostrophes
+when escaping text and in addition all numeric entities when
+unescaping text.
+
** Dired
+++
diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el
index f6bdfc6384..52d14bd800 100644
--- a/lisp/textmodes/sgml-mode.el
+++ b/lisp/textmodes/sgml-mode.el
@@ -1241,8 +1241,11 @@ sgml-value
(defun sgml-quote (start end &optional unquotep)
"Quote SGML text in region START ... END.
-Only &, < and > are quoted, the rest is left untouched.
-With prefix argument UNQUOTEP, unquote the region."
+Only &, <, >, ' and \" characters are quoted, the rest is left
+untouched. This is sufficient to use quoted text as SGML argument.
+
+With prefix argument UNQUOTEP, unquote the region. All numeric entities,
+\"amp\", \"lt\", \"gt\" and \"quot\" named entities are unquoted."
(interactive "r\nP")
(save-restriction
(narrow-to-region start end)
@@ -1250,14 +1253,23 @@ sgml-quote
(if unquotep
;; FIXME: We should unquote other named character references as well.
(while (re-search-forward
- "\\(&\\(amp\\|\\(l\\|\\(g\\)\\)t\\)\\)[][<>&;\n\t \"%!'(),/=?]"
+
"\\(&\\(amp\\|quot\\|lt\\|gt\\|#\\([0-9]+\\|[xX][0-9a-fA-F]+\\)\\)\\)\\([][<>&;\n\t
\"%!'(),/=?]\\|$\\)"
nil t)
- (replace-match (if (match-end 4) ">" (if (match-end 3) "<" "&")) t t
- nil (if (eq (char-before (match-end 0)) ?\;) 0 1)))
- (while (re-search-forward "[&<>]" nil t)
+ (replace-match
+ (string
+ (or (cdr (assq (char-after (match-beginning 2))
+ '((?a . ?&) (?q . ?\") (?l . ?<) (?g . ?>))))
+ (let ((num (match-string 3)))
+ (if (or (eq ?x (aref num 0)) (eq ?X (aref num 0)))
+ (string-to-number (substring num 1) 16)
+ (string-to-number num 10)))))
+ t t nil (if (eq (char-before (match-end 0)) ?\;) 0 1)))
+ (while (re-search-forward "[&<>\"']" nil t)
(replace-match (cdr (assq (char-before) '((?& . "&")
(?< . "<")
- (?> . ">"))))
+ (?> . ">")
+ (?\" . """)
+ (?' . "'"))))
t t)))))
(defun sgml-pretty-print (beg end)
diff --git a/test/lisp/textmodes/sgml-mode-tests.el
b/test/lisp/textmodes/sgml-mode-tests.el
index 7ca6e676c6..6c0070ccb1 100644
--- a/test/lisp/textmodes/sgml-mode-tests.el
+++ b/test/lisp/textmodes/sgml-mode-tests.el
@@ -131,5 +131,35 @@ sgml-with-content
(sgml-delete-tag 1)
(should (string= "Winter is comin'" (buffer-string)))))
+(ert-deftest sgml-quote-works ()
+ (let ((text "Foo<Bar> \"Baz\" 'Qux'\n"))
+ (with-temp-buffer
+ ;; Back and forth transformation.
+ (insert text)
+ (sgml-quote (point-min) (point-max))
+ (should (string= "Foo<Bar> "Baz" 'Qux'\n"
+ (buffer-string)))
+ (sgml-quote (point-min) (point-max) t)
+ (should (string= text (buffer-string)))
+
+ ;; The same text escaped differently.
+ (erase-buffer)
+ (insert "Foo<Bar> "Baz" 'Qux'\n")
+ (sgml-quote (point-min) (point-max) t)
+ (should (string= text (buffer-string)))
+
+ ;; Lack of semicolon.
+ (erase-buffer)
+ (insert "&&")
+ (sgml-quote (point-min) (point-max) t)
+ (should (string= "&&" (buffer-string)))
+
+ ;; Double quoting
+ (sgml-quote (point-min) (point-max))
+ (sgml-quote (point-min) (point-max))
+ (sgml-quote (point-min) (point-max) t)
+ (sgml-quote (point-min) (point-max) t)
+ (should (string= "&&" (buffer-string))))))
+
(provide 'sgml-mode-tests)
;;; sgml-mode-tests.el ends here
--
2.16.2
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- bug#31006: [PATCH] Handle quotation marks and apostrophes in ‘sgml-quote’,
Michal Nazarewicz <=