summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libroff.h2
-rw-r--r--mandoc.h14
-rw-r--r--out.c2
-rw-r--r--tbl.3125
-rw-r--r--tbl.c6
-rw-r--r--tbl_data.c9
-rw-r--r--tbl_html.c14
-rw-r--r--tbl_layout.c31
-rw-r--r--tbl_term.c35
9 files changed, 124 insertions, 114 deletions
diff --git a/libroff.h b/libroff.h
index 4079002b..537b9f5b 100644
--- a/libroff.h
+++ b/libroff.h
@@ -34,8 +34,6 @@ struct tbl_node {
struct tbl_span *first_span;
struct tbl_span *current_span;
struct tbl_span *last_span;
- struct tbl_head *first_head;
- struct tbl_head *last_head;
struct tbl_node *next;
};
diff --git a/mandoc.h b/mandoc.h
index bf0a1ad1..2267f1d8 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -204,17 +204,6 @@ struct tbl_opts {
int rvert; /* width of right vertical line */
};
-/*
- * The head of a table specifies all of its columns. When formatting a
- * tbl_span, iterate over these and plug in data from the tbl_span when
- * appropriate, using tbl_cell as a guide to placement.
- */
-struct tbl_head {
- int ident; /* 0 <= unique id < cols */
- struct tbl_head *next;
- struct tbl_head *prev;
-};
-
enum tbl_cellt {
TBL_CELL_CENTRE, /* c, C */
TBL_CELL_RIGHT, /* r, R */
@@ -236,6 +225,7 @@ struct tbl_cell {
int vert; /* width of subsequent vertical line */
enum tbl_cellt pos;
size_t spacing;
+ int col; /* column number, starting from 0 */
int flags;
#define TBL_CELL_TALIGN (1 << 0) /* t, T */
#define TBL_CELL_BALIGN (1 << 1) /* d, D */
@@ -245,7 +235,6 @@ struct tbl_cell {
#define TBL_CELL_UP (1 << 5) /* u, U */
#define TBL_CELL_WIGN (1 << 6) /* z, Z */
#define TBL_CELL_WMAX (1 << 7) /* x, X */
- struct tbl_head *head;
};
/*
@@ -290,7 +279,6 @@ enum tbl_spant {
*/
struct tbl_span {
struct tbl_opts *opts;
- struct tbl_head *head;
struct tbl_row *layout; /* layout row */
struct tbl_dat *first;
struct tbl_dat *last;
diff --git a/out.c b/out.c
index 68e00253..d22b96ad 100644
--- a/out.c
+++ b/out.c
@@ -140,7 +140,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
spans = dp->spans;
if (1 < spans)
continue;
- icol = dp->layout->head->ident;
+ icol = dp->layout->col;
if (maxcol < icol)
maxcol = icol;
col = tbl->cols + icol;
diff --git a/tbl.3 b/tbl.3
index 8a0f1842..0715c9b8 100644
--- a/tbl.3
+++ b/tbl.3
@@ -79,12 +79,37 @@ It is defined in
created in
.Fn tbl_alloc ,
and stored in the members
-.Va first_tbl ,
-.Va last_tbl ,
+.Fa first_tbl ,
+.Fa last_tbl ,
and
-.Va tbl
+.Fa tbl
of
.Vt struct roff Bq Pa roff.c .
+.Pp
+The
+.Fa first_span ,
+.Fa current_span ,
+.Fa last_span ,
+and
+.Fa next
+members may be
+.Dv NULL .
+The
+.Fa first_row
+and
+.Fa last_row
+members may be
+.Dv NULL ,
+but if there is a span, the function
+.Fn tbl_layout
+guarantees that these pointers are not
+.Dv NULL .
+The function
+.Fn tbl_alloc
+guarantees that the
+.Fa parse
+member is not
+.Dv NULL .
.It Vt struct tbl_opts
This structure describes the options of one table.
It is used as a substructure of
@@ -92,26 +117,27 @@ It is used as a substructure of
and thus created and deleted together with it.
It is filled in
.Fn tbl_options .
-.It Vt struct tbl_head
-This structure describes one layout column in a table,
-in particular the vertical line to its left.
-It is allocated and filled in
-.Fn cell_alloc Bq Pa tbl_layout.c
-and referenced from the
-.Va first_head
-and
-.Va last_head
-members of
-.Vt struct tbl_node .
.It Vt struct tbl_row
This structure describes one layout line in a table
by maintaining a list of all the cells in that line.
It is allocated and filled in
.Fn row Bq Pa tbl_layout.c
and referenced from the
-.Va layout
+.Fa layout
member of
.Vt struct tbl_node .
+.Pp
+The
+.Fa next
+member may be
+.Dv NULL .
+The function
+.Fn tbl_layout
+guarantees that the
+.Fa first
+and
+.Fa last
+members are not NULL.
.It Vt struct tbl_cell
This structure describes one layout cell in a table,
in particular its alignment, membership in spans, and
@@ -119,11 +145,16 @@ usage for lines.
It is allocated and filled in
.Fn cell_alloc Bq Pa tbl_layout.c
and referenced from the
-.Va first
+.Fa first
and
-.Va last
+.Fa last
members of
.Vt struct tbl_row .
+.Pp
+The
+.Fa next
+member may be
+.Dv NULL .
.It Vt struct tbl_span
This structure describes one data line in a table
by maintaining a list of all data cells in that line
@@ -133,14 +164,14 @@ It is allocated and filled in
which is called from
.Fn tbl_data
and referenced from the
-.Va first_span ,
-.Va current_span ,
+.Fa first_span ,
+.Fa current_span ,
and
-.Va last_span
+.Fa last_span
members of
.Vt struct tbl_node ,
and from the
-.Va span
+.Fa span
members of
.Vt struct man_node
and
@@ -149,18 +180,48 @@ from
.In man.h
and
.In mdoc.h .
+.Pp
+The
+.Fa first ,
+.Fa last ,
+.Fa prev ,
+and
+.Fa next
+members may be
+.Dv NULL .
+The function
+.Fn newspan Bq Pa tbl_data.c
+guarantees that the
+.Fa opts
+and
+.Fa layout
+members are not
+.Dv NULL .
.It Vt struct tbl_dat
This structure describes one data cell in a table by specifying
whether it contains a line or data, whether it spans additional
layout cells, and by storing the data.
It is allocated and filled in
-.Fn data
+.Fn tbl_data
and referenced from the
-.Va first
+.Fa first
and
-.Va last
+.Fa last
members of
.Vt struct tbl_span .
+.Pp
+The
+.Fa string
+and
+.Fa next
+members may be
+.Dv NULL .
+The function
+.Fn getdata
+guarantees that the
+.Fa layout
+member is not
+.Dv NULL .
.El
.Ss Interface functions
The following functions are implemented in
@@ -185,7 +246,7 @@ Called from
.Fn roff_parseln .
.It Fn tbl_restart
Resets the
-.Va part
+.Fa part
member of
.Vt struct tbl_node
to
@@ -210,7 +271,7 @@ and
.It Fn tbl_free
Frees the specified
.Vt struct tbl_node
-and all the tbl_row, tbl_cell, tbl_span, tbl_dat and tbl_head structures
+and all the tbl_row, tbl_cell, tbl_span, and tbl_dat structures
referenced from it.
Called from
.Fn roff_free
@@ -228,10 +289,8 @@ called from
.Fn tbl_read .
.It Ft int Fn tbl_layout "struct tbl_node *tbl" "int ln" "const char *p"
Allocates and fills one
-.Vt struct tbl_head
-for each layout column, one
.Vt struct tbl_row
-for each layout line, and one
+for each layout line and one
.Vt struct tbl_cell
for each layout cell.
Implemented in
@@ -242,8 +301,8 @@ called from
Allocates one
.Vt struct tbl_span
for each data line and calls
-.Fn data
-on that line.
+.Fn getdata
+for each data cell.
Implemented in
.Pa tbl_data.c ,
called from
@@ -255,7 +314,7 @@ When finding
switches back to
.Dv TBL_PART_DATA
mode and calls
-.Fn data
+.Fn getdata
if there are more data cells on the line.
Otherwise, appends the data to the current data cell.
Implemented in
@@ -264,7 +323,7 @@ called from
.Fn tbl_read .
.It Xo
.Ft int
-.Fo data
+.Fo getdata
.Fa "struct tbl_node *tbl"
.Fa "struct tbl_span *dp"
.Fa "int ln"
diff --git a/tbl.c b/tbl.c
index b596dd1f..1a9f01a5 100644
--- a/tbl.c
+++ b/tbl.c
@@ -108,7 +108,6 @@ tbl_free(struct tbl_node *tbl)
struct tbl_cell *cp;
struct tbl_span *sp;
struct tbl_dat *dp;
- struct tbl_head *hp;
while ((rp = tbl->first_row) != NULL) {
tbl->first_row = rp->next;
@@ -131,11 +130,6 @@ tbl_free(struct tbl_node *tbl)
free(sp);
}
- while ((hp = tbl->first_head) != NULL) {
- tbl->first_head = hp->next;
- free(hp);
- }
-
free(tbl);
}
diff --git a/tbl_data.c b/tbl_data.c
index 77c04cf2..697b9073 100644
--- a/tbl_data.c
+++ b/tbl_data.c
@@ -44,13 +44,9 @@ getdata(struct tbl_node *tbl, struct tbl_span *dp,
struct tbl_cell *cp;
int sv;
- cp = dp->last == NULL ? dp->layout->first : dp->last->layout->next;
-
- /*
- * Skip over spanners, since
- * we want to match data with data layout cells in the header.
- */
+ /* Advance to the next layout cell, skipping spanners. */
+ cp = dp->last == NULL ? dp->layout->first : dp->last->layout->next;
while (cp != NULL && cp->pos == TBL_CELL_SPAN)
cp = cp->next;
@@ -172,7 +168,6 @@ newspan(struct tbl_node *tbl, int line, struct tbl_row *rp)
dp->line = line;
dp->opts = &tbl->opts;
dp->layout = rp;
- dp->head = tbl->first_head;
dp->prev = tbl->last_span;
if (dp->prev == NULL) {
diff --git a/tbl_html.c b/tbl_html.c
index 08dc1c7a..617ade75 100644
--- a/tbl_html.c
+++ b/tbl_html.c
@@ -49,10 +49,10 @@ html_tbl_strlen(const char *p, void *arg)
static void
html_tblopen(struct html *h, const struct tbl_span *sp)
{
- const struct tbl_head *hp;
struct htmlpair tag;
struct roffsu su;
struct roffcol *col;
+ int ic;
if (sp->flags & TBL_SPAN_FIRST) {
h->tbl.len = html_tbl_len;
@@ -64,9 +64,9 @@ html_tblopen(struct html *h, const struct tbl_span *sp)
PAIR_CLASS_INIT(&tag, "tbl");
h->tblt = print_otag(h, TAG_TABLE, 1, &tag);
- for (hp = sp->head; hp; hp = hp->next) {
+ for (ic = 0; ic < sp->opts->cols; ic++) {
bufinit(h);
- col = &h->tbl.cols[hp->ident];
+ col = h->tbl.cols + ic;
SCALE_HS_INIT(&su, col->width);
bufcat_su(h, "width", &su);
PAIR_STYLE_INIT(&tag, h);
@@ -88,10 +88,10 @@ print_tblclose(struct html *h)
void
print_tbl(struct html *h, const struct tbl_span *sp)
{
- const struct tbl_head *hp;
const struct tbl_dat *dp;
struct htmlpair tag;
struct tag *tt;
+ int ic;
/* Inhibit printing of spaces: we do padding ourselves. */
@@ -114,12 +114,12 @@ print_tbl(struct html *h, const struct tbl_span *sp)
break;
default:
dp = sp->first;
- for (hp = sp->head; hp; hp = hp->next) {
+ for (ic = 0; ic < sp->opts->cols; ic++) {
print_stagq(h, tt);
print_otag(h, TAG_TD, 0, NULL);
- if (dp == NULL)
- break;
+ if (dp == NULL || dp->layout->col > ic)
+ continue;
if (dp->layout->pos != TBL_CELL_DOWN)
if (dp->string != NULL)
print_text(h, dp->string);
diff --git a/tbl_layout.c b/tbl_layout.c
index fbd0ebf8..9366b5dd 100644
--- a/tbl_layout.c
+++ b/tbl_layout.c
@@ -282,7 +282,7 @@ tbl_layout(struct tbl_node *tbl, int ln, const char *p, int pos)
if (tbl->opts.lvert < rp->vert)
tbl->opts.lvert = rp->vert;
if (rp->last != NULL &&
- rp->last->head == tbl->last_head &&
+ rp->last->col + 1 == tbl->opts.cols &&
tbl->opts.rvert < rp->last->vert)
tbl->opts.rvert = rp->last->vert;
@@ -324,38 +324,19 @@ static struct tbl_cell *
cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos)
{
struct tbl_cell *p, *pp;
- struct tbl_head *h, *hp;
p = mandoc_calloc(1, sizeof(*p));
+ p->pos = pos;
if ((pp = rp->last) != NULL) {
pp->next = p;
- h = pp->head->next;
- } else {
+ p->col = pp->col + 1;
+ } else
rp->first = p;
- h = tbl->first_head;
- }
rp->last = p;
- p->pos = pos;
-
- /* Re-use header. */
-
- if (h != NULL) {
- p->head = h;
- return(p);
- }
-
- hp = mandoc_calloc(1, sizeof(*hp));
- hp->ident = tbl->opts.cols++;
-
- if (tbl->last_head != NULL) {
- hp->prev = tbl->last_head;
- tbl->last_head->next = hp;
- } else
- tbl->first_head = hp;
- tbl->last_head = hp;
+ if (tbl->opts.cols <= p->col)
+ tbl->opts.cols = p->col + 1;
- p->head = hp;
return(p);
}
diff --git a/tbl_term.c b/tbl_term.c
index 949cfaff..8e42fe38 100644
--- a/tbl_term.c
+++ b/tbl_term.c
@@ -60,12 +60,11 @@ term_tbl_len(size_t sz, void *arg)
void
term_tbl(struct termp *tp, const struct tbl_span *sp)
{
- const struct tbl_head *hp;
const struct tbl_cell *cp;
const struct tbl_dat *dp;
static size_t offset;
size_t rmargin, maxrmargin, tsz;
- int horiz, spans, vert;
+ int ic, horiz, spans, vert;
rmargin = tp->rmargin;
maxrmargin = tp->maxrmargin;
@@ -97,8 +96,8 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
if (sp->opts->opts & TBL_OPT_CENTRE) {
tsz = sp->opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX)
? 2 : !!sp->opts->lvert + !!sp->opts->rvert;
- for (hp = sp->head; hp != NULL; hp = hp->next)
- tsz += tp->tbl.cols[hp->ident].width + 3;
+ for (ic = 0; ic < sp->opts->cols; ic++)
+ tsz += tp->tbl.cols[ic].width + 3;
tsz -= 3;
if (offset + tsz > rmargin)
tsz -= 1;
@@ -127,16 +126,14 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
/*
* Now print the actual data itself depending on the span type.
- * Spanner spans get a horizontal rule; data spanners have their
- * data printed by matching data to header.
+ * Match data cells to column numbers.
*/
if (sp->pos == TBL_SPAN_DATA) {
- /* Iterate over template headers. */
cp = sp->layout->first;
dp = sp->first;
spans = 0;
- for (hp = sp->head; hp != NULL; hp = hp->next) {
+ for (ic = 0; ic < sp->opts->cols; ic++) {
/*
* Remeber whether we need a vertical bar
@@ -150,8 +147,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
*/
if (spans == 0) {
- tbl_data(tp, sp->opts, dp,
- tp->tbl.cols + hp->ident);
+ tbl_data(tp, sp->opts, dp, tp->tbl.cols + ic);
if (dp != NULL) {
spans = dp->spans;
dp = dp->next;
@@ -166,13 +162,13 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
* of spans and after the last cell.
*/
- if (hp->next == NULL || spans)
+ if (ic + 1 == sp->opts->cols || spans)
continue;
tbl_char(tp, ASCII_NBRSP, 1);
if (vert > 0)
tbl_char(tp, '|', vert);
- if (vert < 2 && hp->next != NULL)
+ if (vert < 2)
tbl_char(tp, ASCII_NBRSP, 2 - vert);
}
} else if (horiz)
@@ -236,7 +232,7 @@ tbl_hrule(struct termp *tp, const struct tbl_span *sp, int kind)
if (c2 == c1)
c2 = NULL;
for (;;) {
- tbl_char(tp, line, tp->tbl.cols[c1->head->ident].width + 1);
+ tbl_char(tp, line, tp->tbl.cols[c1->col].width + 1);
vert = c1->vert;
if ((c1 = c1->next) == NULL)
break;
@@ -332,17 +328,16 @@ static void
tbl_literal(struct termp *tp, const struct tbl_dat *dp,
const struct roffcol *col)
{
- struct tbl_head *hp;
- size_t width, len, padl, padr;
- int spans;
+ size_t len, padl, padr, width;
+ int ic, spans;
assert(dp->string);
len = term_strlen(tp, dp->string);
-
- hp = dp->layout->head->next;
width = col->width;
- for (spans = dp->spans; spans--; hp = hp->next)
- width += tp->tbl.cols[hp->ident].width + 3;
+ ic = dp->layout->col;
+ spans = dp->spans;
+ while (spans--)
+ width += tp->tbl.cols[++ic].width + 3;
padr = width > len ? width - len : 0;
padl = 0;