]> git.cameronkatri.com Git - mandoc.git/blobdiff - mdoc_html.c
Added enum mdoc_disp (similar to enum mdoc_list). Display types are now
[mandoc.git] / mdoc_html.c
index 43abe55d4580ca0986277d38ae06f5cae175d71c..0df11dc355e3b2836a7e7db90709ccd05ff80b16 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_html.c,v 1.58 2010/04/06 07:27:42 kristaps Exp $ */
+/*     $Id: mdoc_html.c,v 1.79 2010/06/12 10:09:19 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -27,6 +27,7 @@
 #include <string.h>
 #include <unistd.h>
 
+#include "mandoc.h"
 #include "out.h"
 #include "html.h"
 #include "mdoc.h"
@@ -52,12 +53,12 @@ static      void              print_mdoc(MDOC_ARGS);
 static void              print_mdoc_head(MDOC_ARGS);
 static void              print_mdoc_node(MDOC_ARGS);
 static void              print_mdoc_nodelist(MDOC_ARGS);
+static void              synopsis_pre(struct html *, 
+                               const struct mdoc_node *);
 
 static void              a2width(const char *, struct roffsu *);
 static void              a2offs(const char *, struct roffsu *);
 
-static int               a2list(const struct mdoc_node *);
-
 static void              mdoc_root_post(MDOC_ARGS);
 static int               mdoc_root_pre(MDOC_ARGS);
 
@@ -97,11 +98,12 @@ static      void              mdoc_fo_post(MDOC_ARGS);
 static int               mdoc_fo_pre(MDOC_ARGS);
 static int               mdoc_ic_pre(MDOC_ARGS);
 static int               mdoc_in_pre(MDOC_ARGS);
-static int               mdoc_it_block_pre(MDOC_ARGS, int, int,
-                               struct roffsu *, struct roffsu *);
-static int               mdoc_it_head_pre(MDOC_ARGS, int, 
+static int               mdoc_it_block_pre(MDOC_ARGS, enum mdoc_list,
+                               int, struct roffsu *, struct roffsu *);
+static int               mdoc_it_head_pre(MDOC_ARGS, enum mdoc_list, 
+                               struct roffsu *);
+static int               mdoc_it_body_pre(MDOC_ARGS, enum mdoc_list,
                                struct roffsu *);
-static int               mdoc_it_body_pre(MDOC_ARGS, int);
 static int               mdoc_it_pre(MDOC_ARGS);
 static int               mdoc_lb_pre(MDOC_ARGS);
 static int               mdoc_li_pre(MDOC_ARGS);
@@ -255,6 +257,7 @@ static      const struct htmlmdoc mdocs[MDOC_MAX] = {
        {mdoc_sp_pre, NULL}, /* br */
        {mdoc_sp_pre, NULL}, /* sp */ 
        {mdoc__x_pre, mdoc__x_post}, /* %U */ 
+       {NULL, NULL}, /* Ta */ 
 };
 
 
@@ -275,50 +278,6 @@ html_mdoc(void *arg, const struct mdoc *m)
 }
 
 
-/*
- * Return the list type for `Bl', e.g., `Bl -column' returns 
- * MDOC_Column.  This can ONLY be run for lists; it will abort() if no
- * list type is found. 
- */
-static int
-a2list(const struct mdoc_node *n)
-{
-       int              i;
-
-       assert(n->args);
-       for (i = 0; i < (int)n->args->argc; i++) 
-               switch (n->args->argv[i].arg) {
-               case (MDOC_Enum):
-                       /* FALLTHROUGH */
-               case (MDOC_Dash):
-                       /* FALLTHROUGH */
-               case (MDOC_Hyphen):
-                       /* FALLTHROUGH */
-               case (MDOC_Bullet):
-                       /* FALLTHROUGH */
-               case (MDOC_Tag):
-                       /* FALLTHROUGH */
-               case (MDOC_Hang):
-                       /* FALLTHROUGH */
-               case (MDOC_Inset):
-                       /* FALLTHROUGH */
-               case (MDOC_Diag):
-                       /* FALLTHROUGH */
-               case (MDOC_Item):
-                       /* FALLTHROUGH */
-               case (MDOC_Column):
-                       /* FALLTHROUGH */
-               case (MDOC_Ohang):
-                       return(n->args->argv[i].arg);
-               default:
-                       break;
-               }
-
-       abort();
-       /* NOTREACHED */
-}
-
-
 /*
  * Calculate the scaling unit passed in a `-width' argument.  This uses
  * either a native scaling unit (e.g., 1i, 2m) or the string length of
@@ -335,6 +294,55 @@ a2width(const char *p, struct roffsu *su)
 }
 
 
+/*
+ * See the same function in mdoc_term.c for documentation.
+ */
+static void
+synopsis_pre(struct html *h, const struct mdoc_node *n)
+{
+       struct roffsu    su;
+       struct htmlpair  tag;
+
+       if (NULL == n->prev || SEC_SYNOPSIS != n->sec)
+               return;
+
+       SCALE_VS_INIT(&su, 1);
+       bufcat_su(h, "margin-top", &su);
+       PAIR_STYLE_INIT(&tag, h);
+
+       if (n->prev->tok == n->tok && 
+                       MDOC_Fo != n->tok && 
+                       MDOC_Ft != n->tok && 
+                       MDOC_Fn != n->tok) {
+               print_otag(h, TAG_DIV, 0, NULL);
+               return;
+       }
+
+       switch (n->prev->tok) {
+       case (MDOC_Fd):
+               /* FALLTHROUGH */
+       case (MDOC_Fn):
+               /* FALLTHROUGH */
+       case (MDOC_Fo):
+               /* FALLTHROUGH */
+       case (MDOC_In):
+               /* FALLTHROUGH */
+       case (MDOC_Vt):
+               print_otag(h, TAG_DIV, 1, &tag);
+               break;
+       case (MDOC_Ft):
+               if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) {
+                       print_otag(h, TAG_DIV, 1, &tag);
+                       break;
+               }
+               /* FALLTHROUGH */
+       default:
+               print_otag(h, TAG_DIV, 0, NULL);
+               break;
+       }
+}
+
+
 /*
  * Calculate the scaling unit passed in an `-offset' argument.  This
  * uses either a native scaling unit (e.g., 1i, 2m), one of a set of
@@ -387,7 +395,7 @@ print_mdoc_head(MDOC_ARGS)
 
        print_gen_head(h);
        bufinit(h);
-       buffmt(h, "%s(%d)", m->title, m->msec);
+       buffmt(h, "%s(%s)", m->title, m->msec);
 
        if (m->arch) {
                bufcat(h, " (");
@@ -509,7 +517,7 @@ mdoc_root_pre(MDOC_ARGS)
        }
 
        (void)snprintf(title, BUFSIZ - 1, 
-                       "%s(%d)", m->title, m->msec);
+                       "%s(%s)", m->title, m->msec);
 
        /* XXX: see note in mdoc_root_post() about divs. */
 
@@ -729,17 +737,15 @@ mdoc_nm_pre(MDOC_ARGS)
 {
        struct htmlpair tag;
 
-       if (SEC_SYNOPSIS == n->sec && n->prev) {
-               bufcat_style(h, "clear", "both");
-               PAIR_STYLE_INIT(&tag, h);
-               print_otag(h, TAG_BR, 1, &tag);
-       }
+       if (NULL == n->child && NULL == m->name)
+               return(1);
+
+       synopsis_pre(h, n);
 
        PAIR_CLASS_INIT(&tag, "name");
        print_otag(h, TAG_SPAN, 1, &tag);
        if (NULL == n->child)
                print_text(h, m->name);
-
        return(1);
 }
 
@@ -863,7 +869,7 @@ mdoc_bx_pre(MDOC_ARGS)
 
 /* ARGSUSED */
 static int
-mdoc_it_block_pre(MDOC_ARGS, int type, int comp,
+mdoc_it_block_pre(MDOC_ARGS, enum mdoc_list type, int comp,
                struct roffsu *offs, struct roffsu *width)
 {
        struct htmlpair          tag;
@@ -871,17 +877,16 @@ mdoc_it_block_pre(MDOC_ARGS, int type, int comp,
        struct roffsu            su;
 
        nn = n->parent->parent;
-       assert(nn->args);
 
        /* XXX: see notes in mdoc_it_pre(). */
 
-       if (MDOC_Column == type) {
+       if (LIST_column == type) {
                /* Don't width-pad on the left. */
                SCALE_HS_INIT(width, 0);
                /* Also disallow non-compact. */
                comp = 1;
        }
-       if (MDOC_Diag == type)
+       if (LIST_diag == type)
                /* Mandate non-compact with empty prior. */
                if (n->prev && NULL == n->prev->body->child)
                        comp = 1;
@@ -918,17 +923,23 @@ mdoc_it_block_pre(MDOC_ARGS, int type, int comp,
 
 /* ARGSUSED */
 static int
-mdoc_it_body_pre(MDOC_ARGS, int type)
+mdoc_it_body_pre(MDOC_ARGS, enum mdoc_list type, struct roffsu *width)
 {
        struct htmlpair  tag;
        struct roffsu    su;
 
        switch (type) {
-       case (MDOC_Item):
+       case (LIST_item):
                /* FALLTHROUGH */
-       case (MDOC_Ohang):
+       case (LIST_ohang):
                /* FALLTHROUGH */
-       case (MDOC_Column):
+       case (LIST_column):
+               bufcat_su(h, "min-width", width);
+               bufcat_style(h, "clear", "none");
+               if (n->next)
+                       bufcat_style(h, "float", "left");
+               PAIR_STYLE_INIT(&tag, h);
+               print_otag(h, TAG_DIV, 1, &tag);
                break;
        default:
                /* 
@@ -948,25 +959,19 @@ mdoc_it_body_pre(MDOC_ARGS, int type)
 
 /* ARGSUSED */
 static int
-mdoc_it_head_pre(MDOC_ARGS, int type, struct roffsu *width)
+mdoc_it_head_pre(MDOC_ARGS, enum mdoc_list type, struct roffsu *width)
 {
        struct htmlpair  tag;
        struct ord      *ord;
        char             nbuf[BUFSIZ];
 
        switch (type) {
-       case (MDOC_Item):
+       case (LIST_item):
                return(0);
-       case (MDOC_Ohang):
+       case (LIST_ohang):
                print_otag(h, TAG_DIV, 0, &tag);
                return(1);
-       case (MDOC_Column):
-               bufcat_su(h, "min-width", width);
-               bufcat_style(h, "clear", "none");
-               if (n->next && MDOC_HEAD == n->next->type)
-                       bufcat_style(h, "float", "left");
-               PAIR_STYLE_INIT(&tag, h);
-               print_otag(h, TAG_DIV, 1, &tag);
+       case (LIST_column):
                break;
        default:
                bufcat_su(h, "min-width", width);
@@ -984,24 +989,24 @@ mdoc_it_head_pre(MDOC_ARGS, int type, struct roffsu *width)
        }
 
        switch (type) {
-       case (MDOC_Diag):
+       case (LIST_diag):
                PAIR_CLASS_INIT(&tag, "diag");
                print_otag(h, TAG_SPAN, 1, &tag);
                break;
-       case (MDOC_Enum):
+       case (LIST_enum):
                ord = h->ords.head;
                assert(ord);
                nbuf[BUFSIZ - 1] = 0;
                (void)snprintf(nbuf, BUFSIZ - 1, "%d.", ord->pos++);
                print_text(h, nbuf);
                return(0);
-       case (MDOC_Dash):
+       case (LIST_dash):
                print_text(h, "\\(en");
                return(0);
-       case (MDOC_Hyphen):
+       case (LIST_hyphen):
                print_text(h, "\\(hy");
                return(0);
-       case (MDOC_Bullet):
+       case (LIST_bullet):
                print_text(h, "\\(bu");
                return(0);
        default:
@@ -1015,9 +1020,10 @@ mdoc_it_head_pre(MDOC_ARGS, int type, struct roffsu *width)
 static int
 mdoc_it_pre(MDOC_ARGS)
 {
-       int                      i, type, wp, comp;
+       int                      i, wp, comp;
        const struct mdoc_node  *bl, *nn;
        struct roffsu            width, offs;
+       enum mdoc_list           type;
 
        /* 
         * XXX: be very careful in changing anything, here.  Lists in
@@ -1029,20 +1035,20 @@ mdoc_it_pre(MDOC_ARGS)
        if (MDOC_BLOCK != n->type)
                bl = bl->parent;
 
-       type = a2list(bl);
+       type = bl->data.list;
 
        /* Set default width and offset. */
 
        SCALE_HS_INIT(&offs, 0);
 
        switch (type) {
-       case (MDOC_Enum):
+       case (LIST_enum):
                /* FALLTHROUGH */
-       case (MDOC_Dash):
+       case (LIST_dash):
                /* FALLTHROUGH */
-       case (MDOC_Hyphen):
+       case (LIST_hyphen):
                /* FALLTHROUGH */
-       case (MDOC_Bullet):
+       case (LIST_bullet):
                SCALE_HS_INIT(&width, 2);
                break;
        default:
@@ -1052,7 +1058,8 @@ mdoc_it_pre(MDOC_ARGS)
 
        /* Get width, offset, and compact arguments. */
 
-       for (wp = -1, comp = i = 0; i < (int)bl->args->argc; i++) 
+       wp = -1;
+       for (comp = i = 0; bl->args && i < (int)bl->args->argc; i++) 
                switch (bl->args->argv[i].arg) {
                case (MDOC_Column):
                        wp = i; /* Save for later. */
@@ -1073,13 +1080,13 @@ mdoc_it_pre(MDOC_ARGS)
        /* Override width in some cases. */
 
        switch (type) {
-       case (MDOC_Ohang):
+       case (LIST_ohang):
                /* FALLTHROUGH */
-       case (MDOC_Item):
+       case (LIST_item):
                /* FALLTHROUGH */
-       case (MDOC_Inset):
+       case (LIST_inset):
                /* FALLTHROUGH */
-       case (MDOC_Diag):
+       case (LIST_diag):
                SCALE_HS_INIT(&width, 0);
                break;
        default:
@@ -1088,25 +1095,21 @@ mdoc_it_pre(MDOC_ARGS)
                break;
        }
 
-       /* Flip to body/block processing. */
-
-       if (MDOC_BODY == n->type)
-               return(mdoc_it_body_pre(m, n, h, type));
-       if (MDOC_BLOCK == n->type)
-               return(mdoc_it_block_pre(m, n, h, type, comp,
-                                       &offs, &width));
-
-       /* Override column widths. */
-
-       if (MDOC_Column == type) {
+       if (LIST_column == type && MDOC_BODY == n->type) {
                nn = n->parent->child;
-               for (i = 0; nn && nn != n; nn = nn->next, i++)
-                       /* Counter... */ ;
+               for (i = 0; nn && nn != n; nn = nn->next)
+                       if (MDOC_BODY == nn->type)
+                               i++;
                if (i < (int)bl->args->argv[wp].sz)
                        a2width(bl->args->argv[wp].value[i], &width);
        }
 
-       return(mdoc_it_head_pre(m, n, h, type, &width));
+       if (MDOC_HEAD == n->type)
+               return(mdoc_it_head_pre(m, n, h, type, &width));
+       else if (MDOC_BODY == n->type)
+               return(mdoc_it_body_pre(m, n, h, type, &width));
+
+       return(mdoc_it_block_pre(m, n, h, type, comp, &offs, &width));
 }
 
 
@@ -1116,9 +1119,11 @@ mdoc_bl_pre(MDOC_ARGS)
 {
        struct ord      *ord;
 
+       if (MDOC_HEAD == n->type)
+               return(0);
        if (MDOC_BLOCK != n->type)
                return(1);
-       if (MDOC_Enum != a2list(n))
+       if (LIST_enum != n->data.list)
                return(1);
 
        ord = malloc(sizeof(struct ord));
@@ -1142,7 +1147,7 @@ mdoc_bl_post(MDOC_ARGS)
 
        if (MDOC_BLOCK != n->type)
                return;
-       if (MDOC_Enum != a2list(n))
+       if (LIST_enum != n->data.list)
                return;
 
        ord = h->ords.head;
@@ -1178,7 +1183,7 @@ mdoc_ex_pre(MDOC_ARGS)
                        h->flags &= ~HTML_NOSPACE;
        }
 
-       if (n->child->next)
+       if (n->child && n->child->next)
                print_text(h, "utilities exit");
        else
                print_text(h, "utility exits");
@@ -1348,7 +1353,7 @@ static int
 mdoc_bd_pre(MDOC_ARGS)
 {
        struct htmlpair          tag[2];
-       int                      type, comp, i;
+       int                      comp, i;
        const struct mdoc_node  *bl, *nn;
        struct roffsu            su;
 
@@ -1361,8 +1366,8 @@ mdoc_bd_pre(MDOC_ARGS)
 
        SCALE_VS_INIT(&su, 0);
 
-       type = comp = 0;
-       for (i = 0; i < (int)bl->args->argc; i++) 
+       comp = 0;
+       for (i = 0; bl->args && i < (int)bl->args->argc; i++) 
                switch (bl->args->argv[i].arg) {
                case (MDOC_Offset):
                        a2offs(bl->args->argv[i].value[0], &su);
@@ -1370,22 +1375,12 @@ mdoc_bd_pre(MDOC_ARGS)
                case (MDOC_Compact):
                        comp = 1;
                        break;
-               case (MDOC_Centred):
-                       /* FALLTHROUGH */
-               case (MDOC_Ragged):
-                       /* FALLTHROUGH */
-               case (MDOC_Filled):
-                       /* FALLTHROUGH */
-               case (MDOC_Unfilled):
-                       /* FALLTHROUGH */
-               case (MDOC_Literal):
-                       type = bl->args->argv[i].arg;
-                       break;
                default:
                        break;
                }
 
        /* FIXME: -centered, etc. formatting. */
+       /* FIXME: does not respect -offset ??? */
 
        if (MDOC_BLOCK == n->type) {
                bufcat_su(h, "margin-left", &su);
@@ -1398,7 +1393,8 @@ mdoc_bd_pre(MDOC_ARGS)
                                break;
                }
                if (comp) {
-                       print_otag(h, TAG_DIV, 0, tag);
+                       PAIR_STYLE_INIT(&tag[0], h);
+                       print_otag(h, TAG_DIV, 1, tag);
                        return(1);
                }
                SCALE_VS_INIT(&su, 1);
@@ -1408,7 +1404,8 @@ mdoc_bd_pre(MDOC_ARGS)
                return(1);
        }
 
-       if (MDOC_Unfilled != type && MDOC_Literal != type)
+       if (DISP_unfilled != n->data.disp && 
+                       DISP_literal != n->data.disp)
                return(1);
 
        PAIR_CLASS_INIT(&tag[0], "lit");
@@ -1475,7 +1472,7 @@ mdoc_cd_pre(MDOC_ARGS)
 {
        struct htmlpair tag;
 
-       print_otag(h, TAG_DIV, 0, NULL);
+       synopsis_pre(h, n);
        PAIR_CLASS_INIT(&tag, "config");
        print_otag(h, TAG_SPAN, 1, &tag);
        return(1);
@@ -1552,17 +1549,8 @@ static int
 mdoc_fd_pre(MDOC_ARGS)
 {
        struct htmlpair  tag;
-       struct roffsu    su;
 
-       if (SEC_SYNOPSIS == n->sec) {
-               if (n->next && MDOC_Fd != n->next->tok) {
-                       SCALE_VS_INIT(&su, 1);
-                       bufcat_su(h, "margin-bottom", &su);
-                       PAIR_STYLE_INIT(&tag, h);
-                       print_otag(h, TAG_DIV, 1, &tag);
-               } else
-                       print_otag(h, TAG_DIV, 0, NULL);
-       }
+       synopsis_pre(h, n);
 
        PAIR_CLASS_INIT(&tag, "macro");
        print_otag(h, TAG_SPAN, 1, &tag);
@@ -1575,18 +1563,12 @@ static int
 mdoc_vt_pre(MDOC_ARGS)
 {
        struct htmlpair  tag;
-       struct roffsu    su;
 
-       if (SEC_SYNOPSIS == n->sec && MDOC_BLOCK == n->type) {
-               if (n->next && MDOC_Vt != n->next->tok) {
-                       SCALE_VS_INIT(&su, 1);
-                       bufcat_su(h, "margin-bottom", &su);
-                       PAIR_STYLE_INIT(&tag, h);
-                       print_otag(h, TAG_DIV, 1, &tag);
-               } else
-                       print_otag(h, TAG_DIV, 0, NULL);
-               
+       if (MDOC_BLOCK == n->type) {
+               synopsis_pre(h, n);
                return(1);
+       } else if (MDOC_ELEM == n->type) {
+               synopsis_pre(h, n);
        } else if (MDOC_HEAD == n->type)
                return(0);
 
@@ -1602,9 +1584,7 @@ mdoc_ft_pre(MDOC_ARGS)
 {
        struct htmlpair  tag;
 
-       if (SEC_SYNOPSIS == n->sec)
-               print_otag(h, TAG_DIV, 0, NULL);
-
+       synopsis_pre(h, n);
        PAIR_CLASS_INIT(&tag, "ftype");
        print_otag(h, TAG_SPAN, 1, &tag);
        return(1);
@@ -1621,20 +1601,8 @@ mdoc_fn_pre(MDOC_ARGS)
        char                     nbuf[BUFSIZ];
        const char              *sp, *ep;
        int                      sz, i;
-       struct roffsu            su;
 
-       if (SEC_SYNOPSIS == n->sec) {
-               SCALE_HS_INIT(&su, INDENT);
-               bufcat_su(h, "margin-left", &su);
-               su.scale = -su.scale;
-               bufcat_su(h, "text-indent", &su);
-               if (n->next) {
-                       SCALE_VS_INIT(&su, 1);
-                       bufcat_su(h, "margin-bottom", &su);
-               }
-               PAIR_STYLE_INIT(&tag[0], h);
-               print_otag(h, TAG_DIV, 1, tag);
-       }
+       synopsis_pre(h, n);
 
        /* Split apart into type and name. */
        assert(n->child->string);
@@ -1819,25 +1787,29 @@ mdoc_mt_pre(MDOC_ARGS)
 static int
 mdoc_fo_pre(MDOC_ARGS)
 {
-       struct htmlpair tag;
-       struct roffsu   su;
+       struct htmlpair  tag;
+       struct tag      *t;
 
        if (MDOC_BODY == n->type) {
                h->flags |= HTML_NOSPACE;
                print_text(h, "(");
                h->flags |= HTML_NOSPACE;
                return(1);
-       } else if (MDOC_BLOCK == n->type && n->next) {
-               SCALE_VS_INIT(&su, 1);
-               bufcat_su(h, "margin-bottom", &su);
-               PAIR_STYLE_INIT(&tag, h);
-               print_otag(h, TAG_DIV, 1, &tag);
+       } else if (MDOC_BLOCK == n->type) {
+               synopsis_pre(h, n);
                return(1);
        }
 
+       /* XXX: we drop non-initial arguments as per groff. */
+
+       assert(n->child);
+       assert(n->child->string);
+
        PAIR_CLASS_INIT(&tag, "fname");
-       print_otag(h, TAG_SPAN, 1, &tag);
-       return(1);
+       t = print_otag(h, TAG_SPAN, 1, &tag);
+       print_text(h, n->child->string);
+       print_tagq(h, t);
+       return(0);
 }
 
 
@@ -1845,6 +1817,7 @@ mdoc_fo_pre(MDOC_ARGS)
 static void
 mdoc_fo_post(MDOC_ARGS)
 {
+
        if (MDOC_BODY != n->type)
                return;
        h->flags |= HTML_NOSPACE;
@@ -1862,31 +1835,18 @@ mdoc_in_pre(MDOC_ARGS)
        struct tag              *t;
        struct htmlpair          tag[2];
        int                      i;
-       struct roffsu            su;
 
-       if (SEC_SYNOPSIS == n->sec) {
-               if (n->next && MDOC_In != n->next->tok) {
-                       SCALE_VS_INIT(&su, 1);
-                       bufcat_su(h, "margin-bottom", &su);
-                       PAIR_STYLE_INIT(&tag[0], h);
-                       print_otag(h, TAG_DIV, 1, tag);
-               } else
-                       print_otag(h, TAG_DIV, 0, NULL);
-       }
-
-       /* FIXME: there's a buffer bug in here somewhere. */
+       synopsis_pre(h, n);
 
        PAIR_CLASS_INIT(&tag[0], "includes");
        print_otag(h, TAG_SPAN, 1, tag);
 
-       if (SEC_SYNOPSIS == n->sec)
+       if (SEC_SYNOPSIS == n->sec && MDOC_LINE & n->flags)
                print_text(h, "#include");
 
        print_text(h, "<");
        h->flags |= HTML_NOSPACE;
 
-       /* XXX -- see warning in termp_in_post(). */
-
        for (nn = n->child; nn; nn = nn->next) {
                PAIR_CLASS_INIT(&tag[0], "link-includes");
                i = 1;
@@ -1946,7 +1906,7 @@ mdoc_rv_pre(MDOC_ARGS)
                        print_text(h, "()");
        }
 
-       if (n->child->next)
+       if (n->child && n->child->next)
                print_text(h, "functions return");
        else
                print_text(h, "function returns");
@@ -2035,8 +1995,7 @@ mdoc_bf_pre(MDOC_ARGS)
                else if ( ! strcmp("Li", n->head->child->string))
                        PAIR_CLASS_INIT(&tag[0], "lit");
        } else {
-               assert(n->args);
-               for (i = 0; i < (int)n->args->argc; i++) 
+               for (i = 0; n->args && i < (int)n->args->argc; i++) 
                        switch (n->args->argv[i].arg) {
                        case (MDOC_Symbolic):
                                PAIR_CLASS_INIT(&tag[0], "symb");
@@ -2169,7 +2128,7 @@ mdoc_lb_pre(MDOC_ARGS)
 {
        struct htmlpair tag;
 
-       if (SEC_SYNOPSIS == n->sec)
+       if (SEC_LIBRARY == n->sec && MDOC_LINE & n->flags)
                print_otag(h, TAG_DIV, 0, NULL);
        PAIR_CLASS_INIT(&tag, "lib");
        print_otag(h, TAG_SPAN, 1, &tag);
@@ -2219,8 +2178,6 @@ mdoc__x_pre(MDOC_ARGS)
                break;
        case(MDOC__T):
                PAIR_CLASS_INIT(&tag[0], "ref-title");
-               print_text(h, "\\(lq");
-               h->flags |= HTML_NOSPACE;
                break;
        case(MDOC__U):
                PAIR_CLASS_INIT(&tag[0], "link-ref");
@@ -2249,14 +2206,8 @@ static void
 mdoc__x_post(MDOC_ARGS)
 {
 
+       /* TODO: %U */
+
        h->flags |= HTML_NOSPACE;
-       switch (n->tok) {
-       case (MDOC__T):
-               print_text(h, "\\(rq");
-               h->flags |= HTML_NOSPACE;
-               break;
-       default:
-               break;
-       }
        print_text(h, n->next ? "," : ".");
 }