/* ARGSUSED */ static int mdoc_bf_pre(MDOC_ARGS) { struct htmlpair tag[2]; struct roffsu su; if (MDOC_HEAD == n->type) return(0); else if (MDOC_BODY != n->type) return(1); if (FONT_Em == n->norm->Bf.font) PAIR_CLASS_INIT(&tag[0], "emph"); else if (FONT_Sy == n->norm->Bf.font) PAIR_CLASS_INIT(&tag[0], "symb"); else if (FONT_Li == n->norm->Bf.font) PAIR_CLASS_INIT(&tag[0], "lit"); else PAIR_CLASS_INIT(&tag[0], "none"); /* * We want this to be inline-formatted, but needs to be div to * accept block children. */ bufcat_style(h, "display", "inline"); SCALE_HS_INIT(&su, 1); /* Needs a left-margin for spacing. */ bufcat_su(h, "margin-left", &su); PAIR_STYLE_INIT(&tag[1], h); print_otag(h, TAG_DIV, 2, tag); return(1); }
static int man_br_pre(MAN_ARGS) { struct roffsu su; struct htmlpair tag; SCALE_VS_INIT(&su, 1); if (MAN_sp == n->tok) { if (NULL != (n = n->child)) if ( ! a2roffsu(n->string, &su, SCALE_VS)) SCALE_VS_INIT(&su, atoi(n->string)); } else su.scale = 0.0; bufinit(h); bufcat_su(h, "height", &su); PAIR_STYLE_INIT(&tag, h); print_otag(h, TAG_DIV, 1, &tag); /* So the div isn't empty: */ print_text(h, "\\~"); return(0); }
/* ARGSUSED */ static int mdoc_d1_pre(MDOC_ARGS) { struct htmlpair tag[2]; struct roffsu su; if (MDOC_BLOCK != n->type) return(1); SCALE_VS_INIT(&su, 0); bufcat_su(h, "margin-top", &su); bufcat_su(h, "margin-bottom", &su); PAIR_STYLE_INIT(&tag[0], h); print_otag(h, TAG_BLOCKQUOTE, 1, tag); /* BLOCKQUOTE needs a block body. */ PAIR_CLASS_INIT(&tag[0], "display"); print_otag(h, TAG_DIV, 1, tag); if (MDOC_Dl == n->tok) { PAIR_CLASS_INIT(&tag[0], "lit"); print_otag(h, TAG_CODE, 1, tag); } return(1); }
static int man_HP_pre(MAN_ARGS) { struct htmlpair tag[2]; struct roffsu su; const struct man_node *np; if (MAN_HEAD == n->type) return(0); else if (MAN_BLOCK != n->type) return(1); np = n->head->child; if (NULL == np || ! a2width(np, &su)) SCALE_HS_INIT(&su, INDENT); bufinit(h); print_bvspace(h, n); bufcat_su(h, "margin-left", &su); su.scale = -su.scale; bufcat_su(h, "text-indent", &su); PAIR_STYLE_INIT(&tag[0], h); PAIR_CLASS_INIT(&tag[1], "spacer"); print_otag(h, TAG_DIV, 2, tag); return(1); }
static void html_tblopen(struct html *h, const struct tbl_span *sp) { struct htmlpair tag; struct roffsu su; struct roffcol *col; int ic; if (h->tbl.cols == NULL) { h->tbl.len = html_tbl_len; h->tbl.slen = html_tbl_strlen; tblcalc(&h->tbl, sp, 0); } assert(NULL == h->tblt); PAIR_CLASS_INIT(&tag, "tbl"); h->tblt = print_otag(h, TAG_TABLE, 1, &tag); for (ic = 0; ic < sp->opts->cols; ic++) { bufinit(h); col = h->tbl.cols + ic; 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); }
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); }
/* ARGSUSED */ static int mdoc_sp_pre(MDOC_ARGS) { struct roffsu su; struct htmlpair tag; SCALE_VS_INIT(&su, 1); if (MDOC_sp == n->tok) { if (n->child) a2roffsu(n->child->string, &su, SCALE_VS); } else su.scale = 0; bufinit(h); bufcat_su(h, "height", &su); PAIR_STYLE_INIT(&tag, h); print_otag(h, TAG_DIV, 1, &tag); /* So the div isn't empty: */ print_text(h, "\\~"); return(0); }
static int mdoc_nm_pre(MDOC_ARGS) { struct htmlpair tag; struct roffsu su; int len; switch (n->type) { case MDOC_ELEM: synopsis_pre(h, n); PAIR_CLASS_INIT(&tag, "name"); print_otag(h, TAG_B, 1, &tag); if (NULL == n->child && meta->name) print_text(h, meta->name); return(1); case MDOC_HEAD: print_otag(h, TAG_TD, 0, NULL); if (NULL == n->child && meta->name) print_text(h, meta->name); return(1); case MDOC_BODY: print_otag(h, TAG_TD, 0, NULL); return(1); default: break; } synopsis_pre(h, n); PAIR_CLASS_INIT(&tag, "synopsis"); print_otag(h, TAG_TABLE, 1, &tag); for (len = 0, n = n->child; n; n = n->next) if (MDOC_TEXT == n->type) len += html_strlen(n->string); if (0 == len && meta->name) len = html_strlen(meta->name); SCALE_HS_INIT(&su, len); bufinit(h); bufcat_su(h, "width", &su); PAIR_STYLE_INIT(&tag, h); print_otag(h, TAG_COL, 1, &tag); print_otag(h, TAG_COL, 0, NULL); print_otag(h, TAG_TBODY, 0, NULL); print_otag(h, TAG_TR, 0, NULL); return(1); }
static int man_RS_pre(MAN_ARGS) { struct htmlpair tag; struct roffsu su; if (MAN_HEAD == n->type) return(0); else if (MAN_BODY == n->type) return(1); SCALE_HS_INIT(&su, INDENT); if (n->head->child) a2width(n->head->child, &su); bufinit(h); bufcat_su(h, "margin-left", &su); PAIR_STYLE_INIT(&tag, h); print_otag(h, TAG_DIV, 1, &tag); return(1); }
/* ARGSUSED */ static int mdoc_bl_pre(MDOC_ARGS) { int i; struct htmlpair tag[3]; struct roffsu su; char buf[BUFSIZ]; if (MDOC_BODY == n->type) { if (LIST_column == n->norm->Bl.type) print_otag(h, TAG_TBODY, 0, NULL); return(1); } if (MDOC_HEAD == n->type) { if (LIST_column != n->norm->Bl.type) return(0); /* * For each column, print out the <COL> tag with our * suggested width. The last column gets min-width, as * in terminal mode it auto-sizes to the width of the * screen and we want to preserve that behaviour. */ for (i = 0; i < (int)n->norm->Bl.ncols; i++) { a2width(n->norm->Bl.cols[i], &su); bufinit(h); if (i < (int)n->norm->Bl.ncols - 1) bufcat_su(h, "width", &su); else bufcat_su(h, "min-width", &su); PAIR_STYLE_INIT(&tag[0], h); print_otag(h, TAG_COL, 1, tag); } return(0); } SCALE_VS_INIT(&su, 0); bufcat_su(h, "margin-top", &su); bufcat_su(h, "margin-bottom", &su); PAIR_STYLE_INIT(&tag[0], h); assert(lists[n->norm->Bl.type]); strlcpy(buf, "list ", BUFSIZ); strlcat(buf, lists[n->norm->Bl.type], BUFSIZ); PAIR_INIT(&tag[1], ATTR_CLASS, buf); /* Set the block's left-hand margin. */ if (n->norm->Bl.offs) { a2offs(n->norm->Bl.offs, &su); bufcat_su(h, "margin-left", &su); } switch (n->norm->Bl.type) { case(LIST_bullet): /* FALLTHROUGH */ case(LIST_dash): /* FALLTHROUGH */ case(LIST_hyphen): /* FALLTHROUGH */ case(LIST_item): print_otag(h, TAG_UL, 2, tag); break; case(LIST_enum): print_otag(h, TAG_OL, 2, tag); break; case(LIST_diag): /* FALLTHROUGH */ case(LIST_hang): /* FALLTHROUGH */ case(LIST_inset): /* FALLTHROUGH */ case(LIST_ohang): /* FALLTHROUGH */ case(LIST_tag): print_otag(h, TAG_DL, 2, tag); break; case(LIST_column): print_otag(h, TAG_TABLE, 2, tag); break; default: abort(); /* NOTREACHED */ } return(1); }
/* ARGSUSED */ static int mdoc_it_pre(MDOC_ARGS) { struct roffsu su; enum mdoc_list type; struct htmlpair tag[2]; const struct mdoc_node *bl; bl = n->parent; while (bl && MDOC_Bl != bl->tok) bl = bl->parent; assert(bl); type = bl->norm->Bl.type; assert(lists[type]); PAIR_CLASS_INIT(&tag[0], lists[type]); if (MDOC_HEAD == n->type) { switch (type) { case(LIST_bullet): /* FALLTHROUGH */ case(LIST_dash): /* FALLTHROUGH */ case(LIST_item): /* FALLTHROUGH */ case(LIST_hyphen): /* FALLTHROUGH */ case(LIST_enum): return(0); case(LIST_diag): /* FALLTHROUGH */ case(LIST_hang): /* FALLTHROUGH */ case(LIST_inset): /* FALLTHROUGH */ case(LIST_ohang): /* FALLTHROUGH */ case(LIST_tag): SCALE_VS_INIT(&su, ! bl->norm->Bl.comp); bufcat_su(h, "margin-top", &su); PAIR_STYLE_INIT(&tag[1], h); print_otag(h, TAG_DT, 2, tag); if (LIST_diag != type) break; PAIR_CLASS_INIT(&tag[0], "diag"); print_otag(h, TAG_B, 1, tag); break; case(LIST_column): break; default: break; } } else if (MDOC_BODY == n->type) { switch (type) { case(LIST_bullet): /* FALLTHROUGH */ case(LIST_hyphen): /* FALLTHROUGH */ case(LIST_dash): /* FALLTHROUGH */ case(LIST_enum): /* FALLTHROUGH */ case(LIST_item): SCALE_VS_INIT(&su, ! bl->norm->Bl.comp); bufcat_su(h, "margin-top", &su); PAIR_STYLE_INIT(&tag[1], h); print_otag(h, TAG_LI, 2, tag); break; case(LIST_diag): /* FALLTHROUGH */ case(LIST_hang): /* FALLTHROUGH */ case(LIST_inset): /* FALLTHROUGH */ case(LIST_ohang): /* FALLTHROUGH */ case(LIST_tag): if (NULL == bl->norm->Bl.width) { print_otag(h, TAG_DD, 1, tag); break; } a2width(bl->norm->Bl.width, &su); bufcat_su(h, "margin-left", &su); PAIR_STYLE_INIT(&tag[1], h); print_otag(h, TAG_DD, 2, tag); break; case(LIST_column): SCALE_VS_INIT(&su, ! bl->norm->Bl.comp); bufcat_su(h, "margin-top", &su); PAIR_STYLE_INIT(&tag[1], h); print_otag(h, TAG_TD, 2, tag); break; default: break; } } else { switch (type) { case (LIST_column): print_otag(h, TAG_TR, 1, tag); break; default: break; } } return(1); }
/* ARGSUSED */ static int mdoc_fn_pre(MDOC_ARGS) { struct tag *t; struct htmlpair tag[2]; char nbuf[BUFSIZ]; const char *sp, *ep; int sz, i, pretty; pretty = MDOC_SYNPRETTY & n->flags; synopsis_pre(h, n); /* Split apart into type and name. */ assert(n->child->string); sp = n->child->string; ep = strchr(sp, ' '); if (NULL != ep) { PAIR_CLASS_INIT(&tag[0], "ftype"); t = print_otag(h, TAG_I, 1, tag); while (ep) { sz = MIN((int)(ep - sp), BUFSIZ - 1); (void)memcpy(nbuf, sp, (size_t)sz); nbuf[sz] = '\0'; print_text(h, nbuf); sp = ++ep; ep = strchr(sp, ' '); } print_tagq(h, t); } PAIR_CLASS_INIT(&tag[0], "fname"); /* * FIXME: only refer to IDs that we know exist. */ #if 0 if (MDOC_SYNPRETTY & n->flags) { nbuf[0] = '\0'; html_idcat(nbuf, sp, BUFSIZ); PAIR_ID_INIT(&tag[1], nbuf); } else { strlcpy(nbuf, "#", BUFSIZ); html_idcat(nbuf, sp, BUFSIZ); PAIR_HREF_INIT(&tag[1], nbuf); } #endif t = print_otag(h, TAG_B, 1, tag); if (sp) { strlcpy(nbuf, sp, BUFSIZ); print_text(h, nbuf); } print_tagq(h, t); h->flags |= HTML_NOSPACE; print_text(h, "("); bufinit(h); PAIR_CLASS_INIT(&tag[0], "farg"); bufcat_style(h, "white-space", "nowrap"); PAIR_STYLE_INIT(&tag[1], h); for (n = n->child->next; n; n = n->next) { i = 1; if (MDOC_SYNPRETTY & n->flags) i = 2; t = print_otag(h, TAG_I, i, tag); print_text(h, n->string); print_tagq(h, t); if (n->next) { h->flags |= HTML_NOSPACE; print_text(h, ","); } } h->flags |= HTML_NOSPACE; print_text(h, ")"); if (pretty) { h->flags |= HTML_NOSPACE; print_text(h, ";"); } return(0); }
/* ARGSUSED */ static int mdoc_bd_pre(MDOC_ARGS) { struct htmlpair tag[2]; int comp, sv; const struct mdoc_node *nn; struct roffsu su; if (MDOC_HEAD == n->type) return(0); if (MDOC_BLOCK == n->type) { comp = n->norm->Bd.comp; for (nn = n; nn && ! comp; nn = nn->parent) { if (MDOC_BLOCK != nn->type) continue; if (MDOC_Ss == nn->tok || MDOC_Sh == nn->tok) comp = 1; if (nn->prev) break; } if ( ! comp) print_otag(h, TAG_P, 0, NULL); return(1); } SCALE_HS_INIT(&su, 0); if (n->norm->Bd.offs) a2offs(n->norm->Bd.offs, &su); bufcat_su(h, "margin-left", &su); PAIR_STYLE_INIT(&tag[0], h); if (DISP_unfilled != n->norm->Bd.type && DISP_literal != n->norm->Bd.type) { PAIR_CLASS_INIT(&tag[1], "display"); print_otag(h, TAG_DIV, 2, tag); return(1); } PAIR_CLASS_INIT(&tag[1], "lit display"); print_otag(h, TAG_PRE, 2, tag); /* This can be recursive: save & set our literal state. */ sv = h->flags & HTML_LITERAL; h->flags |= HTML_LITERAL; for (nn = n->child; nn; nn = nn->next) { print_mdoc_node(m, nn, h); /* * If the printed node flushes its own line, then we * needn't do it here as well. This is hacky, but the * notion of selective eoln whitespace is pretty dumb * anyway, so don't sweat it. */ switch (nn->tok) { case (MDOC_Sm): /* FALLTHROUGH */ case (MDOC_br): /* FALLTHROUGH */ case (MDOC_sp): /* FALLTHROUGH */ case (MDOC_Bl): /* FALLTHROUGH */ case (MDOC_D1): /* FALLTHROUGH */ case (MDOC_Dl): /* FALLTHROUGH */ case (MDOC_Lp): /* FALLTHROUGH */ case (MDOC_Pp): continue; default: break; } if (nn->next && nn->next->line == nn->line) continue; else if (nn->next) print_text(h, "\n"); h->flags |= HTML_NOSPACE; } if (0 == sv) h->flags &= ~HTML_LITERAL; return(0); }
static int mdoc_bd_pre(MDOC_ARGS) { struct htmlpair tag[2]; int comp, sv; struct mdoc_node *nn; struct roffsu su; if (MDOC_HEAD == n->type) return(0); if (MDOC_BLOCK == n->type) { comp = n->norm->Bd.comp; for (nn = n; nn && ! comp; nn = nn->parent) { if (MDOC_BLOCK != nn->type) continue; if (MDOC_Ss == nn->tok || MDOC_Sh == nn->tok) comp = 1; if (nn->prev) break; } if ( ! comp) print_paragraph(h); return(1); } /* Handle the -offset argument. */ if (n->norm->Bd.offs == NULL || ! strcmp(n->norm->Bd.offs, "left")) SCALE_HS_INIT(&su, 0); else if ( ! strcmp(n->norm->Bd.offs, "indent")) SCALE_HS_INIT(&su, INDENT); else if ( ! strcmp(n->norm->Bd.offs, "indent-two")) SCALE_HS_INIT(&su, INDENT * 2); else a2width(n->norm->Bd.offs, &su); bufinit(h); bufcat_su(h, "margin-left", &su); PAIR_STYLE_INIT(&tag[0], h); if (DISP_unfilled != n->norm->Bd.type && DISP_literal != n->norm->Bd.type) { PAIR_CLASS_INIT(&tag[1], "display"); print_otag(h, TAG_DIV, 2, tag); return(1); } PAIR_CLASS_INIT(&tag[1], "lit display"); print_otag(h, TAG_PRE, 2, tag); /* This can be recursive: save & set our literal state. */ sv = h->flags & HTML_LITERAL; h->flags |= HTML_LITERAL; for (nn = n->child; nn; nn = nn->next) { print_mdoc_node(meta, nn, h); /* * If the printed node flushes its own line, then we * needn't do it here as well. This is hacky, but the * notion of selective eoln whitespace is pretty dumb * anyway, so don't sweat it. */ switch (nn->tok) { case MDOC_Sm: /* FALLTHROUGH */ case MDOC_br: /* FALLTHROUGH */ case MDOC_sp: /* FALLTHROUGH */ case MDOC_Bl: /* FALLTHROUGH */ case MDOC_D1: /* FALLTHROUGH */ case MDOC_Dl: /* FALLTHROUGH */ case MDOC_Lp: /* FALLTHROUGH */ case MDOC_Pp: continue; default: break; } if (h->flags & HTML_NONEWLINE || (nn->next && ! (nn->next->flags & MDOC_LINE))) continue; else if (nn->next) print_text(h, "\n"); h->flags |= HTML_NOSPACE; } if (0 == sv) h->flags &= ~HTML_LITERAL; return(0); }