summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2018-11-25 19:24:20 +0000
committerIngo Schwarze <schwarze@openbsd.org>2018-11-25 19:24:20 +0000
commit059731525cc9a54258e9e3b825e28777a212ff15 (patch)
tree30d57f784c3cfd5db5e6193905cb1ac682176943
parent146de3f75b3f64ddd06ababf395811b3abbb2fb3 (diff)
downloadmandoc-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--TODO8
-rw-r--r--mandoc.h3
-rw-r--r--out.c10
-rw-r--r--tbl_data.c47
-rw-r--r--tbl_html.c55
-rw-r--r--tbl_term.c34
-rw-r--r--tree.c56
7 files changed, 140 insertions, 73 deletions
diff --git a/TODO b/TODO
index 81ef36a4..130c975a 100644
--- a/TODO
+++ b/TODO
@@ -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 **
diff --git a/mandoc.h b/mandoc.h
index ad1a6d3c..541e7d71 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -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;
};
diff --git a/out.c b/out.c
index bd4c01da..43a4ca4b 100644
--- a/out.c
+++ b/out.c
@@ -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)
diff --git a/tbl_data.c b/tbl_data.c
index 01bc62d2..58637d35 100644
--- a/tbl_data.c
+++ b/tbl_data.c
@@ -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
diff --git a/tbl_html.c b/tbl_html.c
index d396cea8..4ace9e09 100644
--- a/tbl_html.c
+++ b/tbl_html.c
@@ -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;
}
diff --git a/tbl_term.c b/tbl_term.c
index c5e22b94..7676dfd5 100644
--- a/tbl_term.c
+++ b/tbl_term.c
@@ -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;
diff --git a/tree.c b/tree.c
index c0949dde..09b53ab3 100644
--- a/tree.c
+++ b/tree.c
@@ -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);
}