groff-commit
[Top][All Lists]
Advanced

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

[Groff-commit] groff ChangeLog NEWS src/preproc/tbl/main.cpp s...


From: Werner LEMBERG
Subject: [Groff-commit] groff ChangeLog NEWS src/preproc/tbl/main.cpp s...
Date: Sun, 16 Nov 2008 17:22:22 +0000

CVSROOT:        /cvsroot/groff
Module name:    groff
Changes by:     Werner LEMBERG <wl>     08/11/16 17:22:21

Modified files:
        .              : ChangeLog NEWS 
        src/preproc/tbl: main.cpp table.cpp table.h tbl.man 

Log message:
        Implement `x' specifier for expanded columns.  Contrary to old DWB
        tbl, more than a single `x' specifier can be used.  At the same
        time, remove most of the code from change 2007-02-09 which collides
        with the new implementation.
        
        * src/preproc/tbl/main.cpp (format): Add `expand' array.
        (format::format, format::~format): Updated.
        (input_entry_format): Add `expand' field.
        (input_entry_format::input_entry_format): Updated.
        (input_entry_format::debug_print): Handle `expand'.
        (process_format): Handle `x' specifier.
        (process_data): Updated.
        
        * src/preproc/tbl/table.cpp (AVAILABLE_REG, COLCOUNT_REG): Remove.
        (EXPAND_REG): New macro.
        (table_entry::divert, block_entry::divert,
        alphabetic_block_entry::divert): Add parameter to control whether
        expanded columns shall be handled.
        (block_entry::do_width): Remove.
        (block_entry::do_divert): Add parameter to control whether expanded
        columns shall be handled.
        Treat expanded columns like columns with a minimum width.
        Remove `experimental' code.
        (table::table, table::~table, table::allocate): Updated.
        (table::set_expand_column): New function.
        (table::count_block_columns): Replace with...
        (table::count_expand_columns): This function.
        (table::divide_span): Handle expanded columns the same as equal
        columns.
        (table::sum_columns): Add parameter to control whether expanded
        columns shall be handled.
        (table::compute_available_block_width): Replace with...
        (table::compute_expand_width): This function.
        (table::compute_total_separation): New function, taking code from
        `compute_separation_factor'.
        (table::compute_separation_factor): Simpler code.  The check for the
        `EXPAND' flag has been moved to the caller.
        (table::compute_widths): Add `top-level' changes to handle expanded
        blocks.
        
        * src/preproc/tbl/table.h (table): New field `total_separation'.
        Remove `blockflag' array.
        Add `expand' array.
        Update member function declarations.
        
        * src/preproc/tbl/tbl.man: Document `x' specifier.
        Expand documentation to cover all aspects of Lesk's tbl reference.
        
        * NEWS: Document `x' specifier.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/groff/ChangeLog?cvsroot=groff&r1=1.1160&r2=1.1161
http://cvs.savannah.gnu.org/viewcvs/groff/NEWS?cvsroot=groff&r1=1.250&r2=1.251
http://cvs.savannah.gnu.org/viewcvs/groff/src/preproc/tbl/main.cpp?cvsroot=groff&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/groff/src/preproc/tbl/table.cpp?cvsroot=groff&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/groff/src/preproc/tbl/table.h?cvsroot=groff&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/groff/src/preproc/tbl/tbl.man?cvsroot=groff&r1=1.24&r2=1.25

Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/groff/groff/ChangeLog,v
retrieving revision 1.1160
retrieving revision 1.1161
diff -u -b -r1.1160 -r1.1161
--- ChangeLog   7 Nov 2008 07:43:55 -0000       1.1160
+++ ChangeLog   16 Nov 2008 17:22:21 -0000      1.1161
@@ -1,3 +1,60 @@
+2008-11-12  Werner LEMBERG  <address@hidden>
+
+       Implement `x' specifier for expanded columns.  Contrary to old DWB
+       tbl, more than a single `x' specifier can be used.  At the same
+       time, remove most of the code from change 2007-02-09 which collides
+       with the new implementation.
+
+       * src/preproc/tbl/main.cpp (format): Add `expand' array.
+       (format::format, format::~format): Updated.
+       (input_entry_format): Add `expand' field.
+       (input_entry_format::input_entry_format): Updated.
+       (input_entry_format::debug_print): Handle `expand'.
+       (process_format): Handle `x' specifier.
+       (process_data): Updated.
+
+       * src/preproc/tbl/table.cpp (AVAILABLE_REG, COLCOUNT_REG): Remove.
+       (EXPAND_REG): New macro.
+       (table_entry::divert, block_entry::divert,
+       alphabetic_block_entry::divert): Add parameter to control whether
+       expanded columns shall be handled.
+       (block_entry::do_width): Remove.
+       (block_entry::do_divert): Add parameter to control whether expanded
+       columns shall be handled.
+       Treat expanded columns like columns with a minimum width.
+       Remove `experimental' code.
+       (table::table, table::~table, table::allocate): Updated.
+       (table::set_expand_column): New function.
+       (table::count_block_columns): Replace with...
+       (table::count_expand_columns): This function.
+       (table::divide_span): Handle expanded columns the same as equal
+       columns.
+       (table::sum_columns): Add parameter to control whether expanded
+       columns shall be handled.
+       (table::compute_available_block_width): Replace with...
+       (table::compute_expand_width): This function.
+       (table::compute_total_separation): New function, taking code from
+       `compute_separation_factor'.
+       (table::compute_separation_factor): Simpler code.  The check for the
+       `EXPAND' flag has been moved to the caller.
+       (table::compute_widths): Add `top-level' changes to handle expanded
+       blocks.
+
+       * src/preproc/tbl/table.h (table): New field `total_separation'.
+       Remove `blockflag' array.
+       Add `expand' array.
+       Update member function declarations.
+
+       * src/preproc/tbl/tbl.man: Document `x' specifier.
+       Expand documentation to cover all aspects of Lesk's tbl reference.
+
+       * NEWS: Document `x' specifier.
+
+2008-11-08  Werner LEMBERG  <address@hidden>
+
+       * src/preproc/tbl/tbl.man: Restructuring.
+       Improve text block documentation.
+
 2008-11-07  Werner LEMBERG  <address@hidden>
 
        * src/preproc/tbl/table.cpp (table::compute_widths): Use default

Index: NEWS
===================================================================
RCS file: /cvsroot/groff/groff/NEWS,v
retrieving revision 1.250
retrieving revision 1.251
diff -u -b -r1.250 -r1.251
--- NEWS        5 Nov 2008 22:58:59 -0000       1.250
+++ NEWS        16 Nov 2008 17:22:21 -0000      1.251
@@ -96,6 +96,16 @@
   `yslanted', which can change the shape of boxes into arbitrary
   parallelograms.
 
+Tbl
+---
+
+o Latest versions of DWB tbl introduced an `x' column specifier for a single
+  column expanded to the line width.  GNU tbl has now been extended to
+  support even multiple `x' specifiers within a table.
+
+o To avoid collision with the new `x' specifier, a block formatting macro
+  must now be selected with specifier letter `m'.
+
 Eqn
 ---
 
@@ -440,7 +450,7 @@
 Tbl
 ---
 
-o New key character `x' to make tbl call a user-defined macro on a table
+o New specifier `x' to make tbl call a user-defined macro on a table
   cell.  Patch by Heinz-Jürgen Oertel <address@hidden>.
 
 Grap2graph

Index: src/preproc/tbl/main.cpp
===================================================================
RCS file: /cvsroot/groff/groff/src/preproc/tbl/main.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- src/preproc/tbl/main.cpp    18 Oct 2008 05:56:19 -0000      1.11
+++ src/preproc/tbl/main.cpp    16 Nov 2008 17:22:21 -0000      1.12
@@ -623,6 +623,7 @@
   int *separation;
   string *width;
   char *equal;
+  char *expand;
   entry_format **entry;
   char **vline;
 
@@ -639,8 +640,11 @@
     separation[i] = -1;
   width = new string[ncolumns];
   equal = new char[ncolumns];
-  for (i = 0; i < ncolumns; i++)
+  expand = new char[ncolumns];
+  for (i = 0; i < ncolumns; i++) {
     equal[i] = 0;
+    expand[i] = 0;
+  }
   entry = new entry_format *[nrows];
   for (i = 0; i < nrows; i++)
     entry[i] = new entry_format[ncolumns];
@@ -680,6 +684,7 @@
   a_delete separation;
   ad_delete(ncolumns) width;
   a_delete equal;
+  a_delete expand;
   for (int i = 0; i < nrows; i++) {
     a_delete vline[i];
     ad_delete(ncolumns) entry[i];
@@ -696,6 +701,7 @@
   int pre_vline;
   int last_column;
   int equal;
+  int expand;
   input_entry_format(format_type, input_entry_format * = 0);
   ~input_entry_format();
   void debug_print();
@@ -709,6 +715,7 @@
   vline = 0;
   pre_vline = 0;
   equal = 0;
+  expand = 0;
 }
 
 input_entry_format::~input_entry_format()
@@ -738,6 +745,8 @@
   }
   if (equal)
     putc('e', stderr);
+  if (expand)
+    putc('x', stderr);
   if (separation >= 0)
     fprintf(stderr, "%d", separation); 
   for (i = 0; i < vline; i++)
@@ -754,6 +763,7 @@
                       format *current_format = 0)
 {
   input_entry_format *list = 0;
+  int have_expand = 0;
   int c = in.get();
   for (;;) {
     int pre_vline = 0;
@@ -873,7 +883,9 @@
       case 'e':
       case 'E':
        c = in.get();
-       list->equal++;
+       list->equal = 1;
+       // `e' and `x' are mutually exclusive
+       list->expand = 0;
        break;
       case 'f':
       case 'F':
@@ -1047,6 +1059,17 @@
            } while (c != EOF && csdigit(c));
          }
        }
+       // `w' and `x' are mutually exclusive
+       list->expand = 0;
+       break;
+      case 'x':
+      case 'X':
+       c = in.get();
+       list->expand = 1;
+       // `x' and `e' are mutually exclusive
+       list->equal = 0;
+       // `x' and `w' are mutually exclusive
+       list->width = "";
        break;
       case 'z':
       case 'Z':
@@ -1143,7 +1166,7 @@
   col = 0;
   for (tem = list; tem; tem = tem->next) {
     f->entry[row][col] = *tem;
-    if (col < ncolumns-1) {
+    if (col < ncolumns - 1) {
       // use the greatest separation
       if (tem->separation > f->separation[col]) {
        if (current_format)
@@ -1160,17 +1183,25 @@
       else
        f->equal[col] = 1;
     }
+    if (tem->expand && !f->expand[col]) {
+      if (current_format)
+       error("cannot change which columns are expanded in continued format");
+      else {
+       f->expand[col] = 1;
+       have_expand = 1;
+      }
+    }
     if (!tem->width.empty()) {
       // use the last width
       if (!f->width[col].empty() && f->width[col] != tem->width)
-       error("multiple widths for column %1", col+1);
+       error("multiple widths for column %1", col + 1);
       f->width[col] = tem->width;
     }
     if (tem->pre_vline) {
       assert(col == 0);
       f->vline[row][col] = tem->pre_vline;
     }
-    f->vline[row][col+1] = tem->vline;
+    f->vline[row][col + 1] = tem->vline;
     if (tem->last_column) {
       row++;
       col = 0;
@@ -1180,7 +1211,7 @@
   }
   free_input_entry_format_list(list);
   for (col = 0; col < ncolumns; col++) {
-    entry_format *e = f->entry[f->nrows-1] + col;
+    entry_format *e = f->entry[f->nrows - 1] + col;
     if (e->type != FORMAT_HLINE
        && e->type != FORMAT_DOUBLE_HLINE
        && e->type != FORMAT_SPAN)
@@ -1191,6 +1222,10 @@
     delete f;
     return 0;
   }
+  if (have_expand && (opt->flags & table::EXPAND)) {
+    error("ignoring global `expand' option because of `x' specifiers");
+    opt->flags &= ~table::EXPAND;
+  }
   return f;
 }
 
@@ -1491,6 +1526,9 @@
   for (i = 0; i < ncolumns; i++)
     if (f->equal[i])
       tbl->set_equal_column(i);
+  for (i = 0; i < ncolumns; i++)
+    if (f->expand[i])
+      tbl->set_expand_column(i);
   return tbl;
 }
 

Index: src/preproc/tbl/table.cpp
===================================================================
RCS file: /cvsroot/groff/groff/src/preproc/tbl/table.cpp,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- src/preproc/tbl/table.cpp   7 Nov 2008 07:43:56 -0000       1.17
+++ src/preproc/tbl/table.cpp   16 Nov 2008 17:22:21 -0000      1.18
@@ -63,8 +63,7 @@
 // this must be one character
 #define COMPATIBLE_REG PREFIX "c"
 
-#define AVAILABLE_REG PREFIX "avail"
-#define COLCOUNT_REG PREFIX "ccount"
+#define EXPAND_REG PREFIX "expand"
 
 #define LEADER_REG PREFIX LEADER
 
@@ -156,7 +155,7 @@
   void set_location();
   table_entry(const table *, const entry_modifier *);
   virtual ~table_entry();
-  virtual int divert(int, const string *, int *);
+  virtual int divert(int, const string *, int *, int);
   virtual void do_width();
   virtual void do_depth();
   virtual void print() = 0;
@@ -294,12 +293,11 @@
 class block_entry : public table_entry {
   char *contents;
 protected:
-  void do_divert(int, int, const string *, int *);
+  void do_divert(int, int, const string *, int *, int);
 public:
   block_entry(const table *, const entry_modifier *, char *);
   ~block_entry();
-  int divert(int, const string *, int *);
-  void do_width();
+  int divert(int, const string *, int *, int);
   void do_depth();
   void position_vertically();
   void print() = 0;
@@ -327,7 +325,7 @@
 public:
   alphabetic_block_entry(const table *, const entry_modifier *, char *);
   void print();
-  int divert(int, const string *, int *);
+  int divert(int, const string *, int *, int);
 };
 
 table_entry::table_entry(const table *p, const entry_modifier *m)
@@ -340,7 +338,7 @@
 {
 }
 
-int table_entry::divert(int, const string *, int *)
+int table_entry::divert(int, const string *, int *, int)
 {
   return 0;
 }
@@ -664,22 +662,33 @@
     prints(".sp -.5v\n");
 }
 
-int block_entry::divert(int ncols, const string *mw, int *sep)
+int block_entry::divert(int ncols, const string *mw, int *sep, int do_expand)
 {
-  do_divert(0, ncols, mw, sep);
+  do_divert(0, ncols, mw, sep, do_expand);
   return 1;
 }
 
 void block_entry::do_divert(int alphabetic, int ncols, const string *mw,
-                           int *sep)
+                           int *sep, int do_expand)
 {
+  int i;
+  for (i = start_col; i <= end_col; i++)
+    if (parent->expand[i])
+      break;
+  if (i > end_col) {
+    if (do_expand)
+      return;
+  }
+  else {
+    if (!do_expand)
+      return;
+  }
   printfs(".di %1\n", block_diversion_name(start_row, start_col));
   prints(".if \\n[" SAVED_FILL_REG "] .fi\n"
         ".in 0\n");
   prints(".ll ");
-  int i;
   for (i = start_col; i <= end_col; i++)
-    if (mw[i].empty())
+    if (mw[i].empty() && !parent->expand[i])
       break;
   if (i > end_col) {
     // Every column spanned by this entry has a minimum width.
@@ -689,18 +698,14 @@
          printfs("+%1n", as_string(sep[j - 1]));
        prints('+');
       }
+      if (parent->expand[j])
+       prints("\\n[" EXPAND_REG "]u");
+      else
       printfs("(n;%1)", mw[j]);
     }
     printfs(">?\\n[%1]u", span_width_reg(start_col, end_col));
   }
   else
-    if (parent->flags & table::EXPERIMENTAL)
-      // Each column containing a block entry gets 1/n of the remaining
-      // available line width, where n is the number of columns with block
-      // entries.
-      printfs("(u;\\n[%1]+(\\n[" AVAILABLE_REG "]/\\n[" COLCOUNT_REG "]))",
-             span_width_reg(start_col, end_col));
-    else
       // Assign each column with a block entry 1/(n+1) of the line
       // width, where n is the column count.
       printfs("(u;\\n[%1]>?(\\n[.l]*%2/%3))", 
@@ -735,12 +740,6 @@
   location_force_filename = 1;
 }
 
-void block_entry::do_width()
-{
-  for (int i = start_col; i <= end_col; i++)
-    parent->blockflag[i] = (char)1;
-}
-
 void block_entry::do_depth()
 {
   printfs(".nr " BOTTOM_REG " \\n[" BOTTOM_REG "]>?(\\n[%1]+\\n[%2])\n",
@@ -800,9 +799,10 @@
 {
 }
 
-int alphabetic_block_entry::divert(int ncols, const string *mw, int *sep)
+int alphabetic_block_entry::divert(int ncols, const string *mw, int *sep,
+                                  int do_expand)
 {
-  do_divert(1, ncols, mw, sep);
+  do_divert(1, ncols, mw, sep, do_expand);
   return 1;
 }
 
@@ -1231,15 +1231,18 @@
   vrule_list(0), stuff_list(0), span_list(0),
   entry_list(0), entry_list_tailp(&entry_list), entry(0),
   vline(0), row_is_all_lines(0), left_separation(0), right_separation(0),
-  allocated_rows(0), blockflag(0), flags(f)
+  total_separation(0), allocated_rows(0), flags(f)
 {
   minimum_width = new string[ncolumns];
   column_separation = ncolumns > 1 ? new int[ncolumns - 1] : 0;
   equal = new char[ncolumns];
+  expand = new char[ncolumns];
   int i;
-  for (i = 0; i < ncolumns; i++)
+  for (i = 0; i < ncolumns; i++) {
     equal[i] = 0;
-  for (i = 0; i < ncolumns-1; i++)
+    expand[i] = 0;
+  }
+  for (i = 0; i < ncolumns - 1; i++)
     column_separation[i] = DEFAULT_COLUMN_SEPARATION;
   delim[0] = delim[1] = '\0';
 }
@@ -1252,7 +1255,6 @@
   }
   a_delete entry;
   a_delete vline;
-  a_delete blockflag;
   while (entry_list) {
     table_entry *tem = entry_list;
     entry_list = entry_list->next;
@@ -1261,6 +1263,7 @@
   ad_delete(ncolumns) minimum_width;
   a_delete column_separation;
   a_delete equal;
+  a_delete expand;
   while (stuff_list) {
     stuff *tem = stuff_list;
     stuff_list = stuff_list->next;
@@ -1303,6 +1306,12 @@
   equal[c] = 1;
 }
 
+void table::set_expand_column(int c)
+{
+  assert(c >= 0 && c < ncolumns);
+  expand[c] = 1;
+}
+
 void table::add_stuff(stuff *p)
 {
   stuff **pp;
@@ -1338,9 +1347,6 @@
          allocated_rows = r + 1;
        entry = new PPtable_entry[allocated_rows];
        vline = new char*[allocated_rows];
-       blockflag = new char[allocated_rows];
-       for (int i = 0; i < allocated_rows; i++)
-         blockflag[i] = 0;
       }
       else {
        table_entry ***old_entry = entry;
@@ -1355,12 +1361,6 @@
        vline = new char*[allocated_rows];
        memcpy(vline, old_vline, sizeof(char*)*old_allocated_rows);
        a_delete old_vline;
-       char *old_blockflag = blockflag;
-       blockflag = new char[allocated_rows];
-       memcpy(blockflag, old_blockflag, sizeof(char)*old_allocated_rows);
-       for (int i = old_allocated_rows; i < allocated_rows; i++)
-         blockflag[i] = 0;
-       a_delete old_blockflag;
       }
     }
     assert(allocated_rows > r);
@@ -1727,11 +1727,11 @@
   }
 }
 
-int table::count_block_columns()
+int table::count_expand_columns()
 {
   int count = 0;
   for (int i = 0; i < ncolumns; i++)
-    if (blockflag[i])
+    if (expand[i])
       count++;
   return count;
 }
@@ -1990,7 +1990,7 @@
            span_width_reg(i, i));
   int equal_flag = 0;
   for (i = start_col; i <= end_col && !equal_flag; i++)
-    if (equal[i])
+    if (equal[i] || expand[i])
       equal_flag = 1;
   if (equal_flag) {
     for (i = 0; i < ncolumns; i++)
@@ -2001,13 +2001,25 @@
   prints(".\\}\n");
 }
 
-void table::sum_columns(int start_col, int end_col)
+void table::sum_columns(int start_col, int end_col, int do_expand)
 {
   assert(end_col > start_col);
+  int i;
+  for (i = start_col; i <= end_col; i++)
+    if (expand[i])
+      break;
+  if (i > end_col) {
+    if (do_expand)
+      return;
+  }
+  else {
+    if (!do_expand)
+      return;
+  }
   printfs(".nr %1 \\n[%2]", 
          span_width_reg(start_col, end_col),
          span_width_reg(start_col, start_col));
-  for (int i = start_col + 1; i <= end_col; i++)
+  for (i = start_col + 1; i <= end_col; i++)
     printfs("+(%1*\\n[" SEPARATION_FACTOR_REG "])+\\n[%2]",
            as_string(column_separation[i - 1]),
            span_width_reg(i, i));
@@ -2054,22 +2066,30 @@
   }
 }
 
-// Compute remaining length for block columns.
-
-void table::compute_available_block_width()
+void table::compute_expand_width()
 {
-  printfs(".nr " COLCOUNT_REG " %1\n", as_string(count_block_columns()));
-  prints(".nr " AVAILABLE_REG " \\n[.l]-\\n[.i]");
-  for (int i = 0; i < ncolumns; i++)
+  int i;
+  int colcount = count_expand_columns();
+  prints(".nr " EXPAND_REG " \\n[.l]-\\n[.i]");
+  for (i = 0; i < ncolumns; i++)
+    if (!expand[i])
     printfs("-\\n[%1]", span_width_reg(i, i));
+  if (total_separation)
+    printfs("-%1n", as_string(total_separation));
   prints("\n");
-  prints(".if \\n[" AVAILABLE_REG "]<0 \\{"
+  prints(".if \\n[" EXPAND_REG "]<0 \\{"
         ".tm warning: page \\n%: table wider than line width\n"
-        ".nr " AVAILABLE_REG " 0\n"
+        ".nr " EXPAND_REG " 0\n"
         ".\\}\n");
+  if (colcount > 1)
+    printfs(".nr " EXPAND_REG " \\n[" EXPAND_REG "]/%1\n",
+           as_string(colcount));
+  for (i = 0; i < ncolumns; i++)
+    if (expand[i])
+      printfs(".nr %1 \\n[%1]>?\\n[" EXPAND_REG "]\n", span_width_reg(i, i));
 }
 
-void table::compute_separation_factor()
+void table::compute_total_separation()
 {
   if (flags & (ALLBOX | BOX | DOUBLEBOX))
     left_separation = right_separation = 1;
@@ -2081,25 +2101,25 @@
        right_separation = 1;
     }
   }
-  if (flags & EXPAND) {
-    int total_sep = left_separation + right_separation;
+  total_separation = left_separation + right_separation;
     int i;
     for (i = 0; i < ncolumns - 1; i++)
-      total_sep += column_separation[i];
-    if (total_sep != 0) {
+    total_separation += column_separation[i];
+}
+
+void table::compute_separation_factor()
+{
       // Don't let the separation factor be negative.
       prints(".nr " SEPARATION_FACTOR_REG " \\n[.l]-\\n[.i]");
-      for (i = 0; i < ncolumns; i++)
+  for (int i = 0; i < ncolumns; i++)
        printfs("-\\n[%1]", span_width_reg(i, i));
-      printfs("/%1\n", as_string(total_sep));
+  printfs("/%1\n", as_string(total_separation));
       prints(".ie \\n[" SEPARATION_FACTOR_REG "]<=0 \\{"
             ".tm warning: page \\n%: column separation set to zero\n"
             ".nr " SEPARATION_FACTOR_REG " 0\n"
             ".\\}\n"
             ".el .if \\n[" SEPARATION_FACTOR_REG "]<1n "
             ".tm warning: page \\n%: table squeezed horizontally to fit line 
length\n");
-    }
-  }
 }
 
 void table::compute_column_positions()
@@ -2190,30 +2210,47 @@
   // This function might increase the width of some columns, too.
   for (p = span_list; p; p = p->next)
     divide_span(p->start_col, p->end_col);
+  compute_total_separation();
   for (p = span_list; p; p = p->next)
-    sum_columns(p->start_col, p->end_col);
-  // Now handle blocks.
-  compute_available_block_width();
+    sum_columns(p->start_col, p->end_col, 0);
+  // Now handle unexpanded blocks.
   int had_spanning_block = 0;
   int had_equal_block = 0;
   for (q = entry_list; q; q = q->next)
     if (q->divert(ncolumns, minimum_width,
-                 (flags & EXPAND) ? column_separation : 0)) {
+                 (flags & EXPAND) ? column_separation : 0, 0)) {
       if (q->end_col > q->start_col)
        had_spanning_block = 1;
       for (i = q->start_col; i <= q->end_col && !had_equal_block; i++)
        if (equal[i])
          had_equal_block = 1;
     }
-  // Second pass.
+  // Adjust widths.
   if (had_equal_block)
     make_columns_equal();
   if (had_spanning_block)
     for (p = span_list; p; p = p->next)
       divide_span(p->start_col, p->end_col);
+  compute_expand_width();
+  if ((flags & EXPAND) && total_separation != 0) {
   compute_separation_factor();
   for (p = span_list; p; p = p->next)
-    sum_columns(p->start_col, p->end_col);
+      sum_columns(p->start_col, p->end_col, 0);
+  }
+  else {
+    // Handle expanded blocks.
+    for (p = span_list; p; p = p->next)
+      sum_columns(p->start_col, p->end_col, 1);
+    for (q = entry_list; q; q = q->next)
+      if (q->divert(ncolumns, minimum_width, 0, 1)) {
+       if (q->end_col > q->start_col)
+         had_spanning_block = 1;
+      }
+    // Adjust widths again.
+    if (had_spanning_block)
+      for (p = span_list; p; p = p->next)
+       divide_span(p->start_col, p->end_col);
+  }
   compute_column_positions();
 }
 

Index: src/preproc/tbl/table.h
===================================================================
RCS file: /cvsroot/groff/groff/src/preproc/tbl/table.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- src/preproc/tbl/table.h     18 Oct 2008 04:43:34 -0000      1.13
+++ src/preproc/tbl/table.h     16 Nov 2008 17:22:21 -0000      1.14
@@ -102,15 +102,17 @@
   char *equal;
   int left_separation;
   int right_separation;
+  int total_separation;
   int allocated_rows;
   void build_span_list();
-  void compute_available_block_width();
+  void compute_expand_width();
   void do_hspan(int r, int c);
   void do_vspan(int r, int c);
   void allocate(int r);
   void compute_widths();
   void divide_span(int, int);
-  void sum_columns(int, int);
+  void sum_columns(int, int, int);
+  void compute_total_separation();
   void compute_separation_factor();
   void compute_column_positions();
   void do_row(int);
@@ -129,9 +131,8 @@
   void compute_vrule_top_adjust(int, int, string &);
   void compute_vrule_bot_adjust(int, int, string &);
   void determine_row_type();
-  int count_block_columns();
+  int count_expand_columns();
 public:
-  char *blockflag;
   unsigned flags;
   enum {
     CENTER       = 0x00000001,
@@ -143,6 +144,7 @@
     NOSPACES     = 0x00000040,
     EXPERIMENTAL = 0x80000000  // undocumented; use as a hook for experiments
     };
+  char *expand;
   table(int nc, unsigned flags, int linesize, char decimal_point_char);
   ~table();
 
@@ -157,6 +159,7 @@
   void set_minimum_width(int c, const string &w);
   void set_column_separation(int c, int n);
   void set_equal_column(int c);
+  void set_expand_column(int c);
   void set_delim(char c1, char c2);
   void print_single_hline(int r);
   void print_double_hline(int r);

Index: src/preproc/tbl/tbl.man
===================================================================
RCS file: /cvsroot/groff/groff/src/preproc/tbl/tbl.man,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -b -r1.24 -r1.25
--- src/preproc/tbl/tbl.man     8 Nov 2008 07:50:37 -0000       1.24
+++ src/preproc/tbl/tbl.man     16 Nov 2008 17:22:21 -0000      1.25
@@ -1,3 +1,4 @@
+'\" t
 .ig
 Copyright (C) 1989-1995, 2001, 2002, 2003, 2004, 2006, 2007, 2008
   Free Software Foundation, Inc.
@@ -82,6 +83,9 @@
 (table start) and
 .B .TE
 (table end) macros.
+.
+.
+.SS Global options
 The line immediately following the
 .B .TS
 macro may contain any of the following global options (ignoring the case of
@@ -129,6 +133,9 @@
 .B expand
 Make the table as wide as the current line length (providing a column
 separation factor).
+Ignored if one or more `x' column specifiers are used (see below).
+.
+.IP
 In case the sum of the column widths is larger than the current line length,
 the column separation factor is set to zero; such tables extend into the
 right margin, and there is no column separation at all.
@@ -150,7 +157,7 @@
 Don't use diversions to prevent page breaks (GNU tbl only).
 Normally
 .B tbl
-attempts to prevent undesirable breaks in the table by using diversions.
+attempts to prevent undesirable breaks in boxed tables by using diversions.
 This can sometimes interact badly with macro packages' own use of
 diversions, when footnotes, for example, are used.
 .
@@ -168,16 +175,17 @@
 The global options must end with a semicolon.
 There might be whitespace between an option and its argument in parentheses.
 .
-.LP
+.
+.SS Table format specification
 After global options come lines describing the format of each line of
 the table.
 Each such format line describes one line of the table itself, except that
 the last format line (which you must end with a period) describes all
 remaining lines of the table.
-A single key character describes each column of each line of the table.
+A single-key character describes each column of each line of the table.
 Key characters can be separated by spaces or tabs.
-You may run format specs for multiple lines together on the same line by
-separating them with commas.
+You may run format specifications for multiple lines together on the same
+line by separating them with commas.
 .
 .LP
 You may follow each key character with specifiers that determine the font
@@ -198,6 +206,50 @@
 .BR a , A
 Center longest line in this column and then left-justifies all other lines
 in this column with respect to that centered line.
+The idea is to use such alphabetic subcolumns (hence the name of the key
+character) in combination with\~
+.BR L ;
+they are called subcolumns because
+.BR A \~items
+are indented by\~1n relative to
+.BR L \~entries.
+Example:
+.RS
+.IP
+.EX
+\&.TS
+\&tab(;);
+\&ln,an.
+\&item one;1
+\&subitem two;2
+\&subitem three;3
+\&.T&
+\&ln,an.
+\&item eleven;11
+\&subitem twentytwo;22
+\&subitem thirtythree;33
+\&.TE
+.EE
+.RE
+.
+.IP
+Result:
+.
+.RS
+.IP
+.TS
+tab(;);
+ln,an.
+item one;1
+subitem two;2
+subitem three;3
+.T&
+ln,an.
+item eleven;11
+subitem twentytwo;22
+subitem thirtythree;33
+.TE
+.RE
 .
 .TP
 .BR c , C
@@ -211,6 +263,80 @@
 .BR n , N
 Numerically justify item in the column: Units positions of numbers are
 aligned vertically.
+If there is one or more dots adjacent to a digit, use the rightmost one for
+vertical alignment.
+If there is no dot, use the rightmost digit for vertical alignment;
+otherwise, center the item within the column.
+Alignment can be forced to a certain position using `\[rs]&'; if there is
+one or more instances of this special (non-printing) character present
+within the data, use the leftmost one for alignment.
+Example:
+.RS
+.IP
+.EX
+\&.TS
+\&n.
+\&1
+\&1.5
+\&1.5.3
+\&abcde
+\&a\[rs]&bcde
+\&.TE
+.EE
+.RE
+.
+.IP
+Result:
+.
+.RS
+.IP
+.TS
+n.
+1
+1.5
+1.5.3
+abcde
+a\&bcde
+.TE
+.RE
+.
+.IP
+If numerical entries are combined with
+.B L
+or
+.BR R \~entries
+\[en] this can happen if the table format is changed with
+.B .T&
+\%\[en],
+center the widest
+.I number
+(of the data entered under the
+.BR N \~specifier
+regime) relative to the widest
+.B L
+or
+.BR R \~entry,
+preserving the alignment of all numerical entries.
+Contrary to
+.BR A \~type
+entries, there is no extra indentation.
+.
+.IP
+Using equations (to be processed with
+.BR eqn )
+within columns which use the
+.BR N \~specifier
+is problematic in most cases due to
+.BR tbl 's
+algorithm for finding the vertical alignment, as described above.
+Using the global
+.B delim
+option, however, it is possible to make
+.B tbl
+ignore the data within
+.B eqn
+delimiters for that purpose.
+.
 .
 .TP
 .BR r , R
@@ -219,10 +345,12 @@
 .TP
 .BR s , S
 Span previous item on the left into this column.
+Not allowed for the first column.
 .
 .TP
 .B ^
 Span down entry from previous row in this column.
+Not allowed for the first row.
 .
 .TP
 .BR _ , -
@@ -239,11 +367,22 @@
 adjacent, a double vertical rule).
 .
 .LP
-A vertical bar to the left of the first key-letter or to the right of the
+A vertical bar to the left of the first key letter or to the right of the
 last one produces a line at the edge of the table.
 .
 .LP
-Here are the specifiers that can appear in suffixes to column key letters:
+To change the data format within a table, use the
+.B .T&
+command (at the start of a line).
+It is followed by format and data lines (but no global options) similar to
+the
+.B .TS
+request.
+.
+.
+.SS Column specifiers
+Here are the specifiers that can appear in suffixes to column key letters
+(in any order):
 .
 .TP
 .BR b , B
@@ -259,6 +398,7 @@
 .TP
 .BR e , E
 Make equally-spaced columns.
+All columns marked with this specifier get the same width.
 .
 .TP
 .BR f , F
@@ -340,6 +480,17 @@
 the last entry takes effect.
 .
 .TP
+.BR x , X
+An expanded column.
+After computing all column widths without an
+.BR x \~specifier,
+use the remaining line width for this column.
+If there is more than one expanded column, distribute the remaining
+horizontal space evenly among the affected columns (this is a GNU
+extension).
+This feature has the same effect as specifying a minimum column width.
+.
+.TP
 .BR z , Z
 Ignore the corresponding column for width-calculation purposes, this is,
 don't use the fields but only the specifiers of this column to compute
@@ -353,6 +504,16 @@
 Default separation is 3n.
 .
 .LP
+The column specifiers
+.BR e ,
+.BR w ,
+and
+.B x
+are mutually exclusive; if specified multiple times for a particular column,
+the last entry takes effect.
+.
+.
+.SS Table data
 The format lines are followed by lines containing the actual data for the
 table, followed finally by
 .BR .TE .
@@ -370,44 +531,36 @@
 which isn't a text block.
 As a consequence, constructions like
 .IP
-.B .TS
-.br
-.B c,l.
-.br
-.B \[rs]s[20]MM
-.br
-.B MMMM
-.br
-.B .TE
-.br
+.EX
+\&.TS
+\&c,l.
+\&\[rs]s[20]MM
+\&MMMM
+\&.TE
+.EE
 .
 .LP
 fail; you must either say
 .IP
-.B .TS
-.br
-.B cp20,lp20.
-.br
-.B MM
-.br
-.B MMMM
-.br
-.B .TE
-.br
+.EX
+\&.TS
+\&cp20,lp20.
+\&MM
+\&MMMM
+\&.TE
+.EE
 .
 .LP
 or
+.
 .IP
-.B .TS
-.br
-.B c,l.
-.br
-.B \[rs]s[20]MM
-.br
-.B \[rs]s[20]MMMM
-.br
-.B .TE
-.br
+.EX
+\&.TS
+\&c,l.
+\&\[rs]s[20]MM
+\&\[rs]s[20]MMMM
+\&.TE
+.EE
 .
 .LP
 A dot starting a line, followed by anything but a digit is handled as a
@@ -432,7 +585,8 @@
 A data item consisting only of `\[rs]^' indicates that the field immediately
 above spans downward over this row.
 .
-.LP
+.
+.SS Text blocks
 A text block can be used to enter data as a single entry which would be
 too long as a simple string between tabs.
 It is started with `T{' and closed with `T}'.
@@ -441,6 +595,8 @@
 with the
 .B tab
 global option).
+.
+.LP
 By default, the text block is formatted with the settings which were
 active before entering the table, possibly overridden by the
 .BR m ,
@@ -455,25 +611,25 @@
 (and
 .B .ad
 after the table).
-If `w' specifiers are not given for all columns of a text block span, the
-default length of the text block (to be more precise, the line length used
-to process the text block diversion) is computed as L\[tmu]C/(N+1), where
-`L' is the current line length, `C' the number of columns spanned by the
-text block, and `N' the total number of columns in the table.
-Note, however, that the actual diversion width as given in register
+.
+.LP
+If either `w' or `x' specifiers are not given for
+.I all
+columns of a text block span, the default length of the text block (to be
+more precise, the line length used to process the text block diversion) is
+computed as L\[tmu]C/(N+1), where `L' is the current line length, `C' the
+number of columns spanned by the text block, and `N' the total number of
+columns in the table.
+Note, however, that the actual diversion width as returned in register
 .B \[rs]n[dl]
 is used eventually as the text block width.
+If necessary, you can also control the text block width with a direct
+insertion of a
+.B .ll
+request right after `T{'.
 .
-.LP
-To change the data format within a table, use the
-.B .T&
-command (at the start of a line).
-It is followed by format and data lines (but no global options) similar to
-the
-.B .TS
-request.
 .
-.LP
+.SS Miscellaneous
 The number register
 .B \[rs]n[TW]
 holds the table width; it can't be used within the table itself but is defined
@@ -540,29 +696,20 @@
 an `end-of-macro' macro.  Additionally, the escape character has to be switched
 off.  Here an example.
 .IP
-.B .eo
-.br
-.B .de ATABLE ..
-.br
-.B .TS
-.br
-.B allbox tab(;);
-.br
-.B cl.
-.br
-.B \[rs]$1;\[rs]$2
-.br
-.B .TE
-.br
-.B ...
-.br
-.B .ec
-.br
-.B .ATABLE A table
-.br
-.B .ATABLE Another table
-.br
-.B .ATABLE And \[dq]another one\[dq]
+.EX
+\&.eo
+\&.de ATABLE ..
+\&.TS
+\&allbox tab(;);
+\&cl.
+\&\[rs]$1;\[rs]$2
+\&.TE
+\&...
+\&.ec
+\&.ATABLE A table
+\&.ATABLE Another table
+\&.ATABLE And \[dq]another one\[dq]
+.EE
 .
 .LP
 Note, however, that not all features of
@@ -602,15 +749,14 @@
 Instead, define
 .B BP
 as follows
+.
 .IP
-.B .de BP
-.br
-.B .ie '\[rs]\[rs]n(.z'' .bp \[rs]\[rs]$1
-.br
-.B .el \[rs]!.BP \[rs]\[rs]$1
-.br
-.B ..
-.br
+.EX
+\&.de BP
+\&.  ie '\[rs]\[rs]n(.z'' .bp \[rs]\[rs]$1
+\&.  el \[rs]!.BP \[rs]\[rs]$1
+\&..
+.EE
 .
 .LP
 and use
@@ -626,17 +772,16 @@
 leader.
 To get leaders use a real leader, either by using a control A or like
 this:
+.
 .IP
-.nf
-.ft B
+.EX
 \&.ds a \[rs]a
 \&.TS
-tab(;);
-lw(1i) l.
-A\[rs]*a;B
+\&tab(;);
+\&lw(1i) l.
+\&A\[rs]*a;B
 \&.TE
-.ft
-.fi
+.EE
 .
 .
 .SH REFERENCE




reply via email to

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