diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2015-01-27 05:21:44 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2015-01-27 05:21:44 +0000 |
commit | 3d1973ffce60279bff4ec548c2c90f4d1d31f1a2 (patch) | |
tree | ff7ba8b19b0c296892ac283cae5c138a94b2e04f /tbl_layout.c | |
parent | fb1f845c9ebafe8648f3df58f8a4581041ff067e (diff) | |
download | mandoc-3d1973ffce60279bff4ec548c2c90f4d1d31f1a2.tar.gz |
Multiple parser and formatter fixes for line drawing in tbl(7).
* Allow mixing vertical line bars with the layout options
of the preceding layout cell.
* Correctly combine box options with layout lines.
* Correctly print vertical lines in data rows, with the right spacing.
* Correctly print cross markers and left and right ends of
horizontal lines even if vertical lines differ above and below.
* Avoid the bogus error message "no table data cells"
when a table data section starts with a horizontal line.
No increase in code size.
Diffstat (limited to 'tbl_layout.c')
-rw-r--r-- | tbl_layout.c | 69 |
1 files changed, 46 insertions, 23 deletions
diff --git a/tbl_layout.c b/tbl_layout.c index 7ca81659..adf728aa 100644 --- a/tbl_layout.c +++ b/tbl_layout.c @@ -54,7 +54,7 @@ static void mods(struct tbl_node *, struct tbl_cell *, static void cell(struct tbl_node *, struct tbl_row *, int, const char *, int *); static struct tbl_cell *cell_alloc(struct tbl_node *, struct tbl_row *, - enum tbl_cellt, int vert); + enum tbl_cellt); static void @@ -69,7 +69,7 @@ mod: /* Row delimiters and cell specifiers end modifier lists. */ - if (strchr(".,-=^_ACLNRSaclnrs|", p[*pos]) != NULL) + if (strchr(".,-=^_ACLNRSaclnrs", p[*pos]) != NULL) return; /* Throw away parenthesised expression. */ @@ -137,6 +137,13 @@ mod: case 'z': cp->flags |= TBL_CELL_WIGN; goto mod; + case '|': + if (cp->vert < 2) + cp->vert++; + else + mandoc_msg(MANDOCERR_TBLLAYOUT_VERT, + tbl->parse, ln, *pos - 1, NULL); + goto mod; default: mandoc_vmsg(MANDOCERR_TBLLAYOUT_CHAR, tbl->parse, ln, *pos - 1, "%c", p[*pos - 1]); @@ -169,17 +176,15 @@ static void cell(struct tbl_node *tbl, struct tbl_row *rp, int ln, const char *p, int *pos) { - int vert, i; + int i; enum tbl_cellt c; - /* Handle vertical lines. */ + /* Handle leading vertical lines */ - vert = 0; -again: while (p[*pos] == ' ' || p[*pos] == '\t' || p[*pos] == '|') { if (p[*pos] == '|') { - if (vert < 2) - vert++; + if (rp->vert < 2) + rp->vert++; else mandoc_msg(MANDOCERR_TBLLAYOUT_VERT, tbl->parse, ln, *pos, NULL); @@ -187,12 +192,12 @@ again: (*pos)++; } - /* Handle trailing vertical lines */ +again: + while (p[*pos] == ' ' || p[*pos] == '\t') + (*pos)++; - if ('.' == p[*pos] || '\0' == p[*pos]) { - rp->vert = vert; + if (p[*pos] == '.' || p[*pos] == '\0') return; - } /* Parse the column position (`c', `l', `r', ...). */ @@ -225,7 +230,7 @@ again: /* Allocate cell then parse its modifiers. */ - mods(tbl, cell_alloc(tbl, rp, c, vert), ln, p, pos); + mods(tbl, cell_alloc(tbl, rp, c), ln, p, pos); } void @@ -253,13 +258,34 @@ tbl_layout(struct tbl_node *tbl, int ln, const char *p) case '.': /* End of layout. */ pos++; tbl->part = TBL_PART_DATA; - if (tbl->first_row != NULL) + + /* + * When the layout is completely empty, + * default to one left-justified column. + */ + + if (tbl->first_row == NULL) { + mandoc_msg(MANDOCERR_TBLLAYOUT_NONE, + tbl->parse, ln, pos, NULL); + rp = mandoc_calloc(1, sizeof(*rp)); + cell_alloc(tbl, rp, TBL_CELL_LEFT); + tbl->first_row = tbl->last_row = rp; return; - mandoc_msg(MANDOCERR_TBLLAYOUT_NONE, - tbl->parse, ln, pos, NULL); - rp = mandoc_calloc(1, sizeof(*rp)); - cell_alloc(tbl, rp, TBL_CELL_LEFT, 0); - tbl->first_row = tbl->last_row = rp; + } + + /* + * Search for the widest line + * along the left and right margins. + */ + + for (rp = tbl->first_row; rp; rp = rp->next) { + if (tbl->opts.lvert < rp->vert) + tbl->opts.lvert = rp->vert; + if (rp->last != NULL && + rp->last->head == tbl->last_head && + tbl->opts.rvert < rp->last->vert) + tbl->opts.rvert = rp->last->vert; + } return; default: /* Cell. */ break; @@ -278,8 +304,7 @@ tbl_layout(struct tbl_node *tbl, int ln, const char *p) } static struct tbl_cell * -cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos, - int vert) +cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos) { struct tbl_cell *p, *pp; struct tbl_head *h, *hp; @@ -296,7 +321,6 @@ cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos, rp->last = p; p->pos = pos; - p->vert = vert; /* Re-use header. */ @@ -307,7 +331,6 @@ cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos, hp = mandoc_calloc(1, sizeof(struct tbl_head)); hp->ident = tbl->opts.cols++; - hp->vert = vert; if (tbl->last_head) { hp->prev = tbl->last_head; |