aboutsummaryrefslogtreecommitdiffstatshomepage
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
commite30a05d61589276c015f65e4ac75df70040c3808 (patch)
treecd0e6ceb3acaf39d7cd2796c21ac8750850a8e15
parent06e66f94d3ea6bc0665d39bb5f02c2acb54c0cc1 (diff)
downloadmandoc-e30a05d61589276c015f65e4ac75df70040c3808.tar.gz
mandoc-e30a05d61589276c015f65e4ac75df70040c3808.tar.zst
mandoc-e30a05d61589276c015f65e4ac75df70040c3808.zip
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--TODO10
-rw-r--r--mandoc.h5
-rw-r--r--out.c12
-rw-r--r--tbl_data.c49
-rw-r--r--tbl_html.c57
-rw-r--r--tbl_term.c36
-rw-r--r--tree.c58
7 files changed, 147 insertions, 80 deletions
diff --git a/TODO b/TODO
index aca76683..48b3be8a 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,6 @@
************************************************************************
* Official mandoc TODO.
-* $Id: TODO,v 1.276 2018/11/25 18:04:58 schwarze Exp $
+* $Id: TODO,v 1.277 2018/11/25 19:24:20 schwarze Exp $
************************************************************************
Many issues are annotated for difficulty as follows:
@@ -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 4adb200b..081d8f8d 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -1,4 +1,4 @@
-/* $Id: mandoc.h,v 1.254 2018/10/25 01:32:40 schwarze Exp $ */
+/* $Id: mandoc.h,v 1.255 2018/11/25 19:24:20 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -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 9b22fe54..ca593578 100644
--- a/out.c
+++ b/out.c
@@ -1,4 +1,4 @@
-/* $Id: out.c,v 1.73 2018/08/19 23:10:28 schwarze Exp $ */
+/* $Id: out.c,v 1.74 2018/11/25 19:24:20 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -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 ae1906ef..9339465e 100644
--- a/tbl_data.c
+++ b/tbl_data.c
@@ -1,7 +1,7 @@
-/* $Id: tbl_data.c,v 1.45 2017/07/08 17:52:50 schwarze Exp $ */
+/* $Id: tbl_data.c,v 1.46 2018/11/25 19:24:20 schwarze Exp $ */
/*
* 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 1080ffdf..b6090038 100644
--- a/tbl_html.c
+++ b/tbl_html.c
@@ -1,4 +1,4 @@
-/* $Id: tbl_html.c,v 1.25 2018/11/24 23:03:18 schwarze Exp $ */
+/* $Id: tbl_html.c,v 1.26 2018/11/25 19:24:20 schwarze Exp $ */
/*
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -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 07ecc036..a552c5e8 100644
--- a/tbl_term.c
+++ b/tbl_term.c
@@ -1,4 +1,4 @@
-/* $Id: tbl_term.c,v 1.60 2018/08/19 23:10:28 schwarze Exp $ */
+/* $Id: tbl_term.c,v 1.61 2018/11/25 19:24:20 schwarze Exp $ */
/*
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011-2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -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 416253f7..f78767ce 100644
--- a/tree.c
+++ b/tree.c
@@ -1,4 +1,4 @@
-/* $Id: tree.c,v 1.79 2018/08/14 01:27:48 schwarze Exp $ */
+/* $Id: tree.c,v 1.80 2018/11/25 19:24:20 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -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);
}