diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2018-11-25 19:24:20 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2018-11-25 19:24:20 +0000 |
commit | 059731525cc9a54258e9e3b825e28777a212ff15 (patch) | |
tree | 30d57f784c3cfd5db5e6193905cb1ac682176943 | |
parent | 146de3f75b3f64ddd06ababf395811b3abbb2fb3 (diff) | |
download | mandoc-059731525cc9a54258e9e3b825e28777a212ff15.tar.gz |
In tbl(7) -T html output,
span cells horizontally and vertically as requested by the layout.
Does not handle spans requested in the data section yet.
To be able to do this, record the number of rows spanned
in the first data cell (struct tbl_dat) of a vertical span.
Missing feature reported by Pali dot Rohar at gmail dot com.
-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); } |