summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2019-01-05 09:14:44 +0000
committerIngo Schwarze <schwarze@openbsd.org>2019-01-05 09:14:44 +0000
commitb039e0910fa465b73d66c37dc6f3c37a0be1e77e (patch)
tree3afc7a4af4cc7ca799ce86b128a2431db6c40aed
parentdf6a082de3c130efd8582d20d12e3dffa98ebd8f (diff)
downloadmandoc-b039e0910fa465b73d66c37dc6f3c37a0be1e77e.tar.gz
Now that the NODE_NOFILL flag in the syntax tree is accurate,
use it in the man(7) HTML formatter rather than keeping fill mode state locally, resulting in massive simplification (minus 40 LOC). Move the html_fillmode() state handler function to the html.c module such that both the man(7) and the roff(7) formatter (and in the future, also the mdoc(7) formatter) can use it. Give it a query mode, to be invoked with TOKEN_NONE.
-rw-r--r--html.c33
-rw-r--r--html.h1
-rw-r--r--man_html.c133
-rw-r--r--roff_html.c22
4 files changed, 70 insertions, 119 deletions
diff --git a/html.c b/html.c
index 4d4dacf3..7744f579 100644
--- a/html.c
+++ b/html.c
@@ -265,6 +265,39 @@ print_metaf(struct html *h, enum mandoc_esc deco)
}
}
+/*
+ * ROFF_nf switches to no-fill mode, ROFF_fi to fill mode.
+ * TOKEN_NONE does not switch. The old mode is returned.
+ */
+enum roff_tok
+html_fillmode(struct html *h, enum roff_tok want)
+{
+ struct tag *t;
+ enum roff_tok had;
+
+ for (t = h->tag; t != NULL; t = t->next)
+ if (t->tag == TAG_PRE)
+ break;
+
+ had = t == NULL ? ROFF_fi : ROFF_nf;
+
+ if (want != had) {
+ switch (want) {
+ case ROFF_fi:
+ print_tagq(h, t);
+ break;
+ case ROFF_nf:
+ print_otag(h, TAG_PRE, "");
+ break;
+ case TOKEN_NONE:
+ break;
+ default:
+ abort();
+ }
+ }
+ return had;
+}
+
char *
html_make_id(const struct roff_node *n, int unique)
{
diff --git a/html.h b/html.h
index 82920154..4adf7801 100644
--- a/html.h
+++ b/html.h
@@ -135,4 +135,5 @@ void print_eqn(struct html *, const struct eqn_box *);
void print_paragraph(struct html *);
void print_endline(struct html *);
+enum roff_tok html_fillmode(struct html *, enum roff_tok);
char *html_make_id(const struct roff_node *, int);
diff --git a/man_html.c b/man_html.c
index 6f102f54..4921105b 100644
--- a/man_html.c
+++ b/man_html.c
@@ -1,7 +1,7 @@
/* $Id$ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2013-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -50,7 +50,6 @@ static void print_man_head(const struct roff_meta *,
struct html *);
static void print_man_nodelist(MAN_ARGS);
static void print_man_node(MAN_ARGS);
-static int fillmode(struct html *, int);
static int man_B_pre(MAN_ARGS);
static int man_HP_pre(MAN_ARGS);
static int man_IP_pre(MAN_ARGS);
@@ -190,95 +189,28 @@ print_man_nodelist(MAN_ARGS)
static void
print_man_node(MAN_ARGS)
{
- static int want_fillmode = ROFF_fi;
- static int save_fillmode;
-
struct tag *t;
int child;
- /*
- * Handle fill mode switch requests up front,
- * they would just cause trouble in the subsequent code.
- */
-
- switch (n->tok) {
- case ROFF_nf:
- case MAN_EX:
- want_fillmode = ROFF_nf;
- return;
- case ROFF_fi:
- case MAN_EE:
- want_fillmode = ROFF_fi;
- if (fillmode(h, 0) == ROFF_fi)
- print_otag(h, TAG_BR, "");
- return;
- default:
- break;
- }
-
- /* Set up fill mode for the upcoming node. */
-
- switch (n->type) {
- case ROFFT_BLOCK:
- save_fillmode = 0;
- /* Some block macros suspend or cancel .nf. */
- switch (n->tok) {
- case MAN_TP: /* Tagged paragraphs */
- case MAN_IP: /* temporarily disable .nf */
- case MAN_HP: /* for the head. */
- save_fillmode = want_fillmode;
- /* FALLTHROUGH */
- case MAN_SH: /* Section headers */
- case MAN_SS: /* permanently cancel .nf. */
- want_fillmode = ROFF_fi;
- /* FALLTHROUGH */
- case MAN_PP: /* These have no head. */
- case MAN_RS: /* They will simply */
- case MAN_UR: /* reopen .nf in the body. */
- case MAN_MT:
- fillmode(h, ROFF_fi);
- break;
- default:
- break;
- }
- break;
- case ROFFT_TBL:
- fillmode(h, ROFF_fi);
- break;
- case ROFFT_ELEM:
- /*
- * Some in-line macros produce tags and/or text
- * in the handler, so they require fill mode to be
- * configured up front just like for text nodes.
- * For the others, keep the traditional approach
- * of doing the same, for now.
- */
- fillmode(h, want_fillmode);
- break;
- case ROFFT_TEXT:
- if (fillmode(h, want_fillmode) == ROFF_fi &&
- want_fillmode == ROFF_fi &&
- n->flags & NODE_LINE && *n->string == ' ' &&
- (h->flags & HTML_NONEWLINE) == 0)
- print_otag(h, TAG_BR, "");
- if (want_fillmode == ROFF_nf || *n->string != '\0')
- break;
- print_paragraph(h);
- return;
- case ROFFT_COMMENT:
- return;
- default:
- break;
- }
-
- /* Produce output for this node. */
+ html_fillmode(h, n->flags & NODE_NOFILL ? ROFF_nf : ROFF_fi);
child = 1;
switch (n->type) {
case ROFFT_TEXT:
+ if (*n->string == '\0') {
+ print_endline(h);
+ return;
+ }
t = h->tag;
+ if (*n->string == ' ' && n->flags & NODE_LINE &&
+ (h->flags & HTML_NONEWLINE) == 0)
+ print_endline(h);
+ else if (n->flags & NODE_DELIMC)
+ h->flags |= HTML_NOSPACE;
print_text(h, n->string);
break;
+ case ROFFT_COMMENT:
+ return;
case ROFFT_EQN:
t = h->tag;
print_eqn(h, n->eqn);
@@ -312,19 +244,14 @@ print_man_node(MAN_ARGS)
t = h->tag;
if (n->tok < ROFF_MAX) {
roff_html_pre(h, n);
- child = 0;
- break;
+ print_stagq(h, t);
+ return;
}
assert(n->tok >= MAN_TH && n->tok < MAN_MAX);
if (man_html_acts[n->tok - MAN_TH].pre != NULL)
child = (*man_html_acts[n->tok - MAN_TH].pre)(man,
n, h);
-
- /* Some block macros resume .nf in the body. */
- if (save_fillmode && n->type == ROFFT_BODY)
- want_fillmode = save_fillmode;
-
break;
}
@@ -334,40 +261,14 @@ print_man_node(MAN_ARGS)
/* This will automatically close out any font scope. */
print_stagq(h, t);
- if (fillmode(h, 0) == ROFF_nf &&
- n->next != NULL && n->next->flags & NODE_LINE) {
+ if (n->flags & NODE_NOFILL &&
+ (n->next == NULL || n->next->flags & NODE_LINE)) {
/* In .nf = <pre>, print even empty lines. */
h->col++;
print_endline(h);
}
}
-/*
- * ROFF_nf switches to no-fill mode, ROFF_fi to fill mode.
- * Other arguments do not switch.
- * The old mode is returned.
- */
-static int
-fillmode(struct html *h, int want)
-{
- struct tag *pre;
- int had;
-
- for (pre = h->tag; pre != NULL; pre = pre->next)
- if (pre->tag == TAG_PRE)
- break;
-
- had = pre == NULL ? ROFF_fi : ROFF_nf;
-
- if (want && want != had) {
- if (want == ROFF_nf)
- print_otag(h, TAG_PRE, "");
- else
- print_tagq(h, pre);
- }
- return had;
-}
-
static void
man_root_pre(const struct roff_meta *man, struct html *h)
{
diff --git a/roff_html.c b/roff_html.c
index 809e9ff8..eca5abd9 100644
--- a/roff_html.c
+++ b/roff_html.c
@@ -1,7 +1,7 @@
/* $Id$ */
/*
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2014, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2014, 2017, 2018, 2019 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -32,17 +32,19 @@ typedef void (*roff_html_pre_fp)(ROFF_HTML_ARGS);
static void roff_html_pre_br(ROFF_HTML_ARGS);
static void roff_html_pre_ce(ROFF_HTML_ARGS);
+static void roff_html_pre_fi(ROFF_HTML_ARGS);
static void roff_html_pre_ft(ROFF_HTML_ARGS);
+static void roff_html_pre_nf(ROFF_HTML_ARGS);
static void roff_html_pre_sp(ROFF_HTML_ARGS);
static const roff_html_pre_fp roff_html_pre_acts[ROFF_MAX] = {
roff_html_pre_br, /* br */
roff_html_pre_ce, /* ce */
- roff_html_pre_br, /* fi */
+ roff_html_pre_fi, /* fi */
roff_html_pre_ft, /* ft */
NULL, /* ll */
NULL, /* mc */
- roff_html_pre_br, /* nf */
+ roff_html_pre_nf, /* nf */
NULL, /* po */
roff_html_pre_ce, /* rj */
roff_html_pre_sp, /* sp */
@@ -80,6 +82,13 @@ roff_html_pre_ce(ROFF_HTML_ARGS)
}
static void
+roff_html_pre_fi(ROFF_HTML_ARGS)
+{
+ if (html_fillmode(h, TOKEN_NONE) == ROFF_fi)
+ print_otag(h, TAG_BR, "");
+}
+
+static void
roff_html_pre_ft(ROFF_HTML_ARGS)
{
const char *cp;
@@ -89,6 +98,13 @@ roff_html_pre_ft(ROFF_HTML_ARGS)
}
static void
+roff_html_pre_nf(ROFF_HTML_ARGS)
+{
+ if (html_fillmode(h, TOKEN_NONE) == ROFF_nf)
+ print_otag(h, TAG_BR, "");
+}
+
+static void
roff_html_pre_sp(ROFF_HTML_ARGS)
{
print_paragraph(h);