summaryrefslogtreecommitdiff
path: root/usr.bin/mandoc/html.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/mandoc/html.c')
-rw-r--r--usr.bin/mandoc/html.c92
1 files changed, 50 insertions, 42 deletions
diff --git a/usr.bin/mandoc/html.c b/usr.bin/mandoc/html.c
index b7a66ebbbfb..23f52e10cb0 100644
--- a/usr.bin/mandoc/html.c
+++ b/usr.bin/mandoc/html.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: html.c,v 1.121 2019/01/11 12:44:10 schwarze Exp $ */
+/* $OpenBSD: html.c,v 1.122 2019/01/18 14:36:16 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
@@ -269,11 +269,19 @@ html_close_paragraph(struct html *h)
{
struct tag *t;
- for (t = h->tag; t != NULL; t = t->next) {
- if (t->tag == TAG_P || t->tag == TAG_PRE) {
+ for (t = h->tag; t != NULL && t->closed == 0; t = t->next) {
+ switch(t->tag) {
+ case TAG_P:
+ case TAG_PRE:
print_tagq(h, t);
break;
+ case TAG_A:
+ print_tagq(h, t);
+ continue;
+ default:
+ continue;
}
+ break;
}
}
@@ -577,6 +585,8 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
t = mandoc_malloc(sizeof(struct tag));
t->tag = tag;
t->next = h->tag;
+ t->refcnt = 0;
+ t->closed = 0;
h->tag = t;
} else
t = NULL;
@@ -709,33 +719,32 @@ print_ctag(struct html *h, struct tag *tag)
{
int tflags;
- /*
- * Remember to close out and nullify the current
- * meta-font and table, if applicable.
- */
- if (tag == h->metaf)
- h->metaf = NULL;
- if (tag == h->tblt)
- h->tblt = NULL;
-
- tflags = htmltags[tag->tag].flags;
-
- if (tflags & HTML_INDENT)
- h->indent--;
- if (tflags & HTML_NOINDENT)
- h->noindent--;
- if (tflags & HTML_NLEND)
- print_endline(h);
- print_indent(h);
- print_byte(h, '<');
- print_byte(h, '/');
- print_word(h, htmltags[tag->tag].name);
- print_byte(h, '>');
- if (tflags & HTML_NLAFTER)
- print_endline(h);
-
- h->tag = tag->next;
- free(tag);
+ if (tag->closed == 0) {
+ tag->closed = 1;
+ if (tag == h->metaf)
+ h->metaf = NULL;
+ if (tag == h->tblt)
+ h->tblt = NULL;
+
+ tflags = htmltags[tag->tag].flags;
+ if (tflags & HTML_INDENT)
+ h->indent--;
+ if (tflags & HTML_NOINDENT)
+ h->noindent--;
+ if (tflags & HTML_NLEND)
+ print_endline(h);
+ print_indent(h);
+ print_byte(h, '<');
+ print_byte(h, '/');
+ print_word(h, htmltags[tag->tag].name);
+ print_byte(h, '>');
+ if (tflags & HTML_NLAFTER)
+ print_endline(h);
+ }
+ if (tag->refcnt == 0) {
+ h->tag = tag->next;
+ free(tag);
+ }
}
void
@@ -822,12 +831,11 @@ print_text(struct html *h, const char *word)
void
print_tagq(struct html *h, const struct tag *until)
{
- struct tag *tag;
+ struct tag *this, *next;
- while ((tag = h->tag) != NULL) {
- print_ctag(h, tag);
- if (tag == until)
- return;
+ for (this = h->tag; this != NULL; this = next) {
+ next = this == until ? NULL : this->next;
+ print_ctag(h, this);
}
}
@@ -839,14 +847,14 @@ print_tagq(struct html *h, const struct tag *until)
void
print_stagq(struct html *h, const struct tag *suntil)
{
- struct tag *tag;
+ struct tag *this, *next;
- while ((tag = h->tag) != NULL) {
- if (tag == suntil ||
- (tag->next == suntil &&
- (tag->tag == TAG_P || tag->tag == TAG_PRE)))
- return;
- print_ctag(h, tag);
+ for (this = h->tag; this != NULL; this = next) {
+ next = this->next;
+ if (this == suntil || (next == suntil &&
+ (this->tag == TAG_P || this->tag == TAG_PRE)))
+ break;
+ print_ctag(h, this);
}
}