예제 #1
0
void
term_tbl(struct termp *tp, const struct tbl_span *sp)
{
	const struct tbl_head	*hp;
	const struct tbl_dat	*dp;
	struct roffcol		*col;
	int			 spans;
	size_t			 rmargin, maxrmargin;

	rmargin = tp->rmargin;
	maxrmargin = tp->maxrmargin;

	tp->rmargin = tp->maxrmargin = TERM_MAXMARGIN;

	/* Inhibit printing of spaces: we do padding ourselves. */

	tp->flags |= TERMP_NONOSPACE;
	tp->flags |= TERMP_NOSPACE;

	/*
	 * The first time we're invoked for a given table block,
	 * calculate the table widths and decimal positions.
	 */

	if (TBL_SPAN_FIRST & sp->flags) {
		term_flushln(tp);

		tp->tbl.len = term_tbl_len;
		tp->tbl.slen = term_tbl_strlen;
		tp->tbl.arg = tp;

		tblcalc(&tp->tbl, sp);
	}

	/* Horizontal frame at the start of boxed tables. */

	if (TBL_SPAN_FIRST & sp->flags) {
		if (TBL_OPT_DBOX & sp->opts->opts)
			tbl_hframe(tp, sp, 1);
		if (TBL_OPT_DBOX & sp->opts->opts ||
		    TBL_OPT_BOX  & sp->opts->opts)
			tbl_hframe(tp, sp, 0);
	}

	/* Vertical frame at the start of each row. */

	if ((TBL_OPT_BOX | TBL_OPT_DBOX) & sp->opts->opts ||
	    sp->head->vert)
		term_word(tp, TBL_SPAN_HORIZ == sp->pos ||
		    TBL_SPAN_DHORIZ == sp->pos ? "+" : "|");

	/*
	 * Now print the actual data itself depending on the span type.
	 * Spanner spans get a horizontal rule; data spanners have their
	 * data printed by matching data to header.
	 */

	switch (sp->pos) {
	case TBL_SPAN_HORIZ:
		/* FALLTHROUGH */
	case TBL_SPAN_DHORIZ:
		tbl_hrule(tp, sp);
		break;
	case TBL_SPAN_DATA:
		/* Iterate over template headers. */
		dp = sp->first;
		spans = 0;
		for (hp = sp->head; hp; hp = hp->next) {

			/*
			 * If the current data header is invoked during
			 * a spanner ("spans" > 0), don't emit anything
			 * at all.
			 */

			if (--spans >= 0)
				continue;

			/* Separate columns. */

			if (NULL != hp->prev)
				tbl_vrule(tp, hp);

			col = &tp->tbl.cols[hp->ident];
			tbl_data(tp, sp->opts, dp, col);

			/*
			 * Go to the next data cell and assign the
			 * number of subsequent spans, if applicable.
			 */

			if (dp) {
				spans = dp->spans;
				dp = dp->next;
			}
		}
		break;
	}

	/* Vertical frame at the end of each row. */

	if ((TBL_OPT_BOX | TBL_OPT_DBOX) & sp->opts->opts ||
	    sp->layout->vert)
		term_word(tp, TBL_SPAN_HORIZ == sp->pos ||
		    TBL_SPAN_DHORIZ == sp->pos ? "+" : " |");
	term_flushln(tp);

	/*
	 * If we're the last row, clean up after ourselves: clear the
	 * existing table configuration and set it to NULL.
	 */

	if (TBL_SPAN_LAST & sp->flags) {
		if (TBL_OPT_DBOX & sp->opts->opts ||
		    TBL_OPT_BOX  & sp->opts->opts) {
			tbl_hframe(tp, sp, 0);
			tp->skipvsp = 1;
		}
		if (TBL_OPT_DBOX & sp->opts->opts) {
			tbl_hframe(tp, sp, 1);
			tp->skipvsp = 2;
		}
		assert(tp->tbl.cols);
		free(tp->tbl.cols);
		tp->tbl.cols = NULL;
	}

	tp->flags &= ~TERMP_NONOSPACE;
	tp->rmargin = rmargin;
	tp->maxrmargin = maxrmargin;

}
예제 #2
0
void
term_tbl(struct termp *tp, const struct tbl_span *sp)
{
	const struct tbl_head	*hp;
	const struct tbl_dat	*dp;
	struct roffcol		*col;
	size_t		   	 rmargin, maxrmargin;

	rmargin = tp->rmargin;
	maxrmargin = tp->maxrmargin;

	tp->rmargin = tp->maxrmargin = TERM_MAXMARGIN;

	/* Inhibit printing of spaces: we do padding ourselves. */

	tp->flags |= TERMP_NONOSPACE;
	tp->flags |= TERMP_NOSPACE;

	/*
	 * The first time we're invoked for a given table block,
	 * calculate the table widths and decimal positions.
	 */

	if (TBL_SPAN_FIRST & sp->flags) {
		term_flushln(tp);

		tp->tbl.len = term_tbl_len;
		tp->tbl.slen = term_tbl_strlen;
		tp->tbl.arg = tp;

		tblcalc(&tp->tbl, sp);
	}

	/* Horizontal frame at the start of boxed tables. */

	if (TBL_SPAN_FIRST & sp->flags)
		tbl_hframe(tp, sp);

	/* Vertical frame at the start of each row. */

	tbl_vframe(tp, sp->tbl);

	/*
	 * Now print the actual data itself depending on the span type.
	 * Spanner spans get a horizontal rule; data spanners have their
	 * data printed by matching data to header.
	 */

	switch (sp->pos) {
	case (TBL_SPAN_HORIZ):
		/* FALLTHROUGH */
	case (TBL_SPAN_DHORIZ):
		tbl_hrule(tp, sp);
		break;
	case (TBL_SPAN_DATA):
		/* Iterate over template headers. */
		dp = sp->first;
		for (hp = sp->head; hp; hp = hp->next) {
			switch (hp->pos) {
			case (TBL_HEAD_VERT):
				/* FALLTHROUGH */
			case (TBL_HEAD_DVERT):
				tbl_vrule(tp, hp);
				continue;
			case (TBL_HEAD_DATA):
				break;
			}

			col = &tp->tbl.cols[hp->ident];
			tbl_data(tp, sp->tbl, dp, col);

			/* Go to the next data cell. */
			if (dp)
				dp = dp->next;
		}
		break;
	}

	tbl_vframe(tp, sp->tbl);
	term_flushln(tp);

	/*
	 * If we're the last row, clean up after ourselves: clear the
	 * existing table configuration and set it to NULL.
	 */

	if (TBL_SPAN_LAST & sp->flags) {
		tbl_hframe(tp, sp);
		assert(tp->tbl.cols);
		free(tp->tbl.cols);
		tp->tbl.cols = NULL;
	}

	tp->flags &= ~TERMP_NONOSPACE;
	tp->rmargin = rmargin;
	tp->maxrmargin = maxrmargin;

}