tbl_term.c revision 95c635efb7c3b86efc493e0447eaec7aecca3f0f
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore/* $Id: tbl_term.c,v 1.21 2011/09/20 23:05:49 schwarze Exp $ */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Permission to use, copy, modify, and distribute this software for any
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * purpose with or without fee is hereby granted, provided that the above
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * copyright notice and this permission notice appear in all copies.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic size_t term_tbl_strlen(const char *, void *);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void tbl_char(struct termp *, char, size_t);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void tbl_data(struct termp *, const struct tbl *,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore const struct tbl_dat *,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore const struct roffcol *);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic size_t tbl_rulewidth(struct termp *, const struct tbl_head *);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void tbl_hframe(struct termp *, const struct tbl_span *, int);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void tbl_literal(struct termp *, const struct tbl_dat *,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore const struct roffcol *);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void tbl_number(struct termp *, const struct tbl *,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore const struct tbl_dat *,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore const struct roffcol *);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void tbl_hrule(struct termp *, const struct tbl_span *);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void tbl_vrule(struct termp *, const struct tbl_head *);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(term_strlen((const struct termp *)arg, p));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(term_len((const struct termp *)arg, sz));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreterm_tbl(struct termp *tp, const struct tbl_span *sp)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore tp->rmargin = tp->maxrmargin = TERM_MAXMARGIN;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Inhibit printing of spaces: we do padding ourselves. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * The first time we're invoked for a given table block,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * calculate the table widths and decimal positions.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Horizontal frame at the start of boxed tables. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Vertical frame at the start of each row. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (TBL_OPT_BOX & sp->tbl->opts || TBL_OPT_DBOX & sp->tbl->opts)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Now print the actual data itself depending on the span type.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Spanner spans get a horizontal rule; data spanners have their
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * data printed by matching data to header.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* FALLTHROUGH */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Iterate over template headers. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * If the current data header is invoked during
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * a spanner ("spans" > 0), don't emit anything
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* FALLTHROUGH */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * All cells get a leading blank, except the
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * first one and those after double rulers.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (hp->prev && TBL_HEAD_DVERT != hp->prev->pos)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* No trailing blanks. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Add another blank between cells,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * or two when there is no vertical ruler.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Go to the next data cell and assign the
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * number of subsequent spans, if applicable.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Vertical frame at the end of each row. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (TBL_OPT_BOX & sp->tbl->opts || TBL_OPT_DBOX & sp->tbl->opts)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * If we're the last row, clean up after ourselves: clear the
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * existing table configuration and set it to NULL.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Horizontal rules extend across the entire table.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Calculate the width by iterating over columns.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoretbl_rulewidth(struct termp *tp, const struct tbl_head *hp)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Account for leading blanks. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (hp->prev && TBL_HEAD_DVERT != hp->prev->pos)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Account for trailing blanks. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Rules inside the table can be single or double
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * and have crossings with vertical rules marked with pluses.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoretbl_hrule(struct termp *tp, const struct tbl_span *sp)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Rules above and below the table are always single
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * and have an additional plus at the beginning and end.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * For double frames, this function is called twice,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * and the outer one does not have crossings.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoretbl_hframe(struct termp *tp, const struct tbl_span *sp, int outer)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore outer || TBL_HEAD_DATA == hp->pos ? '-' : '+',
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoretbl_data(struct termp *tp, const struct tbl *tbl,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* FALLTHROUGH */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* FALLTHROUGH */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* FALLTHROUGH */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* FALLTHROUGH */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* FALLTHROUGH */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* NOTREACHED */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoretbl_vrule(struct termp *tp, const struct tbl_head *hp)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoretbl_char(struct termp *tp, char c, size_t len)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoretbl_literal(struct termp *tp, const struct tbl_dat *dp,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore padr = col->width > len ? col->width - len : 0;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoretbl_number(struct termp *tp, const struct tbl *tbl,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * See calc_data_number(). Left-pad by taking the offset of our
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * and the maximum decimal; right-pad by the remaining amount.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (NULL != (cp = strrchr(dp->string, tbl->decimal))) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore for (ssz = 0, i = 0; cp != &dp->string[i]; i++) {