+ /* Print the data cells. */
+
+ more = 0;
+ if (horiz) {
+ tbl_hrule(tp, sp, 0);
+ term_flushln(tp);
+ } else {
+ cp = sp->layout->first;
+ cpn = sp->next == NULL ? NULL :
+ sp->next->layout->first;
+ cpp = sp->prev == NULL ? NULL :
+ sp->prev->layout->first;
+ dp = sp->first;
+ spans = 0;
+ for (ic = 0; ic < sp->opts->cols; ic++) {
+
+ /*
+ * Figure out whether to print a
+ * vertical line after this cell
+ * and advance to next layout cell.
+ */
+
+ if (cp != NULL) {
+ vert = cp->vert;
+ switch (cp->pos) {
+ case TBL_CELL_HORIZ:
+ fc = '-';
+ break;
+ case TBL_CELL_DHORIZ:
+ fc = '=';
+ break;
+ default:
+ fc = ' ';
+ break;
+ }
+ } else {
+ vert = 0;
+ fc = ' ';
+ }
+ if (cpp != NULL) {
+ if (vert == 0 &&
+ cp != NULL &&
+ ((IS_HORIZ(cp) &&
+ !IS_HORIZ(cpp)) ||
+ (cp->next != NULL &&
+ cpp->next != NULL &&
+ IS_HORIZ(cp->next) &&
+ !IS_HORIZ(cpp->next))))
+ vert = cpp->vert;
+ cpp = cpp->next;
+ }
+ if (vert == 0 &&
+ sp->opts->opts & TBL_OPT_ALLBOX)
+ vert = 1;
+ if (cpn != NULL) {
+ if (vert == 0)
+ vert = cpn->vert;
+ cpn = cpn->next;
+ }
+ if (cp != NULL)
+ cp = cp->next;
+
+ /*
+ * Skip later cells in a span,
+ * figure out whether to start a span,
+ * and advance to next data cell.
+ */
+
+ if (spans) {
+ spans--;
+ continue;
+ }
+ if (dp != NULL) {
+ spans = dp->spans;
+ if (ic || sp->layout->first->pos
+ != TBL_CELL_SPAN)
+ dp = dp->next;
+ }
+
+ /*
+ * Print one line of text in the cell
+ * and remember whether there is more.
+ */
+
+ tp->tcol++;
+ if (tp->tcol->col < tp->tcol->lastcol)
+ term_flushln(tp);
+ if (tp->tcol->col < tp->tcol->lastcol)
+ more = 1;
+
+ /*
+ * Vertical frames between data cells,
+ * but not after the last column.
+ */
+
+ if (fc == ' ' && ((vert == 0 &&
+ (cp == NULL || !IS_HORIZ(cp))) ||
+ tp->tcol + 1 == tp->tcols + tp->lasttcol))
+ continue;
+
+ if (tp->viscol < tp->tcol->rmargin) {
+ (*tp->advance)(tp, tp->tcol->rmargin
+ - tp->viscol);
+ tp->viscol = tp->tcol->rmargin;
+ }
+ while (tp->viscol < tp->tcol->rmargin +
+ tp->tbl.cols[ic].spacing / 2) {
+ (*tp->letter)(tp, fc);
+ tp->viscol++;
+ }
+
+ if (tp->tcol + 1 == tp->tcols + tp->lasttcol)
+ continue;
+
+ if (fc == ' ' && cp != NULL) {
+ switch (cp->pos) {
+ case TBL_CELL_HORIZ:
+ fc = '-';
+ break;
+ case TBL_CELL_DHORIZ:
+ fc = '=';
+ break;
+ default:
+ break;
+ }
+ }
+ if (tp->tbl.cols[ic].spacing) {
+ (*tp->letter)(tp, fc == ' ' ? '|' :
+ vert ? '+' : fc);
+ tp->viscol++;
+ }
+
+ if (fc != ' ') {
+ if (cp != NULL &&
+ cp->pos == TBL_CELL_HORIZ)
+ fc = '-';
+ else if (cp != NULL &&
+ cp->pos == TBL_CELL_DHORIZ)
+ fc = '=';
+ else
+ fc = ' ';
+ }
+ if (tp->tbl.cols[ic].spacing > 2 &&
+ (vert > 1 || fc != ' ')) {
+ (*tp->letter)(tp, fc == ' ' ? '|' :
+ vert > 1 ? '+' : fc);
+ tp->viscol++;
+ }
+ }
+ }
+
+ /* Print the vertical frame at the end of each row. */
+
+ fc = '\0';
+ if ((sp->layout->last->vert &&
+ sp->layout->last->col + 1 == sp->opts->cols) ||
+ (sp->next != NULL &&
+ sp->next->layout->last->vert &&
+ sp->next->layout->last->col + 1 == sp->opts->cols) ||
+ (sp->prev != NULL &&
+ sp->prev->layout->last->vert &&
+ sp->prev->layout->last->col + 1 == sp->opts->cols &&
+ (horiz || (IS_HORIZ(sp->layout->last) &&
+ !IS_HORIZ(sp->prev->layout->last)))) ||
+ (sp->opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX)))
+ fc = horiz || IS_HORIZ(sp->layout->last) ? '+' : '|';
+ else if (horiz && sp->opts->rvert)
+ fc = '-';
+ if (fc != '\0') {
+ if (horiz == 0 && (IS_HORIZ(sp->layout->last) == 0 ||
+ sp->layout->last->col + 1 < sp->opts->cols)) {
+ tp->tcol++;
+ (*tp->advance)(tp,
+ tp->tcol->offset > tp->viscol ?
+ tp->tcol->offset - tp->viscol : 1);
+ }
+ (*tp->letter)(tp, fc);
+ }
+ (*tp->endline)(tp);
+ tp->viscol = 0;
+ } while (more);