]> git.wh0rd.org Git - nano.git/commitdiff
make the rest of the justify code support multibyte characters
authorDavid Lawrence Ramsey <pooka109@gmail.com>
Tue, 15 Mar 2005 05:44:03 +0000 (05:44 +0000)
committerDavid Lawrence Ramsey <pooka109@gmail.com>
Tue, 15 Mar 2005 05:44:03 +0000 (05:44 +0000)
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2371 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
src/chars.c
src/nano.c
src/proto.h

index 62054409c2309cfa89568732056af4dce13ce5a8..109edc6fac32489c53f669e7d540be5e397b5f3c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -175,12 +175,12 @@ CVS code -
          paragraph-searching utility functions when possible instead of
          duplicating code.  Also overhaul the justify code to make it
          leave the right number of spaces at the ends of the lines of a
-         paragraph, to make it (partially) support multibyte
-         characters, and to make it simpler.  Also, don't remove a
-         space after a duplicate character in punct anymore, as it
-         doesn't really make us more compatible with Pico.  New
-         functions do_para_begin_void() and do_para_end_void(); changes
-         to justify_format(), do_para_begin(), inpar(), do_para_end(),
+         paragraph, to make it support multibyte characters, and to
+         make it simpler.  Also, don't remove a space after a duplicate
+         character in punct anymore, as it doesn't really make us more
+         compatible with Pico.  New functions mbstrchr(),
+         do_para_begin_void(), and do_para_end_void(); changes to
+         justify_format(), do_para_begin(), inpar(), do_para_end(),
          break_line(), do_para_search() (renamed find_paragraph()), and
          do_justify(); removal of breakable(). (DLR)
        - Still more steps toward full wide/multibyte character support.
index ae807a7b204ce98ef8e01daabf8dd0d5ae225831..79c66b89b1d29f8e4f0a9d9ae1ea3a3806728d08 100644 (file)
@@ -811,3 +811,48 @@ size_t mbstrnlen(const char *s, size_t maxlen)
                nstrnlen(s, maxlen);
 #endif
 }
+
+#ifndef DISABLE_JUSTIFY
+/* This function is equivalent to strchr() for multibyte strings. */
+char *mbstrchr(const char *s, char *c)
+{
+    assert(s != NULL && c != NULL);
+
+#ifdef NANO_WIDE
+    if (!ISSET(NO_UTF8)) {
+       char *s_mb = charalloc(MB_CUR_MAX);
+       const char *q = s;
+       wchar_t ws, wc;
+       int s_mb_len, c_mb_len = mbtowc(&wc, c, MB_CUR_MAX);
+
+       if (c_mb_len <= 0) {
+           mbtowc(NULL, NULL, 0);
+           wc = (unsigned char)*c;
+       }
+
+       while (*s != '\0') {
+           s_mb_len = parse_mbchar(s, s_mb, NULL, NULL);
+
+           if (mbtowc(&ws, s_mb, s_mb_len) <= 0) {
+               mbtowc(NULL, NULL, 0);
+               ws = (unsigned char)*s;
+           }
+
+           if (ws == wc)
+               break;
+
+           s += s_mb_len;
+           q += s_mb_len;
+       }
+
+       free(s_mb);
+
+       if (ws != wc)
+           q = NULL;
+
+       return (char *)q;
+    } else
+#endif
+       return strchr(s, *c);
+}
+#endif
index cdf6685e371507e86ef5ec9aeefb8230fa13ebbe..83bf41e19c9516bfe2325a95644c5f74a395b7be 100644 (file)
@@ -2382,68 +2382,95 @@ void justify_format(filestruct *paragraph, size_t skip)
     new_end = new_paragraph_data + skip;
 
     while (*end != '\0') {
+       int end_len;
+
        /* If this character is blank, make sure that it's a space with
         * no blanks after it. */
-       if (is_blank_char(*end)) {
+       if (is_blank_mbchar(end)) {
+           end_len = parse_mbchar(end, NULL, NULL, NULL);
+
            *new_end = ' ';
            new_end++;
-           end++;
+           end += end_len;
 
-           while (*end != '\0' && is_blank_char(*end)) {
-               end++;
-               shift++;
+           while (*end != '\0' && is_blank_mbchar(end)) {
+               end_len = parse_mbchar(end, NULL, NULL, NULL);
+
+               end += end_len;
+               shift += end_len;
 
 #ifndef NANO_SMALL
                /* Keep track of the change in the current line. */
                if (mark_beginbuf == paragraph &&
                        mark_beginx >= end - paragraph->data)
-                   mark_shift++;
+                   mark_shift += end_len;
 #endif
            }
        /* If this character is punctuation optionally followed by a
         * bracket and then followed by blanks, make sure there are no
         * more than two blanks after it, and make sure that the blanks
         * are spaces. */
-       } else if (strchr(punct, *end) != NULL) {
-           *new_end = *end;
-           new_end++;
-           end++;
+       } else if (mbstrchr(punct, end) != NULL) {
+           end_len = parse_mbchar(end, NULL, NULL, NULL);
 
-           if (*end != '\0' && strchr(brackets, *end) != NULL) {
+           while (end_len > 0) {
                *new_end = *end;
                new_end++;
                end++;
+               end_len--;
+           }
+
+           if (*end != '\0' && mbstrchr(brackets, end) != NULL) {
+               end_len = parse_mbchar(end, NULL, NULL, NULL);
+
+               while (end_len > 0) {
+                   *new_end = *end;
+                   new_end++;
+                   end++;
+                   end_len--;
+               }
            }
 
-           if (*end != '\0' && is_blank_char(*end)) {
+           if (*end != '\0' && is_blank_mbchar(end)) {
+               end_len = parse_mbchar(end, NULL, NULL, NULL);
+
                *new_end = ' ';
                new_end++;
-               end++;
+               end += end_len;
            }
 
-           if (*end != '\0' && is_blank_char(*end)) {
+           if (*end != '\0' && is_blank_mbchar(end)) {
+               end_len = parse_mbchar(end, NULL, NULL, NULL);
+
                *new_end = ' ';
                new_end++;
-               end++;
+               end += end_len;
            }
 
-           while (*end != '\0' && is_blank_char(*end)) {
-               end++;
-               shift++;
+           while (*end != '\0' && is_blank_mbchar(end)) {
+               end_len = parse_mbchar(end, NULL, NULL, NULL);
+
+               end += end_len;
+               shift += end_len;
 
 #ifndef NANO_SMALL
-           /* Keep track of the change in the current line. */
-           if (mark_beginbuf == paragraph &&
-               mark_beginx >= end - paragraph->data)
-               mark_shift++;
+               /* Keep track of the change in the current line. */
+               if (mark_beginbuf == paragraph &&
+                       mark_beginx >= end - paragraph->data)
+                   mark_shift += end_len;
 #endif
            }
        /* If this character is neither blank nor punctuation, leave it
         * alone. */
        } else {
-           *new_end = *end;
-           new_end++;
-           end++;
+           end_len = parse_mbchar(end, NULL, NULL, NULL);
+
+           while (end_len > 0) {
+               *new_end = *end;
+               new_end++;
+               end++;
+               end_len--;
+           }
        }
     }
 
@@ -2743,11 +2770,11 @@ ssize_t break_line(const char *line, ssize_t goal, bool force)
         * found with short enough display width.  */
     ssize_t cur_loc = 0;
        /* Current index in line. */
+    int line_len;
 
     assert(line != NULL);
 
     while (*line != '\0' && goal >= 0) {
-       int line_len;
        size_t pos = 0;
 
        line_len = parse_mbchar(line, NULL, NULL, &pos);
@@ -2770,7 +2797,7 @@ ssize_t break_line(const char *line, ssize_t goal, bool force)
            bool found_blank = FALSE;
 
            while (*line != '\0') {
-               int line_len = parse_mbchar(line, NULL, NULL, NULL);
+               line_len = parse_mbchar(line, NULL, NULL, NULL);
 
                if (is_blank_mbchar(line)) {
                    if (!found_blank)
@@ -2786,11 +2813,18 @@ ssize_t break_line(const char *line, ssize_t goal, bool force)
        }
     }
 
-    /* Perhaps the character after blank_loc is a blank.  But because
-     * of justify_format(), there can be only two adjacent. */
-    if (*(line - cur_loc + blank_loc + 1) == ' ' ||
-       *(line - cur_loc + blank_loc + 1) == '\0')
-       blank_loc++;
+    /* Move to the last blank after blank_loc, if there is one. */
+    line -= cur_loc;
+    line += blank_loc;
+    line_len = parse_mbchar(line, NULL, NULL, NULL);
+    line += line_len;
+
+    while (*line != '\0' && is_blank_mbchar(line)) {
+       line_len = parse_mbchar(line, NULL, NULL, NULL);
+
+       line += line_len;
+       blank_loc += line_len;
+    }
 
     return blank_loc;
 }
index b6841634e49f577655bdd493986f482cc540577e..01b9a9a2af4f1a34ec31ffe8660bf6026dffae1b 100644 (file)
@@ -207,6 +207,9 @@ size_t mbstrlen(const char *s);
 size_t nstrnlen(const char *s, size_t maxlen);
 #endif
 size_t mbstrnlen(const char *s, size_t maxlen);
+#ifndef DISABLE_JUSTIFY
+char *mbstrchr(const char *s, char *c);
+#endif
 
 /* Public functions in color.c. */
 #ifdef ENABLE_COLOR