=================================================================== RCS file: /cvs/mandoc/tbl_term.c,v retrieving revision 1.21 retrieving revision 1.28 diff -u -p -r1.21 -r1.28 --- mandoc/tbl_term.c 2011/09/20 23:05:49 1.21 +++ mandoc/tbl_term.c 2014/08/10 23:54:41 1.28 @@ -1,7 +1,7 @@ -/* $Id: tbl_term.c,v 1.21 2011/09/20 23:05:49 schwarze Exp $ */ +/* $Id: tbl_term.c,v 1.28 2014/08/10 23:54:41 schwarze Exp $ */ /* * Copyright (c) 2009, 2011 Kristaps Dzonsons - * Copyright (c) 2011 Ingo Schwarze + * Copyright (c) 2011, 2012, 2014 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -15,10 +15,10 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif +#include + #include #include #include @@ -31,15 +31,15 @@ static size_t term_tbl_len(size_t, void *); static size_t term_tbl_strlen(const char *, void *); static void tbl_char(struct termp *, char, size_t); -static void tbl_data(struct termp *, const struct tbl *, - const struct tbl_dat *, +static void tbl_data(struct termp *, const struct tbl_opts *, + const struct tbl_dat *, const struct roffcol *); static size_t tbl_rulewidth(struct termp *, const struct tbl_head *); static void tbl_hframe(struct termp *, const struct tbl_span *, int); -static void tbl_literal(struct termp *, const struct tbl_dat *, +static void tbl_literal(struct termp *, const struct tbl_dat *, const struct roffcol *); -static void tbl_number(struct termp *, const struct tbl *, - const struct tbl_dat *, +static void tbl_number(struct termp *, const struct tbl_opts *, + const struct tbl_dat *, const struct roffcol *); static void tbl_hrule(struct termp *, const struct tbl_span *); static void tbl_vrule(struct termp *, const struct tbl_head *); @@ -66,7 +66,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) const struct tbl_dat *dp; struct roffcol *col; int spans; - size_t rmargin, maxrmargin; + size_t rmargin, maxrmargin; rmargin = tp->rmargin; maxrmargin = tp->maxrmargin; @@ -96,18 +96,19 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) /* Horizontal frame at the start of boxed tables. */ if (TBL_SPAN_FIRST & sp->flags) { - if (TBL_OPT_DBOX & sp->tbl->opts) + if (TBL_OPT_DBOX & sp->opts->opts) tbl_hframe(tp, sp, 1); - if (TBL_OPT_DBOX & sp->tbl->opts || - TBL_OPT_BOX & sp->tbl->opts) + 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 & sp->tbl->opts || TBL_OPT_DBOX & sp->tbl->opts) + 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 ? "+" : "|"); + TBL_SPAN_DHORIZ == sp->pos ? "+" : "|"); /* * Now print the actual data itself depending on the span type. @@ -116,61 +117,35 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) */ switch (sp->pos) { - case (TBL_SPAN_HORIZ): + case TBL_SPAN_HORIZ: /* FALLTHROUGH */ - case (TBL_SPAN_DHORIZ): + case TBL_SPAN_DHORIZ: tbl_hrule(tp, sp); break; - case (TBL_SPAN_DATA): + 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. */ - switch (hp->pos) { - case (TBL_HEAD_VERT): - /* FALLTHROUGH */ - case (TBL_HEAD_DVERT): - if (spans <= 0) - tbl_vrule(tp, hp); - continue; - case (TBL_HEAD_DATA): - break; - } if (--spans >= 0) continue; - /* - * All cells get a leading blank, except the - * first one and those after double rulers. - */ + /* Separate columns. */ - if (hp->prev && TBL_HEAD_DVERT != hp->prev->pos) - tbl_char(tp, ASCII_NBRSP, 1); + if (NULL != hp->prev) + tbl_vrule(tp, hp); col = &tp->tbl.cols[hp->ident]; - tbl_data(tp, sp->tbl, dp, col); + tbl_data(tp, sp->opts, dp, col); - /* No trailing blanks. */ - - if (NULL == hp->next) - break; - /* - * Add another blank between cells, - * or two when there is no vertical ruler. - */ - - tbl_char(tp, ASCII_NBRSP, - TBL_HEAD_VERT == hp->next->pos || - TBL_HEAD_DVERT == hp->next->pos ? 1 : 2); - - /* * Go to the next data cell and assign the * number of subsequent spans, if applicable. */ @@ -185,9 +160,10 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) /* Vertical frame at the end of each row. */ - if (TBL_OPT_BOX & sp->tbl->opts || TBL_OPT_DBOX & sp->tbl->opts) + 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 ? "+" : " |"); + TBL_SPAN_DHORIZ == sp->pos ? "+" : " |"); term_flushln(tp); /* @@ -196,11 +172,15 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) */ if (TBL_SPAN_LAST & sp->flags) { - if (TBL_OPT_DBOX & sp->tbl->opts || - TBL_OPT_BOX & sp->tbl->opts) + if (TBL_OPT_DBOX & sp->opts->opts || + TBL_OPT_BOX & sp->opts->opts) { tbl_hframe(tp, sp, 0); - if (TBL_OPT_DBOX & sp->tbl->opts) + 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; @@ -222,17 +202,14 @@ tbl_rulewidth(struct termp *tp, const struct tbl_head size_t width; width = tp->tbl.cols[hp->ident].width; - if (TBL_HEAD_DATA == hp->pos) { - /* Account for leading blanks. */ - if (hp->prev && TBL_HEAD_DVERT != hp->prev->pos) - width++; - /* Account for trailing blanks. */ - width++; - if (hp->next && - TBL_HEAD_VERT != hp->next->pos && - TBL_HEAD_DVERT != hp->next->pos) - width++; - } + + /* Account for leading blanks. */ + if (hp->prev) + width += 2 - hp->vert; + + /* Account for trailing blank. */ + width++; + return(width); } @@ -250,10 +227,11 @@ tbl_hrule(struct termp *tp, const struct tbl_span *sp) if (TBL_SPAN_DHORIZ == sp->pos) c = '='; - for (hp = sp->head; hp; hp = hp->next) - tbl_char(tp, - TBL_HEAD_DATA == hp->pos ? c : '+', - tbl_rulewidth(tp, hp)); + for (hp = sp->head; hp; hp = hp->next) { + if (hp->prev && hp->vert) + tbl_char(tp, '+', hp->vert); + tbl_char(tp, c, tbl_rulewidth(tp, hp)); + } } /* @@ -268,18 +246,19 @@ tbl_hframe(struct termp *tp, const struct tbl_span *sp const struct tbl_head *hp; term_word(tp, "+"); - for (hp = sp->head; hp; hp = hp->next) - tbl_char(tp, - outer || TBL_HEAD_DATA == hp->pos ? '-' : '+', - tbl_rulewidth(tp, hp)); + for (hp = sp->head; hp; hp = hp->next) { + if (hp->prev && hp->vert) + tbl_char(tp, (outer ? '-' : '+'), hp->vert); + tbl_char(tp, '-', tbl_rulewidth(tp, hp)); + } term_word(tp, "+"); term_flushln(tp); } static void -tbl_data(struct termp *tp, const struct tbl *tbl, - const struct tbl_dat *dp, - const struct roffcol *col) +tbl_data(struct termp *tp, const struct tbl_opts *opts, + const struct tbl_dat *dp, + const struct roffcol *col) { if (NULL == dp) { @@ -289,43 +268,43 @@ tbl_data(struct termp *tp, const struct tbl *tbl, assert(dp->layout); switch (dp->pos) { - case (TBL_DATA_NONE): + case TBL_DATA_NONE: tbl_char(tp, ASCII_NBRSP, col->width); return; - case (TBL_DATA_HORIZ): + case TBL_DATA_HORIZ: /* FALLTHROUGH */ - case (TBL_DATA_NHORIZ): + case TBL_DATA_NHORIZ: tbl_char(tp, '-', col->width); return; - case (TBL_DATA_NDHORIZ): + case TBL_DATA_NDHORIZ: /* FALLTHROUGH */ - case (TBL_DATA_DHORIZ): + case TBL_DATA_DHORIZ: tbl_char(tp, '=', col->width); return; default: break; } - + switch (dp->layout->pos) { - case (TBL_CELL_HORIZ): + case TBL_CELL_HORIZ: tbl_char(tp, '-', col->width); break; - case (TBL_CELL_DHORIZ): + case TBL_CELL_DHORIZ: tbl_char(tp, '=', col->width); break; - case (TBL_CELL_LONG): + case TBL_CELL_LONG: /* FALLTHROUGH */ - case (TBL_CELL_CENTRE): + case TBL_CELL_CENTRE: /* FALLTHROUGH */ - case (TBL_CELL_LEFT): + case TBL_CELL_LEFT: /* FALLTHROUGH */ - case (TBL_CELL_RIGHT): + case TBL_CELL_RIGHT: tbl_literal(tp, dp, col); break; - case (TBL_CELL_NUMBER): - tbl_number(tp, tbl, dp, col); + case TBL_CELL_NUMBER: + tbl_number(tp, opts, dp, col); break; - case (TBL_CELL_DOWN): + case TBL_CELL_DOWN: tbl_char(tp, ASCII_NBRSP, col->width); break; default: @@ -338,16 +317,11 @@ static void tbl_vrule(struct termp *tp, const struct tbl_head *hp) { - switch (hp->pos) { - case (TBL_HEAD_VERT): - term_word(tp, "|"); - break; - case (TBL_HEAD_DVERT): - term_word(tp, "||"); - break; - default: - break; - } + tbl_char(tp, ASCII_NBRSP, 1); + if (0 < hp->vert) + tbl_char(tp, '|', hp->vert); + if (2 > hp->vert) + tbl_char(tp, ASCII_NBRSP, 2 - hp->vert); } static void @@ -366,28 +340,36 @@ tbl_char(struct termp *tp, char c, size_t len) } static void -tbl_literal(struct termp *tp, const struct tbl_dat *dp, +tbl_literal(struct termp *tp, const struct tbl_dat *dp, const struct roffcol *col) { - size_t len, padl, padr; + struct tbl_head *hp; + size_t width, len, padl, padr; + int spans; assert(dp->string); len = term_strlen(tp, dp->string); - padr = col->width > len ? col->width - len : 0; + + hp = dp->layout->head->next; + width = col->width; + for (spans = dp->spans; spans--; hp = hp->next) + width += tp->tbl.cols[hp->ident].width + 3; + + padr = width > len ? width - len : 0; padl = 0; switch (dp->layout->pos) { - case (TBL_CELL_LONG): + case TBL_CELL_LONG: padl = term_len(tp, 1); padr = padr > padl ? padr - padl : 0; break; - case (TBL_CELL_CENTRE): + case TBL_CELL_CENTRE: if (2 > padr) break; padl = padr / 2; padr -= padl; break; - case (TBL_CELL_RIGHT): + case TBL_CELL_RIGHT: padl = padr; padr = 0; break; @@ -401,7 +383,7 @@ tbl_literal(struct termp *tp, const struct tbl_dat *dp } static void -tbl_number(struct termp *tp, const struct tbl *tbl, +tbl_number(struct termp *tp, const struct tbl_opts *opts, const struct tbl_dat *dp, const struct roffcol *col) { @@ -419,12 +401,12 @@ tbl_number(struct termp *tp, const struct tbl *tbl, sz = term_strlen(tp, dp->string); - buf[0] = tbl->decimal; + buf[0] = opts->decimal; buf[1] = '\0'; psz = term_strlen(tp, buf); - if (NULL != (cp = strrchr(dp->string, tbl->decimal))) { + if (NULL != (cp = strrchr(dp->string, opts->decimal))) { buf[1] = '\0'; for (ssz = 0, i = 0; cp != &dp->string[i]; i++) { buf[0] = dp->string[i];