From b3ea03504ba905470ba5c486ba69062c89034488 Mon Sep 17 00:00:00 2001 From: Kristaps Dzonsons Date: Mon, 10 Jan 2011 14:40:30 +0000 Subject: First, make extra data cells be thrown away. This makes "dp->layout" always hold, which cleans up the table stuff a bit. Second, set a "spans" value per data cell consisting of the number of skipped TBL_CELL_SPAN layout cells. Third, make tbl_term.c understand how to skip over spanned sections when iterating over the header queue. What remains is to calculate the widths of spanned cells. --- main.c | 6 ++---- mandoc.h | 7 +++---- out.c | 5 ++--- tbl.7 | 12 ++++++++---- tbl_data.c | 31 ++++++++++++++++++++++++------- tbl_layout.c | 25 ++++++++++++++++++++----- tbl_term.c | 39 ++++++++++++++++++++++++++------------- tree.c | 9 +++++++-- 8 files changed, 92 insertions(+), 42 deletions(-) diff --git a/main.c b/main.c index 2be68a93..941fa5e2 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.135 2011/01/04 15:02:00 kristaps Exp $ */ +/* $Id: main.c,v 1.136 2011/01/10 14:40:30 kristaps Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010 Ingo Schwarze @@ -178,9 +178,6 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "unknown escape sequence", "unterminated quoted string", - /* related to tables */ - "extra data cells", - "generic error", /* related to tables */ @@ -191,6 +188,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "no table data cells specified", "ignore data in cell", "data block still open", + "ignoring extra data cells", "input stack limit exceeded, infinite loop?", "skipping bad character", diff --git a/mandoc.h b/mandoc.h index 9dd448e6..260ce40a 100644 --- a/mandoc.h +++ b/mandoc.h @@ -1,4 +1,4 @@ -/* $Id: mandoc.h,v 1.49 2011/01/06 13:45:47 kristaps Exp $ */ +/* $Id: mandoc.h,v 1.50 2011/01/10 14:40:30 kristaps Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons * @@ -100,9 +100,6 @@ enum mandocerr { MANDOCERR_BADESCAPE, /* unknown escape sequence */ MANDOCERR_BADQUOTE, /* unterminated quoted string */ - /* related to tables */ - MANDOCERR_TBLEXTRADAT, /* extra data cells */ - MANDOCERR_ERROR, /* ===== start of errors ===== */ /* related to tables */ @@ -113,6 +110,7 @@ enum mandocerr { MANDOCERR_TBLNODATA, /* no table data cells specified */ MANDOCERR_TBLIGNDATA, /* ignore data in cell */ MANDOCERR_TBLBLOCK, /* data block still open */ + MANDOCERR_TBLEXTRADAT, /* ignoring extra data cells */ MANDOCERR_ROFFLOOP, /* input stack limit exceeded, infinite loop? */ MANDOCERR_BADCHAR, /* skipping bad character */ @@ -238,6 +236,7 @@ enum tbl_datt { */ struct tbl_dat { struct tbl_cell *layout; /* layout cell: CAN BE NULL */ + int spans; /* how many spans follow */ struct tbl_dat *next; char *string; enum tbl_datt pos; diff --git a/out.c b/out.c index 58fdf951..b13d783f 100644 --- a/out.c +++ b/out.c @@ -1,4 +1,4 @@ -/* $Id: out.c,v 1.32 2011/01/08 17:16:48 kristaps Exp $ */ +/* $Id: out.c,v 1.33 2011/01/10 14:40:30 kristaps Exp $ */ /* * Copyright (c) 2009, 2010 Kristaps Dzonsons * @@ -399,8 +399,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp) * to data cells in the data section. */ for (dp = sp->first; dp; dp = dp->next) { - if (NULL == dp->layout) - continue; + assert(dp->layout); col = &tbl->cols[dp->layout->head->ident]; tblcalc_data(tbl, col, sp->tbl, dp); } diff --git a/tbl.7 b/tbl.7 index e901623b..683e80f1 100644 --- a/tbl.7 +++ b/tbl.7 @@ -1,4 +1,4 @@ -.\" $Id: tbl.7,v 1.7 2011/01/08 17:30:03 kristaps Exp $ +.\" $Id: tbl.7,v 1.8 2011/01/10 14:40:30 kristaps Exp $ .\" .\" Copyright (c) 2010 Kristaps Dzonsons .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 8 2011 $ +.Dd $Mdocdate: January 10 2011 $ .Dt TBL 7 .Os .Sh NAME @@ -209,8 +209,12 @@ Justify a number around its last decimal point. If the decimal point is not found on the number, it's assumed to trail the number. .It Cm s -This option is not supported by -.Xr mandoc 1 . +Span columns from the last non-span data cell. +It is an error if spanning columns follow a +.Cm \- +or +.Cm \(ba +cell, or come first. .It Cm a Left-justify a literal string and pad with one space. .It Cm ^ diff --git a/tbl_data.c b/tbl_data.c index 67e7485c..c7bca649 100644 --- a/tbl_data.c +++ b/tbl_data.c @@ -1,4 +1,4 @@ -/* $Id: tbl_data.c,v 1.15 2011/01/09 23:14:41 kristaps Exp $ */ +/* $Id: tbl_data.c,v 1.16 2011/01/10 14:40:30 kristaps Exp $ */ /* * Copyright (c) 2009, 2010 Kristaps Dzonsons * @@ -37,7 +37,7 @@ data(struct tbl_node *tbl, struct tbl_span *dp, { struct tbl_dat *dat; struct tbl_cell *cp; - int sv; + int sv, spans; cp = NULL; if (dp->last && dp->last->layout) @@ -55,12 +55,32 @@ data(struct tbl_node *tbl, struct tbl_span *dp, TBL_CELL_SPAN == cp->pos)) cp = cp->next; + /* + * Stop processing when we reach the end of the available layout + * cells. This means that we have extra input. + */ + + if (NULL == cp) { + TBL_MSG(tbl, MANDOCERR_TBLEXTRADAT, ln, *pos); + /* Skip to the end... */ + while (p[*pos]) + (*pos)++; + return(1); + } + dat = mandoc_calloc(1, sizeof(struct tbl_dat)); dat->layout = cp; dat->pos = TBL_DATA_NONE; - if (NULL == dat->layout) - TBL_MSG(tbl, MANDOCERR_TBLEXTRADAT, ln, *pos); + assert(TBL_CELL_SPAN != cp->pos); + + for (spans = 0, cp = cp->next; cp; cp = cp->next) + if (TBL_CELL_SPAN == cp->pos) + spans++; + else + break; + + dat->spans = spans; if (dp->last) { dp->last->next = dat; @@ -101,9 +121,6 @@ data(struct tbl_node *tbl, struct tbl_span *dp, else dat->pos = TBL_DATA_DATA; - if (NULL == dat->layout) - return(1); - if (TBL_CELL_HORIZ == dat->layout->pos || TBL_CELL_DHORIZ == dat->layout->pos) if (TBL_DATA_DATA == dat->pos && '\0' != *dat->string) diff --git a/tbl_layout.c b/tbl_layout.c index 59490ad4..12d53fad 100644 --- a/tbl_layout.c +++ b/tbl_layout.c @@ -1,4 +1,4 @@ -/* $Id: tbl_layout.c,v 1.13 2011/01/09 05:38:23 joerg Exp $ */ +/* $Id: tbl_layout.c,v 1.14 2011/01/10 14:40:30 kristaps Exp $ */ /* * Copyright (c) 2009, 2010 Kristaps Dzonsons * @@ -197,12 +197,27 @@ cell(struct tbl_node *tbl, struct tbl_row *rp, /* * If a span cell is found first, raise a warning and abort the - * parse. FIXME: recover from this somehow? + * parse. If a span cell is found and the last layout element + * isn't a "normal" layout, bail. + * + * FIXME: recover from this somehow? */ - if (NULL == rp->first && TBL_CELL_SPAN == c) { - TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos); - return(0); + if (TBL_CELL_SPAN == c) { + if (NULL == rp->first) { + TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos); + return(0); + } else if (rp->last) + switch (rp->last->pos) { + case (TBL_CELL_VERT): + case (TBL_CELL_DVERT): + case (TBL_CELL_HORIZ): + case (TBL_CELL_DHORIZ): + TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos); + return(0); + default: + break; + } } (*pos)++; diff --git a/tbl_term.c b/tbl_term.c index 34a445cd..23a48de9 100644 --- a/tbl_term.c +++ b/tbl_term.c @@ -1,4 +1,4 @@ -/* $Id: tbl_term.c,v 1.15 2011/01/08 17:16:48 kristaps Exp $ */ +/* $Id: tbl_term.c,v 1.16 2011/01/10 14:40:30 kristaps Exp $ */ /* * Copyright (c) 2009 Kristaps Dzonsons * @@ -64,6 +64,7 @@ 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; @@ -115,23 +116,39 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) 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): - tbl_vrule(tp, hp); + if (spans <= 0) + tbl_vrule(tp, hp); continue; case (TBL_HEAD_DATA): break; } + if (--spans >= 0) + continue; + col = &tp->tbl.cols[hp->ident]; tbl_data(tp, sp->tbl, dp, col); - /* Go to the next data cell. */ - if (dp) + /* + * Go to the next data cell and assign the + * number of subsequent spans, if applicable. + */ + + if (dp) { + spans = dp->spans; dp = dp->next; + } } break; } @@ -244,12 +261,12 @@ tbl_data(struct termp *tp, const struct tbl *tbl, const struct tbl_dat *dp, const struct roffcol *col) { - enum tbl_cellt pos; if (NULL == dp) { tbl_char(tp, ASCII_NBRSP, col->width); return; } + assert(dp->layout); switch (dp->pos) { case (TBL_DATA_NONE): @@ -269,9 +286,7 @@ tbl_data(struct termp *tp, const struct tbl *tbl, break; } - pos = dp && dp->layout ? dp->layout->pos : TBL_CELL_LEFT; - - switch (pos) { + switch (dp->layout->pos) { case (TBL_CELL_HORIZ): tbl_char(tp, '-', col->width); break; @@ -340,17 +355,15 @@ tbl_literal(struct termp *tp, const struct tbl_dat *dp, const struct roffcol *col) { size_t padl, padr, ssz; - enum tbl_cellt pos; const char *str; padl = padr = 0; - pos = dp && dp->layout ? dp->layout->pos : TBL_CELL_LEFT; - str = dp && dp->string ? dp->string : ""; + str = dp->string ? dp->string : ""; ssz = term_len(tp, 1); - switch (pos) { + switch (dp->layout->pos) { case (TBL_CELL_LONG): padl = ssz; padr = col->width - term_strlen(tp, str) - ssz; @@ -391,7 +404,7 @@ tbl_number(struct termp *tp, const struct tbl *tbl, * and the maximum decimal; right-pad by the remaining amount. */ - str = dp && dp->string ? dp->string : ""; + str = dp->string ? dp->string : ""; sz = term_strlen(tp, str); diff --git a/tree.c b/tree.c index 70bd73d9..427a9d41 100644 --- a/tree.c +++ b/tree.c @@ -1,4 +1,4 @@ -/* $Id: tree.c,v 1.31 2011/01/03 13:59:21 kristaps Exp $ */ +/* $Id: tree.c,v 1.32 2011/01/10 14:40:30 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -282,7 +282,12 @@ print_span(const struct tbl_span *sp, int indent) default: break; } - printf("[%s%s]", dp->string, dp->layout ? "" : "*"); + printf("[\"%s\"", dp->string ? dp->string : ""); + if (dp->spans) + printf("(%d)", dp->spans); + if (NULL == dp->layout) + putchar('*'); + putchar(']'); if (dp->next) putchar(' '); } -- cgit v1.2.3-56-ge451