1 /* GNU Emacs case conversion functions.
2 Copyright (C) 1985, 1994, 1997 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
25 #include "character.h"
28 #include "composite.h"
31 enum case_action
{CASE_UP
, CASE_DOWN
, CASE_CAPITALIZE
, CASE_CAPITALIZE_UP
};
33 Lisp_Object Qidentity
;
36 casify_object (flag
, obj
)
37 enum case_action flag
;
41 register int inword
= flag
== CASE_DOWN
;
43 /* If the case table is flagged as modified, rescan it. */
44 if (NILP (XCHAR_TABLE (current_buffer
->downcase_table
)->extras
[1]))
45 Fset_case_table (current_buffer
->downcase_table
);
51 int flagbits
= (CHAR_ALT
| CHAR_SUPER
| CHAR_HYPER
52 | CHAR_SHIFT
| CHAR_CTL
| CHAR_META
);
53 int flags
= XINT (obj
) & flagbits
;
54 int multibyte
= ! NILP (current_buffer
->enable_multibyte_characters
);
56 c1
= XFASTINT (obj
) & ~flagbits
;
58 MAKE_CHAR_MULTIBYTE (c1
);
60 if (inword
|| c
== c1
)
65 MAKE_CHAR_UNIBYTE (c
);
66 XSETFASTINT (obj
, c
| flags
);
73 int multibyte
= STRING_MULTIBYTE (obj
);
75 int size
= SCHARS (obj
);
77 obj
= Fcopy_sequence (obj
);
78 for (i
= i_byte
= 0; i
< size
; i
++, i_byte
+= len
)
81 c
= STRING_CHAR_AND_LENGTH (SDATA (obj
) + i_byte
, 0, len
);
84 c
= SREF (obj
, i_byte
);
86 MAKE_CHAR_MULTIBYTE (c
);
89 if (inword
&& flag
!= CASE_CAPITALIZE_UP
)
91 else if (!UPPERCASEP (c
)
92 && (!inword
|| flag
!= CASE_CAPITALIZE_UP
))
94 if ((int) flag
>= (int) CASE_CAPITALIZE
)
95 inword
= (SYNTAX (c
) == Sword
);
100 MAKE_CHAR_UNIBYTE (c
);
101 SSET (obj
, i_byte
, c
);
103 else if (ASCII_CHAR_P (c1
) && ASCII_CHAR_P (c
))
104 SSET (obj
, i_byte
, c
);
107 Faset (obj
, make_number (i
), make_number (c
));
108 i_byte
+= CHAR_BYTES (c
) - len
;
114 obj
= wrong_type_argument (Qchar_or_string_p
, obj
);
118 DEFUN ("upcase", Fupcase
, Supcase
, 1, 1, 0,
119 doc
: /* Convert argument to upper case and return that.
120 The argument may be a character or string. The result has the same type.
121 The argument object is not altered--the value is a copy.
122 See also `capitalize', `downcase' and `upcase-initials'. */)
126 return casify_object (CASE_UP
, obj
);
129 DEFUN ("downcase", Fdowncase
, Sdowncase
, 1, 1, 0,
130 doc
: /* Convert argument to lower case and return that.
131 The argument may be a character or string. The result has the same type.
132 The argument object is not altered--the value is a copy. */)
136 return casify_object (CASE_DOWN
, obj
);
139 DEFUN ("capitalize", Fcapitalize
, Scapitalize
, 1, 1, 0,
140 doc
: /* Convert argument to capitalized form and return that.
141 This means that each word's first character is upper case
142 and the rest is lower case.
143 The argument may be a character or string. The result has the same type.
144 The argument object is not altered--the value is a copy. */)
148 return casify_object (CASE_CAPITALIZE
, obj
);
151 /* Like Fcapitalize but change only the initials. */
153 DEFUN ("upcase-initials", Fupcase_initials
, Supcase_initials
, 1, 1, 0,
154 doc
: /* Convert the initial of each word in the argument to upper case.
155 Do not change the other letters of each word.
156 The argument may be a character or string. The result has the same type.
157 The argument object is not altered--the value is a copy. */)
161 return casify_object (CASE_CAPITALIZE_UP
, obj
);
164 /* flag is CASE_UP, CASE_DOWN or CASE_CAPITALIZE or CASE_CAPITALIZE_UP.
165 b and e specify range of buffer to operate on. */
168 casify_region (flag
, b
, e
)
169 enum case_action flag
;
173 register int inword
= flag
== CASE_DOWN
;
174 register int multibyte
= !NILP (current_buffer
->enable_multibyte_characters
);
176 int start_byte
, end_byte
;
179 int opoint_byte
= PT_BYTE
;
182 /* Not modifying because nothing marked */
185 /* If the case table is flagged as modified, rescan it. */
186 if (NILP (XCHAR_TABLE (current_buffer
->downcase_table
)->extras
[1]))
187 Fset_case_table (current_buffer
->downcase_table
);
189 validate_region (&b
, &e
);
190 start
= XFASTINT (b
);
192 modify_region (current_buffer
, start
, end
);
193 record_change (start
, end
- start
);
194 start_byte
= CHAR_TO_BYTE (start
);
195 end_byte
= CHAR_TO_BYTE (end
);
203 c
= FETCH_MULTIBYTE_CHAR (start_byte
);
204 len
= CHAR_BYTES (c
);
208 c
= FETCH_BYTE (start_byte
);
209 MAKE_CHAR_MULTIBYTE (c
);
213 if (inword
&& flag
!= CASE_CAPITALIZE_UP
)
215 else if (!UPPERCASEP (c
)
216 && (!inword
|| flag
!= CASE_CAPITALIZE_UP
))
218 if ((int) flag
>= (int) CASE_CAPITALIZE
)
219 inword
= ((SYNTAX (c
) == Sword
) && (inword
|| !SYNTAX_PREFIX (c
)));
225 MAKE_CHAR_UNIBYTE (c
);
226 FETCH_BYTE (start_byte
) = c
;
228 else if (ASCII_CHAR_P (c2
) && ASCII_CHAR_P (c
))
229 FETCH_BYTE (start_byte
) = c
;
230 else if (len
== CHAR_BYTES (c
))
233 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
235 CHAR_STRING (c
, str
);
236 for (j
= 0; j
< len
; ++j
)
237 FETCH_BYTE (start_byte
+ j
) = str
[j
];
241 TEMP_SET_PT_BOTH (start
, start_byte
);
242 del_range_2 (start
, start_byte
, start
+ 1, start_byte
+ len
, 0);
244 len
= CHAR_BYTES (c
);
252 TEMP_SET_PT_BOTH (opoint
, opoint_byte
);
256 start
= XFASTINT (b
);
257 signal_after_change (start
, end
- start
, end
- start
);
258 update_compositions (start
, end
, CHECK_ALL
);
262 DEFUN ("upcase-region", Fupcase_region
, Supcase_region
, 2, 2, "r",
263 doc
: /* Convert the region to upper case. In programs, wants two arguments.
264 These arguments specify the starting and ending character numbers of
265 the region to operate on. When used as a command, the text between
266 point and the mark is operated on.
267 See also `capitalize-region'. */)
269 Lisp_Object beg
, end
;
271 casify_region (CASE_UP
, beg
, end
);
275 DEFUN ("downcase-region", Fdowncase_region
, Sdowncase_region
, 2, 2, "r",
276 doc
: /* Convert the region to lower case. In programs, wants two arguments.
277 These arguments specify the starting and ending character numbers of
278 the region to operate on. When used as a command, the text between
279 point and the mark is operated on. */)
281 Lisp_Object beg
, end
;
283 casify_region (CASE_DOWN
, beg
, end
);
287 DEFUN ("capitalize-region", Fcapitalize_region
, Scapitalize_region
, 2, 2, "r",
288 doc
: /* Convert the region to capitalized form.
289 Capitalized form means each word's first character is upper case
290 and the rest of it is lower case.
291 In programs, give two arguments, the starting and ending
292 character positions to operate on. */)
294 Lisp_Object beg
, end
;
296 casify_region (CASE_CAPITALIZE
, beg
, end
);
300 /* Like Fcapitalize_region but change only the initials. */
302 DEFUN ("upcase-initials-region", Fupcase_initials_region
,
303 Supcase_initials_region
, 2, 2, "r",
304 doc
: /* Upcase the initial of each word in the region.
305 Subsequent letters of each word are not changed.
306 In programs, give two arguments, the starting and ending
307 character positions to operate on. */)
309 Lisp_Object beg
, end
;
311 casify_region (CASE_CAPITALIZE_UP
, beg
, end
);
316 operate_on_word (arg
, newpoint
)
326 farend
= scan_words (PT
, iarg
);
328 farend
= iarg
> 0 ? ZV
: BEGV
;
330 *newpoint
= PT
> farend
? PT
: farend
;
331 XSETFASTINT (val
, farend
);
336 DEFUN ("upcase-word", Fupcase_word
, Supcase_word
, 1, 1, "p",
337 doc
: /* Convert following word (or ARG words) to upper case, moving over.
338 With negative argument, convert previous words but do not move.
339 See also `capitalize-word'. */)
343 Lisp_Object beg
, end
;
345 XSETFASTINT (beg
, PT
);
346 end
= operate_on_word (arg
, &newpoint
);
347 casify_region (CASE_UP
, beg
, end
);
352 DEFUN ("downcase-word", Fdowncase_word
, Sdowncase_word
, 1, 1, "p",
353 doc
: /* Convert following word (or ARG words) to lower case, moving over.
354 With negative argument, convert previous words but do not move. */)
358 Lisp_Object beg
, end
;
360 XSETFASTINT (beg
, PT
);
361 end
= operate_on_word (arg
, &newpoint
);
362 casify_region (CASE_DOWN
, beg
, end
);
367 DEFUN ("capitalize-word", Fcapitalize_word
, Scapitalize_word
, 1, 1, "p",
368 doc
: /* Capitalize the following word (or ARG words), moving over.
369 This gives the word(s) a first character in upper case
370 and the rest lower case.
371 With negative argument, capitalize previous words but do not move. */)
375 Lisp_Object beg
, end
;
377 XSETFASTINT (beg
, PT
);
378 end
= operate_on_word (arg
, &newpoint
);
379 casify_region (CASE_CAPITALIZE
, beg
, end
);
385 syms_of_casefiddle ()
387 Qidentity
= intern ("identity");
388 staticpro (&Qidentity
);
390 defsubr (&Sdowncase
);
391 defsubr (&Scapitalize
);
392 defsubr (&Supcase_initials
);
393 defsubr (&Supcase_region
);
394 defsubr (&Sdowncase_region
);
395 defsubr (&Scapitalize_region
);
396 defsubr (&Supcase_initials_region
);
397 defsubr (&Supcase_word
);
398 defsubr (&Sdowncase_word
);
399 defsubr (&Scapitalize_word
);
403 keys_of_casefiddle ()
405 initial_define_key (control_x_map
, Ctl('U'), "upcase-region");
406 Fput (intern ("upcase-region"), Qdisabled
, Qt
);
407 initial_define_key (control_x_map
, Ctl('L'), "downcase-region");
408 Fput (intern ("downcase-region"), Qdisabled
, Qt
);
410 initial_define_key (meta_map
, 'u', "upcase-word");
411 initial_define_key (meta_map
, 'l', "downcase-word");
412 initial_define_key (meta_map
, 'c', "capitalize-word");
415 /* arch-tag: 60a73c66-5489-47e7-a81f-cead4057c526
416 (do not change this comment) */