From: Andreas Schwab Date: Sun, 23 Aug 2015 11:43:34 +0000 (+0200) Subject: Revert "Extend ‘format’ to translate curved quotes" X-Git-Tag: emacs-25.0.90~1289 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=6b1765e05db432007ede6f1af3744e71063a728b;p=emacs.git Revert "Extend ‘format’ to translate curved quotes" This reverts commit 244c801689d2f7a80480d83cd7d092d4762ebe08. --- diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi index ab1696e6712..ca8ae3f314a 100644 --- a/doc/lispref/help.texi +++ b/doc/lispref/help.texi @@ -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 diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 8de1473b83d..580eb43acca 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -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 diff --git a/etc/NEWS b/etc/NEWS index 72af95e8de5..d3a01c20247 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -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 diff --git a/lisp/calc/calc-help.el b/lisp/calc/calc-help.el index 01ab49510cd..50a0291e4cd 100644 --- a/lisp/calc/calc-help.el +++ b/lisp/calc/calc-help.el @@ -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)\\|\\" makeinfo can append diff --git a/src/editfns.c b/src/editfns.c index 0e1b0c8f01d..8ac0ef16999 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -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 (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 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) - { - Lisp_Object len, new_len, props; - struct gcpro gcpro1; + if (string_intervals (args[0]) || arg_intervals) + { + Lisp_Object len, new_len, props; + struct gcpro gcpro1; - /* 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); + /* 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 (CONSP (props)) + if (CONSP (props)) + { + ptrdiff_t bytepos = 0, position = 0, translated = 0; + ptrdiff_t argn = 1; + Lisp_Object list; + + /* Adjust the bounds of each text property + to the proper start and end in the output string. */ + + /* 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; - - /* Adjust the bounds of each text property - to the proper start and end in the output string. */ - - /* 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)) - { - Lisp_Object item; - ptrdiff_t pos; + Lisp_Object item; + ptrdiff_t pos; - item = XCAR (list); + item = XCAR (list); - /* First adjust the property start position. */ - pos = XINT (XCAR (item)); + /* First adjust the property start position. */ + pos = XINT (XCAR (item)); - /* Advance BYTEPOS, POSITION, TRANSLATED and ARGN - up to this position. */ - for (; position < pos; bytepos++) + /* 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)); + XSETCAR (item, make_number (translated)); - /* Likewise adjust the property end position. */ - pos = XINT (XCAR (XCDR (item))); + /* Likewise adjust the property end position. */ + pos = XINT (XCAR (XCDR (item))); - for (; position < pos; bytepos++) + 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 (XCDR (item), make_number (translated)); } - add_text_properties_from_list (val, props, make_number (0)); + 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. */