Subject: bug#23425: master branch: `message' wrongly corrupts ' to curly quote.

From: Paul Eggert <[email-masked]>
Date: Tue, 3 May 2016 08:17:56 -0700

On 05/02/2016 12:10 PM, Alan Mackenzie wrote:
>
>> (message "%s" M) is the usual way to output a message M without
>> formatting it, and something like this is needed anyway if M might
>> contain %.
> That is the case for a string that might contain percent characters.  It
> is not the case for a string known to be without percents.

Sure, but the most common problem here is using (message M) to output an 
arbitrary string M that is under user control, which is why the advice 
about (message "%s" M) is helpful. This advice works for all format 
directives, not just % directives.

> There is no mention of its corruption of quotes in
> `messages''s doc string.

Thanks, good point. I fixed it by installing the attached patch, which 
should address the other documentation problems you mention too.

> It appears to me that these substitutions are only done on pairs of
> quote marks, not single quotes.

What gives you that impression? Substitutions are done on all quotes, 
not just paired quotes.

> Properly, for me, means that it handles percent escape sequences, AND
> OTHERWISE LEAVES THE STRING UNCHANGED.

This alternative was considered when designing text-quoting-style, but 
at the time we didn't see a need for the extra complexity. The 
particular glitch you ran into is not a strong argument for revisiting 
this now.

> Why is it not in the section "incompatible Lisp changes"?

It is in that section, under "** New variable 'text-quoting-style' ...".

From ee2f178502594f3c0813b61a64c4da501a8c72fb Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Tue, 3 May 2016 08:02:16 -0700
Subject: [PATCH] Doc fixes for quoting

* doc/emacs/text.texi, doc/lispintro/emacs-lisp-intro.texi:
* doc/lispref/control.texi, doc/lispref/display.texi:
* doc/lispref/help.texi, doc/lispref/strings.texi, lisp/subr.el:
* src/callint.c, src/doprnt.c, src/editfns.c:
Document quoting a bit more systematically.
Problem reported by Alan Mackenzie (Bug#23425).
---
 doc/emacs/text.texi                 |  4 ++--
 doc/lispintro/emacs-lisp-intro.texi | 28 +++++++++++-----------------
 doc/lispref/control.texi            | 10 ++++++----
 doc/lispref/display.texi            | 10 ++++++----
 doc/lispref/help.texi               |  4 ++++
 doc/lispref/strings.texi            | 10 ++++++++--
 lisp/subr.el                        | 14 ++++++++++----
 src/callint.c                       |  2 +-
 src/doprnt.c                        |  6 +++---
 src/editfns.c                       | 13 ++++++++-----
 10 files changed, 59 insertions(+), 42 deletions(-)

diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi
index 66f01b4..579f788 100644
--- a/doc/emacs/text.texi
+++ b/doc/emacs/text.texi
@@ -862,8 +862,8 @@ Text Mode
 
   Text mode turns off the features concerned with comments except when
 you explicitly invoke them.  It changes the syntax table so that
-single-quotes are considered part of words (e.g., @samp{don't} is
-considered one word).  However, if a word starts with a single-quote,
+apostrophes are considered part of words (e.g., @samp{don't} is
+considered one word).  However, if a word starts with an apostrophe,
 it is treated as a prefix for the purposes of capitalization
 (e.g., @kbd{M-c} converts @samp{'hello'} into @samp{'Hello'}, as
 expected).
diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi
index 78c1865..eea46af 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -1004,11 +1004,11 @@ List Processing
 claim is unwarranted.  Lisp stands for LISt Processing, and the
 programming language handles @emph{lists} (and lists of lists) by
 putting them between parentheses.  The parentheses mark the boundaries
-of the list.  Sometimes a list is preceded by a single apostrophe or
-quotation mark, @samp{'}@footnote{The single apostrophe or quotation
-mark is an abbreviation for the function @code{quote}; you need not
-think about functions now; functions are defined in @ref{Making
-Errors, , Generate an Error Message}.}  Lists are the basis of Lisp.
+of the list.  Sometimes a list is preceded by an apostrophe @samp{'},
+called a @dfn{single-quote} in Lisp.@footnote{A single-quote is an
+abbreviation for the special form @code{quote}; you need not think
+about special forms now.  @xref{Complications}.}  Lists are the basis
+of Lisp.
 
 @menu
 * Lisp Lists::                  What are lists?
@@ -2490,14 +2490,7 @@ Summary
 Then the instructions in the function definition are carried out.
 
 @item
-A single quotation mark,
-@ifinfo
-'
-@end ifinfo
-@ifnotinfo
-@code{'}
-@end ifnotinfo
-, tells the Lisp interpreter that it should
+A single-quote @samp{'} tells the Lisp interpreter that it should
 return the following expression as written, and not evaluate it as it
 would if the quote were not there.
 
@@ -7610,7 +7603,8 @@ Complete zap-to-char
 suitable for use as quotes.  On most modern displays this is no longer
 true, and when these two ASCII characters appear in documentation
 strings or diagnostic message formats, Emacs typically transliterates
-them to curved single quotes, so that the abovequoted symbol appears
+them to @dfn{curved quotes} (left and right single quotation marks),
+so that the abovequoted symbol appears
 as @t{‘case-fold-search’}.  Source-code strings can also simply use
 curved quotes directly.
 
@@ -17117,7 +17111,7 @@ Text and Auto-fill
 
 We are already familiar with @code{setq}.  It sets the following variable,
 @code{major-mode}, to the subsequent value, which is @code{text-mode}.
-The single quote mark before @code{text-mode} tells Emacs to deal directly
+The single-quote before @code{text-mode} tells Emacs to deal directly
 with the @code{text-mode} symbol, not with whatever it might stand for.
 @xref{set & setq, , Setting the Value of a Variable},
 for a reminder of how @code{setq} works.
@@ -17284,11 +17278,11 @@ Keybindings
 details.)
 
 The command invoked by the keys is @code{compare-windows}.  Note that
-@code{compare-windows} is preceded by a single quote; otherwise, Emacs
+@code{compare-windows} is preceded by a single-quote; otherwise, Emacs
 would first try to evaluate the symbol to determine its value.
 
 These three things, the double quotation marks, the backslash before
-the @samp{C}, and the single quote mark are necessary parts of
+the @samp{C}, and the single-quote are necessary parts of
 keybinding that I tend to forget.  Fortunately, I have come to
 remember that I should look at my existing @file{.emacs} file, and
 adapt what is there.
diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi
index 3f48c45..75d8d28 100644
--- a/doc/lispref/control.texi
+++ b/doc/lispref/control.texi
@@ -1100,10 +1100,12 @@ Signaling Errors
 error symbol @code{error}, and a list containing the string returned by
 @code{format-message}.
 
-In a format string containing single quotes, curved quotes @t{‘like
-this’} and grave quotes @t{`like this'} work better than straight
-quotes @t{'like this'}, as @code{error} typically formats every
-straight quote as a curved closing quote.
+A format that quotes with grave accents and apostrophes @t{`like
+this'} typically generates curved quotes @t{‘like this’}.  In
+contrast, a format that quotes with only apostrophes @t{'like this'}
+typically generates two closing curved quotes @t{’like this’}, an
+unusual style in English.  @xref{Keys in Documentation}, for how the
+@code{text-quoting-style} variable affects generated quotes.
 
 @strong{Warning:} If you want to use your own string as an error message
 verbatim, don't just write @code{(error @var{string})}.  If @var{string}
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index c80f78c..b0cd873 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -265,10 +265,12 @@ Displaying Messages
 The string is also added to the @file{*Messages*} buffer, but without
 text properties (@pxref{Logging Messages}).
 
-In a format string containing single quotes, curved quotes @t{‘like
-this’} and grave quotes @t{`like this'} work better than straight
-quotes @t{'like this'}, as @code{message} typically formats every
-straight quote as a curved closing quote.
+A format that quotes with grave accents and apostrophes @t{`like
+this'} typically generates curved quotes @t{‘like this’}.  In
+contrast, a format that quotes with only apostrophes @t{'like this'}
+typically generates two closing curved quotes @t{’like this’}, an
+unusual style in English.  @xref{Keys in Documentation}, for how the
+@code{text-quoting-style} variable affects generated quotes.
 
 In batch mode, the message is printed to the standard error stream,
 followed by a newline.
diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi
index 58a11f2..b945e43 100644
--- a/doc/lispref/help.texi
+++ b/doc/lispref/help.texi
@@ -335,10 +335,14 @@ Keys in Documentation
 @item ‘
 @itemx `
 (left single quotation mark and grave accent) both stand for a left quote.
+This generates a left single quotation mark, an apostrophe, or a grave
+accent depending on the value of @code{text-quoting-style}.
 
 @item ’
 @itemx '
 (right single quotation mark and apostrophe) both stand for a right quote.
+This generates a right single quotation mark or an apostrophe
+depending on the value of @code{text-quoting-style}.
 
 @item \=
 quotes the following character and is discarded; thus, @samp{\=`} puts
diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi
index 9d6613c..c6563f7 100644
--- a/doc/lispref/strings.texi
+++ b/doc/lispref/strings.texi
@@ -834,8 +834,14 @@ Formatting Strings
 This function acts like @code{format}, except it also converts any
 curved single quotes in @var{string} as per the value of
 @code{text-quoting-style}, and treats grave accent (@t{`}) and
-apostrophe (@t{'}) as if they were curved single quotes.  @xref{Keys
-in Documentation}.
+apostrophe (@t{'}) as if they were curved single quotes.
+
+A format that quotes with grave accents and apostrophes @t{`like
+this'} typically generates curved quotes @t{‘like this’}.  In
+contrast, a format that quotes with only apostrophes @t{'like this'}
+typically generates two closing curved quotes @t{’like this’}, an
+unusual style in English.  @xref{Keys in Documentation}, for how the
+@code{text-quoting-style} variable affects generated quotes.
 @end defun
 
 @cindex @samp{%} in format
diff --git a/lisp/subr.el b/lisp/subr.el
index 0f02170..3ac61f9 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -290,21 +290,27 @@ ignore
 
 ;; Signal a compile-error if the first arg is missing.
 (defun error (&rest args)
-  "Signal an error, making error message by passing all args to `format'.
+  "Signal an error, making a message by passing args to `format-message'.
 In Emacs, the convention is that error messages start with a capital
 letter but *do not* end with a period.  Please follow this convention
-for the sake of consistency."
+for the sake of consistency.
+
+Note: (error \"%s\" VALUE) makes the message VALUE without
+interpreting format characters like `%', `\\=`', and `\\=''."
   (declare (advertised-calling-convention (string &rest args) "23.1"))
   (signal 'error (list (apply #'format-message args))))
 
 (defun user-error (format &rest args)
-  "Signal a pilot error, making error message by passing all args to `format'.
+  "Signal a pilot error, making a message by passing args to `format-message'.
 In Emacs, the convention is that error messages start with a capital
 letter but *do not* end with a period.  Please follow this convention
 for the sake of consistency.
 This is just like `error' except that `user-error's are expected to be the
 result of an incorrect manipulation on the part of the user, rather than the
-result of an actual problem."
+result of an actual problem.
+
+Note: (user-error \"%s\" VALUE) makes the message VALUE without
+interpreting format characters like `%', `\\=`', and `\\=''."
   (signal 'user-error (list (apply #'format-message format args))))
 
 (defun define-error (name message &optional parent)
diff --git a/src/callint.c b/src/callint.c
index e56f7cd..053ee6c 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -272,7 +272,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
 {
   /* `args' will contain the array of arguments to pass to the function.
      `visargs' will contain the same list but in a nicer form, so that if we
-     pass it to `Fformat' it will be understandable to a human.  */
+     pass it to `Fformat_message' it will be understandable to a human.  */
   Lisp_Object *args, *visargs;
   Lisp_Object specs;
   Lisp_Object filter_specs;
diff --git a/src/doprnt.c b/src/doprnt.c
index 506bbc3..9d8b783 100644
--- a/src/doprnt.c
+++ b/src/doprnt.c
@@ -46,15 +46,15 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    ignored %s and %c conversions.  (See below for the detailed documentation of
    what is supported.)  However, this is okay, as this function is supposed to
    be called from `error' and similar functions, and thus does not need to
-   support features beyond those in `Fformat', which is used by `error' on the
-   Lisp level.  */
+   support features beyond those in `Fformat_message', which is used
+   by `error' on the Lisp level.  */
 
 /* In the FORMAT argument this function supports ` and ' as directives
    that output left and right quotes as per ‘text-quoting style’.  It
    also supports the following %-sequences:
 
    %s means print a string argument.
-   %S is silently treated as %s, for loose compatibility with `Fformat'.
+   %S is treated as %s, for loose compatibility with `Fformat_message'.
    %d means print a `signed int' argument in decimal.
    %o means print an `unsigned int' argument in octal.
    %x means print an `unsigned int' argument in hex.
diff --git a/src/editfns.c b/src/editfns.c
index f0ce4e7..a858e6e 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3665,10 +3665,11 @@ In batch mode, the message is printed to the standard error stream,
 followed by a newline.
 
 The first argument is a format control string, and the rest are data
-to be formatted under control of the string.  See `format' for details.
+to be formatted under control of the string.  See `format-message' for
+details.
 
-Note: Use (message "%s" VALUE) to print the value of expressions and
-variables to avoid accidentally interpreting `%' as format specifiers.
+Note: (message "%s" VALUE) displays the string VALUE without
+interpreting format characters like `%', `\\=`', and `\\=''.
 
 If the first argument is nil or the empty string, the function clears
 any existing message; this lets the minibuffer contents show.  See
@@ -3696,7 +3697,8 @@ DEFUN ("message-box", Fmessage_box, Smessage_box, 1, MANY, 0,
        doc: /* Display a message, in a dialog box if possible.
 If a dialog box is not available, use the echo area.
 The first argument is a format control string, and the rest are data
-to be formatted under control of the string.  See `format' for details.
+to be formatted under control of the string.  See `format-message' for
+details.
 
 If the first argument is nil or the empty string, clear any existing
 message; let the minibuffer contents show.
@@ -3727,7 +3729,8 @@ If this command was invoked with the mouse, use a dialog box if
 `use-dialog-box' is non-nil.
 Otherwise, use the echo area.
 The first argument is a format control string, and the rest are data
-to be formatted under control of the string.  See `format' for details.
+to be formatted under control of the string.  See `format-message' for
+details.
 
 If the first argument is nil or the empty string, clear any existing
 message; let the minibuffer contents show.
-- 
2.5.5