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
= XSTRING (obj
)->size
;
77 obj
= Fcopy_sequence (obj
);
78 for (i
= i_byte
= 0; i
< size
; i
++, i_byte
+= len
)
81 c
= STRING_CHAR_AND_LENGTH (XSTRING (obj
)->data
+ i_byte
,
85 c
= XSTRING (obj
)->data
[i_byte
];
87 MAKE_CHAR_MULTIBYTE (c
);
90 if (inword
&& flag
!= CASE_CAPITALIZE_UP
)
92 else if (!UPPERCASEP (c
)
93 && (!inword
|| flag
!= CASE_CAPITALIZE_UP
))
95 if ((int) flag
>= (int) CASE_CAPITALIZE
)
96 inword
= SYNTAX (c
) == Sword
;
101 MAKE_CHAR_UNIBYTE (c
);
102 XSTRING (obj
)->data
[i_byte
] = c
;
104 else if (ASCII_CHAR_P (c1
) && ASCII_CHAR_P (c
))
105 XSTRING (obj
)->data
[i_byte
] = c
;
108 Faset (obj
, make_number (i
), make_number (c
));
109 i_byte
+= CHAR_BYTES (c
) - len
;
115 obj
= wrong_type_argument (Qchar_or_string_p
, obj
);
119 DEFUN ("upcase", Fupcase
, Supcase
, 1, 1, 0,
120 doc
: /* Convert argument to upper case and return that.
121 The argument may be a character or string. The result has the same type.
122 The argument object is not altered--the value is a copy.
123 See also `capitalize', `downcase' and `upcase-initials'. */)
127 return casify_object (CASE_UP
, obj
);
130 DEFUN ("downcase", Fdowncase
, Sdowncase
, 1, 1, 0,
131 doc
: /* Convert argument to lower case and return that.
132 The argument may be a character or string. The result has the same type.
133 The argument object is not altered--the value is a copy. */)
137 return casify_object (CASE_DOWN
, obj
);
140 DEFUN ("capitalize", Fcapitalize
, Scapitalize
, 1, 1, 0,
141 doc
: /* Convert argument to capitalized form and return that.
142 This means that each word's first character is upper case
143 and the rest is lower case.
144 The argument may be a character or string. The result has the same type.
145 The argument object is not altered--the value is a copy. */)
149 return casify_object (CASE_CAPITALIZE
, obj
);
152 /* Like Fcapitalize but change only the initials. */
154 DEFUN ("upcase-initials", Fupcase_initials
, Supcase_initials
, 1, 1, 0,
155 doc
: /* Convert the initial of each word in the argument to upper case.
156 Do not change the other letters of each word.
157 The argument may be a character or string. The result has the same type.
158 The argument object is not altered--the value is a copy. */)
162 return casify_object (CASE_CAPITALIZE_UP
, obj
);
165 /* flag is CASE_UP, CASE_DOWN or CASE_CAPITALIZE or CASE_CAPITALIZE_UP.
166 b and e specify range of buffer to operate on. */
169 casify_region (flag
, b
, e
)
170 enum case_action flag
;
175 register int inword
= flag
== CASE_DOWN
;
176 register int multibyte
= !NILP (current_buffer
->enable_multibyte_characters
);
178 int start_byte
, end_byte
;
181 int opoint_byte
= PT_BYTE
;
184 /* Not modifying because nothing marked */
187 /* If the case table is flagged as modified, rescan it. */
188 if (NILP (XCHAR_TABLE (current_buffer
->downcase_table
)->extras
[1]))
189 Fset_case_table (current_buffer
->downcase_table
);
191 validate_region (&b
, &e
);
192 start
= XFASTINT (b
);
194 modify_region (current_buffer
, start
, end
);
195 record_change (start
, end
- start
);
196 start_byte
= CHAR_TO_BYTE (start
);
197 end_byte
= CHAR_TO_BYTE (end
);
205 c
= FETCH_MULTIBYTE_CHAR (start_byte
);
206 len
= CHAR_BYTES (c
);
210 c
= FETCH_BYTE (start_byte
);
211 MAKE_CHAR_MULTIBYTE (c
);
215 if (inword
&& flag
!= CASE_CAPITALIZE_UP
)
217 else if (!UPPERCASEP (c
)
218 && (!inword
|| flag
!= CASE_CAPITALIZE_UP
))
220 if ((int) flag
>= (int) CASE_CAPITALIZE
)
221 inword
= SYNTAX (c
) == Sword
;
227 MAKE_CHAR_UNIBYTE (c
);
228 FETCH_BYTE (start_byte
) = c
;
230 else if (ASCII_CHAR_P (c2
) && ASCII_CHAR_P (c
))
231 FETCH_BYTE (start_byte
) = c
;
232 else if (len
== CHAR_BYTES (c
))
235 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
237 CHAR_STRING (c
, str
);
238 for (j
= 0; j
< len
; ++j
)
239 FETCH_BYTE (start_byte
+ j
) = str
[j
];
243 TEMP_SET_PT_BOTH (start
, start_byte
);
244 del_range_2 (start
, start_byte
, start
+ 1, start_byte
+ len
, 0);
246 len
= CHAR_BYTES (c
);
255 start
= XFASTINT (b
);
256 signal_after_change (start
, end
- start
, end
- start
);
257 update_compositions (start
, end
, CHECK_ALL
);
261 DEFUN ("upcase-region", Fupcase_region
, Supcase_region
, 2, 2, "r",
262 doc
: /* Convert the region to upper case. In programs, wants two arguments.
263 These arguments specify the starting and ending character numbers of
264 the region to operate on. When used as a command, the text between
265 point and the mark is operated on.
266 See also `capitalize-region'. */)
268 Lisp_Object beg
, end
;
270 casify_region (CASE_UP
, beg
, end
);
274 DEFUN ("downcase-region", Fdowncase_region
, Sdowncase_region
, 2, 2, "r",
275 doc
: /* Convert the region to lower case. In programs, wants two arguments.
276 These arguments specify the starting and ending character numbers of
277 the region to operate on. When used as a command, the text between
278 point and the mark is operated on. */)
280 Lisp_Object beg
, end
;
282 casify_region (CASE_DOWN
, beg
, end
);
286 DEFUN ("capitalize-region", Fcapitalize_region
, Scapitalize_region
, 2, 2, "r",
287 doc
: /* Convert the region to capitalized form.
288 Capitalized form means each word's first character is upper case
289 and the rest of it is lower case.
290 In programs, give two arguments, the starting and ending
291 character positions to operate on. */)
293 Lisp_Object beg
, end
;
295 casify_region (CASE_CAPITALIZE
, beg
, end
);
299 /* Like Fcapitalize_region but change only the initials. */
301 DEFUN ("upcase-initials-region", Fupcase_initials_region
,
302 Supcase_initials_region
, 2, 2, "r",
303 doc
: /* Upcase the initial of each word in the region.
304 Subsequent letters of each word are not changed.
305 In programs, give two arguments, the starting and ending
306 character positions to operate on. */)
308 Lisp_Object beg
, end
;
310 casify_region (CASE_CAPITALIZE_UP
, beg
, end
);
315 operate_on_word (arg
, newpoint
)
325 farend
= scan_words (PT
, iarg
);
327 farend
= iarg
> 0 ? ZV
: BEGV
;
329 *newpoint
= PT
> farend
? PT
: farend
;
330 XSETFASTINT (val
, farend
);
335 DEFUN ("upcase-word", Fupcase_word
, Supcase_word
, 1, 1, "p",
336 doc
: /* Convert following word (or ARG words) to upper case, moving over.
337 With negative argument, convert previous words but do not move.
338 See also `capitalize-word'. */)
342 Lisp_Object beg
, end
;
344 XSETFASTINT (beg
, PT
);
345 end
= operate_on_word (arg
, &newpoint
);
346 casify_region (CASE_UP
, beg
, end
);
351 DEFUN ("downcase-word", Fdowncase_word
, Sdowncase_word
, 1, 1, "p",
352 doc
: /* Convert following word (or ARG words) to lower case, moving over.
353 With negative argument, convert previous words but do not move. */)
357 Lisp_Object beg
, end
;
359 XSETFASTINT (beg
, PT
);
360 end
= operate_on_word (arg
, &newpoint
);
361 casify_region (CASE_DOWN
, beg
, end
);
366 DEFUN ("capitalize-word", Fcapitalize_word
, Scapitalize_word
, 1, 1, "p",
367 doc
: /* Capitalize the following word (or ARG words), moving over.
368 This gives the word(s) a first character in upper case
369 and the rest lower case.
370 With negative argument, capitalize previous words but do not move. */)
374 Lisp_Object beg
, end
;
376 XSETFASTINT (beg
, PT
);
377 end
= operate_on_word (arg
, &newpoint
);
378 casify_region (CASE_CAPITALIZE
, beg
, end
);
384 syms_of_casefiddle ()
386 Qidentity
= intern ("identity");
387 staticpro (&Qidentity
);
389 defsubr (&Sdowncase
);
390 defsubr (&Scapitalize
);
391 defsubr (&Supcase_initials
);
392 defsubr (&Supcase_region
);
393 defsubr (&Sdowncase_region
);
394 defsubr (&Scapitalize_region
);
395 defsubr (&Supcase_initials_region
);
396 defsubr (&Supcase_word
);
397 defsubr (&Sdowncase_word
);
398 defsubr (&Scapitalize_word
);
402 keys_of_casefiddle ()
404 initial_define_key (control_x_map
, Ctl('U'), "upcase-region");
405 Fput (intern ("upcase-region"), Qdisabled
, Qt
);
406 initial_define_key (control_x_map
, Ctl('L'), "downcase-region");
407 Fput (intern ("downcase-region"), Qdisabled
, Qt
);
409 initial_define_key (meta_map
, 'u', "upcase-word");
410 initial_define_key (meta_map
, 'l', "downcase-word");
411 initial_define_key (meta_map
, 'c', "capitalize-word");