-/* $Id: mdoc_html.c,v 1.306 2018/06/10 16:15:43 schwarze Exp $ */
+/* $Id: mdoc_html.c,v 1.322 2018/12/31 10:35:56 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
#include "html.h"
#include "main.h"
-#define INDENT 5
-
#define MDOC_ARGS const struct roff_meta *meta, \
struct roff_node *n, \
struct html *h
#define MIN(a,b) ((/*CONSTCOND*/(a)<(b))?(a):(b))
#endif
-struct htmlmdoc {
+struct mdoc_html_act {
int (*pre)(MDOC_ARGS);
void (*post)(MDOC_ARGS);
};
static void mdoc__x_post(MDOC_ARGS);
static int mdoc__x_pre(MDOC_ARGS);
+static int mdoc_abort_pre(MDOC_ARGS);
static int mdoc_ad_pre(MDOC_ARGS);
static int mdoc_an_pre(MDOC_ARGS);
static int mdoc_ap_pre(MDOC_ARGS);
static int mdoc_xr_pre(MDOC_ARGS);
static int mdoc_xx_pre(MDOC_ARGS);
-static const struct htmlmdoc __mdocs[MDOC_MAX - MDOC_Dd] = {
+static const struct mdoc_html_act mdoc_html_acts[MDOC_MAX - MDOC_Dd] = {
{NULL, NULL}, /* Dd */
{NULL, NULL}, /* Dt */
{NULL, NULL}, /* Os */
{mdoc_nd_pre, NULL}, /* Nd */
{mdoc_nm_pre, NULL}, /* Nm */
{mdoc_quote_pre, mdoc_quote_post}, /* Op */
- {mdoc_ft_pre, NULL}, /* Ot */
+ {mdoc_abort_pre, NULL}, /* Ot */
{mdoc_pa_pre, NULL}, /* Pa */
{mdoc_ex_pre, NULL}, /* Rv */
{mdoc_st_pre, NULL}, /* St */
{mdoc_em_pre, NULL}, /* Fr */
{NULL, NULL}, /* Ud */
{mdoc_lb_pre, NULL}, /* Lb */
- {mdoc_pp_pre, NULL}, /* Lp */
+ {mdoc_abort_pre, NULL}, /* Lp */
{mdoc_lk_pre, NULL}, /* Lk */
{mdoc_mt_pre, NULL}, /* Mt */
{mdoc_quote_pre, mdoc_quote_post}, /* Brq */
{mdoc__x_pre, mdoc__x_post}, /* %U */
{NULL, NULL}, /* Ta */
};
-static const struct htmlmdoc *const mdocs = __mdocs - MDOC_Dd;
/*
}
void
-html_mdoc(void *arg, const struct roff_man *mdoc)
+html_mdoc(void *arg, const struct roff_meta *mdoc)
{
struct html *h;
struct roff_node *n;
if (n->type == ROFFT_COMMENT)
print_gen_comment(h, n);
t = print_otag(h, TAG_HEAD, "");
- print_mdoc_head(&mdoc->meta, h);
+ print_mdoc_head(mdoc, h);
print_tagq(h, t);
print_otag(h, TAG_BODY, "");
}
- mdoc_root_pre(&mdoc->meta, h);
+ mdoc_root_pre(mdoc, h);
t = print_otag(h, TAG_DIV, "c", "manual-text");
- print_mdoc_nodelist(&mdoc->meta, n, h);
+ print_mdoc_nodelist(mdoc, n, h);
print_tagq(h, t);
- mdoc_root_post(&mdoc->meta, h);
+ mdoc_root_post(mdoc, h);
print_tagq(h, NULL);
}
* (i.e., within a <PRE>) don't print the newline.
*/
if (*n->string == ' ' && n->flags & NODE_LINE &&
- (h->flags & (HTML_LITERAL | HTML_NONEWLINE)) == 0)
+ (h->flags & HTML_NONEWLINE) == 0 &&
+ (n->flags & NODE_NOFILL) == 0)
print_otag(h, TAG_BR, "");
if (NODE_DELIMC & n->flags)
h->flags |= HTML_NOSPACE;
break;
}
assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX);
- if (mdocs[n->tok].pre != NULL &&
+ if (mdoc_html_acts[n->tok - MDOC_Dd].pre != NULL &&
(n->end == ENDBODY_NOT || n->child != NULL))
- child = (*mdocs[n->tok].pre)(meta, n, h);
+ child = (*mdoc_html_acts[n->tok - MDOC_Dd].pre)(meta,
+ n, h);
break;
}
break;
default:
if (n->tok < ROFF_MAX ||
- mdocs[n->tok].post == NULL ||
+ mdoc_html_acts[n->tok - MDOC_Dd].post == NULL ||
n->flags & NODE_ENDED)
break;
- (*mdocs[n->tok].post)(meta, n, h);
+ (*mdoc_html_acts[n->tok - MDOC_Dd].post)(meta, n, h);
if (n->end != ENDBODY_NOT)
n->body->flags |= NODE_ENDED;
break;
static int
mdoc_sh_pre(MDOC_ARGS)
{
- char *id;
+ struct roff_node *sn, *subn;
+ struct tag *t, *tsec, *tsub;
+ char *id;
+ int sc;
switch (n->type) {
+ case ROFFT_BLOCK:
+ if ((h->oflags & HTML_TOC) == 0 ||
+ h->flags & HTML_TOCDONE ||
+ n->sec <= SEC_SYNOPSIS)
+ break;
+ h->flags |= HTML_TOCDONE;
+ sc = 0;
+ for (sn = n->next; sn != NULL; sn = sn->next)
+ if (sn->sec == SEC_CUSTOM)
+ if (++sc == 2)
+ break;
+ if (sc < 2)
+ break;
+ t = print_otag(h, TAG_H1, "c", "Sh");
+ print_text(h, "TABLE OF CONTENTS");
+ print_tagq(h, t);
+ t = print_otag(h, TAG_UL, "c", "Bl-compact");
+ for (sn = n; sn != NULL; sn = sn->next) {
+ tsec = print_otag(h, TAG_LI, "");
+ id = html_make_id(sn->head, 0);
+ tsub = print_otag(h, TAG_A, "hR", id);
+ free(id);
+ print_mdoc_nodelist(meta, sn->head->child, h);
+ print_tagq(h, tsub);
+ tsub = NULL;
+ for (subn = sn->body->child; subn != NULL;
+ subn = subn->next) {
+ if (subn->tok != MDOC_Ss)
+ continue;
+ id = html_make_id(subn->head, 0);
+ if (id == NULL)
+ continue;
+ if (tsub == NULL)
+ print_otag(h, TAG_UL,
+ "c", "Bl-compact");
+ tsub = print_otag(h, TAG_LI, "");
+ print_otag(h, TAG_A, "hR", id);
+ free(id);
+ print_mdoc_nodelist(meta,
+ subn->head->child, h);
+ print_tagq(h, tsub);
+ }
+ print_tagq(h, tsec);
+ }
+ print_tagq(h, t);
+ break;
case ROFFT_HEAD:
id = html_make_id(n, 1);
print_otag(h, TAG_H1, "cTi", "Sh", id);
if (NULL == n->child)
return 0;
- if (h->base_man)
+ if (h->base_man1)
print_otag(h, TAG_A, "cThM", "Xr",
n->child->string, n->child->next == NULL ?
NULL : n->child->next->string);
break;
case ROFFT_BODY:
if (n->child == NULL) {
- print_otag(h, TAG_DD, "ss?",
- "width", "auto");
+ print_otag(h, TAG_DD, "s", "width", "auto");
print_text(h, "\\ ");
} else
print_otag(h, TAG_DD, "");
static int
mdoc_bl_pre(MDOC_ARGS)
{
- char cattr[28];
- struct tag *t;
+ char cattr[32];
struct mdoc_bl *bl;
- size_t i;
enum htmltag elemtype;
- bl = &n->norm->Bl;
-
switch (n->type) {
case ROFFT_BODY:
return 1;
-
case ROFFT_HEAD:
- if (bl->type != LIST_column || bl->ncols == 0)
- 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.
- */
-
- t = print_otag(h, TAG_COLGROUP, "");
- for (i = 0; i < bl->ncols - 1; i++)
- print_otag(h, TAG_COL, "sw+w", bl->cols[i]);
- print_otag(h, TAG_COL, "swW", bl->cols[i]);
- print_tagq(h, t);
return 0;
-
default:
break;
}
+ bl = &n->norm->Bl;
switch (bl->type) {
case LIST_bullet:
elemtype = TAG_UL;
static int
mdoc_bd_pre(MDOC_ARGS)
{
- int comp, sv;
+ int comp;
struct roff_node *nn;
if (n->type == ROFFT_HEAD)
return 1;
print_otag(h, TAG_PRE, "c", "Li");
-
- /* 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);
/*
case MDOC_Bl:
case MDOC_D1:
case MDOC_Dl:
- case MDOC_Lp:
case MDOC_Pp:
continue;
default:
h->flags |= HTML_NOSPACE;
}
-
- if (0 == sv)
- h->flags &= ~HTML_LITERAL;
-
return 0;
}
for (n = n->child->next; n; n = n->next) {
if (NODE_SYNPRETTY & n->flags)
- t = print_otag(h, TAG_VAR, "cTss?", "Fa",
+ t = print_otag(h, TAG_VAR, "cTs", "Fa",
"white-space", "nowrap");
else
t = print_otag(h, TAG_VAR, "cT", "Fa");
cattr = "Bf No";
/* Cannot use TAG_SPAN because it may contain blocks. */
- print_otag(h, TAG_DIV, "cshl", cattr, 1);
+ print_otag(h, TAG_DIV, "c", cattr);
return 1;
}
else if ( ! tail)
h->flags &= ~HTML_NOSPACE;
}
+
+static int
+mdoc_abort_pre(MDOC_ARGS)
+{
+ abort();
+}