1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-23 07:19:15 +00:00

Revert "Extend ‘format’ to translate curved quotes"

This reverts commit 244c801689.
This commit is contained in:
Andreas Schwab 2015-08-23 13:43:34 +02:00
parent 0b0c9565d0
commit 6b1765e05d
7 changed files with 124 additions and 191 deletions

View File

@ -347,11 +347,19 @@ and @samp{\=\=} puts @samp{\=} into the output.
@strong{Please note:} Each @samp{\} must be doubled when written in a
string in Emacs Lisp.
@defvar text-quoting-style
@cindex curved quotes
@cindex curly quotes
The value of the @code{text-quoting-style} variable specifies the style
The value of this variable specifies the style
@code{substitute-command-keys} uses when generating left and right
quotes. @xref{Formatting Strings}, for more information.
quotes. If the variable's value is @code{curve}, the style is
@t{like this} with curved single quotes. If the value is
@code{straight}, the style is @t{'like this'} with straight
apostrophes. If the value is @code{grave}, the style is @t{`like
this'} with grave accent and apostrophe. The default value @code{nil}
acts like @code{curve} if curved single quotes are displayable, and
like @code{grave} otherwise.
@end defvar
@defun substitute-command-keys string
This function scans @var{string} for the above special sequences and

View File

@ -805,27 +805,22 @@ formatting feature described here; they differ from @code{format} only
in how they use the result of formatting.
@defun format string &rest objects
This function returns a string that is equivalent to copying
This function returns a new string that is made by copying
@var{string} and then replacing any format specification
in the copy with encodings of the corresponding @var{objects}. The
arguments @var{objects} are the computed values to be formatted.
The characters in @var{string}, other than the format specifications,
are copied directly into the output, including their text properties,
if any. If the output equals @var{string}, this function may return
@var{string} itself rather than a new copy.
if any.
@end defun
@cindex @samp{%} in format
@cindex format specification
@cindex curved quotes
@cindex curly quotes
A format specification is a sequence of characters beginning with a
@samp{%} or is a curved single quotation mark. Except for @samp{%%}
and quotation marks, each format specification says how to represent
one of the arguments @var{objects}. For example, if there
is a @samp{%d} in @var{string}, the @code{format} function replaces it
with the decimal representation of the integer to be formatted.
@samp{%}. Thus, if there is a @samp{%d} in @var{string}, the
@code{format} function replaces it with the printed representation of
one of the values to be formatted (one of the arguments @var{objects}).
For example:
@example
@ -835,12 +830,11 @@ For example:
@end group
@end example
Since @code{format} interprets @samp{%}, @samp{} and @samp{}
characters as format
Since @code{format} interprets @samp{%} characters as format
specifications, you should @emph{never} pass an arbitrary string as
the first argument. This is particularly true when the string is
generated by some Lisp code. Unless the string is @emph{known} to
never include any of the three special characters, pass @code{"%s"}, described
never include any @samp{%} characters, pass @code{"%s"}, described
below, as the first argument, and the string as the second, like this:
@example
@ -914,27 +908,17 @@ is shorter.
Replace the specification with a single @samp{%}. This format
specification is unusual in that it does not use a value. For example,
@code{(format "%% %d" 30)} returns @code{"% 30"}.
@item
@itemx
@cindex curved quotes
@cindex curly quotes
Replace the specification with a left or right quote, respectively.
Although typically a curved single quotation mark stands for itself,
other quoting styles are available as per the variable
@samp{text-quoting-style} described below.
@end table
Any other format character after @samp{%} results in an @samp{Invalid format
Any other format character results in an @samp{Invalid format
operation} error.
Here are several examples, which assume the typical quoting style
where curved single quotes stand for themselves:
Here are several examples:
@example
@group
(format "The name of this buffer is %s." (buffer-name))
@result{} "The name of this buffer is strings.texi."
(format "The name of this buffer is %s." (buffer-name))
@result{} "The name of this buffer is strings.texi."
(format "The buffer object prints as %qs." (current-buffer))
@result{} "The buffer object prints as strings.texi."
@ -948,7 +932,7 @@ where curved single quotes stand for themselves:
@cindex field width
@cindex padding
A @samp{%} specification can have a @dfn{width}, which is a decimal number
A specification can have a @dfn{width}, which is a decimal number
between the @samp{%} and the specification character. If the printed
representation of the object contains fewer characters than this
width, @code{format} extends it with padding. The width specifier is
@ -964,7 +948,7 @@ the width specifier normally consists of spaces inserted on the left:
If the width is too small, @code{format} does not truncate the
object's printed representation. Thus, you can use a width to specify
a minimum spacing between columns with no risk of losing information.
In the following two examples, @samp{%7s} specifies a minimum width
In the following three examples, @samp{%7s} specifies a minimum width
of 7. In the first case, the string inserted in place of @samp{%7s}
has only 3 letters, and needs 4 blank spaces as padding. In the
second case, the string @code{"specification"} is 13 letters wide but
@ -972,12 +956,12 @@ is not truncated.
@example
@group
(format "The word %7s has %d letters in it."
(format "The word '%7s' has %d letters in it."
"foo" (length "foo"))
@result{} "The word foo has 3 letters in it."
(format "The word %7s has %d letters in it."
@result{} "The word ' foo' has 3 letters in it."
(format "The word '%7s' has %d letters in it."
"specification" (length "specification"))
@result{} "The word specification has 13 letters in it."
@result{} "The word 'specification' has 13 letters in it."
@end group
@end example
@ -1022,14 +1006,14 @@ variable @samp{text-quoting-style} described below.
(format "%q-6d is padded on the right" 123)
@result{} "123 is padded on the right"
(format "The word %-7s actually has %d letters in it."
(format "The word '%-7s' actually has %d letters in it."
"foo" (length "foo"))
@result{} "The word foo actually has 3 letters in it."
@result{} "The word 'foo ' actually has 3 letters in it."
@end group
@end example
@cindex precision in format specifications
The @samp{%} specification characters allow an optional @dfn{precision}
All the specification characters allow an optional @dfn{precision}
before the character (after the width, if present). The precision is
a decimal-point @samp{.} followed by a digit-string. For the
floating-point specifications (@samp{%e}, @samp{%f}, @samp{%g}), the
@ -1040,19 +1024,6 @@ shows only the first three characters of the representation for
@var{object}. Precision has no effect for other specification
characters.
@defvar text-quoting-style
@cindex curved quotes
@cindex curly quotes
This variable specifies the style @code{format} uses when generating
left and right quotes. If the value is @code{curve}, the style is
@t{like this} with curved single quotes. If the value is
@code{straight}, the style is @t{'like this'} with straight
apostrophes. If the value is @code{grave}, the style is @t{`like
this'} with grave accent and apostrophe. The default value @code{nil}
acts like @code{curve} if curved single quotes are displayable, and
like @code{grave} otherwise.
@end defvar
@node Case Conversion
@section Case Conversion in Lisp
@cindex upper case

View File

@ -909,19 +909,6 @@ when signaling a file error. For example, it now reports "Permission
denied" instead of "permission denied". The old behavior was problematic
in languages like German where downcasing rules depend on grammar.
+++
** format now replaces curved single quotes.
That is, it replaces strings' curved single quotes (also known as
curly quotes) as per the value of the new custom variable
text-quoting-style: curve means replace curved quotes with
themselves like this, straight means use straight apostrophes
'like this', grave means use grave accent and apostrophe `like
this', and nil (default) means use curved quotes if displayable and
grave accent and apostrophe otherwise. Because it now may be used
in many contexts where it's a no-op, format is no longer required to
create a string, and may return its first argument if the argument
already has the correct value.
+++
** New format flag q
The new q flag causes format to quote the output representation as

View File

@ -365,7 +365,7 @@ C-w Describe how there is no warranty for Calc."
(let (Info-history)
(Info-goto-node (buffer-substring (match-beginning 1) (match-end 1))))
(let* ((string-target (or target thing))
(quoted (concat "['`]" (regexp-quote string-target) "[']"))
(quoted (format "['`]%s[']" (regexp-quote string-target)))
(bracketed (format "\\[%s\\]\\|(%s)\\|\\<The[ \n]%s"
quoted quoted quoted)))
(or (let ((case-fold-search nil))

View File

@ -331,10 +331,9 @@ which more-or-less shadow%s %s's corresponding table%s."
"\n\nThis mode "
(concat
"\n\nIn addition to any hooks its parent mode "
(if (string-match (concat "[`%]"
(if (string-match (format "[`]%s[']"
(regexp-quote
(symbol-name parent))
"['%]")
(symbol-name parent)))
docstring)
nil
(format "`%s' " parent))

View File

@ -3398,12 +3398,10 @@ Give an empty topic name to go to the Index node itself."
(re-search-forward (format
"[a-zA-Z]+: [a-zA-Z0-9_ *&]+ %s\\( \\|$\\)"
(regexp-quote name)) nil t)
(search-forward (concat "['`]" name "[']") nil t)
(search-forward (format "['`]%s[']" name) nil t)
(and (string-match "\\`.*\\( (.*)\\)\\'" name)
(search-forward
(concat "['`%]"
(substring name 0 (match-beginning 1))
"['%]")
(format "['`]%s[']" (substring name 0 (match-beginning 1)))
nil t))
(search-forward name nil t)
;; Try again without the " <1>" makeinfo can append

View File

@ -3800,9 +3800,8 @@ DEFUN ("format", Fformat, Sformat, 1, MANY, 0,
The first argument is a format control string.
The other arguments are substituted into it to make the result, a string.
The format control string may contain ordinary characters,
%-sequences meaning to substitute the next available argument,
and curved single quotation marks meaning to substitute quotes.
The format control string may contain %-sequences meaning to substitute
the next available argument:
%s means print a string argument. Actually, prints any object, with `princ'.
%d means print as number in decimal (%o octal, %x hex).
@ -3850,12 +3849,6 @@ precision specifier says how many decimal places to show; if zero, the
decimal point itself is omitted. For %s and %S, the precision
specifier truncates the string to the given width.
\\= and \\= means print left and right quotes as per
text-quoting-style.
Return the first argument if it contains no format directives.
Otherwise, return a new string.
usage: (format STRING &rest OBJECTS) */)
(ptrdiff_t nargs, Lisp_Object *args)
{
@ -3868,7 +3861,6 @@ usage: (format STRING &rest OBJECTS) */)
ptrdiff_t buf_save_value_index IF_LINT (= 0);
char *format, *end, *format_start;
ptrdiff_t formatlen, nchars;
bool changed = false;
/* True if the format is multibyte. */
bool multibyte_format = 0;
/* True if the output should be a multibyte string,
@ -4020,7 +4012,6 @@ usage: (format STRING &rest OBJECTS) */)
if (format == end)
error ("Format string ends in middle of format specifier");
changed = true;
memset (&discarded[format0 - format_start], 1, format - format0);
conversion = *format;
if (conversion == '%')
@ -4493,20 +4484,6 @@ usage: (format STRING &rest OBJECTS) */)
convbytes = format - src;
memset (&discarded[src + 1 - format_start], 2, convbytes - 1);
if (quoting_style != CURVE_QUOTING_STYLE && convbytes == 3
&& (unsigned char) src[0] == uLSQM0
&& (unsigned char) src[1] == uLSQM1
&& ((unsigned char) src[2] == uLSQM2
|| (unsigned char) src[2] == uRSQM2))
{
convbytes = 1;
str[0] = (((unsigned char) src[2] == uLSQM2
&& quoting_style == GRAVE_QUOTING_STYLE)
? '`' : '\'');
src = (char *) str;
changed = true;
}
}
else
{
@ -4518,7 +4495,6 @@ usage: (format STRING &rest OBJECTS) */)
int c = BYTE8_TO_CHAR (uc);
convbytes = CHAR_STRING (c, str);
src = (char *) str;
changed = true;
}
}
@ -4566,119 +4542,113 @@ usage: (format STRING &rest OBJECTS) */)
if (bufsize < p - buf)
emacs_abort ();
if (!changed)
val = args[0];
else
if (maybe_combine_byte)
nchars = multibyte_chars_in_text ((unsigned char *) buf, p - buf);
val = make_specified_string (buf, nchars, p - buf, multibyte);
/* If the format string has text properties, or any of the string
arguments has text properties, set up text properties of the
result string. */
if (string_intervals (args[0]) || arg_intervals)
{
if (maybe_combine_byte)
nchars = multibyte_chars_in_text ((unsigned char *) buf, p - buf);
val = make_specified_string (buf, nchars, p - buf, multibyte);
Lisp_Object len, new_len, props;
struct gcpro gcpro1;
/* If the format string has text properties, or any of the string
arguments has text properties, set up text properties of the
result string. */
/* Add text properties from the format string. */
len = make_number (SCHARS (args[0]));
props = text_property_list (args[0], make_number (0), len, Qnil);
GCPRO1 (props);
if (string_intervals (args[0]) || arg_intervals)
if (CONSP (props))
{
Lisp_Object len, new_len, props;
struct gcpro gcpro1;
ptrdiff_t bytepos = 0, position = 0, translated = 0;
ptrdiff_t argn = 1;
Lisp_Object list;
/* Add text properties from the format string. */
len = make_number (SCHARS (args[0]));
props = text_property_list (args[0], make_number (0), len, Qnil);
GCPRO1 (props);
/* Adjust the bounds of each text property
to the proper start and end in the output string. */
if (CONSP (props))
/* Put the positions in PROPS in increasing order, so that
we can do (effectively) one scan through the position
space of the format string. */
props = Fnreverse (props);
/* BYTEPOS is the byte position in the format string,
POSITION is the untranslated char position in it,
TRANSLATED is the translated char position in BUF,
and ARGN is the number of the next arg we will come to. */
for (list = props; CONSP (list); list = XCDR (list))
{
ptrdiff_t bytepos = 0, position = 0, translated = 0;
ptrdiff_t argn = 1;
Lisp_Object list;
Lisp_Object item;
ptrdiff_t pos;
/* Adjust the bounds of each text property
to the proper start and end in the output string. */
item = XCAR (list);
/* Put the positions in PROPS in increasing order, so that
we can do (effectively) one scan through the position
space of the format string. */
props = Fnreverse (props);
/* First adjust the property start position. */
pos = XINT (XCAR (item));
/* BYTEPOS is the byte position in the format string,
POSITION is the untranslated char position in it,
TRANSLATED is the translated char position in BUF,
and ARGN is the number of the next arg we will come to. */
for (list = props; CONSP (list); list = XCDR (list))
/* Advance BYTEPOS, POSITION, TRANSLATED and ARGN
up to this position. */
for (; position < pos; bytepos++)
{
Lisp_Object item;
ptrdiff_t pos;
item = XCAR (list);
/* First adjust the property start position. */
pos = XINT (XCAR (item));
/* Advance BYTEPOS, POSITION, TRANSLATED and ARGN
up to this position. */
for (; position < pos; bytepos++)
if (! discarded[bytepos])
position++, translated++;
else if (discarded[bytepos] == 1)
{
if (! discarded[bytepos])
position++, translated++;
else if (discarded[bytepos] == 1)
position++;
if (translated == info[argn].start)
{
position++;
if (translated == info[argn].start)
{
translated += info[argn].end - info[argn].start;
argn++;
}
translated += info[argn].end - info[argn].start;
argn++;
}
}
XSETCAR (item, make_number (translated));
/* Likewise adjust the property end position. */
pos = XINT (XCAR (XCDR (item)));
for (; position < pos; bytepos++)
{
if (! discarded[bytepos])
position++, translated++;
else if (discarded[bytepos] == 1)
{
position++;
if (translated == info[argn].start)
{
translated += info[argn].end - info[argn].start;
argn++;
}
}
}
XSETCAR (XCDR (item), make_number (translated));
}
add_text_properties_from_list (val, props, make_number (0));
XSETCAR (item, make_number (translated));
/* Likewise adjust the property end position. */
pos = XINT (XCAR (XCDR (item)));
for (; position < pos; bytepos++)
{
if (! discarded[bytepos])
position++, translated++;
else if (discarded[bytepos] == 1)
{
position++;
if (translated == info[argn].start)
{
translated += info[argn].end - info[argn].start;
argn++;
}
}
}
XSETCAR (XCDR (item), make_number (translated));
}
/* Add text properties from arguments. */
if (arg_intervals)
for (n = 1; n < nargs; ++n)
if (info[n].intervals)
{
len = make_number (SCHARS (args[n]));
new_len = make_number (info[n].end - info[n].start);
props = text_property_list (args[n], make_number (0),
len, Qnil);
props = extend_property_ranges (props, new_len);
/* If successive arguments have properties, be sure that
the value of `composition' property be the copy. */
if (n > 1 && info[n - 1].end)
make_composition_value_copy (props);
add_text_properties_from_list (val, props,
make_number (info[n].start));
}
UNGCPRO;
add_text_properties_from_list (val, props, make_number (0));
}
/* Add text properties from arguments. */
if (arg_intervals)
for (n = 1; n < nargs; ++n)
if (info[n].intervals)
{
len = make_number (SCHARS (args[n]));
new_len = make_number (info[n].end - info[n].start);
props = text_property_list (args[n], make_number (0), len, Qnil);
props = extend_property_ranges (props, new_len);
/* If successive arguments have properties, be sure that
the value of `composition' property be the copy. */
if (n > 1 && info[n - 1].end)
make_composition_value_copy (props);
add_text_properties_from_list (val, props,
make_number (info[n].start));
}
UNGCPRO;
}
/* If we allocated BUF or INFO with malloc, free it too. */