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
;
59 MAKE_CHAR_UNIBYTE (c1
);
62 if (inword
|| c
== c1
)
68 MAKE_CHAR_MULTIBYTE (c
);
70 XSETFASTINT (obj
, c
| flags
);
77 int multibyte
= STRING_MULTIBYTE (obj
);
79 int size
= XSTRING (obj
)->size
;
81 obj
= Fcopy_sequence (obj
);
82 for (i
= i_byte
= 0; i
< size
; i
++, i_byte
+= len
)
85 c
= STRING_CHAR_AND_LENGTH (XSTRING (obj
)->data
+ i_byte
,
89 c
= XSTRING (obj
)->data
[i_byte
];
91 MAKE_CHAR_MULTIBYTE (c
);
94 if (inword
&& flag
!= CASE_CAPITALIZE_UP
)
96 else if (!UPPERCASEP (c
)
97 && (!inword
|| flag
!= CASE_CAPITALIZE_UP
))
99 if ((int) flag
>= (int) CASE_CAPITALIZE
)
100 inword
= SYNTAX (c
) == Sword
;
105 MAKE_CHAR_UNIBYTE (c
);
106 XSTRING (obj
)->data
[i_byte
] = c
;
108 else if (ASCII_CHAR_P (c1
) && ASCII_CHAR_P (c
))
109 XSTRING (obj
)->data
[i_byte
] = c
;
112 Faset (obj
, make_number (i
), make_number (c
));
113 i_byte
+= CHAR_BYTES (c
) - len
;
119 obj
= wrong_type_argument (Qchar_or_string_p
, obj
);
123 DEFUN ("upcase", Fupcase
, Supcase
, 1, 1, 0,
124 doc
: /* Convert argument to upper case and return that.
125 The argument may be a character or string. The result has the same type.
126 The argument object is not altered--the value is a copy.
127 See also `capitalize', `downcase' and `upcase-initials'. */)
131 return casify_object (CASE_UP
, obj
);
134 DEFUN ("downcase", Fdowncase
, Sdowncase
, 1, 1, 0,
135 doc
: /* Convert argument to lower case and return that.
136 The argument may be a character or string. The result has the same type.
137 The argument object is not altered--the value is a copy. */)
141 return casify_object (CASE_DOWN
, obj
);
144 DEFUN ("capitalize", Fcapitalize
, Scapitalize
, 1, 1, 0,
145 doc
: /* Convert argument to capitalized form and return that.
146 This means that each word's first character is upper case
147 and the rest is lower case.
148 The argument may be a character or string. The result has the same type.
149 The argument object is not altered--the value is a copy. */)
153 return casify_object (CASE_CAPITALIZE
, obj
);
156 /* Like Fcapitalize but change only the initials. */
158 DEFUN ("upcase-initials", Fupcase_initials
, Supcase_initials
, 1, 1, 0,
159 doc
: /* Convert the initial of each word in the argument to upper case.
160 Do not change the other letters of each word.
161 The argument may be a character or string. The result has the same type.
162 The argument object is not altered--the value is a copy. */)
166 return casify_object (CASE_CAPITALIZE_UP
, obj
);
169 /* flag is CASE_UP, CASE_DOWN or CASE_CAPITALIZE or CASE_CAPITALIZE_UP.
170 b and e specify range of buffer to operate on. */
173 casify_region (flag
, b
, e
)
174 enum case_action flag
;
179 register int inword
= flag
== CASE_DOWN
;
180 register int multibyte
= !NILP (current_buffer
->enable_multibyte_characters
);
182 int start_byte
, end_byte
;
185 int opoint_byte
= PT_BYTE
;
188 /* Not modifying because nothing marked */
191 /* If the case table is flagged as modified, rescan it. */
192 if (NILP (XCHAR_TABLE (current_buffer
->downcase_table
)->extras
[1]))
193 Fset_case_table (current_buffer
->downcase_table
);
195 validate_region (&b
, &e
);
196 start
= XFASTINT (b
);
198 modify_region (current_buffer
, start
, end
);
199 record_change (start
, end
- start
);
200 start_byte
= CHAR_TO_BYTE (start
);
201 end_byte
= CHAR_TO_BYTE (end
);
209 c
= FETCH_MULTIBYTE_CHAR (start_byte
);
210 len
= CHAR_BYTES (c
);
214 c
= FETCH_BYTE (start_byte
);
215 MAKE_CHAR_MULTIBYTE (c
);
219 if (inword
&& flag
!= CASE_CAPITALIZE_UP
)
221 else if (!UPPERCASEP (c
)
222 && (!inword
|| flag
!= CASE_CAPITALIZE_UP
))
224 if ((int) flag
>= (int) CASE_CAPITALIZE
)
225 inword
= SYNTAX (c
) == Sword
;
231 MAKE_CHAR_UNIBYTE (c
);
232 FETCH_BYTE (start_byte
) = c
;
234 else if (ASCII_CHAR_P (c2
) && ASCII_CHAR_P (c
))
235 FETCH_BYTE (start_byte
) = c
;
236 else if (len
== CHAR_BYTES (c
))
239 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
241 CHAR_STRING (c
, str
);
242 for (j
= 0; j
< len
; ++j
)
243 FETCH_BYTE (start_byte
+ j
) = str
[j
];
247 TEMP_SET_PT_BOTH (start
, start_byte
);
248 del_range_2 (start
, start_byte
, start
+ 1, start_byte
+ len
, 0);
250 len
= CHAR_BYTES (c
);
259 start
= XFASTINT (b
);
260 signal_after_change (start
, end
- start
, end
- start
);
261 update_compositions (start
, end
, CHECK_ALL
);
265 DEFUN ("upcase-region", Fupcase_region
, Supcase_region
, 2, 2, "r",
266 doc
: /* Convert the region to upper case. In programs, wants two arguments.
267 These arguments specify the starting and ending character numbers of
268 the region to operate on. When used as a command, the text between
269 point and the mark is operated on.
270 See also `capitalize-region'. */)
272 Lisp_Object beg
, end
;
274 casify_region (CASE_UP
, beg
, end
);
278 DEFUN ("downcase-region", Fdowncase_region
, Sdowncase_region
, 2, 2, "r",
279 doc
: /* Convert the region to lower case. In programs, wants two arguments.
280 These arguments specify the starting and ending character numbers of
281 the region to operate on. When used as a command, the text between
282 point and the mark is operated on. */)
284 Lisp_Object beg
, end
;
286 casify_region (CASE_DOWN
, beg
, end
);
290 DEFUN ("capitalize-region", Fcapitalize_region
, Scapitalize_region
, 2, 2, "r",
291 doc
: /* Convert the region to capitalized form.
292 Capitalized form means each word's first character is upper case
293 and the rest of it is lower case.
294 In programs, give two arguments, the starting and ending
295 character positions to operate on. */)
297 Lisp_Object beg
, end
;
299 casify_region (CASE_CAPITALIZE
, beg
, end
);
303 /* Like Fcapitalize_region but change only the initials. */
305 DEFUN ("upcase-initials-region", Fupcase_initials_region
,
306 Supcase_initials_region
, 2, 2, "r",
307 doc
: /* Upcase the initial of each word in the region.
308 Subsequent letters of each word are not changed.
309 In programs, give two arguments, the starting and ending
310 character positions to operate on. */)
312 Lisp_Object beg
, end
;
314 casify_region (CASE_CAPITALIZE_UP
, beg
, end
);
319 operate_on_word (arg
, newpoint
)
329 farend
= scan_words (PT
, iarg
);
331 farend
= iarg
> 0 ? ZV
: BEGV
;
333 *newpoint
= PT
> farend
? PT
: farend
;
334 XSETFASTINT (val
, farend
);
339 DEFUN ("upcase-word", Fupcase_word
, Supcase_word
, 1, 1, "p",
340 doc
: /* Convert following word (or ARG words) to upper case, moving over.
341 With negative argument, convert previous words but do not move.
342 See also `capitalize-word'. */)
346 Lisp_Object beg
, end
;
348 XSETFASTINT (beg
, PT
);
349 end
= operate_on_word (arg
, &newpoint
);
350 casify_region (CASE_UP
, beg
, end
);
355 DEFUN ("downcase-word", Fdowncase_word
, Sdowncase_word
, 1, 1, "p",
356 doc
: /* Convert following word (or ARG words) to lower case, moving over.
357 With negative argument, convert previous words but do not move. */)
361 Lisp_Object beg
, end
;
363 XSETFASTINT (beg
, PT
);
364 end
= operate_on_word (arg
, &newpoint
);
365 casify_region (CASE_DOWN
, beg
, end
);
370 DEFUN ("capitalize-word", Fcapitalize_word
, Scapitalize_word
, 1, 1, "p",
371 doc
: /* Capitalize the following word (or ARG words), moving over.
372 This gives the word(s) a first character in upper case
373 and the rest lower case.
374 With negative argument, capitalize previous words but do not move. */)
378 Lisp_Object beg
, end
;
380 XSETFASTINT (beg
, PT
);
381 end
= operate_on_word (arg
, &newpoint
);
382 casify_region (CASE_CAPITALIZE
, beg
, end
);
388 syms_of_casefiddle ()
390 Qidentity
= intern ("identity");
391 staticpro (&Qidentity
);
393 defsubr (&Sdowncase
);
394 defsubr (&Scapitalize
);
395 defsubr (&Supcase_initials
);
396 defsubr (&Supcase_region
);
397 defsubr (&Sdowncase_region
);
398 defsubr (&Scapitalize_region
);
399 defsubr (&Supcase_initials_region
);
400 defsubr (&Supcase_word
);
401 defsubr (&Sdowncase_word
);
402 defsubr (&Scapitalize_word
);
406 keys_of_casefiddle ()
408 initial_define_key (control_x_map
, Ctl('U'), "upcase-region");
409 Fput (intern ("upcase-region"), Qdisabled
, Qt
);
410 initial_define_key (control_x_map
, Ctl('L'), "downcase-region");
411 Fput (intern ("downcase-region"), Qdisabled
, Qt
);
413 initial_define_key (meta_map
, 'u', "upcase-word");
414 initial_define_key (meta_map
, 'l', "downcase-word");
415 initial_define_key (meta_map
, 'c', "capitalize-word");