=================================================================== RCS file: /cvs/mandoc/mdoc_html.c,v retrieving revision 1.324 retrieving revision 1.331 diff -u -p -r1.324 -r1.331 --- mandoc/mdoc_html.c 2019/01/10 07:40:10 1.324 +++ mandoc/mdoc_html.c 2019/09/15 00:08:55 1.331 @@ -1,7 +1,7 @@ -/* $Id: mdoc_html.c,v 1.324 2019/01/10 07:40:10 schwarze Exp $ */ +/* $Id: mdoc_html.c,v 1.331 2019/09/15 00:08:55 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons - * Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze + * Copyright (c) 2014-2019 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -294,7 +294,7 @@ html_mdoc(void *arg, const struct roff_meta *mdoc) if ((h->oflags & HTML_FRAGMENT) == 0) { print_gen_decls(h); print_otag(h, TAG_HTML, ""); - if (n->type == ROFFT_COMMENT) + if (n != NULL && n->type == ROFFT_COMMENT) print_gen_comment(h, n); t = print_otag(h, TAG_HEAD, ""); print_mdoc_head(mdoc, h); @@ -351,27 +351,34 @@ print_mdoc_node(MDOC_ARGS) if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT) return; - html_fillmode(h, n->flags & NODE_NOFILL ? ROFF_nf : ROFF_fi); + if (n->flags & NODE_NOFILL) { + html_fillmode(h, ROFF_nf); + if (n->flags & NODE_LINE) + print_endline(h); + } else + html_fillmode(h, ROFF_fi); child = 1; - t = h->tag; - if (t->tag == TAG_P || t->tag == TAG_PRE) - t = t->next; - n->flags &= ~NODE_ENDED; switch (n->type) { case ROFFT_TEXT: - /* No tables in this mode... */ - assert(NULL == h->tblt); - - /* - * Make sure that if we're in a literal mode already - * (i.e., within a
) don't print the newline.
-		 */
-		if (*n->string == ' ' && n->flags & NODE_LINE &&
-		    (h->flags & HTML_NONEWLINE) == 0 &&
-		    (n->flags & NODE_NOFILL) == 0)
-			print_otag(h, TAG_BR, "");
+		if (n->flags & NODE_LINE) {
+			switch (*n->string) {
+			case '\0':
+				h->col = 1;
+				print_endline(h);
+				return;
+			case ' ':
+				if ((h->flags & HTML_NONEWLINE) == 0 &&
+				    (n->flags & NODE_NOFILL) == 0)
+					print_otag(h, TAG_BR, "");
+				break;
+			default:
+				break;
+			}
+		}
+		t = h->tag;
+		t->refcnt++;
 		if (NODE_DELIMC & n->flags)
 			h->flags |= HTML_NOSPACE;
 		print_text(h, n->string);
@@ -379,6 +386,8 @@ print_mdoc_node(MDOC_ARGS)
 			h->flags |= HTML_NOSPACE;
 		break;
 	case ROFFT_EQN:
+		t = h->tag;
+		t->refcnt++;
 		print_eqn(h, n->eqn);
 		break;
 	case ROFFT_TBL:
@@ -395,13 +404,14 @@ print_mdoc_node(MDOC_ARGS)
 		 * the "meta" table state.  This will be reopened on the
 		 * next table element.
 		 */
-		if (h->tblt != NULL) {
+		if (h->tblt != NULL)
 			print_tblclose(h);
-			t = h->tag;
-		}
 		assert(h->tblt == NULL);
+		t = h->tag;
+		t->refcnt++;
 		if (n->tok < ROFF_MAX) {
 			roff_html_pre(h, n);
+			t->refcnt--;
 			print_stagq(h, t);
 			return;
 		}
@@ -421,6 +431,7 @@ print_mdoc_node(MDOC_ARGS)
 	if (child && n->child != NULL)
 		print_mdoc_nodelist(meta, n->child, h);
 
+	t->refcnt--;
 	print_stagq(h, t);
 
 	switch (n->type) {
@@ -436,12 +447,6 @@ print_mdoc_node(MDOC_ARGS)
 			n->body->flags |= NODE_ENDED;
 		break;
 	}
-
-	if (n->flags & NODE_NOFILL &&
-	    (n->next == NULL || n->next->flags & NODE_LINE)) {
-		h->col++;
-		print_endline(h);
-	}
 }
 
 static void
@@ -528,8 +533,10 @@ mdoc_sh_pre(MDOC_ARGS)
 		html_close_paragraph(h);
 		if ((h->oflags & HTML_TOC) == 0 ||
 		    h->flags & HTML_TOCDONE ||
-		    n->sec <= SEC_SYNOPSIS)
+		    n->sec <= SEC_SYNOPSIS) {
+			print_otag(h, TAG_SECTION, "c", "Sh");
 			break;
+		}
 		h->flags |= HTML_TOCDONE;
 		sc = 0;
 		for (sn = n->next; sn != NULL; sn = sn->next)
@@ -570,10 +577,11 @@ mdoc_sh_pre(MDOC_ARGS)
 			print_tagq(h, tsec);
 		}
 		print_tagq(h, t);
+		print_otag(h, TAG_SECTION, "c", "Sh");
 		break;
 	case ROFFT_HEAD:
 		id = html_make_id(n, 1);
-		print_otag(h, TAG_H1, "cTi", "Sh", id);
+		print_otag(h, TAG_H1, "ci", "Sh", id);
 		if (id != NULL)
 			print_otag(h, TAG_A, "chR", "permalink", id);
 		break;
@@ -595,6 +603,7 @@ mdoc_ss_pre(MDOC_ARGS)
 	switch (n->type) {
 	case ROFFT_BLOCK:
 		html_close_paragraph(h);
+		print_otag(h, TAG_SECTION, "c", "Ss");
 		return 1;
 	case ROFFT_HEAD:
 		break;
@@ -605,7 +614,7 @@ mdoc_ss_pre(MDOC_ARGS)
 	}
 
 	id = html_make_id(n, 1);
-	print_otag(h, TAG_H2, "cTi", "Ss", id);
+	print_otag(h, TAG_H2, "ci", "Ss", id);
 	if (id != NULL)
 		print_otag(h, TAG_A, "chR", "permalink", id);
 	return 1;
@@ -618,7 +627,7 @@ mdoc_fl_pre(MDOC_ARGS)
 
 	if ((id = cond_id(n)) != NULL)
 		print_otag(h, TAG_A, "chR", "permalink", id);
-	print_otag(h, TAG_CODE, "cTi", "Fl", id);
+	print_otag(h, TAG_CODE, "ci", "Fl", id);
 
 	print_text(h, "\\-");
 	if (!(n->child == NULL &&
@@ -637,7 +646,7 @@ mdoc_cm_pre(MDOC_ARGS)
 
 	if ((id = cond_id(n)) != NULL)
 		print_otag(h, TAG_A, "chR", "permalink", id);
-	print_otag(h, TAG_CODE, "cTi", "Cm", id);
+	print_otag(h, TAG_CODE, "ci", "Cm", id);
 	return 1;
 }
 
@@ -646,7 +655,6 @@ mdoc_nd_pre(MDOC_ARGS)
 {
 	switch (n->type) {
 	case ROFFT_BLOCK:
-		html_close_paragraph(h);
 		return 1;
 	case ROFFT_HEAD:
 		return 0;
@@ -656,8 +664,7 @@ mdoc_nd_pre(MDOC_ARGS)
 		abort();
 	}
 	print_text(h, "\\(em");
-	/* Cannot use TAG_SPAN because it may contain blocks. */
-	print_otag(h, TAG_DIV, "cT", "Nd");
+	print_otag(h, TAG_SPAN, "c", "Nd");
 	return 1;
 }
 
@@ -671,7 +678,7 @@ mdoc_nm_pre(MDOC_ARGS)
 		print_otag(h, TAG_TD, "");
 		/* FALLTHROUGH */
 	case ROFFT_ELEM:
-		print_otag(h, TAG_CODE, "cT", "Nm");
+		print_otag(h, TAG_CODE, "c", "Nm");
 		return 1;
 	case ROFFT_BODY:
 		print_otag(h, TAG_TD, "");
@@ -693,11 +700,11 @@ mdoc_xr_pre(MDOC_ARGS)
 		return 0;
 
 	if (h->base_man1)
-		print_otag(h, TAG_A, "cThM", "Xr",
+		print_otag(h, TAG_A, "chM", "Xr",
 		    n->child->string, n->child->next == NULL ?
 		    NULL : n->child->next->string);
 	else
-		print_otag(h, TAG_A, "cT", "Xr");
+		print_otag(h, TAG_A, "c", "Xr");
 
 	n = n->child;
 	print_text(h, n->string);
@@ -726,7 +733,7 @@ mdoc_ns_pre(MDOC_ARGS)
 static int
 mdoc_ar_pre(MDOC_ARGS)
 {
-	print_otag(h, TAG_VAR, "cT", "Ar");
+	print_otag(h, TAG_VAR, "c", "Ar");
 	return 1;
 }
 
@@ -898,14 +905,14 @@ mdoc_ex_pre(MDOC_ARGS)
 static int
 mdoc_st_pre(MDOC_ARGS)
 {
-	print_otag(h, TAG_SPAN, "cT", "St");
+	print_otag(h, TAG_SPAN, "c", "St");
 	return 1;
 }
 
 static int
 mdoc_em_pre(MDOC_ARGS)
 {
-	print_otag(h, TAG_I, "cT", "Em");
+	print_otag(h, TAG_I, "c", "Em");
 	return 1;
 }
 
@@ -935,7 +942,7 @@ mdoc_sx_pre(MDOC_ARGS)
 	char	*id;
 
 	id = html_make_id(n, 0);
-	print_otag(h, TAG_A, "cThR", "Sx", id);
+	print_otag(h, TAG_A, "chR", "Sx", id);
 	free(id);
 	return 1;
 }
@@ -987,7 +994,7 @@ mdoc_bd_pre(MDOC_ARGS)
 static int
 mdoc_pa_pre(MDOC_ARGS)
 {
-	print_otag(h, TAG_SPAN, "cT", "Pa");
+	print_otag(h, TAG_SPAN, "c", "Pa");
 	return 1;
 }
 
@@ -1018,7 +1025,7 @@ mdoc_an_pre(MDOC_ARGS)
 	if (n->sec == SEC_AUTHORS && ! (h->flags & HTML_NOSPLIT))
 		h->flags |= HTML_SPLIT;
 
-	print_otag(h, TAG_SPAN, "cT", "An");
+	print_otag(h, TAG_SPAN, "c", "An");
 	return 1;
 }
 
@@ -1026,7 +1033,7 @@ static int
 mdoc_cd_pre(MDOC_ARGS)
 {
 	synopsis_pre(h, n);
-	print_otag(h, TAG_CODE, "cT", "Cd");
+	print_otag(h, TAG_CODE, "c", "Cd");
 	return 1;
 }
 
@@ -1037,7 +1044,7 @@ mdoc_dv_pre(MDOC_ARGS)
 
 	if ((id = cond_id(n)) != NULL)
 		print_otag(h, TAG_A, "chR", "permalink", id);
-	print_otag(h, TAG_CODE, "cTi", "Dv", id);
+	print_otag(h, TAG_CODE, "ci", "Dv", id);
 	return 1;
 }
 
@@ -1048,7 +1055,7 @@ mdoc_ev_pre(MDOC_ARGS)
 
 	if ((id = cond_id(n)) != NULL)
 		print_otag(h, TAG_A, "chR", "permalink", id);
-	print_otag(h, TAG_CODE, "cTi", "Ev", id);
+	print_otag(h, TAG_CODE, "ci", "Ev", id);
 	return 1;
 }
 
@@ -1065,7 +1072,7 @@ mdoc_er_pre(MDOC_ARGS)
 
 	if (id != NULL)
 		print_otag(h, TAG_A, "chR", "permalink", id);
-	print_otag(h, TAG_CODE, "cTi", "Er", id);
+	print_otag(h, TAG_CODE, "ci", "Er", id);
 	return 1;
 }
 
@@ -1076,12 +1083,12 @@ mdoc_fa_pre(MDOC_ARGS)
 	struct tag		*t;
 
 	if (n->parent->tok != MDOC_Fo) {
-		print_otag(h, TAG_VAR, "cT", "Fa");
+		print_otag(h, TAG_VAR, "c", "Fa");
 		return 1;
 	}
 
 	for (nn = n->child; nn; nn = nn->next) {
-		t = print_otag(h, TAG_VAR, "cT", "Fa");
+		t = print_otag(h, TAG_VAR, "c", "Fa");
 		print_text(h, nn->string);
 		print_tagq(h, t);
 		if (nn->next) {
@@ -1112,11 +1119,11 @@ mdoc_fd_pre(MDOC_ARGS)
 	assert(n->type == ROFFT_TEXT);
 
 	if (strcmp(n->string, "#include")) {
-		print_otag(h, TAG_CODE, "cT", "Fd");
+		print_otag(h, TAG_CODE, "c", "Fd");
 		return 1;
 	}
 
-	print_otag(h, TAG_CODE, "cT", "In");
+	print_otag(h, TAG_CODE, "c", "In");
 	print_text(h, n->string);
 
 	if (NULL != (n = n->next)) {
@@ -1130,10 +1137,10 @@ mdoc_fd_pre(MDOC_ARGS)
 			cp = strchr(buf, '\0') - 1;
 			if (cp >= buf && (*cp == '>' || *cp == '"'))
 				*cp = '\0';
-			t = print_otag(h, TAG_A, "cThI", "In", buf);
+			t = print_otag(h, TAG_A, "chI", "In", buf);
 			free(buf);
 		} else
-			t = print_otag(h, TAG_A, "cT", "In");
+			t = print_otag(h, TAG_A, "c", "In");
 
 		print_text(h, n->string);
 		print_tagq(h, t);
@@ -1160,7 +1167,7 @@ mdoc_vt_pre(MDOC_ARGS)
 	} else if (n->type == ROFFT_HEAD)
 		return 0;
 
-	print_otag(h, TAG_VAR, "cT", "Vt");
+	print_otag(h, TAG_VAR, "c", "Vt");
 	return 1;
 }
 
@@ -1168,7 +1175,7 @@ static int
 mdoc_ft_pre(MDOC_ARGS)
 {
 	synopsis_pre(h, n);
-	print_otag(h, TAG_VAR, "cT", "Ft");
+	print_otag(h, TAG_VAR, "c", "Ft");
 	return 1;
 }
 
@@ -1189,7 +1196,7 @@ mdoc_fn_pre(MDOC_ARGS)
 
 	ep = strchr(sp, ' ');
 	if (NULL != ep) {
-		t = print_otag(h, TAG_VAR, "cT", "Ft");
+		t = print_otag(h, TAG_VAR, "c", "Ft");
 
 		while (ep) {
 			sz = MIN((int)(ep - sp), BUFSIZ - 1);
@@ -1202,7 +1209,7 @@ mdoc_fn_pre(MDOC_ARGS)
 		print_tagq(h, t);
 	}
 
-	t = print_otag(h, TAG_CODE, "cT", "Fn");
+	t = print_otag(h, TAG_CODE, "c", "Fn");
 
 	if (sp)
 		print_text(h, sp);
@@ -1215,10 +1222,10 @@ mdoc_fn_pre(MDOC_ARGS)
 
 	for (n = n->child->next; n; n = n->next) {
 		if (NODE_SYNPRETTY & n->flags)
-			t = print_otag(h, TAG_VAR, "cTs", "Fa",
+			t = print_otag(h, TAG_VAR, "cs", "Fa",
 			    "white-space", "nowrap");
 		else
-			t = print_otag(h, TAG_VAR, "cT", "Fa");
+			t = print_otag(h, TAG_VAR, "c", "Fa");
 		print_text(h, n->string);
 		print_tagq(h, t);
 		if (n->next) {
@@ -1265,7 +1272,11 @@ mdoc_skip_pre(MDOC_ARGS)
 static int
 mdoc_pp_pre(MDOC_ARGS)
 {
-	if ((n->flags & NODE_NOFILL) == 0) {
+	if (n->flags & NODE_NOFILL) {
+		print_endline(h);
+		h->col = 1;
+		print_endline(h);
+	} else {
 		html_close_paragraph(h);
 		print_otag(h, TAG_P, "c", "Pp");
 	}
@@ -1291,7 +1302,7 @@ mdoc_lk_pre(MDOC_ARGS)
 	descr = link->next;
 	if (descr == punct)
 		descr = link;  /* no text */
-	t = print_otag(h, TAG_A, "cTh", "Lk", link->string);
+	t = print_otag(h, TAG_A, "ch", "Lk", link->string);
 	do {
 		if (descr->flags & (NODE_DELIMC | NODE_DELIMO))
 			h->flags |= HTML_NOSPACE;
@@ -1319,7 +1330,7 @@ mdoc_mt_pre(MDOC_ARGS)
 		assert(n->type == ROFFT_TEXT);
 
 		mandoc_asprintf(&cp, "mailto:%s", n->string);
-		t = print_otag(h, TAG_A, "cTh", "Mt", cp);
+		t = print_otag(h, TAG_A, "ch", "Mt", cp);
 		print_text(h, n->string);
 		print_tagq(h, t);
 		free(cp);
@@ -1347,7 +1358,7 @@ mdoc_fo_pre(MDOC_ARGS)
 		return 0;
 
 	assert(n->child->string);
-	t = print_otag(h, TAG_CODE, "cT", "Fn");
+	t = print_otag(h, TAG_CODE, "c", "Fn");
 	print_text(h, n->child->string);
 	print_tagq(h, t);
 	return 0;
@@ -1371,7 +1382,7 @@ mdoc_in_pre(MDOC_ARGS)
 	struct tag	*t;
 
 	synopsis_pre(h, n);
-	print_otag(h, TAG_CODE, "cT", "In");
+	print_otag(h, TAG_CODE, "c", "In");
 
 	/*
 	 * The first argument of the `In' gets special treatment as
@@ -1390,9 +1401,9 @@ mdoc_in_pre(MDOC_ARGS)
 		assert(n->type == ROFFT_TEXT);
 
 		if (h->base_includes)
-			t = print_otag(h, TAG_A, "cThI", "In", n->string);
+			t = print_otag(h, TAG_A, "chI", "In", n->string);
 		else
-			t = print_otag(h, TAG_A, "cT", "In");
+			t = print_otag(h, TAG_A, "c", "In");
 		print_text(h, n->string);
 		print_tagq(h, t);
 
@@ -1417,14 +1428,14 @@ mdoc_ic_pre(MDOC_ARGS)
 
 	if ((id = cond_id(n)) != NULL)
 		print_otag(h, TAG_A, "chR", "permalink", id);
-	print_otag(h, TAG_CODE, "cTi", "Ic", id);
+	print_otag(h, TAG_CODE, "ci", "Ic", id);
 	return 1;
 }
 
 static int
 mdoc_va_pre(MDOC_ARGS)
 {
-	print_otag(h, TAG_VAR, "cT", "Va");
+	print_otag(h, TAG_VAR, "c", "Va");
 	return 1;
 }
 
@@ -1476,7 +1487,7 @@ mdoc_ms_pre(MDOC_ARGS)
 
 	if ((id = cond_id(n)) != NULL)
 		print_otag(h, TAG_A, "chR", "permalink", id);
-	print_otag(h, TAG_SPAN, "cTi", "Ms", id);
+	print_otag(h, TAG_SPAN, "ci", "Ms", id);
 	return 1;
 }
 
@@ -1509,7 +1520,7 @@ mdoc_rs_pre(MDOC_ARGS)
 	case ROFFT_BODY:
 		if (n->sec == SEC_SEE_ALSO)
 			print_otag(h, TAG_P, "c", "Pp");
-		print_otag(h, TAG_CITE, "cT", "Rs");
+		print_otag(h, TAG_CITE, "c", "Rs");
 		break;
 	default:
 		abort();
@@ -1542,7 +1553,7 @@ mdoc_li_pre(MDOC_ARGS)
 static int
 mdoc_sy_pre(MDOC_ARGS)
 {
-	print_otag(h, TAG_B, "cT", "Sy");
+	print_otag(h, TAG_B, "c", "Sy");
 	return 1;
 }
 
@@ -1552,7 +1563,7 @@ mdoc_lb_pre(MDOC_ARGS)
 	if (SEC_LIBRARY == n->sec && NODE_LINE & n->flags && n->prev)
 		print_otag(h, TAG_BR, "");
 
-	print_otag(h, TAG_SPAN, "cT", "Lb");
+	print_otag(h, TAG_SPAN, "c", "Lb");
 	return 1;
 }
 
@@ -1693,7 +1704,7 @@ mdoc_quote_pre(MDOC_ARGS)
 		/*
 		 * Give up on semantic markup for now.
 		 * We cannot use TAG_SPAN because .Oo may contain blocks.
-		 * We cannot use TAG_IDIV because we might be in a
+		 * We cannot use TAG_DIV because we might be in a
 		 * phrasing context (like .Dl or .Pp); we cannot
 		 * close out a .Pp at this point either because
 		 * that would break the line.