function drush_table_column_autowidth

8.0.x output.inc drush_table_column_autowidth($rows, $widths)
6.x output.inc drush_table_column_autowidth($rows, $widths)
7.x output.inc drush_table_column_autowidth($rows, $widths)
3.x drush.inc drush_table_column_autowidth($rows, $widths)
4.x drush.inc drush_table_column_autowidth($rows, $widths)
5.x output.inc drush_table_column_autowidth($rows, $widths)
master output.inc drush_table_column_autowidth($rows, $widths)

Determine the best fit for column widths.

Parameters

$rows: The rows to use for calculations.

$widths: Manually specified widths of each column (in characters) - these will be left as is.

Related topics

1 call to drush_table_column_autowidth()

File

includes/output.inc, line 615

Code

function drush_table_column_autowidth($rows, $widths) {
  $auto_widths = $widths;

  // First we determine the distribution of row lengths in each column.
  // This is an array of descending character length keys (i.e. starting at
  // the rightmost character column), with the value indicating the number
  // of rows where that character column is present.
  $col_dist = array();
  foreach ($rows as $rowkey => $row) {
    foreach ($row as $col_id => $cell) {
      if (empty($widths[$col_id])) {
        $length = strlen($cell);
        if ($length == 0) {
          $col_dist[$col_id][0] = 0;
        }
        while ($length > 0) {
          if (!isset($col_dist[$col_id][$length])) {
            $col_dist[$col_id][$length] = 0;
          }
          $col_dist[$col_id][$length]++;
          $length--;
        }
      }
    }
  }
  foreach ($col_dist as $col_id => $count) {
    // Sort the distribution in decending key order.
    krsort($col_dist[$col_id]);
    // Initially we set all columns to their "ideal" longest width
    // - i.e. the width of their longest column.
    $auto_widths[$col_id] = max(array_keys($col_dist[$col_id]));
  }

  // We determine what width we have available to use, and what width the
  // above "ideal" columns take up.
  $available_width = drush_get_context('DRUSH_COLUMNS', 80) - (count($auto_widths) * 2);
  $auto_width_current = array_sum($auto_widths);

  // If we need to reduce a column so that we can fit the space we use this
  // loop to figure out which column will cause the "least wrapping",
  // (relative to the other columns) and reduce the width of that column.
  while ($auto_width_current > $available_width) {
    $count = 0;
    $width = 0;
    foreach ($col_dist as $col_id => $counts) {
      // If we are just starting out, select the first column.
      if ($count == 0 || 
      // OR: if this column would cause less wrapping than the currently
      // selected column, then select it.
      (current($counts) < $count) || 
      // OR: if this column would cause the same amount of wrapping, but is
      // longer, then we choose to wrap the longer column (proportionally
      // less wrapping, and helps avoid triple line wraps).
      (current($counts) == $count && key($counts) > $width)) {
        // Select the column number, and record the count and current width
        // for later comparisons.
        $column = $col_id;
        $count = current($counts);
        $width = key($counts);
      }
    }
    if ($width <= 1) {
      // If we have reached a width of 1 then give up, so wordwrap can still progress.
      break;
    }
    // Reduce the width of the selected column.
    $auto_widths[$column]--;
    // Reduce our overall table width counter.
    $auto_width_current--;
    // Remove the corresponding data from the disctribution, so next time
    // around we use the data for the row to the left.
    unset($col_dist[$column][$width]);
  }
  return $auto_widths;
}