diff options
| author | Michal Nazarewicz | 2016-08-12 01:38:49 +0200 |
|---|---|---|
| committer | Michal Nazarewicz | 2017-04-06 20:54:57 +0200 |
| commit | 13d813b1a093e9039a63b11021a8a92c9c5950d1 (patch) | |
| tree | 184ce8d5b36320140b2fbe9581370565e49e066b /src | |
| parent | 8e5b909fe6e20858d023f33617785b2f556a0f13 (diff) | |
| download | emacs-13d813b1a093e9039a63b11021a8a92c9c5950d1.tar.gz emacs-13d813b1a093e9039a63b11021a8a92c9c5950d1.zip | |
Add support for title-casing letters (bug#24603)
* src/casefiddle.c (struct casing_context, prepare_casing_context): Add
titlecase_char_table member. It’s set to the ‘titlecase’ Unicode
property table if capitalisation has been requested.
(case_character): Make use of the titlecase_char_table to title-case
initial characters when capitalising.
* test/src/casefiddle-tests.el (casefiddle-tests--characters,
casefiddle-tests-casing): Update test cases which are now passing.
Diffstat (limited to 'src')
| -rw-r--r-- | src/casefiddle.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/src/casefiddle.c b/src/casefiddle.c index dfbb5c3e172..a83469cbdc7 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c | |||
| @@ -33,6 +33,9 @@ enum case_action {CASE_UP, CASE_DOWN, CASE_CAPITALIZE, CASE_CAPITALIZE_UP}; | |||
| 33 | 33 | ||
| 34 | /* State for casing individual characters. */ | 34 | /* State for casing individual characters. */ |
| 35 | struct casing_context { | 35 | struct casing_context { |
| 36 | /* A char-table with title-case character mappings or nil. Non-nil implies | ||
| 37 | flag is CASE_CAPITALIZE or CASE_CAPITALIZE_UP. */ | ||
| 38 | Lisp_Object titlecase_char_table; | ||
| 36 | /* User-requested action. */ | 39 | /* User-requested action. */ |
| 37 | enum case_action flag; | 40 | enum case_action flag; |
| 38 | /* If true, function operates on a buffer as opposed to a string or character. | 41 | /* If true, function operates on a buffer as opposed to a string or character. |
| @@ -53,6 +56,8 @@ prepare_casing_context (struct casing_context *ctx, | |||
| 53 | ctx->flag = flag; | 56 | ctx->flag = flag; |
| 54 | ctx->inbuffer = inbuffer; | 57 | ctx->inbuffer = inbuffer; |
| 55 | ctx->inword = flag == CASE_DOWN; | 58 | ctx->inword = flag == CASE_DOWN; |
| 59 | ctx->titlecase_char_table = (int)flag < (int)CASE_CAPITALIZE ? Qnil : | ||
| 60 | uniprop_table (intern_c_string ("titlecase")); | ||
| 56 | 61 | ||
| 57 | /* If the case table is flagged as modified, rescan it. */ | 62 | /* If the case table is flagged as modified, rescan it. */ |
| 58 | if (NILP (XCHAR_TABLE (BVAR (current_buffer, downcase_table))->extras[1])) | 63 | if (NILP (XCHAR_TABLE (BVAR (current_buffer, downcase_table))->extras[1])) |
| @@ -67,10 +72,16 @@ prepare_casing_context (struct casing_context *ctx, | |||
| 67 | static int | 72 | static int |
| 68 | case_character (struct casing_context *ctx, int ch) | 73 | case_character (struct casing_context *ctx, int ch) |
| 69 | { | 74 | { |
| 75 | Lisp_Object prop; | ||
| 76 | |||
| 70 | if (ctx->inword) | 77 | if (ctx->inword) |
| 71 | ch = ctx->flag == CASE_CAPITALIZE_UP ? ch : downcase (ch); | 78 | ch = ctx->flag == CASE_CAPITALIZE_UP ? ch : downcase (ch); |
| 79 | else if (!NILP (ctx->titlecase_char_table) && | ||
| 80 | CHARACTERP (prop = CHAR_TABLE_REF (ctx->titlecase_char_table, ch))) | ||
| 81 | ch = XFASTINT (prop); | ||
| 72 | else | 82 | else |
| 73 | ch = upcase(ch); | 83 | ch = upcase(ch); |
| 84 | |||
| 74 | if ((int) ctx->flag >= (int) CASE_CAPITALIZE) | 85 | if ((int) ctx->flag >= (int) CASE_CAPITALIZE) |
| 75 | ctx->inword = SYNTAX (ch) == Sword && | 86 | ctx->inword = SYNTAX (ch) == Sword && |
| 76 | (!ctx->inbuffer || ctx->inword || !syntax_prefix_flag_p (ch)); | 87 | (!ctx->inbuffer || ctx->inword || !syntax_prefix_flag_p (ch)); |
| @@ -198,8 +209,8 @@ The argument object is not altered--the value is a copy. */) | |||
| 198 | 209 | ||
| 199 | DEFUN ("capitalize", Fcapitalize, Scapitalize, 1, 1, 0, | 210 | DEFUN ("capitalize", Fcapitalize, Scapitalize, 1, 1, 0, |
| 200 | doc: /* Convert argument to capitalized form and return that. | 211 | doc: /* Convert argument to capitalized form and return that. |
| 201 | This means that each word's first character is upper case | 212 | This means that each word's first character is converted to either |
| 202 | and the rest is lower case. | 213 | title case or upper case, and the rest to lower case. |
| 203 | The argument may be a character or string. The result has the same type. | 214 | The argument may be a character or string. The result has the same type. |
| 204 | The argument object is not altered--the value is a copy. */) | 215 | The argument object is not altered--the value is a copy. */) |
| 205 | (Lisp_Object obj) | 216 | (Lisp_Object obj) |
| @@ -211,7 +222,8 @@ The argument object is not altered--the value is a copy. */) | |||
| 211 | 222 | ||
| 212 | DEFUN ("upcase-initials", Fupcase_initials, Supcase_initials, 1, 1, 0, | 223 | DEFUN ("upcase-initials", Fupcase_initials, Supcase_initials, 1, 1, 0, |
| 213 | doc: /* Convert the initial of each word in the argument to upper case. | 224 | doc: /* Convert the initial of each word in the argument to upper case. |
| 214 | Do not change the other letters of each word. | 225 | This means that each word's first character is converted to either |
| 226 | title case or upper case, and the rest are left unchanged. | ||
| 215 | The argument may be a character or string. The result has the same type. | 227 | The argument may be a character or string. The result has the same type. |
| 216 | The argument object is not altered--the value is a copy. */) | 228 | The argument object is not altered--the value is a copy. */) |
| 217 | (Lisp_Object obj) | 229 | (Lisp_Object obj) |
| @@ -375,8 +387,8 @@ point and the mark is operated on. */) | |||
| 375 | 387 | ||
| 376 | DEFUN ("capitalize-region", Fcapitalize_region, Scapitalize_region, 2, 2, "r", | 388 | DEFUN ("capitalize-region", Fcapitalize_region, Scapitalize_region, 2, 2, "r", |
| 377 | doc: /* Convert the region to capitalized form. | 389 | doc: /* Convert the region to capitalized form. |
| 378 | Capitalized form means each word's first character is upper case | 390 | This means that each word's first character is converted to either |
| 379 | and the rest of it is lower case. | 391 | title case or upper case, and the rest to lower case. |
| 380 | In programs, give two arguments, the starting and ending | 392 | In programs, give two arguments, the starting and ending |
| 381 | character positions to operate on. */) | 393 | character positions to operate on. */) |
| 382 | (Lisp_Object beg, Lisp_Object end) | 394 | (Lisp_Object beg, Lisp_Object end) |
| @@ -390,7 +402,8 @@ character positions to operate on. */) | |||
| 390 | DEFUN ("upcase-initials-region", Fupcase_initials_region, | 402 | DEFUN ("upcase-initials-region", Fupcase_initials_region, |
| 391 | Supcase_initials_region, 2, 2, "r", | 403 | Supcase_initials_region, 2, 2, "r", |
| 392 | doc: /* Upcase the initial of each word in the region. | 404 | doc: /* Upcase the initial of each word in the region. |
| 393 | Subsequent letters of each word are not changed. | 405 | This means that each word's first character is converted to either |
| 406 | title case or upper case, and the rest are left unchanged. | ||
| 394 | In programs, give two arguments, the starting and ending | 407 | In programs, give two arguments, the starting and ending |
| 395 | character positions to operate on. */) | 408 | character positions to operate on. */) |
| 396 | (Lisp_Object beg, Lisp_Object end) | 409 | (Lisp_Object beg, Lisp_Object end) |