diff options
author | Kristaps Dzonsons <kristaps@bsd.lv> | 2011-01-10 14:40:30 +0000 |
---|---|---|
committer | Kristaps Dzonsons <kristaps@bsd.lv> | 2011-01-10 14:40:30 +0000 |
commit | dede963eacb17dcdbe0624bf76ab3f4045147541 (patch) | |
tree | c83ed7ba5f2d938f2f5cd04b659ac67d5da157ee | |
parent | 4f674421b17961b1c6630a984ebea196eb7eed7a (diff) | |
download | mandoc-dede963eacb17dcdbe0624bf76ab3f4045147541.tar.gz |
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.
-rw-r--r-- | main.c | 4 | ||||
-rw-r--r-- | mandoc.h | 5 | ||||
-rw-r--r-- | out.c | 3 | ||||
-rw-r--r-- | tbl.7 | 8 | ||||
-rw-r--r-- | tbl_data.c | 29 | ||||
-rw-r--r-- | tbl_layout.c | 23 | ||||
-rw-r--r-- | tbl_term.c | 37 | ||||
-rw-r--r-- | tree.c | 7 |
8 files changed, 83 insertions, 33 deletions
@@ -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", @@ -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; @@ -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); } @@ -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 ^ @@ -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 cc4fdfb5..ea93f645 100644 --- a/tbl_layout.c +++ b/tbl_layout.c @@ -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)++; @@ -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); @@ -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(' '); } |