aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Schwab2015-08-23 13:43:34 +0200
committerAndreas Schwab2015-08-23 16:33:39 +0200
commit6b1765e05db432007ede6f1af3744e71063a728b (patch)
treef8e0b1cf2b8238a292b6896cf664079765f53861
parent0b0c9565d050bfecc581b342c40b719917395896 (diff)
downloademacs-6b1765e05db432007ede6f1af3744e71063a728b.tar.gz
emacs-6b1765e05db432007ede6f1af3744e71063a728b.zip
Revert "Extend ‘format’ to translate curved quotes"
This reverts commit 244c801689d2f7a80480d83cd7d092d4762ebe08.
-rw-r--r--doc/lispref/help.texi12
-rw-r--r--doc/lispref/strings.texi69
-rw-r--r--etc/NEWS13
-rw-r--r--lisp/calc/calc-help.el2
-rw-r--r--lisp/emacs-lisp/derived.el5
-rw-r--r--lisp/info.el6
-rw-r--r--src/editfns.c200
7 files changed, 120 insertions, 187 deletions
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.
347@strong{Please note:} Each @samp{\} must be doubled when written in a 347@strong{Please note:} Each @samp{\} must be doubled when written in a
348string in Emacs Lisp. 348string in Emacs Lisp.
349 349
350@defvar text-quoting-style
350@cindex curved quotes 351@cindex curved quotes
351@cindex curly quotes 352@cindex curly quotes
352The value of the @code{text-quoting-style} variable specifies the style 353The value of this variable specifies the style
353@code{substitute-command-keys} uses when generating left and right 354@code{substitute-command-keys} uses when generating left and right
354quotes. @xref{Formatting Strings}, for more information. 355quotes. If the variable's value is @code{curve}, the style is
356@t{‘like this’} with curved single quotes. If the value is
357@code{straight}, the style is @t{'like this'} with straight
358apostrophes. If the value is @code{grave}, the style is @t{`like
359this'} with grave accent and apostrophe. The default value @code{nil}
360acts like @code{curve} if curved single quotes are displayable, and
361like @code{grave} otherwise.
362@end defvar
355 363
356@defun substitute-command-keys string 364@defun substitute-command-keys string
357This function scans @var{string} for the above special sequences and 365This 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
805in how they use the result of formatting. 805in how they use the result of formatting.
806 806
807@defun format string &rest objects 807@defun format string &rest objects
808This function returns a string that is equivalent to copying 808This function returns a new string that is made by copying
809@var{string} and then replacing any format specification 809@var{string} and then replacing any format specification
810in the copy with encodings of the corresponding @var{objects}. The 810in the copy with encodings of the corresponding @var{objects}. The
811arguments @var{objects} are the computed values to be formatted. 811arguments @var{objects} are the computed values to be formatted.
812 812
813The characters in @var{string}, other than the format specifications, 813The characters in @var{string}, other than the format specifications,
814are copied directly into the output, including their text properties, 814are copied directly into the output, including their text properties,
815if any. If the output equals @var{string}, this function may return 815if any.
816@var{string} itself rather than a new copy.
817@end defun 816@end defun
818 817
819@cindex @samp{%} in format 818@cindex @samp{%} in format
820@cindex format specification 819@cindex format specification
821@cindex curved quotes
822@cindex curly quotes
823 A format specification is a sequence of characters beginning with a 820 A format specification is a sequence of characters beginning with a
824@samp{%} or is a curved single quotation mark. Except for @samp{%%} 821@samp{%}. Thus, if there is a @samp{%d} in @var{string}, the
825and quotation marks, each format specification says how to represent 822@code{format} function replaces it with the printed representation of
826one of the arguments @var{objects}. For example, if there 823one of the values to be formatted (one of the arguments @var{objects}).
827is a @samp{%d} in @var{string}, the @code{format} function replaces it
828with the decimal representation of the integer to be formatted.
829For example: 824For example:
830 825
831@example 826@example
@@ -835,12 +830,11 @@ For example:
835@end group 830@end group
836@end example 831@end example
837 832
838 Since @code{format} interprets @samp{%}, @samp{‘} and @samp{’} 833 Since @code{format} interprets @samp{%} characters as format
839characters as format
840specifications, you should @emph{never} pass an arbitrary string as 834specifications, you should @emph{never} pass an arbitrary string as
841the first argument. This is particularly true when the string is 835the first argument. This is particularly true when the string is
842generated by some Lisp code. Unless the string is @emph{known} to 836generated by some Lisp code. Unless the string is @emph{known} to
843never include any of the three special characters, pass @code{"%s"}, described 837never include any @samp{%} characters, pass @code{"%s"}, described
844below, as the first argument, and the string as the second, like this: 838below, as the first argument, and the string as the second, like this:
845 839
846@example 840@example
@@ -914,27 +908,17 @@ is shorter.
914Replace the specification with a single @samp{%}. This format 908Replace the specification with a single @samp{%}. This format
915specification is unusual in that it does not use a value. For example, 909specification is unusual in that it does not use a value. For example,
916@code{(format "%% %d" 30)} returns @code{"% 30"}. 910@code{(format "%% %d" 30)} returns @code{"% 30"}.
917
918@item ‘
919@itemx ’
920@cindex curved quotes
921@cindex curly quotes
922Replace the specification with a left or right quote, respectively.
923Although typically a curved single quotation mark stands for itself,
924other quoting styles are available as per the variable
925@samp{text-quoting-style} described below.
926@end table 911@end table
927 912
928 Any other format character after @samp{%} results in an @samp{Invalid format 913 Any other format character results in an @samp{Invalid format
929operation} error. 914operation} error.
930 915
931 Here are several examples, which assume the typical quoting style 916 Here are several examples:
932where curved single quotes stand for themselves:
933 917
934@example 918@example
935@group 919@group
936(format "The name of this buffer is %s." (buffer-name)) 920(format "The name of this buffer is %s." (buffer-name))
937 @result{} "The name of this buffer is strings.texi." 921 @result{} "The name of this buffer is strings.texi."
938 922
939(format "The buffer object prints as %qs." (current-buffer)) 923(format "The buffer object prints as %qs." (current-buffer))
940 @result{} "The buffer object prints as ‘strings.texi’." 924 @result{} "The buffer object prints as ‘strings.texi’."
@@ -948,7 +932,7 @@ where curved single quotes stand for themselves:
948 932
949@cindex field width 933@cindex field width
950@cindex padding 934@cindex padding
951 A @samp{%} specification can have a @dfn{width}, which is a decimal number 935 A specification can have a @dfn{width}, which is a decimal number
952between the @samp{%} and the specification character. If the printed 936between the @samp{%} and the specification character. If the printed
953representation of the object contains fewer characters than this 937representation of the object contains fewer characters than this
954width, @code{format} extends it with padding. The width specifier is 938width, @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:
964If the width is too small, @code{format} does not truncate the 948If the width is too small, @code{format} does not truncate the
965object's printed representation. Thus, you can use a width to specify 949object's printed representation. Thus, you can use a width to specify
966a minimum spacing between columns with no risk of losing information. 950a minimum spacing between columns with no risk of losing information.
967In the following two examples, @samp{%7s} specifies a minimum width 951In the following three examples, @samp{%7s} specifies a minimum width
968of 7. In the first case, the string inserted in place of @samp{%7s} 952of 7. In the first case, the string inserted in place of @samp{%7s}
969has only 3 letters, and needs 4 blank spaces as padding. In the 953has only 3 letters, and needs 4 blank spaces as padding. In the
970second case, the string @code{"specification"} is 13 letters wide but 954second case, the string @code{"specification"} is 13 letters wide but
@@ -972,12 +956,12 @@ is not truncated.
972 956
973@example 957@example
974@group 958@group
975(format "The word %7s has %d letters in it." 959(format "The word '%7s' has %d letters in it."
976 "foo" (length "foo")) 960 "foo" (length "foo"))
977 @result{} "The word foo has 3 letters in it." 961 @result{} "The word ' foo' has 3 letters in it."
978(format "The word %7s has %d letters in it." 962(format "The word '%7s' has %d letters in it."
979 "specification" (length "specification")) 963 "specification" (length "specification"))
980 @result{} "The word specification has 13 letters in it." 964 @result{} "The word 'specification' has 13 letters in it."
981@end group 965@end group
982@end example 966@end example
983 967
@@ -1022,14 +1006,14 @@ variable @samp{text-quoting-style} described below.
1022(format "%q-6d is padded on the right" 123) 1006(format "%q-6d is padded on the right" 123)
1023 @result{} "‘123 ’ is padded on the right" 1007 @result{} "‘123 ’ is padded on the right"
1024 1008
1025(format "The word %-7s actually has %d letters in it." 1009(format "The word '%-7s' actually has %d letters in it."
1026 "foo" (length "foo")) 1010 "foo" (length "foo"))
1027 @result{} "The word foo actually has 3 letters in it." 1011 @result{} "The word 'foo ' actually has 3 letters in it."
1028@end group 1012@end group
1029@end example 1013@end example
1030 1014
1031@cindex precision in format specifications 1015@cindex precision in format specifications
1032 The @samp{%} specification characters allow an optional @dfn{precision} 1016 All the specification characters allow an optional @dfn{precision}
1033before the character (after the width, if present). The precision is 1017before the character (after the width, if present). The precision is
1034a decimal-point @samp{.} followed by a digit-string. For the 1018a decimal-point @samp{.} followed by a digit-string. For the
1035floating-point specifications (@samp{%e}, @samp{%f}, @samp{%g}), the 1019floating-point specifications (@samp{%e}, @samp{%f}, @samp{%g}), the
@@ -1040,19 +1024,6 @@ shows only the first three characters of the representation for
1040@var{object}. Precision has no effect for other specification 1024@var{object}. Precision has no effect for other specification
1041characters. 1025characters.
1042 1026
1043@defvar text-quoting-style
1044@cindex curved quotes
1045@cindex curly quotes
1046This variable specifies the style @code{format} uses when generating
1047left and right quotes. If the value is @code{curve}, the style is
1048@t{‘like this’} with curved single quotes. If the value is
1049@code{straight}, the style is @t{'like this'} with straight
1050apostrophes. If the value is @code{grave}, the style is @t{`like
1051this'} with grave accent and apostrophe. The default value @code{nil}
1052acts like @code{curve} if curved single quotes are displayable, and
1053like @code{grave} otherwise.
1054@end defvar
1055
1056@node Case Conversion 1027@node Case Conversion
1057@section Case Conversion in Lisp 1028@section Case Conversion in Lisp
1058@cindex upper case 1029@cindex upper case
diff --git a/etc/NEWS b/etc/NEWS
index 72af95e8de5..d3a01c20247 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -910,19 +910,6 @@ denied" instead of "permission denied". The old behavior was problematic
910in languages like German where downcasing rules depend on grammar. 910in languages like German where downcasing rules depend on grammar.
911 911
912+++ 912+++
913** ‘format’ now replaces curved single quotes.
914That is, it replaces strings' curved single quotes (also known as
915curly quotes) as per the value of the new custom variable
916‘text-quoting-style’: ‘curve’ means replace curved quotes with
917themselves ‘like this’, ‘straight’ means use straight apostrophes
918'like this', ‘grave’ means use grave accent and apostrophe `like
919this', and nil (default) means use curved quotes if displayable and
920grave accent and apostrophe otherwise. Because it now may be used
921in many contexts where it's a no-op, ‘format’ is no longer required to
922create a string, and may return its first argument if the argument
923already has the correct value.
924
925+++
926** New ‘format’ flag ‘q’ 913** New ‘format’ flag ‘q’
927The new ‘q’ flag causes ‘format’ to quote the output representation as 914The new ‘q’ flag causes ‘format’ to quote the output representation as
928per the value of ‘text quoting-style’. E.g., (format "%qs failed" 915per the value of ‘text quoting-style’. E.g., (format "%qs failed"
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."
365 (let (Info-history) 365 (let (Info-history)
366 (Info-goto-node (buffer-substring (match-beginning 1) (match-end 1)))) 366 (Info-goto-node (buffer-substring (match-beginning 1) (match-end 1))))
367 (let* ((string-target (or target thing)) 367 (let* ((string-target (or target thing))
368 (quoted (concat "['`‘]" (regexp-quote string-target) "['’]")) 368 (quoted (format "['`‘]%s['’]" (regexp-quote string-target)))
369 (bracketed (format "\\[%s\\]\\|(%s)\\|\\<The[ \n]%s" 369 (bracketed (format "\\[%s\\]\\|(%s)\\|\\<The[ \n]%s"
370 quoted quoted quoted))) 370 quoted quoted quoted)))
371 (or (let ((case-fold-search nil)) 371 (or (let ((case-fold-search nil))
diff --git a/lisp/emacs-lisp/derived.el b/lisp/emacs-lisp/derived.el
index 1f8572b278b..ee137f1771e 100644
--- a/lisp/emacs-lisp/derived.el
+++ b/lisp/emacs-lisp/derived.el
@@ -331,10 +331,9 @@ which more-or-less shadow%s %s's corresponding table%s."
331 "\n\nThis mode " 331 "\n\nThis mode "
332 (concat 332 (concat
333 "\n\nIn addition to any hooks its parent mode " 333 "\n\nIn addition to any hooks its parent mode "
334 (if (string-match (concat "[`%‘]" 334 (if (string-match (format "[`‘]%s['’]"
335 (regexp-quote 335 (regexp-quote
336 (symbol-name parent)) 336 (symbol-name parent)))
337 "['%’]")
338 docstring) 337 docstring)
339 nil 338 nil
340 (format "`%s' " parent)) 339 (format "`%s' " parent))
diff --git a/lisp/info.el b/lisp/info.el
index 8a43a8182aa..454fadaca03 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -3398,12 +3398,10 @@ Give an empty topic name to go to the Index node itself."
3398 (re-search-forward (format 3398 (re-search-forward (format
3399 "[a-zA-Z]+: [a-zA-Z0-9_ *&]+ %s\\( \\|$\\)" 3399 "[a-zA-Z]+: [a-zA-Z0-9_ *&]+ %s\\( \\|$\\)"
3400 (regexp-quote name)) nil t) 3400 (regexp-quote name)) nil t)
3401 (search-forward (concat "['`‘]" name "['’]") nil t) 3401 (search-forward (format "['`‘]%s['’]" name) nil t)
3402 (and (string-match "\\`.*\\( (.*)\\)\\'" name) 3402 (and (string-match "\\`.*\\( (.*)\\)\\'" name)
3403 (search-forward 3403 (search-forward
3404 (concat "['`%‘]" 3404 (format "['`‘]%s['’]" (substring name 0 (match-beginning 1)))
3405 (substring name 0 (match-beginning 1))
3406 "['%’]")
3407 nil t)) 3405 nil t))
3408 (search-forward name nil t) 3406 (search-forward name nil t)
3409 ;; Try again without the " <1>" makeinfo can append 3407 ;; Try again without the " <1>" 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,
3800The first argument is a format control string. 3800The first argument is a format control string.
3801The other arguments are substituted into it to make the result, a string. 3801The other arguments are substituted into it to make the result, a string.
3802 3802
3803The format control string may contain ordinary characters, 3803The format control string may contain %-sequences meaning to substitute
3804%-sequences meaning to substitute the next available argument, 3804the next available argument:
3805and curved single quotation marks meaning to substitute quotes.
3806 3805
3807%s means print a string argument. Actually, prints any object, with `princ'. 3806%s means print a string argument. Actually, prints any object, with `princ'.
3808%d means print as number in decimal (%o octal, %x hex). 3807%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
3850decimal point itself is omitted. For %s and %S, the precision 3849decimal point itself is omitted. For %s and %S, the precision
3851specifier truncates the string to the given width. 3850specifier truncates the string to the given width.
3852 3851
3853\\=‘ and \\=’ means print left and right quotes as per
3854‘text-quoting-style’.
3855
3856Return the first argument if it contains no format directives.
3857Otherwise, return a new string.
3858
3859usage: (format STRING &rest OBJECTS) */) 3852usage: (format STRING &rest OBJECTS) */)
3860 (ptrdiff_t nargs, Lisp_Object *args) 3853 (ptrdiff_t nargs, Lisp_Object *args)
3861{ 3854{
@@ -3868,7 +3861,6 @@ usage: (format STRING &rest OBJECTS) */)
3868 ptrdiff_t buf_save_value_index IF_LINT (= 0); 3861 ptrdiff_t buf_save_value_index IF_LINT (= 0);
3869 char *format, *end, *format_start; 3862 char *format, *end, *format_start;
3870 ptrdiff_t formatlen, nchars; 3863 ptrdiff_t formatlen, nchars;
3871 bool changed = false;
3872 /* True if the format is multibyte. */ 3864 /* True if the format is multibyte. */
3873 bool multibyte_format = 0; 3865 bool multibyte_format = 0;
3874 /* True if the output should be a multibyte string, 3866 /* True if the output should be a multibyte string,
@@ -4020,7 +4012,6 @@ usage: (format STRING &rest OBJECTS) */)
4020 if (format == end) 4012 if (format == end)
4021 error ("Format string ends in middle of format specifier"); 4013 error ("Format string ends in middle of format specifier");
4022 4014
4023 changed = true;
4024 memset (&discarded[format0 - format_start], 1, format - format0); 4015 memset (&discarded[format0 - format_start], 1, format - format0);
4025 conversion = *format; 4016 conversion = *format;
4026 if (conversion == '%') 4017 if (conversion == '%')
@@ -4493,20 +4484,6 @@ usage: (format STRING &rest OBJECTS) */)
4493 4484
4494 convbytes = format - src; 4485 convbytes = format - src;
4495 memset (&discarded[src + 1 - format_start], 2, convbytes - 1); 4486 memset (&discarded[src + 1 - format_start], 2, convbytes - 1);
4496
4497 if (quoting_style != CURVE_QUOTING_STYLE && convbytes == 3
4498 && (unsigned char) src[0] == uLSQM0
4499 && (unsigned char) src[1] == uLSQM1
4500 && ((unsigned char) src[2] == uLSQM2
4501 || (unsigned char) src[2] == uRSQM2))
4502 {
4503 convbytes = 1;
4504 str[0] = (((unsigned char) src[2] == uLSQM2
4505 && quoting_style == GRAVE_QUOTING_STYLE)
4506 ? '`' : '\'');
4507 src = (char *) str;
4508 changed = true;
4509 }
4510 } 4487 }
4511 else 4488 else
4512 { 4489 {
@@ -4518,7 +4495,6 @@ usage: (format STRING &rest OBJECTS) */)
4518 int c = BYTE8_TO_CHAR (uc); 4495 int c = BYTE8_TO_CHAR (uc);
4519 convbytes = CHAR_STRING (c, str); 4496 convbytes = CHAR_STRING (c, str);
4520 src = (char *) str; 4497 src = (char *) str;
4521 changed = true;
4522 } 4498 }
4523 } 4499 }
4524 4500
@@ -4566,119 +4542,113 @@ usage: (format STRING &rest OBJECTS) */)
4566 if (bufsize < p - buf) 4542 if (bufsize < p - buf)
4567 emacs_abort (); 4543 emacs_abort ();
4568 4544
4569 if (!changed) 4545 if (maybe_combine_byte)
4570 val = args[0]; 4546 nchars = multibyte_chars_in_text ((unsigned char *) buf, p - buf);
4571 else 4547 val = make_specified_string (buf, nchars, p - buf, multibyte);
4572 {
4573 if (maybe_combine_byte)
4574 nchars = multibyte_chars_in_text ((unsigned char *) buf, p - buf);
4575 val = make_specified_string (buf, nchars, p - buf, multibyte);
4576 4548
4577 /* If the format string has text properties, or any of the string 4549 /* If the format string has text properties, or any of the string
4578 arguments has text properties, set up text properties of the 4550 arguments has text properties, set up text properties of the
4579 result string. */ 4551 result string. */
4580 4552
4581 if (string_intervals (args[0]) || arg_intervals) 4553 if (string_intervals (args[0]) || arg_intervals)
4582 { 4554 {
4583 Lisp_Object len, new_len, props; 4555 Lisp_Object len, new_len, props;
4584 struct gcpro gcpro1; 4556 struct gcpro gcpro1;
4585 4557
4586 /* Add text properties from the format string. */ 4558 /* Add text properties from the format string. */
4587 len = make_number (SCHARS (args[0])); 4559 len = make_number (SCHARS (args[0]));
4588 props = text_property_list (args[0], make_number (0), len, Qnil); 4560 props = text_property_list (args[0], make_number (0), len, Qnil);
4589 GCPRO1 (props); 4561 GCPRO1 (props);
4590 4562
4591 if (CONSP (props)) 4563 if (CONSP (props))
4564 {
4565 ptrdiff_t bytepos = 0, position = 0, translated = 0;
4566 ptrdiff_t argn = 1;
4567 Lisp_Object list;
4568
4569 /* Adjust the bounds of each text property
4570 to the proper start and end in the output string. */
4571
4572 /* Put the positions in PROPS in increasing order, so that
4573 we can do (effectively) one scan through the position
4574 space of the format string. */
4575 props = Fnreverse (props);
4576
4577 /* BYTEPOS is the byte position in the format string,
4578 POSITION is the untranslated char position in it,
4579 TRANSLATED is the translated char position in BUF,
4580 and ARGN is the number of the next arg we will come to. */
4581 for (list = props; CONSP (list); list = XCDR (list))
4592 { 4582 {
4593 ptrdiff_t bytepos = 0, position = 0, translated = 0; 4583 Lisp_Object item;
4594 ptrdiff_t argn = 1; 4584 ptrdiff_t pos;
4595 Lisp_Object list;
4596
4597 /* Adjust the bounds of each text property
4598 to the proper start and end in the output string. */
4599
4600 /* Put the positions in PROPS in increasing order, so that
4601 we can do (effectively) one scan through the position
4602 space of the format string. */
4603 props = Fnreverse (props);
4604
4605 /* BYTEPOS is the byte position in the format string,
4606 POSITION is the untranslated char position in it,
4607 TRANSLATED is the translated char position in BUF,
4608 and ARGN is the number of the next arg we will come to. */
4609 for (list = props; CONSP (list); list = XCDR (list))
4610 {
4611 Lisp_Object item;
4612 ptrdiff_t pos;
4613 4585
4614 item = XCAR (list); 4586 item = XCAR (list);
4615 4587
4616 /* First adjust the property start position. */ 4588 /* First adjust the property start position. */
4617 pos = XINT (XCAR (item)); 4589 pos = XINT (XCAR (item));
4618 4590
4619 /* Advance BYTEPOS, POSITION, TRANSLATED and ARGN 4591 /* Advance BYTEPOS, POSITION, TRANSLATED and ARGN
4620 up to this position. */ 4592 up to this position. */
4621 for (; position < pos; bytepos++) 4593 for (; position < pos; bytepos++)
4594 {
4595 if (! discarded[bytepos])
4596 position++, translated++;
4597 else if (discarded[bytepos] == 1)
4622 { 4598 {
4623 if (! discarded[bytepos]) 4599 position++;
4624 position++, translated++; 4600 if (translated == info[argn].start)
4625 else if (discarded[bytepos] == 1)
4626 { 4601 {
4627 position++; 4602 translated += info[argn].end - info[argn].start;
4628 if (translated == info[argn].start) 4603 argn++;
4629 {
4630 translated += info[argn].end - info[argn].start;
4631 argn++;
4632 }
4633 } 4604 }
4634 } 4605 }
4606 }
4635 4607
4636 XSETCAR (item, make_number (translated)); 4608 XSETCAR (item, make_number (translated));
4637 4609
4638 /* Likewise adjust the property end position. */ 4610 /* Likewise adjust the property end position. */
4639 pos = XINT (XCAR (XCDR (item))); 4611 pos = XINT (XCAR (XCDR (item)));
4640 4612
4641 for (; position < pos; bytepos++) 4613 for (; position < pos; bytepos++)
4614 {
4615 if (! discarded[bytepos])
4616 position++, translated++;
4617 else if (discarded[bytepos] == 1)
4642 { 4618 {
4643 if (! discarded[bytepos]) 4619 position++;
4644 position++, translated++; 4620 if (translated == info[argn].start)
4645 else if (discarded[bytepos] == 1)
4646 { 4621 {
4647 position++; 4622 translated += info[argn].end - info[argn].start;
4648 if (translated == info[argn].start) 4623 argn++;
4649 {
4650 translated += info[argn].end - info[argn].start;
4651 argn++;
4652 }
4653 } 4624 }
4654 } 4625 }
4655
4656 XSETCAR (XCDR (item), make_number (translated));
4657 } 4626 }
4658 4627
4659 add_text_properties_from_list (val, props, make_number (0)); 4628 XSETCAR (XCDR (item), make_number (translated));
4660 } 4629 }
4661 4630
4662 /* Add text properties from arguments. */ 4631 add_text_properties_from_list (val, props, make_number (0));
4663 if (arg_intervals)
4664 for (n = 1; n < nargs; ++n)
4665 if (info[n].intervals)
4666 {
4667 len = make_number (SCHARS (args[n]));
4668 new_len = make_number (info[n].end - info[n].start);
4669 props = text_property_list (args[n], make_number (0),
4670 len, Qnil);
4671 props = extend_property_ranges (props, new_len);
4672 /* If successive arguments have properties, be sure that
4673 the value of `composition' property be the copy. */
4674 if (n > 1 && info[n - 1].end)
4675 make_composition_value_copy (props);
4676 add_text_properties_from_list (val, props,
4677 make_number (info[n].start));
4678 }
4679
4680 UNGCPRO;
4681 } 4632 }
4633
4634 /* Add text properties from arguments. */
4635 if (arg_intervals)
4636 for (n = 1; n < nargs; ++n)
4637 if (info[n].intervals)
4638 {
4639 len = make_number (SCHARS (args[n]));
4640 new_len = make_number (info[n].end - info[n].start);
4641 props = text_property_list (args[n], make_number (0), len, Qnil);
4642 props = extend_property_ranges (props, new_len);
4643 /* If successive arguments have properties, be sure that
4644 the value of `composition' property be the copy. */
4645 if (n > 1 && info[n - 1].end)
4646 make_composition_value_copy (props);
4647 add_text_properties_from_list (val, props,
4648 make_number (info[n].start));
4649 }
4650
4651 UNGCPRO;
4682 } 4652 }
4683 4653
4684 /* If we allocated BUF or INFO with malloc, free it too. */ 4654 /* If we allocated BUF or INFO with malloc, free it too. */