1 /* XEmacs case conversion functions.
2 Copyright (C) 1985, 1992, 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
3 Copyright (C) 2001 MORIOKA Tomohiko
5 This file is part of XEmacs.
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* Synched up with: FSF 19.34, but substantially rewritten by Martin. */
31 enum case_action {CASE_UP, CASE_DOWN, CASE_CAPITALIZE, CASE_CAPITALIZE_UP};
34 casify_object (enum case_action flag, Lisp_Object string_or_char,
37 struct buffer *buf = decode_buffer (buffer, 0);
41 if (CHAR_OR_CHAR_INTP (string_or_char))
44 CHECK_CHAR_COERCE_INT (string_or_char);
45 c = XCHAR (string_or_char);
46 c = (flag == CASE_DOWN) ? DOWNCASE (buf, c) : UPCASE (buf, c);
50 if (STRINGP (string_or_char))
53 Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->syntax_table);
55 Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
58 alloca_array (Bufbyte, XSTRING_LENGTH (string_or_char) * MAX_EMCHAR_LEN);
59 Bufbyte *newp = storage;
60 Bufbyte *oldp = XSTRING_DATA (string_or_char);
61 int wordp = 0, wordp_prev;
65 Emchar c = charptr_emchar (oldp);
72 c = DOWNCASE (buf, c);
75 case CASE_CAPITALIZE_UP:
77 wordp = WORD_SYNTAX_P (syntax_table, c);
81 if (flag == CASE_CAPITALIZE)
82 c = DOWNCASE (buf, c);
89 newp += set_charptr_emchar (newp, c);
93 return make_string (storage, newp - storage);
96 string_or_char = wrong_type_argument (Qchar_or_string_p, string_or_char);
100 DEFUN ("upcase", Fupcase, 1, 2, 0, /*
101 Convert STRING-OR-CHAR to upper case and return that.
102 STRING-OR-CHAR may be a character or string. The result has the same type.
103 STRING-OR-CHAR is not altered--the value is a copy.
104 See also `capitalize', `downcase' and `upcase-initials'.
105 Optional second arg BUFFER specifies which buffer's case tables to use,
106 and defaults to the current buffer.
108 (string_or_char, buffer))
110 return casify_object (CASE_UP, string_or_char, buffer);
113 DEFUN ("downcase", Fdowncase, 1, 2, 0, /*
114 Convert STRING-OR-CHAR to lower case and return that.
115 STRING-OR-CHAR may be a character or string. The result has the same type.
116 STRING-OR-CHAR is not altered--the value is a copy.
117 Optional second arg BUFFER specifies which buffer's case tables to use,
118 and defaults to the current buffer.
120 (string_or_char, buffer))
122 return casify_object (CASE_DOWN, string_or_char, buffer);
125 DEFUN ("capitalize", Fcapitalize, 1, 2, 0, /*
126 Convert STRING-OR-CHAR to capitalized form and return that.
127 This means that each word's first character is upper case
128 and the rest is lower case.
129 STRING-OR-CHAR may be a character or string. The result has the same type.
130 STRING-OR-CHAR is not altered--the value is a copy.
131 Optional second arg BUFFER specifies which buffer's case tables to use,
132 and defaults to the current buffer.
134 (string_or_char, buffer))
136 return casify_object (CASE_CAPITALIZE, string_or_char, buffer);
139 /* Like Fcapitalize but change only the initial characters. */
141 DEFUN ("upcase-initials", Fupcase_initials, 1, 2, 0, /*
142 Convert the initial of each word in STRING-OR-CHAR to upper case.
143 Do not change the other letters of each word.
144 STRING-OR-CHAR may be a character or string. The result has the same type.
145 STRING-OR-CHAR is not altered--the value is a copy.
146 Optional second arg BUFFER specifies which buffer's case tables to use,
147 and defaults to the current buffer.
149 (string_or_char, buffer))
151 return casify_object (CASE_CAPITALIZE_UP, string_or_char, buffer);
154 /* flag is CASE_UP, CASE_DOWN or CASE_CAPITALIZE or CASE_CAPITALIZE_UP.
155 START and END specify range of buffer to operate on. */
158 casify_region_internal (enum case_action flag, Lisp_Object start,
159 Lisp_Object end, struct buffer *buf)
161 /* This function can GC */
164 Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->syntax_table);
166 Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
169 int wordp = 0, wordp_prev;
172 /* Not modifying because nothing marked */
175 get_buffer_range_char (buf, start, end, &s, &e, 0);
177 mccount = begin_multiple_change (buf, s, e);
178 record_change (buf, s, e - s);
180 for (pos = s; pos < e; pos++)
182 Emchar oldc = BUF_FETCH_CHAR (buf, pos);
188 c = UPCASE (buf, oldc);
191 c = DOWNCASE (buf, oldc);
193 case CASE_CAPITALIZE:
194 case CASE_CAPITALIZE_UP:
195 /* !!#### need to revalidate the start and end pointers in case
196 the buffer was changed */
198 wordp = WORD_SYNTAX_P (syntax_table, c);
199 if (!wordp) continue;
202 if (flag == CASE_CAPITALIZE)
203 c = DOWNCASE (buf, c);
210 if (oldc == c) continue;
211 buffer_replace_char (buf, pos, c, 1, (pos == s));
215 end_multiple_change (buf, mccount);
219 casify_region (enum case_action flag, Lisp_Object start, Lisp_Object end,
222 casify_region_internal (flag, start, end, decode_buffer (buffer, 1));
226 DEFUN ("upcase-region", Fupcase_region, 2, 3, "r", /*
227 Convert the region to upper case. In programs, wants two arguments.
228 These arguments specify the starting and ending character numbers of
229 the region to operate on. When used as a command, the text between
230 point and the mark is operated on.
231 See also `capitalize-region'.
232 Optional third arg BUFFER defaults to the current buffer.
234 (start, end, buffer))
236 /* This function can GC */
237 return casify_region (CASE_UP, start, end, buffer);
240 DEFUN ("downcase-region", Fdowncase_region, 2, 3, "r", /*
241 Convert the region to lower case. In programs, wants two arguments.
242 These arguments specify the starting and ending character numbers of
243 the region to operate on. When used as a command, the text between
244 point and the mark is operated on.
245 Optional third arg BUFFER defaults to the current buffer.
247 (start, end, buffer))
249 /* This function can GC */
250 return casify_region (CASE_DOWN, start, end, buffer);
253 DEFUN ("capitalize-region", Fcapitalize_region, 2, 3, "r", /*
254 Convert the region to capitalized form.
255 Capitalized form means each word's first character is upper case
256 and the rest of it is lower case.
257 In programs, give two arguments, the starting and ending
258 character positions to operate on.
259 Optional third arg BUFFER defaults to the current buffer.
261 (start, end, buffer))
263 /* This function can GC */
264 return casify_region (CASE_CAPITALIZE, start, end, buffer);
267 /* Like Fcapitalize_region but change only the initials. */
269 DEFUN ("upcase-initials-region", Fupcase_initials_region, 2, 3, "r", /*
270 Upcase the initial of each word in the region.
271 Subsequent letters of each word are not changed.
272 In programs, give two arguments, the starting and ending
273 character positions to operate on.
274 Optional third arg BUFFER defaults to the current buffer.
276 (start, end, buffer))
278 return casify_region (CASE_CAPITALIZE_UP, start, end, buffer);
283 casify_word (enum case_action flag, Lisp_Object arg, Lisp_Object buffer)
286 struct buffer *buf = decode_buffer (buffer, 1);
290 farend = scan_words (buf, BUF_PT (buf), XINT (arg));
292 farend = XINT (arg) > 0 ? BUF_ZV (buf) : BUF_BEGV (buf);
294 casify_region_internal (flag, make_int (BUF_PT (buf)), make_int (farend), buf);
295 BUF_SET_PT (buf, max (BUF_PT (buf), farend));
299 DEFUN ("upcase-word", Fupcase_word, 1, 2, "p", /*
300 Convert following word (or COUNT words) to upper case, moving over.
301 With negative argument, convert previous words but do not move.
302 See also `capitalize-word'.
303 Optional second arg BUFFER defaults to the current buffer.
307 /* This function can GC */
308 return casify_word (CASE_UP, count, buffer);
311 DEFUN ("downcase-word", Fdowncase_word, 1, 2, "p", /*
312 Convert following word (or COUNT words) to lower case, moving over.
313 With negative argument, convert previous words but do not move.
314 Optional second arg BUFFER defaults to the current buffer.
318 /* This function can GC */
319 return casify_word (CASE_DOWN, count, buffer);
322 DEFUN ("capitalize-word", Fcapitalize_word, 1, 2, "p", /*
323 Capitalize the following word (or COUNT words), moving over.
324 This gives the word(s) a first character in upper case
325 and the rest lower case.
326 With negative argument, capitalize previous words but do not move.
327 Optional second arg BUFFER defaults to the current buffer.
331 /* This function can GC */
332 return casify_word (CASE_CAPITALIZE, count, buffer);
337 syms_of_casefiddle (void)
341 DEFSUBR (Fcapitalize);
342 DEFSUBR (Fupcase_initials);
343 DEFSUBR (Fupcase_region);
344 DEFSUBR (Fdowncase_region);
345 DEFSUBR (Fcapitalize_region);
346 DEFSUBR (Fupcase_initials_region);
347 DEFSUBR (Fupcase_word);
348 DEFSUBR (Fdowncase_word);
349 DEFSUBR (Fcapitalize_word);