⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 table.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 5 页
字号:
	    e = new numeric_text_entry(s, f, pos);	}      }      else	e = new empty_entry(f);      break;    case FORMAT_ALPHABETIC:      if (!str.empty()) {	s = str.extract();	if (is_block)	  e = new alphabetic_block_entry(s, f);	else	  e = new alphabetic_text_entry(s, f);      }      else	e = new empty_entry(f);      break;    case FORMAT_VSPAN:      do_vspan(r, c);      break;    case FORMAT_HLINE:      if (str.length() != 0)	error_with_file_and_line(fn, ln,				 "non-empty data entry for `_' format ignored");      e = new single_line_entry(f);      break;    case FORMAT_DOUBLE_HLINE:      if (str.length() != 0)	error_with_file_and_line(fn, ln,				 "non-empty data entry for `=' format ignored");      e = new double_line_entry(f);      break;    default:      assert(0);    }  }  if (e) {    table_entry *preve = entry[r][c];    if (preve) {      /* c s         ^ l */      error_with_file_and_line(fn, ln, "row %1, column %2 already spanned",			       r + 1, c + 1);      delete e;    }    else {      e->input_lineno = ln;      e->input_filename = fn;      e->start_row = e->end_row = r;      e->start_col = e->end_col = c;      for (table_entry **p = &entry_list; *p; p = &(*p)->next)	;      *p = e;      entry[r][c] = e;    }  }}// add vertical lines for row rvoid table::add_vlines(int r, const char *v){  allocate(r);  for (int i = 0; i < ncolumns+1; i++)    vline[r][i] = v[i];}void table::check(){  table_entry *p = entry_list;  int i, j;  while (p) {    for (i = p->start_row; i <= p->end_row; i++)      for (j = p->start_col; j <= p->end_col; j++)	assert(entry[i][j] == p);    p = p->next;  }}void table::print(){  location_force_filename = 1;  check();  init_output();  determine_row_type();  compute_widths();  if (!(flags & CENTER))    prints(".if \\n[" SAVED_CENTER_REG "] \\{");  prints(".in +(u;\\n[.l]-\\n[.i]-\\n[TW]/2)\n"	 ".nr " SAVED_INDENT_REG " \\n[.i]\n");  if (!(flags & CENTER))    prints(".\\}\n");  build_vrule_list();  define_bottom_macro();  do_top();  for (int i = 0; i < nrows; i++)    do_row(i);  do_bottom();}void table::determine_row_type(){  row_is_all_lines = new char[nrows];  for (int i = 0; i < nrows; i++) {    int had_single = 0;    int had_double = 0;    int had_non_line = 0;    for (int c = 0; c < ncolumns; c++) {      table_entry *e = entry[i][c];      if (e != 0) {	if (e->start_row == e->end_row) {	  int t = e->line_type();	  switch (t) {	  case -1:	    had_non_line = 1;	    break;	  case 0:	    // empty	    break;	  case 1:	    had_single = 1;	    break;	  case 2:	    had_double = 1;	    break;	  default:	    assert(0);	  }	  if (had_non_line)	    break;	}	c = e->end_col;      }    }    if (had_non_line)      row_is_all_lines[i] = 0;    else if (had_double)      row_is_all_lines[i] = 2;    else if (had_single)      row_is_all_lines[i] = 1;    else      row_is_all_lines[i] = 0;  }}void table::init_output(){  prints(".nr " COMPATIBLE_REG " \\n(.C\n"	 ".cp 0\n");  if (linesize > 0)    printfs(".nr " LINESIZE_REG " %1\n", as_string(linesize));  else    prints(".nr " LINESIZE_REG " \\n[.s]\n");  if (!(flags & CENTER))    prints(".nr " SAVED_CENTER_REG " \\n[.ce]\n");  prints(".de " RESET_MACRO_NAME "\n"	 ".ft \\n[.f]\n"	 ".ps \\n[.s]\n"	 ".vs \\n[.v]u\n"	 ".in \\n[.i]u\n"	 ".ll \\n[.l]u\n"	 ".ls \\n[.L]\n"	 ".ad \\n[.j]\n"	 ".ie \\n[.u] .fi\n"	 ".el .nf\n"	 ".ce \\n[.ce]\n"	 "..\n"	 ".nr " SAVED_INDENT_REG " \\n[.i]\n"	 ".nr " SAVED_FONT_REG " \\n[.f]\n"	 ".nr " SAVED_SIZE_REG " \\n[.s]\n"	 ".nr " SAVED_FILL_REG " \\n[.u]\n"	 ".nr T. 0\n"	 ".nr " CURRENT_ROW_REG " 0-1\n"	 ".nr " LAST_PASSED_ROW_REG " 0-1\n"	 ".nr " SECTION_DIVERSION_FLAG_REG " 0\n"	 ".ds " TRANSPARENT_STRING_NAME "\n"	 ".ds " QUOTE_STRING_NAME "\n"	 ".nr " NEED_BOTTOM_RULE_REG " 1\n"	 ".nr " SUPPRESS_BOTTOM_REG " 0\n"	 ".eo\n"	 ".de " REPEATED_MARK_MACRO "\n"	 ".mk \\$1\n"	 ".if !'\\n(.z'' \\!." REPEATED_MARK_MACRO " \"\\$1\"\n"	 "..\n"	 ".de " REPEATED_VPT_MACRO "\n"	 ".vpt \\$1\n"	 ".if !'\\n(.z'' \\!." REPEATED_VPT_MACRO " \"\\$1\"\n"	 "..\n");  if (!(flags & NOKEEP))    prints(".de " KEEP_MACRO_NAME "\n"	   ".if '\\n[.z]'' \\{.ds " QUOTE_STRING_NAME " \\\\\n"	   ".ds " TRANSPARENT_STRING_NAME " \\!\n"	   ".di " SECTION_DIVERSION_NAME "\n"	   ".nr " SECTION_DIVERSION_FLAG_REG " 1\n"	   ".in 0\n"	   ".\\}\n"	   "..\n"	   ".de " RELEASE_MACRO_NAME "\n"	   ".if \\n[" SECTION_DIVERSION_FLAG_REG "] \\{"	   ".di\n"	   ".in \\n[" SAVED_INDENT_REG "]u\n"	   ".nr " SAVED_DN_REG " \\n[dn]\n"	   ".ds " QUOTE_STRING_NAME "\n"	   ".ds " TRANSPARENT_STRING_NAME "\n"	   ".nr " SECTION_DIVERSION_FLAG_REG " 0\n"	   ".if \\n[.t]<=\\n[dn] \\{"	   ".nr T. 1\n"	   ".T#\n"	   ".nr " SUPPRESS_BOTTOM_REG " 1\n"	   ".sp \\n[.t]u\n"	   ".nr " SUPPRESS_BOTTOM_REG " 0\n"	   ".mk #T\n"	   ".\\}\n"	   ".if \\n[.t]<=\\n[" SAVED_DN_REG "] "	   /* Since we turn off traps, it won't get into an infinite loop	   when we try and print it; it will just go off the bottom of the	   page. */	   ".tm warning: page \\n%: table text block will not fit on one page\n"	   ".nf\n"	   ".ls 1\n"	   "." SECTION_DIVERSION_NAME "\n"	   ".ls\n"	   ".rm " SECTION_DIVERSION_NAME "\n"	   ".\\}\n"	   "..\n"	   ".nr " TABLE_DIVERSION_FLAG_REG " 0\n"	   ".de " TABLE_KEEP_MACRO_NAME "\n"	   ".if '\\n[.z]'' \\{"	   ".di " TABLE_DIVERSION_NAME "\n"	   ".nr " TABLE_DIVERSION_FLAG_REG " 1\n"	   ".\\}\n"	   "..\n"	   ".de " TABLE_RELEASE_MACRO_NAME "\n"	   ".if \\n[" TABLE_DIVERSION_FLAG_REG "] \\{.br\n"	   ".di\n"	   ".nr " SAVED_DN_REG " \\n[dn]\n"	   ".ne \\n[dn]u+\\n[.V]u\n"	   ".ie \\n[.t]<=\\n[" SAVED_DN_REG "] "	   ".tm error: page \\n%: table will not fit on one page; use .TS H/.TH with a supporting macro package\n"	   ".el \\{"	   ".in 0\n"	   ".ls 1\n"	   ".nf\n"	   "." TABLE_DIVERSION_NAME "\n"	   ".\\}\n"	   ".rm " TABLE_DIVERSION_NAME "\n"	   ".\\}\n"	   "..\n");  prints(".ec\n"	 ".ce 0\n"	 ".nf\n");}string block_width_reg(int r, int c){  static char name[sizeof(BLOCK_WIDTH_PREFIX)+INT_DIGITS+1+INT_DIGITS];  sprintf(name, BLOCK_WIDTH_PREFIX "%d,%d", r, c);  return string(name);}string block_diversion_name(int r, int c){  static char name[sizeof(BLOCK_DIVERSION_PREFIX)+INT_DIGITS+1+INT_DIGITS];  sprintf(name, BLOCK_DIVERSION_PREFIX "%d,%d", r, c);  return string(name);}string block_height_reg(int r, int c){  static char name[sizeof(BLOCK_HEIGHT_PREFIX)+INT_DIGITS+1+INT_DIGITS];  sprintf(name, BLOCK_HEIGHT_PREFIX "%d,%d", r, c);  return string(name);}string span_width_reg(int start_col, int end_col){  static char name[sizeof(SPAN_WIDTH_PREFIX)+INT_DIGITS+1+INT_DIGITS];  sprintf(name, SPAN_WIDTH_PREFIX "%d", start_col);  if (end_col != start_col)    sprintf(strchr(name, '\0'), ",%d", end_col);  return string(name);}string span_left_numeric_width_reg(int start_col, int end_col){  static char name[sizeof(SPAN_LEFT_NUMERIC_WIDTH_PREFIX)+INT_DIGITS+1+INT_DIGITS];  sprintf(name, SPAN_LEFT_NUMERIC_WIDTH_PREFIX "%d", start_col);  if (end_col != start_col)    sprintf(strchr(name, '\0'), ",%d", end_col);  return string(name);}string span_right_numeric_width_reg(int start_col, int end_col){  static char name[sizeof(SPAN_RIGHT_NUMERIC_WIDTH_PREFIX)+INT_DIGITS+1+INT_DIGITS];  sprintf(name, SPAN_RIGHT_NUMERIC_WIDTH_PREFIX "%d", start_col);  if (end_col != start_col)    sprintf(strchr(name, '\0'), ",%d", end_col);  return string(name);}string span_alphabetic_width_reg(int start_col, int end_col){  static char name[sizeof(SPAN_ALPHABETIC_WIDTH_PREFIX)+INT_DIGITS+1+INT_DIGITS];  sprintf(name, SPAN_ALPHABETIC_WIDTH_PREFIX "%d", start_col);  if (end_col != start_col)    sprintf(strchr(name, '\0'), ",%d", end_col);  return string(name);}string column_separation_reg(int col){  static char name[sizeof(COLUMN_SEPARATION_PREFIX)+INT_DIGITS];  sprintf(name, COLUMN_SEPARATION_PREFIX "%d", col);  return string(name);}string row_start_reg(int row){  static char name[sizeof(ROW_START_PREFIX)+INT_DIGITS];  sprintf(name, ROW_START_PREFIX "%d", row);  return string(name);}  string column_start_reg(int col){  static char name[sizeof(COLUMN_START_PREFIX)+INT_DIGITS];  sprintf(name, COLUMN_START_PREFIX "%d", col);  return string(name);}  string column_end_reg(int col){  static char name[sizeof(COLUMN_END_PREFIX)+INT_DIGITS];  sprintf(name, COLUMN_END_PREFIX "%d", col);  return string(name);}string column_divide_reg(int col){  static char name[sizeof(COLUMN_DIVIDE_PREFIX)+INT_DIGITS];  sprintf(name, COLUMN_DIVIDE_PREFIX "%d", col);  return string(name);}string row_top_reg(int row){  static char name[sizeof(ROW_TOP_PREFIX)+INT_DIGITS];  sprintf(name, ROW_TOP_PREFIX "%d", row);  return string(name);}void init_span_reg(int start_col, int end_col){  printfs(".nr %1 \\n(.H\n.nr %2 0\n.nr %3 0\n.nr %4 0\n",	  span_width_reg(start_col, end_col),	  span_alphabetic_width_reg(start_col, end_col),	  span_left_numeric_width_reg(start_col, end_col),	  span_right_numeric_width_reg(start_col, end_col));}void compute_span_width(int start_col, int end_col){  printfs(".nr %1 \\n[%1]>?(\\n[%2]+\\n[%3])\n"	  ".if \\n[%4] .nr %1 \\n[%1]>?(\\n[%4]+2n)\n", 	  span_width_reg(start_col, end_col),	  span_left_numeric_width_reg(start_col, end_col),	  span_right_numeric_width_reg(start_col, end_col),	  span_alphabetic_width_reg(start_col, end_col));	 }// Increase the widths of columns so that the width of any spanning entry// is no greater than the sum of the widths of the columns that it spans.// Ensure that the widths of columns remain equal.void table::divide_span(int start_col, int end_col){  assert(end_col > start_col);  printfs(".nr " NEEDED_REG " \\n[%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++) {    // The column separation may shrink with the expand option.    if (!(flags & EXPAND))      printfs("+%1n", as_string(column_separation[i - 1]));    printfs("+\\n[%1]", span_width_reg(i, i));  }  prints(")\n");  printfs(".nr " NEEDED_REG " \\n[" NEEDED_REG "]/%1\n",	  as_string(end_col - start_col + 1));  prints(".if \\n[" NEEDED_REG "] \\{");  for (i = start_col; i <= end_col; i++)    printfs(".nr %1 +\\n[" NEEDED_REG "]\n", 	    span_width_reg(i, i));  int equal_flag = 0;  for (i = start_col; i <= end_col && !equal_flag; i++)    if (equal[i])      equal_flag = 1;  if (equal_flag) {    for (i = 0; i < ncolumns; i++)      if (i < start_col || i > end_col)	printfs(".nr %1 +\\n[" NEEDED_REG "]\n", 	    span_width_reg(i, i));  }  prints(".\\}\n");}void table::sum_columns(int start_col, int end_col){  assert(end_col > start_col);  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++)    printfs("+(%1*\\n[" SEPARATION_FACTOR_REG "])+\\n[%2]",	    as_string(column_separation[i - 1]),	    span_width_reg(i, i));  prints('\n');}horizontal_span::horizontal_span(int sc, int ec, horizontal_span *p): start_col(sc), end_col(ec), next(p){}void table::build_span_list(){  span_list = 0;  table_entry *p = entry_list;  while (p) {    if (p->end_col != p->start_col) {      for (horizontal_span *q = span_list; q; q = q->next)	if (q->start_col == p->start_col	    && q->end_col == p->end_col)	  break;      if (!q)	span_list = new horizontal_span(p->start_col, p->end_col, span_list);    }    p = p->next;  }  // Now sort span_list primarily by order of end_row, and secondarily  // by reverse order of start_row. This ensures that if we divide  // spans using the order in span_list, we will get reasonable results.  horizontal_span *unsorted = span_list;  span_list = 0;  while (unsorted) {    for (horizontal_span **pp = &span_list; *pp; pp = &(*pp)->next)      if (unsorted->end_col < (*pp)->end_col	  || (unsorted->end_col == (*pp)->end_col	      && (unsorted->start_col > (*pp)->start_col)))	break;    horizontal_span *tem = unsorted->next;    unsorted->next = *pp;    *pp = unsorted;    unsorted = tem;  }}void table::compute_separation_factor(){  if (flags & (ALLBOX|BOX|DOUBLEBOX))    left_separation = right_separation = 1;  else {    for (int i = 0; i < nrows; i++) {      if (vline[i][0] > 0)	left_separation = 1;      if (vline[i][ncolumns] > 0)	right_separation = 1;    }  }  if (flags & EXPAND) {    int total_sep = left_separation + right_separation;    for (int i = 0; i < ncolumns - 1; i++)      total_sep += column_separation[i];    if (total_sep != 0) {      // Don't let the separation factor be negative.      prints(".nr " SEPARATION_FACTOR_REG " \\n[.l]-\\n[.i]");      for (i = 0; i < ncolumns; i++)	printfs("-\\n[%1]", span_width_reg(i, i));      printfs("/%1>?0\n", as_string(total_sep));    }  }}void table::compute_column_positions(){  printfs(".nr %1 0\n", column_divide_reg(0));  printfs(".nr %1 %2*\\n[" SEPARATION_FACTOR_REG "]\n",	  column_start_reg(0),	  as_string(left_separation));  for (int i = 1;; i++) {    printfs(".nr %1 \\n[%2]+\\n[%3]\n",	    column_end_reg(i-1),	    column_start_reg(i-1),	    span_width_reg(i-1, i-1));    if (i >= ncolumns)      break;    printfs(".nr %1 \\n[%2]+(%3*\\n[" SEPARATION_FACTOR_REG "])\n",	    column_start_reg(i),	    column_end_reg(i-1),	    as_string(column_separation[i-1]));    printfs(".nr %1 \\n[%2]+\\n[%3]/2\n",	    column_divide_reg(i),	    column_end_reg(i-1),	    column_start_reg(i));  }  printfs(".nr %1 \\n[%2]+(%3*\\n[" SEPARATION_FACTOR_REG "])\n",	  column_divide_reg(ncolumns),	  column_end_reg(i-1),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -