aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2011-01-13 14:30:13 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2011-01-13 14:30:13 +0000
commitfa547cebe06d42ee136cd3db4c7459b4d8d5d733 (patch)
tree864789a2f76536034eabbee53825ef74ea5eed38
parentb35c31f766657bf4a7337b30d10f61bd8b018af4 (diff)
downloadmandoc-fa547cebe06d42ee136cd3db4c7459b4d8d5d733.tar.gz
mandoc-fa547cebe06d42ee136cd3db4c7459b4d8d5d733.tar.zst
mandoc-fa547cebe06d42ee136cd3db4c7459b4d8d5d733.zip
Change how -Thtml behaves with tables: use multiple rows, with widths
set by COL, until an external macro is encountered. At this point in time, close out the table and process the macro. When the first table row is again re-encountered, re-start the table. This requires a bit of tracking added to "struct html", but the change is very small and follows the logic of meta-fonts. This all follows a bug-report by joerg@.
-rw-r--r--html.c15
-rw-r--r--html.h5
-rw-r--r--man_html.c20
-rw-r--r--mdoc_html.c24
-rw-r--r--tbl_html.c107
5 files changed, 117 insertions, 54 deletions
diff --git a/html.c b/html.c
index 70403ff7..b884dab1 100644
--- a/html.c
+++ b/html.c
@@ -1,4 +1,4 @@
-/* $Id: html.c,v 1.124 2010/12/27 21:41:05 schwarze Exp $ */
+/* $Id: html.c,v 1.125 2011/01/13 14:30:13 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -90,6 +90,7 @@ static const char *const htmlattrs[ATTR_MAX] = {
"id", /* ATTR_ID */
"summary", /* ATTR_SUMMARY */
"align", /* ATTR_ALIGN */
+ "colspan", /* ATTR_COLSPAN */
};
static void print_spec(struct html *, enum roffdeco,
@@ -581,8 +582,14 @@ print_tagq(struct html *h, const struct tag *until)
struct tag *tag;
while ((tag = h->tags.head) != NULL) {
+ /*
+ * Remember to close out and nullify the current
+ * meta-font and table, if applicable.
+ */
if (tag == h->metaf)
h->metaf = NULL;
+ if (tag == h->tblt)
+ h->tblt = NULL;
print_ctag(h, tag->tag);
h->tags.head = tag->next;
free(tag);
@@ -600,8 +607,14 @@ print_stagq(struct html *h, const struct tag *suntil)
while ((tag = h->tags.head) != NULL) {
if (suntil && tag == suntil)
return;
+ /*
+ * Remember to close out and nullify the current
+ * meta-font and table, if applicable.
+ */
if (tag == h->metaf)
h->metaf = NULL;
+ if (tag == h->tblt)
+ h->tblt = NULL;
print_ctag(h, tag->tag);
h->tags.head = tag->next;
free(tag);
diff --git a/html.h b/html.h
index 8d9db890..da31f2ed 100644
--- a/html.h
+++ b/html.h
@@ -1,4 +1,4 @@
-/* $Id: html.h,v 1.38 2011/01/06 11:55:39 kristaps Exp $ */
+/* $Id: html.h,v 1.39 2011/01/13 14:30:13 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -67,6 +67,7 @@ enum htmlattr {
ATTR_ID,
ATTR_SUMMARY,
ATTR_ALIGN,
+ ATTR_COLSPAN,
ATTR_MAX
};
@@ -117,6 +118,7 @@ struct html {
#define HTML_NONOSPACE (1 << 4)
struct tagq tags; /* stack of open tags */
struct rofftbl tbl; /* current table */
+ struct tag *tblt; /* current open table scope */
void *symtab; /* character-escapes */
char *base_man; /* base for manpage href */
char *base_includes; /* base for include href */
@@ -136,6 +138,7 @@ struct tag *print_otag(struct html *, enum htmltag,
void print_tagq(struct html *, const struct tag *);
void print_stagq(struct html *, const struct tag *);
void print_text(struct html *, const char *);
+void print_tblclose(struct html *);
void print_tbl(struct html *, const struct tbl_span *);
void bufcat_su(struct html *, const char *,
diff --git a/man_html.c b/man_html.c
index ab1afb43..1110b548 100644
--- a/man_html.c
+++ b/man_html.c
@@ -1,4 +1,4 @@
-/* $Id: man_html.c,v 1.65 2011/01/12 15:41:09 kristaps Exp $ */
+/* $Id: man_html.c,v 1.66 2011/01/13 14:30:13 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -216,18 +216,32 @@ print_man_node(MAN_ARGS)
print_otag(h, TAG_BR, 0, NULL);
return;
case (MAN_TBL):
+ /*
+ * This will take care of initialising all of the table
+ * state data for the first table, then tearing it down
+ * for the last one.
+ */
print_tbl(h, n->span);
return;
default:
/*
* Close out scope of font prior to opening a macro
- * scope. Assert that the metafont is on the top of the
- * stack (it's never nested).
+ * scope.
*/
if (HTMLFONT_NONE != h->metac) {
h->metal = h->metac;
h->metac = HTMLFONT_NONE;
}
+
+ /*
+ * Close out the current table, if it's open, and unset
+ * the "meta" table state. This will be reopened on the
+ * next table element.
+ */
+ if (h->tblt) {
+ print_tblclose(h);
+ t = h->tags.head;
+ }
if (mans[n->tok].pre)
child = (*mans[n->tok].pre)(m, n, mh, h);
break;
diff --git a/mdoc_html.c b/mdoc_html.c
index b2a421bd..15d87f7e 100644
--- a/mdoc_html.c
+++ b/mdoc_html.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_html.c,v 1.143 2011/01/12 10:43:22 kristaps Exp $ */
+/* $Id: mdoc_html.c,v 1.144 2011/01/13 14:30:13 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -420,14 +420,32 @@ print_mdoc_node(MDOC_ARGS)
child = mdoc_root_pre(m, n, h);
break;
case (MDOC_TEXT):
+ /* No tables in this mode... */
+ assert(NULL == h->tblt);
if (' ' == *n->string && MDOC_LINE & n->flags)
print_otag(h, TAG_BR, 0, NULL);
print_text(h, n->string);
return;
case (MDOC_TBL):
+ /*
+ * This will take care of initialising all of the table
+ * state data for the first table, then tearing it down
+ * for the last one.
+ */
print_tbl(h, n->span);
- break;
+ return;
default:
+ /*
+ * Close out the current table, if it's open, and unset
+ * the "meta" table state. This will be reopened on the
+ * next table element.
+ */
+ if (h->tblt) {
+ print_tblclose(h);
+ t = h->tags.head;
+ }
+
+ assert(NULL == h->tblt);
if (mdocs[n->tok].pre && ENDBODY_NOT == n->end)
child = (*mdocs[n->tok].pre)(m, n, h);
break;
@@ -455,8 +473,6 @@ print_mdoc_node(MDOC_ARGS)
case (MDOC_ROOT):
mdoc_root_post(m, n, h);
break;
- case (MDOC_TBL):
- break;
default:
if (mdocs[n->tok].post && ENDBODY_NOT == n->end)
(*mdocs[n->tok].post)(m, n, h);
diff --git a/tbl_html.c b/tbl_html.c
index ebad7c77..68d3f9c5 100644
--- a/tbl_html.c
+++ b/tbl_html.c
@@ -1,4 +1,4 @@
-/* $Id: tbl_html.c,v 1.6 2011/01/11 14:12:01 kristaps Exp $ */
+/* $Id: tbl_html.c,v 1.7 2011/01/13 14:30:13 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -27,6 +27,7 @@
#include "out.h"
#include "html.h"
+static void html_tblopen(struct html *, const struct tbl_span *);
static size_t html_tbl_len(size_t, void *);
static size_t html_tbl_strlen(const char *, void *);
@@ -46,89 +47,105 @@ html_tbl_strlen(const char *p, void *arg)
return(strlen(p));
}
+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;
+
+ if (TBL_SPAN_FIRST & sp->flags) {
+ h->tbl.len = html_tbl_len;
+ h->tbl.slen = html_tbl_strlen;
+ tblcalc(&h->tbl, sp);
+ }
+
+ assert(NULL == h->tblt);
+ PAIR_CLASS_INIT(&tag, "tbl");
+ h->tblt = print_otag(h, TAG_TABLE, 1, &tag);
+
+ for (hp = sp->head; hp; hp = hp->next) {
+ bufinit(h);
+ col = &h->tbl.cols[hp->ident];
+ SCALE_HS_INIT(&su, col->width);
+ bufcat_su(h, "width", &su);
+ PAIR_STYLE_INIT(&tag, h);
+ print_otag(h, TAG_COL, 1, &tag);
+ }
+
+ print_otag(h, TAG_TBODY, 0, NULL);
+}
+
+void
+print_tblclose(struct html *h)
+{
+
+ assert(h->tblt);
+ print_tagq(h, h->tblt);
+ h->tblt = NULL;
+}
+
void
print_tbl(struct html *h, const struct tbl_span *sp)
{
const struct tbl_head *hp;
const struct tbl_dat *dp;
- struct tag *tt;
struct htmlpair tag;
- struct roffsu su;
- struct roffcol *col;
+ struct tag *tt;
/* Inhibit printing of spaces: we do padding ourselves. */
+ if (NULL == h->tblt)
+ html_tblopen(h, sp);
+
+ assert(h->tblt);
+
h->flags |= HTML_NONOSPACE;
h->flags |= HTML_NOSPACE;
- /* First pass: calculate widths. */
-
- if (TBL_SPAN_FIRST & sp->flags) {
- h->tbl.len = html_tbl_len;
- h->tbl.slen = html_tbl_strlen;
- tblcalc(&h->tbl, sp);
- }
+ tt = print_otag(h, TAG_TR, 0, NULL);
switch (sp->pos) {
case (TBL_SPAN_HORIZ):
/* FALLTHROUGH */
case (TBL_SPAN_DHORIZ):
+ PAIR_INIT(&tag, ATTR_COLSPAN, "0");
+ print_otag(h, TAG_TD, 1, &tag);
break;
default:
- PAIR_CLASS_INIT(&tag, "tbl");
- print_otag(h, TAG_TABLE, 1, &tag);
- print_otag(h, TAG_TR, 0, NULL);
-
- /* Iterate over template headers. */
-
dp = sp->first;
for (hp = sp->head; hp; hp = hp->next) {
+ print_stagq(h, tt);
+ print_otag(h, TAG_TD, 0, NULL);
+
switch (hp->pos) {
case (TBL_HEAD_VERT):
/* FALLTHROUGH */
case (TBL_HEAD_DVERT):
continue;
case (TBL_HEAD_DATA):
- break;
- }
-
- /*
- * For the time being, use the simplest possible
- * table styling: setting the widths of data
- * columns.
- */
-
- col = &h->tbl.cols[hp->ident];
- SCALE_HS_INIT(&su, col->width);
- bufcat_su(h, "width", &su);
- PAIR_STYLE_INIT(&tag, h);
- tt = print_otag(h, TAG_TD, 1, &tag);
-
- if (dp) {
- switch (dp->layout->pos) {
- case (TBL_CELL_DOWN):
- break;
- default:
- if (NULL == dp->string)
- break;
- print_text(h, dp->string);
+ if (NULL == dp)
break;
- }
+ if (TBL_CELL_DOWN != dp->layout->pos)
+ if (dp->string)
+ print_text(h, dp->string);
dp = dp->next;
+ break;
}
-
- print_tagq(h, tt);
}
break;
}
- h->flags &= ~HTML_NONOSPACE;
+ print_tagq(h, tt);
- /* Close out column specifiers on the last span. */
+ h->flags &= ~HTML_NONOSPACE;
if (TBL_SPAN_LAST & sp->flags) {
assert(h->tbl.cols);
free(h->tbl.cols);
h->tbl.cols = NULL;
+ print_tblclose(h);
}
+
}