diff options
-rw-r--r-- | TODO | 8 | ||||
-rw-r--r-- | mandoc.h | 3 | ||||
-rw-r--r-- | out.c | 10 | ||||
-rw-r--r-- | tbl_data.c | 47 | ||||
-rw-r--r-- | tbl_html.c | 55 | ||||
-rw-r--r-- | tbl_term.c | 34 | ||||
-rw-r--r-- | tree.c | 56 |
7 files changed, 140 insertions, 73 deletions
@@ -168,6 +168,10 @@ are mere guesses, and some may be wrong. --- missing tbl features ----------------------------------------------- +- vertically spanning cells by \^ in the data section + pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200 + loc * exist * algo * size * imp *** + - the "s" layout column specifier is used for placement of data into columns, but ignored during column width calculations synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400 @@ -195,10 +199,6 @@ are mere guesses, and some may be wrong. suggested by bentley@ Tue, 14 Oct 2014 04:10:55 -0600 loc * exist ** algo * size * imp ** -- implement cell spanning in HTML output - pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200 - loc * exist * algo ** size ** imp ** - - implement table borders in HTML output pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200 loc * exist * algo ** size ** imp ** @@ -320,7 +320,8 @@ struct tbl_dat { struct tbl_cell *layout; /* layout cell */ struct tbl_dat *next; char *string; /* data (NULL if not TBL_DATA_DATA) */ - int spans; /* how many spans follow */ + int hspans; /* how many horizontal spans follow */ + int vspans; /* how many vertical spans follow */ int block; /* T{ text block T} */ enum tbl_datt pos; }; @@ -112,7 +112,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp, const struct tbl_dat *dp; struct roffcol *col; size_t ewidth, xwidth; - int spans; + int hspans; int icol, maxcol, necol, nxcol, quirkcol; /* @@ -129,17 +129,17 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp, for (maxcol = -1; sp; sp = sp->next) { if (TBL_SPAN_DATA != sp->pos) continue; - spans = 1; + hspans = 1; /* * Account for the data cells in the layout, matching it * to data cells in the data section. */ for (dp = sp->first; dp; dp = dp->next) { /* Do not used spanned cells in the calculation. */ - if (0 < --spans) + if (0 < --hspans) continue; - spans = dp->spans; - if (1 < spans) + hspans = dp->hspans; + if (1 < hspans) continue; icol = dp->layout->col; while (maxcol < icol) @@ -1,7 +1,7 @@ /* $Id$ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2011, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2011, 2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -40,8 +40,9 @@ static void getdata(struct tbl_node *tbl, struct tbl_span *dp, int ln, const char *p, int *pos) { - struct tbl_dat *dat; + struct tbl_dat *dat, *pdat; struct tbl_cell *cp; + struct tbl_span *pdp; int sv; /* Advance to the next layout cell, skipping spanners. */ @@ -73,16 +74,52 @@ getdata(struct tbl_node *tbl, struct tbl_span *dp, } } - dat = mandoc_calloc(1, sizeof(*dat)); + dat = mandoc_malloc(sizeof(*dat)); dat->layout = cp; + dat->next = NULL; + dat->string = NULL; + dat->hspans = 0; + dat->vspans = 0; + dat->block = 0; dat->pos = TBL_DATA_NONE; - dat->spans = 0; + + /* + * Increment the number of vertical spans in a data cell above, + * if this cell vertically extends one or more cells above. + * The iteration must be done over data rows, + * not over layout rows, because one layout row + * can be reused for more than one data row. + */ + + if (cp->pos == TBL_CELL_DOWN) { + pdp = dp; + while ((pdp = pdp->prev) != NULL) { + pdat = pdp->first; + while (pdat != NULL && + pdat->layout->col < dat->layout->col) + pdat = pdat->next; + if (pdat == NULL) + break; + if (pdat->layout->pos != TBL_CELL_DOWN) { + pdat->vspans++; + break; + } + } + } + + /* + * Count the number of horizontal spans to the right of this cell. + * This is purely a matter of the layout, independent of the data. + */ + for (cp = cp->next; cp != NULL; cp = cp->next) if (cp->pos == TBL_CELL_SPAN) - dat->spans++; + dat->hspans++; else break; + /* Append the new data cell to the data row. */ + if (dp->last == NULL) dp->first = dat; else @@ -101,10 +101,10 @@ print_tblclose(struct html *h) void print_tbl(struct html *h, const struct tbl_span *sp) { - const struct tbl_dat *dp; - struct tag *tt; - const char *halign, *valign; - int ic; + const struct tbl_dat *dp; + struct tag *tt; + const char *hspans, *vspans, *halign, *valign; + char hbuf[4], vbuf[4]; /* Inhibit printing of spaces: we do padding ourselves. */ @@ -124,13 +124,31 @@ print_tbl(struct html *h, const struct tbl_span *sp) print_otag(h, TAG_TD, "?", "colspan", "0"); break; default: - dp = sp->first; - for (ic = 0; ic < sp->opts->cols; ic++) { + for (dp = sp->first; dp != NULL; dp = dp->next) { print_stagq(h, tt); - if (dp == NULL || dp->layout->col > ic) { - print_otag(h, TAG_TD, ""); + switch (dp->layout->pos) { + case TBL_CELL_SPAN: + case TBL_CELL_DOWN: continue; + default: + break; } + + /* Determine the attribute values. */ + + if (dp->hspans > 0) { + (void)snprintf(hbuf, sizeof(hbuf), + "%d", dp->hspans + 1); + hspans = hbuf; + } else + hspans = NULL; + if (dp->vspans > 0) { + (void)snprintf(vbuf, sizeof(vbuf), + "%d", dp->vspans + 1); + vspans = vbuf; + } else + vspans = NULL; + switch (dp->layout->pos) { case TBL_CELL_CENTRE: halign = "center"; @@ -149,22 +167,27 @@ print_tbl(struct html *h, const struct tbl_span *sp) valign = "bottom"; else valign = NULL; + + /* Print the element and the attributes. */ + if (halign == NULL && valign == NULL) - print_otag(h, TAG_TD, ""); + print_otag(h, TAG_TD, "??", + "colspan", hspans, "rowspan", vspans); else if (halign == NULL) - print_otag(h, TAG_TD, "s", + print_otag(h, TAG_TD, "??s", + "colspan", hspans, "rowspan", vspans, "vertical-align", valign); else if (valign == NULL) - print_otag(h, TAG_TD, "s", + print_otag(h, TAG_TD, "??s", + "colspan", hspans, "rowspan", vspans, "text-align", halign); else - print_otag(h, TAG_TD, "ss", + print_otag(h, TAG_TD, "??ss", + "colspan", hspans, "rowspan", vspans, "vertical-align", valign, "text-align", halign); - if (dp->layout->pos != TBL_CELL_DOWN) - if (dp->string != NULL) - print_text(h, dp->string); - dp = dp->next; + if (dp->string != NULL) + print_text(h, dp->string); } break; } @@ -77,7 +77,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) const struct tbl_dat *dp; static size_t offset; size_t coloff, tsz; - int ic, horiz, spans, vert, more; + int ic, horiz, hspans, vert, more; char fc; /* Inhibit printing of spaces: we do padding ourselves. */ @@ -157,9 +157,9 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) /* Set up the data columns. */ dp = sp->first; - spans = 0; + hspans = 0; for (ic = 0; ic < sp->opts->cols; ic++) { - if (spans == 0) { + if (hspans == 0) { tp->tcol++; tp->tcol->offset = coloff; } @@ -167,13 +167,13 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) tp->tcol->rmargin = coloff; if (ic + 1 < sp->opts->cols) coloff += tp->tbl.cols[ic].spacing; - if (spans) { - spans--; + if (hspans) { + hspans--; continue; } if (dp == NULL) continue; - spans = dp->spans; + hspans = dp->hspans; if (ic || sp->layout->first->pos != TBL_CELL_SPAN) dp = dp->next; } @@ -193,14 +193,14 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) tp->tcol = tp->tcols; cp = cpn = sp->layout->first; dp = sp->first; - spans = 0; + hspans = 0; for (ic = 0; ic < sp->opts->cols; ic++) { if (cpn != NULL) { cp = cpn; cpn = cpn->next; } - if (spans) { - spans--; + if (hspans) { + hspans--; continue; } tp->tcol++; @@ -208,7 +208,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) tbl_data(tp, sp->opts, cp, dp, tp->tbl.cols + ic); if (dp == NULL) continue; - spans = dp->spans; + hspans = dp->hspans; if (cp->pos != TBL_CELL_SPAN) dp = dp->next; } @@ -249,7 +249,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) cpp = sp->prev == NULL ? NULL : sp->prev->layout->first; dp = sp->first; - spans = 0; + hspans = 0; for (ic = 0; ic < sp->opts->cols; ic++) { /* @@ -304,12 +304,12 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) * and advance to next data cell. */ - if (spans) { - spans--; + if (hspans) { + hspans--; continue; } if (dp != NULL) { - spans = dp->spans; + hspans = dp->hspans; if (ic || sp->layout->first->pos != TBL_CELL_SPAN) dp = dp->next; @@ -592,14 +592,14 @@ tbl_literal(struct termp *tp, const struct tbl_dat *dp, const struct roffcol *col) { size_t len, padl, padr, width; - int ic, spans; + int ic, hspans; assert(dp->string); len = term_strlen(tp, dp->string); width = col->width; ic = dp->layout->col; - spans = dp->spans; - while (spans--) + hspans = dp->hspans; + while (hspans--) width += tp->tbl.cols[++ic].width + 3; padr = width > len ? width - len : 0; @@ -379,35 +379,41 @@ print_span(const struct tbl_span *sp, int indent) switch (sp->pos) { case TBL_SPAN_HORIZ: putchar('-'); - return; + putchar(' '); + break; case TBL_SPAN_DHORIZ: putchar('='); - return; - default: + putchar(' '); break; - } - - for (dp = sp->first; dp; dp = dp->next) { - switch (dp->pos) { - case TBL_DATA_HORIZ: - case TBL_DATA_NHORIZ: - putchar('-'); - continue; - case TBL_DATA_DHORIZ: - case TBL_DATA_NDHORIZ: - putchar('='); - continue; - default: - break; + default: + for (dp = sp->first; dp; dp = dp->next) { + switch (dp->pos) { + case TBL_DATA_HORIZ: + case TBL_DATA_NHORIZ: + putchar('-'); + putchar(' '); + continue; + case TBL_DATA_DHORIZ: + case TBL_DATA_NDHORIZ: + putchar('='); + putchar(' '); + continue; + default: + break; + } + printf("[\"%s\"", dp->string ? dp->string : ""); + if (dp->hspans) + printf(">%d", dp->hspans); + if (dp->vspans) + printf("v%d", dp->vspans); + if (dp->layout == NULL) + putchar('*'); + else if (dp->layout->pos == TBL_CELL_DOWN) + putchar('^'); + putchar(']'); + putchar(' '); } - printf("[\"%s\"", dp->string ? dp->string : ""); - if (dp->spans) - printf("(%d)", dp->spans); - if (NULL == dp->layout) - putchar('*'); - putchar(']'); - putchar(' '); + break; } - printf("(tbl) %d:1\n", sp->line); } |