summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);
}