bug-texinfo
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCHes] Add basic multibyte charset handling to makeinfo


From: Miloslav Trmac
Subject: Re: [PATCHes] Add basic multibyte charset handling to makeinfo
Date: Tue, 05 Dec 2006 17:27:46 +0100
User-agent: Thunderbird 1.5.0.8 (X11/20061107)

Miloslav Trmac napsal(a):
> Karl Berry napsal(a):
>>     The attached patches add support for multibyte character sets (e.g.
>>     UTF-8) and multi-column characters (e.g. Chinese) to makeinfo.
>> Wow.  Thank you very much, Miloslav.  I will work on installing it as
>> soon as I can.
> Please don't, I have just noticed some bugs.  I'll send updated patches
> soon.
Attached.  They fix width computation for non-breaking spaces and
preserve current column over flush_output ().

texinfo-4.8-0xA0.patch:
        * makeinfo/makeinfo.h (NON_BREAKING_SPACE): New macro.
        (control_character_bit, meta_character_bit, CTL, UNCTL, META)
        (UNMETA): Remove.
        * makeinfo/makeinfo.c (add_char, flush_output): Use
        NON_BREAKING_SPACE instead of META (' ').
        (get_char_len): NON_BREAKING_SPACE is only one column wide.

texinfo-4.8-makeinfo-multibyte.patch:
        * configure.ac: Test wcwidth () availability.
        * makeinfo/makeinfo.h (string_width, current_output_column): New
        declarations.
        (output_column): Remove.  All users replaced by
        current_output_column (), all modifications dropped.
        * makeinfo/makeinfo.c (output_paragraph_start_column): New
        variable.
        (string_width, current_output_column): New functions.
        (get_char_len): Remove.
        (init_paragraph): Initialize output_paragraph_start_column.
        (flush_output): Update output_paragraph_start_column.

        * makeinfo/cmds.c (cm_center)
        * makeinfo/index.c (insert_index_output_line_no, cm_printindex):
        * makeinfo/makeinfo.c (do_flush_right_indentation)
        * makeinfo/multi.c (output_multitable_row):
        Don't assume number of columns == number of bytes.


        Mirek.
--- texinfo-4.8/makeinfo/makeinfo.c.0xA0        2004-12-19 18:15:42.000000000 
+0100
+++ texinfo-4.8/makeinfo/makeinfo.c     2006-12-04 22:37:54.000000000 +0100
@@ -2427,6 +2427,10 @@
       len = fill_column - output_column;
       break;
 
+    case NON_BREAKING_SPACE:
+      len = 1;
+      break;
+
     default:
       /* ASCII control characters appear as two characters in the output
          (e.g., ^A).  But characters with the high bit set are just one
@@ -2584,7 +2588,7 @@
           character = ';';
         }
       else
-        character = META (' '); /* unmeta-d in flush_output */
+        character = NON_BREAKING_SPACE; /* restored in flush_output */
     }
 
   insertion_paragraph_closed = 0;
@@ -2922,17 +2926,11 @@
           node_line_number++;
         }
 
-      /* If we turned on the 8th bit for a space inside @w, turn it
-         back off for output.  This might be problematic, since the
-         0x80 character may be used in 8-bit character sets.  Sigh.
-         In any case, don't do this for HTML, since the nbsp character
-         is valid input and must be passed along to the browser.  */
-      if (!html && (output_paragraph[i] & meta_character_bit))
-        {
-          int temp = UNMETA (output_paragraph[i]);
-          if (temp == ' ')
-            output_paragraph[i] &= 0x7f;
-        }
+      /* If we turned on the 8th bit for a space inside @w, turn it back off
+         for output.  Don't do this for HTML, since the nbsp character is valid
+         input and must be passed along to the browser.  */
+      if (!html && output_paragraph[i] == NON_BREAKING_SPACE)
+       output_paragraph[i] = ' ';
     }
 
   fwrite (output_paragraph, 1, output_paragraph_offset, output_stream);
--- texinfo-4.8/makeinfo/makeinfo.h.0xA0        2004-11-30 03:03:23.000000000 
+0100
+++ texinfo-4.8/makeinfo/makeinfo.h     2006-12-04 22:35:06.000000000 +0100
@@ -242,13 +242,6 @@
 #define coerce_to_upper(c) ((islower(c) ? toupper(c) : (c)))
 #define coerce_to_lower(c) ((isupper(c) ? tolower(c) : (c)))
 
-#define control_character_bit 0x40 /* %01000000, must be off. */
-#define meta_character_bit 0x080/* %10000000, must be on.  */
-#define CTL(c) ((c) & (~control_character_bit))
-#define UNCTL(c) coerce_to_upper(((c)|control_character_bit))
-#define META(c) ((c) | (meta_character_bit))
-#define UNMETA(c) ((c) & (~meta_character_bit))
-
 #define whitespace(c)       ((c) == '\t' || (c) == ' ')
 #define sentence_ender(c)   ((c) == '.'  || (c) == '?' || (c) == '!')
 #define cr_or_whitespace(c) (whitespace(c) || (c) == '\r' || (c) == '\n')
@@ -282,6 +275,9 @@
 
 #define COMMAND_PREFIX '@'
 
+/* A byte value to represent a non-breaking space until flush_output (). */
+#define NON_BREAKING_SPACE 036
+
 #define END_VERBATIM "end verbatim"
 
 /* Stuff for splitting large files.  The numbers for Emacs
diff -ur texinfo/configure.ac texinfo-4.8/configure.ac
--- texinfo/configure.ac        2004-12-31 19:00:48.000000000 +0100
+++ texinfo-4.8/configure.ac    2006-12-04 22:51:18.000000000 +0100
@@ -69,7 +69,7 @@
 # that anyone compiling new texinfo still has such a thing? we'll see.
 # AC_FUNC_SETVBUF_REVERSED
 AC_CHECK_FUNCS(bzero getcwd memset setvbuf sigaction sigprocmask \
-               sigsetmask strchr)
+               sigsetmask strchr wcwidth)
 AC_REPLACE_FUNCS(memcpy memmove strdup strerror)
 
 # strcasecmp and strncasecmp, gnulib-style.
diff -ur texinfo/makeinfo/cmds.c texinfo-4.8/makeinfo/cmds.c
--- texinfo/makeinfo/cmds.c     2004-12-14 01:15:36.000000000 +0100
+++ texinfo-4.8/makeinfo/cmds.c 2006-12-04 22:51:18.000000000 +0100
@@ -1501,7 +1501,7 @@
     }
   else
     {
-      int i, start, length;
+      int i, start, length, width;
       char *line;
       int save_indented_fill = indented_fill;
       int save_filling_enabled = filling_enabled;
@@ -1530,13 +1530,14 @@
 
            output_paragraph_offset = ++i;
            length = output_paragraph_offset - start;
+          width = string_width ((char *)(output_paragraph + start), length);
 
-           if (length < (fill_column - fudge_factor))
+           if (width < (fill_column - fudge_factor))
              {
                line = xmalloc (1 + length);
                memcpy (line, (char *)(output_paragraph + start), length);
 
-               i = (fill_column - fudge_factor - length) / 2;
+               i = (fill_column - fudge_factor - width) / 2;
                output_paragraph_offset = start;
 
                while (i--)
diff -ur texinfo/makeinfo/index.c texinfo-4.8/makeinfo/index.c
--- texinfo/makeinfo/index.c    2004-11-30 03:03:23.000000000 +0100
+++ texinfo-4.8/makeinfo/index.c        2006-12-04 22:51:18.000000000 +0100
@@ -657,7 +657,7 @@
 static void
 insert_index_output_line_no (int line_number, int output_line_number_len)
 {
-  int last_column;
+  int last_column, out_line_no_width;
   int str_size = output_line_number_len + strlen (_("(line )"))
     + sizeof (NULL);
   char *out_line_no_str = (char *) xmalloc (str_size + 1);
@@ -673,16 +673,18 @@
     int i = output_paragraph_offset; 
     while (0 < i && output_paragraph[i-1] != '\n')
       i--;
-    last_column = output_paragraph_offset - i;
+    last_column = string_width ((char *)(output_paragraph + i),
+                               output_paragraph_offset - i);
   }
 
-  if (last_column + strlen (out_line_no_str) > fill_column)
+  out_line_no_width = string_width (out_line_no_str, strlen (out_line_no_str));
+  if (last_column + out_line_no_width > fill_column)
     {
       insert ('\n');
       last_column = 0;
     }
 
-  while (last_column + strlen (out_line_no_str) < fill_column)
+  while (last_column + out_line_no_width < fill_column)
     {
       insert (' ');
       last_column++;
@@ -877,7 +879,10 @@
             }
           else
             {
-              unsigned new_length = strlen (index->entry);
+#define MIN_ENTRY_COLUMNS 37
+             /* Make sure there is enough space even if index->entry has zero
+                width. */
+              unsigned new_length = strlen (index->entry) + MIN_ENTRY_COLUMNS;
 
               if (new_length < 50) /* minimum length used below */
                 new_length = 50;
@@ -894,7 +899,13 @@
                  @@ has turned into @. */
               if (!no_headers)
                 {
-                  sprintf (line, "* %-37s  ", index->entry);
+                 int width;
+
+                 width = string_width (index->entry, strlen (index->entry));
+                  sprintf (line, "* %*s  ", width < MIN_ENTRY_COLUMNS
+                          ? -(strlen (index->entry)
+                              + (MIN_ENTRY_COLUMNS - width))
+                          : 0, index->entry);
                   line[2 + strlen (index->entry)] = ':';
                   insert_string (line);
                   /* Make sure any non-macros in the node name are expanded.  
*/
diff -ur texinfo/makeinfo/insertion.c texinfo-4.8/makeinfo/insertion.c
--- texinfo/makeinfo/insertion.c        2004-11-11 19:34:28.000000000 +0100
+++ texinfo-4.8/makeinfo/insertion.c    2006-12-04 22:51:18.000000000 +0100
@@ -370,7 +370,7 @@
   else
     sprintf (temp, "%d. ", current_enumval);
 
-  indent (output_column += (current_indent - strlen (temp)));
+  indent (current_output_column () + (current_indent - strlen (temp)));
   add_word (temp);
   current_enumval++;
 }
@@ -2194,8 +2194,7 @@
 
                   if (current_item_function ())
                     {
-                      output_column = current_indent - 2;
-                      indent (output_column);
+                      indent (current_indent - 2);
 
                       /* The item marker can be given with or without
                          braces -- @bullet and @bullet{} are both ok.
@@ -2214,7 +2213,6 @@
                             execute_string ("%s", item_func);
                         }
                       insert (' ');
-                      output_column++;
                     }
                   else
                     enumerate_item ();
diff -ur texinfo/makeinfo/macro.c texinfo-4.8/makeinfo/macro.c
--- texinfo/makeinfo/macro.c    2004-04-11 19:56:47.000000000 +0200
+++ texinfo-4.8/makeinfo/macro.c        2006-12-04 22:51:18.000000000 +0100
@@ -899,13 +899,12 @@
 void
 me_execute_string_keep_state (char *execution_string, char *append_string)
 {
-  int op_orig, opcol_orig, popen_orig;
+  int op_orig, popen_orig;
   int fill_orig, newline_orig, indent_orig, meta_pos_orig;
 
   remember_itext (input_text, input_text_offset);
   op_orig = output_paragraph_offset;
   meta_pos_orig = meta_char_pos;
-  opcol_orig = output_column;
   popen_orig = paragraph_is_open;
   fill_orig = filling_enabled;
   newline_orig = last_char_was_newline;
@@ -917,7 +916,6 @@
     write_region_to_macro_output (append_string, 0, strlen (append_string));
   output_paragraph_offset = op_orig;
   meta_char_pos = meta_pos_orig;
-  output_column = opcol_orig;
   paragraph_is_open = popen_orig;
   filling_enabled = fill_orig;
   last_char_was_newline = newline_orig;
diff -ur texinfo/makeinfo/makeinfo.c texinfo-4.8/makeinfo/makeinfo.c
--- texinfo/makeinfo/makeinfo.c 2006-12-04 22:50:59.000000000 +0100
+++ texinfo-4.8/makeinfo/makeinfo.c     2006-12-05 16:48:35.000000000 +0100
@@ -39,6 +39,10 @@
 #include "toc.h"
 #include "xml.h"
 
+#ifdef HAVE_WCWIDTH
+# include <wchar.h>
+#endif
+
 /* You can change some of the behavior of Makeinfo by changing the
    following defines: */
 
@@ -143,6 +147,11 @@
 /* True when we are inside a <li> block of a menu.  */
 static int in_menu_item = 0;
 
+/* The column position of output_paragraph[0].  This is not saved and restored
+   in the multitable code because flush_output () is only called in environment
+   0. */
+static int output_paragraph_start_column = 0;
+
 typedef struct brace_element
 {
   struct brace_element *next;
@@ -1843,7 +1852,7 @@
   output_paragraph = xmalloc (paragraph_buffer_len);
   output_paragraph[0] = 0;
   output_paragraph_offset = 0;
-  output_column = 0;
+  output_paragraph_start_column = 0;
   paragraph_is_open = 0;
   current_indent = 0;
   meta_char_pos = 0;
@@ -2407,41 +2416,102 @@
     }
 }
 
-static int
-get_char_len (int character)
+/* Return the number of columns necessary for displaying STRING of LEN
+   bytes. */
+int
+string_width (const char *string, size_t length)
 {
-  /* Return the printed length of the character. */
-  int len;
+#ifdef HAVE_WCWIDTH
+  int width;
 
-  switch (character)
-    {
-    case '\t':
-      len = (output_column + 8) & 0xf7;
-      if (len > fill_column)
-        len = fill_column - output_column;
+  mbtowc (NULL, NULL, 0);
+  width = 0;
+  while (length > 0)
+    {
+      wchar_t wc;
+      int l, w;
+
+      l = mbtowc (&wc, string, length);
+      if (l == -1)
+       {
+         mbtowc (NULL, NULL, 0);
+         w = 1;
+         l = 1;
+       }
       else
-        len = len - output_column;
-      break;
+       {
+         if (l == 0)
+           l = 1;
+         w = wcwidth (wc);
+         if (w == -1)
+           w = 1;
+       }
+      width += w;
+      string += l;
+      length -= l;
+    }
+  return width;
+#endif
+  return length;
+}
 
-    case '\n':
-      len = fill_column - output_column;
-      break;
+/* Return the 0-based number of the current output column */
+int
+current_output_column (void)
+{
+  int i, column;
 
-    case NON_BREAKING_SPACE:
-      len = 1;
-      break;
+  for (i = output_paragraph_offset; i > 0 && output_paragraph[i - 1] != '\n';
+       i--)
+     ;
+  if (i == 0)
+    column = output_paragraph_start_column;
+  else
+    column = 0;
+  while (i < output_paragraph_offset)
+    {
+      int j;
 
-    default:
-      /* ASCII control characters appear as two characters in the output
-         (e.g., ^A).  But characters with the high bit set are just one
-         on suitable terminals, so don't count them as two for line
-         breaking purposes.  */
-      if (0 <= character && character < ' ')
-        len = 2;
-      else
-        len = 1;
+      /* Find a span of non-control characters */
+      for (j = i; j < output_paragraph_offset; j++)
+       {
+         char c;
+
+         c = output_paragraph[j];
+         if ((0 <= c && c < ' ') || c == '\t' || c == NON_BREAKING_SPACE)
+           break;
+       }
+      if (i < j)
+       {
+         column += string_width ((char *)(output_paragraph + i), j - i);
+         i = j;
+       }
+      if (i < output_paragraph_offset)
+       {
+         char c;
+
+         /* Handle a control character */
+         c = output_paragraph[i];
+         if (c == '\t')
+           {
+             column = (column + 8) & ~0x7;
+             if (column > fill_column)
+               column = fill_column;
+           }
+         else if (c == NON_BREAKING_SPACE)
+           column++;
+         else
+           {
+             /* ASCII control characters appear as two characters in the
+                output (e.g., ^A).  */
+             if (!(0 <= c && c < ' '))
+               abort ();
+             column += 2;
+           }
+         i++;
+       }
     }
-  return len;
+  return column;
 }
 
 void
@@ -2566,13 +2636,13 @@
      ignore close_paragraph () calls any more. */
   if (must_start_paragraph && character != '\n')
     {
+      int column;
+
       must_start_paragraph = 0;
       line_already_broken = 0;  /* The line is no longer broken. */
-      if (current_indent > output_column)
-        {
-          indent (current_indent - output_column);
-          output_column = current_indent;
-        }
+      column = current_output_column ();
+      if (current_indent > column)
+       indent (current_indent - column);
     }
 
   if (non_splitting_words
@@ -2607,17 +2677,14 @@
               flush_output ();
             }
 
-          output_column = 0;
-
           if (!no_indent && paragraph_is_open)
-            indent (output_column = current_indent);
+            indent (current_indent);
           break;
         }
       else if (end_of_sentence_p ())
         /* CHARACTER is newline, and filling is enabled. */
         {
           insert (' ');
-          output_column++;
           last_inserted_character = character;
         }
 
@@ -2635,13 +2702,12 @@
             insert ('\n');
           else
             insert (' ');
-          output_column++;
         }
       break;
 
     default: /* not at newline */
       {
-        int len = get_char_len (character);
+        int column;
         int suppress_insert = 0;
 
         if ((character == ' ') && (last_char_was_newline))
@@ -2689,8 +2755,20 @@
               }
           }
 
-        output_column += len;
-        if (output_column > fill_column)
+       output_paragraph[output_paragraph_offset] = character;
+       output_paragraph_offset++;
+       column = current_output_column ();
+       output_paragraph_offset--;
+       /* The string_width () in current_output_column () cannot predict
+          future incoming bytes.  So if output_paragraph ends in a partial
+          multibyte character, its bytes are counted as separate column
+          positions.  This may push column past fill_column, even though the
+          finished multibyte character would fit on the current line.
+
+          This is too hard to fix without modifying add_char () to recieve
+          complete multibyte characters at a time, and causes only slightly
+          incorrect paragraph filling, so we punt.  */
+        if (column > fill_column)
           {
             if (filling_enabled && !html)
               {
@@ -2777,11 +2855,6 @@
                             output_paragraph_offset += current_indent;
                             free (temp_buffer);
                           }
-                        output_column = 0;
-                        while (temp < output_paragraph_offset)
-                          output_column +=
-                            get_char_len (output_paragraph[temp++]);
-                        output_column += len;
                         break;
                       }
                   }
@@ -2874,7 +2947,6 @@
   /* Handle infinite case first. */
   if (count < 0)
     {
-      output_column = 0;
       while (output_paragraph_offset)
         {
           if (whitespace (output_paragraph[output_paragraph_offset - 1]))
@@ -2936,6 +3008,7 @@
   fwrite (output_paragraph, 1, output_paragraph_offset, output_stream);
 
   output_position += output_paragraph_offset;
+  output_paragraph_start_column = current_output_column ();
   output_paragraph_offset = 0;
   meta_char_pos = 0;
 }
@@ -2986,6 +3059,8 @@
     }
   else
     {
+      int column;
+
       /* If the insertion paragraph is closed already, then we are seeing
          two address@hidden' commands in a row.  Note that the first one we 
saw was
          handled in the first part of this if-then-else clause, and at that
@@ -2993,8 +3068,9 @@
          indentation of the current line.  However, the indentation level
          may have just changed again, so we may have to outdent the current
          line to the new indentation level. */
-      if (current_indent < output_column)
-        kill_self_indent (output_column - current_indent);
+      column = current_output_column ();
+      if (current_indent < column)
+        kill_self_indent (column - current_indent);
     }
 
   insertion_paragraph_closed = 1;
@@ -3060,7 +3136,6 @@
       flush_output ();
       paragraph_is_open = 0;
       no_indent = 0;
-      output_column = 0;
     }
 
   ignore_blank_line ();
@@ -3074,38 +3149,39 @@
   last_char_was_newline = 1;
 }
 
-/* Align the end of the text in output_paragraph with fill_column. */
+/* Align the end of the text in output_paragraph with fill_column.  The last
+   character in output_paragraph is '\n'. */
 static void
 do_flush_right_indentation (void)
 {
   char *temp;
-  int temp_len;
 
   kill_self_indent (-1);
 
   if (output_paragraph[0] != '\n')
     {
-      output_paragraph[output_paragraph_offset] = 0;
+      int width;
 
-      if (output_paragraph_offset < fill_column)
+      width = string_width((char *)output_paragraph, output_paragraph_offset);
+      if (width < fill_column)
         {
           int i;
 
-          if (fill_column >= paragraph_buffer_len)
+          if (output_paragraph_offset + (fill_column - width)
+             >= paragraph_buffer_len)
             output_paragraph =
               xrealloc (output_paragraph,
                         (paragraph_buffer_len += fill_column));
 
-          temp_len = strlen ((char *)output_paragraph);
-          temp = xmalloc (temp_len + 1);
-          memcpy (temp, (char *)output_paragraph, temp_len);
+          temp = xmalloc (output_paragraph_offset);
+          memcpy (temp, (char *)output_paragraph, output_paragraph_offset);
 
-          for (i = 0; i < fill_column - output_paragraph_offset; i++)
+          for (i = 0; i < fill_column - width; i++)
             output_paragraph[i] = ' ';
 
-          memcpy ((char *)output_paragraph + i, temp, temp_len);
+          memcpy ((char *)output_paragraph + i, temp, output_paragraph_offset);
           free (temp);
-          output_paragraph_offset = fill_column;
+          output_paragraph_offset += i;
           adjust_braces_following (0, i);
         }
     }
@@ -3135,6 +3211,8 @@
       /* If doing indentation, then insert the appropriate amount. */
       if (!no_indent)
         {
+         int column;
+
           if (inhibit_paragraph_indentation)
             {
               amount_to_indent = current_indent;
@@ -3146,12 +3224,9 @@
           else
             amount_to_indent = current_indent + paragraph_start_indent;
 
-          if (amount_to_indent >= output_column)
-            {
-              amount_to_indent -= output_column;
-              indent (amount_to_indent);
-              output_column += amount_to_indent;
-            }
+         column = current_output_column ();
+          if (amount_to_indent >= column)
+           indent (amount_to_indent - column);
         }
     }
   else
@@ -3640,7 +3715,6 @@
       output_paragraph[end_pos] = 0;
       name = xstrdup (name);
       value = set_p (name);
-      output_column -= end_pos - start_pos;
       output_paragraph_offset = start_pos;
 
       /* Restore the previous value of meta_char_pos if the stuff
@@ -4059,7 +4133,6 @@
   /* Inhibit any real output.  */
   int start = output_paragraph_offset;
   int saved_paragraph_is_open = paragraph_is_open;
-  int saved_output_column = output_column;
 
   /* More output state to save.  */
   int saved_meta_pos = meta_char_pos;
@@ -4094,7 +4167,6 @@
 
   output_paragraph_offset = start;
   paragraph_is_open = saved_paragraph_is_open;
-  output_column = saved_output_column;
 
   meta_char_pos = saved_meta_pos;
   last_inserted_character = saved_last_char;
diff -ur texinfo/makeinfo/makeinfo.h texinfo-4.8/makeinfo/makeinfo.h
--- texinfo/makeinfo/makeinfo.h 2006-12-04 22:50:59.000000000 +0100
+++ texinfo-4.8/makeinfo/makeinfo.h     2006-12-04 22:51:18.000000000 +0100
@@ -53,9 +53,6 @@
 /* Offset into OUTPUT_PARAGRAPH. */
 DECLARE (int, output_paragraph_offset, 0);
 
-/* The output paragraph "cursor" horizontal position. */
-DECLARE (int, output_column, 0);
-
 /* Position in the output file. */
 DECLARE (int, output_position, 0);
 
@@ -358,6 +355,8 @@
   search_forward (char *string, int from),
   search_forward_until_pos (char *string, int from, int end_pos),
   next_nonwhitespace_character (void),
+  string_width (const char *string, size_t length),
+  current_output_column (void),
   fs_error (char *filename);
 
 #if defined (VA_FPRINTF) && __STDC__
diff -ur texinfo/makeinfo/multi.c texinfo-4.8/makeinfo/multi.c
--- texinfo/makeinfo/multi.c    2004-04-11 19:56:47.000000000 +0200
+++ texinfo-4.8/makeinfo/multi.c        2006-12-04 22:51:18.000000000 +0100
@@ -59,7 +59,6 @@
   unsigned char *output_paragraph;
   int output_paragraph_offset;
   int meta_char_pos;
-  int output_column;
   int paragraph_is_open;
   int current_indent;
   int fill_column;
@@ -143,7 +142,6 @@
   e->output_paragraph = output_paragraph;
   e->output_paragraph_offset = output_paragraph_offset;
   e->meta_char_pos = meta_char_pos;
-  e->output_column = output_column;
   e->paragraph_is_open = paragraph_is_open;
   e->current_indent = current_indent;
   e->fill_column = fill_column;
@@ -154,7 +152,6 @@
   output_paragraph = e->output_paragraph;
   output_paragraph_offset = e->output_paragraph_offset;
   meta_char_pos = e->meta_char_pos;
-  output_column = e->output_column;
   paragraph_is_open = e->paragraph_is_open;
   current_indent = e->current_indent;
   fill_column = e->fill_column;
@@ -467,15 +464,16 @@
           break;
         out_char (CHAR_AT (j));
       }
-      offset[i] += j + 1;       /* skip last text plus skip the newline */
-      
       /* Do not output trailing blanks if we're in the last column and
          there will be no trailing |.  */
       if (i < last_column && !vsep)
-        for (; j <= envs[i].fill_column; j++)
+        for (s = string_width ((char *)&CHAR_AT (0), j);
+            s <= envs[i].fill_column; s++)
           out_char (' ');
       if (vsep)
         out_char ('|'); /* draw column separator */
+
+      offset[i] += j + 1;       /* skip last text plus skip the newline */
     }
     out_char ('\n');    /* end of line */
     had_newline = 1;

reply via email to

[Prev in Thread] Current Thread [Next in Thread]