summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/mandoc/man_term.c67
-rw-r--r--usr.bin/mandoc/tag.c6
2 files changed, 68 insertions, 5 deletions
diff --git a/usr.bin/mandoc/man_term.c b/usr.bin/mandoc/man_term.c
index ebd59958884..d39326adab8 100644
--- a/usr.bin/mandoc/man_term.c
+++ b/usr.bin/mandoc/man_term.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: man_term.c,v 1.183 2019/07/01 22:43:03 schwarze Exp $ */
+/* $OpenBSD: man_term.c,v 1.184 2019/07/22 03:20:55 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
@@ -25,10 +25,12 @@
#include <string.h>
#include "mandoc_aux.h"
+#include "mandoc.h"
#include "roff.h"
#include "man.h"
#include "out.h"
#include "term.h"
+#include "tag.h"
#include "main.h"
#define MAXMARGINS 64 /* maximum number of indented scopes */
@@ -90,6 +92,8 @@ static void post_SY(DECL_ARGS);
static void post_TP(DECL_ARGS);
static void post_UR(DECL_ARGS);
+static void tag_man(struct termp *, struct roff_node *);
+
static const struct man_term_act man_term_acts[MAN_MAX - MAN_TH] = {
{ NULL, NULL, 0 }, /* TH */
{ pre_SH, post_SH, 0 }, /* SH */
@@ -532,8 +536,10 @@ pre_IP(DECL_ARGS)
case ROFFT_HEAD:
p->tcol->offset = mt->offset;
p->tcol->rmargin = mt->offset + len;
- if (n->child != NULL)
+ if (n->child != NULL) {
print_man_node(p, mt, n->child, meta);
+ tag_man(p, n->child);
+ }
return 0;
case ROFFT_BODY:
p->tcol->offset = mt->offset + len;
@@ -1146,3 +1152,60 @@ print_man_head(struct termp *p, const struct roff_meta *meta)
}
free(title);
}
+
+/*
+ * Skip leading whitespace, dashes, backslashes, and font escapes,
+ * then create a tag if the first following byte is a letter.
+ * Priority is high unless whitespace is present.
+ */
+static void
+tag_man(struct termp *p, struct roff_node *n)
+{
+ const char *cp, *arg;
+ int prio, sz;
+
+ assert(n->type == ROFFT_TEXT);
+ cp = n->string;
+ prio = 1;
+ for (;;) {
+ switch (*cp) {
+ case ' ':
+ case '\t':
+ prio = INT_MAX;
+ /* FALLTHROUGH */
+ case '-':
+ cp++;
+ break;
+ case '\\':
+ cp++;
+ switch (mandoc_escape(&cp, &arg, &sz)) {
+ case ESCAPE_FONT:
+ case ESCAPE_FONTROMAN:
+ case ESCAPE_FONTITALIC:
+ case ESCAPE_FONTBOLD:
+ case ESCAPE_FONTPREV:
+ case ESCAPE_FONTBI:
+ break;
+ case ESCAPE_SPECIAL:
+ if (sz != 1)
+ return;
+ switch (*arg) {
+ case '&':
+ case '-':
+ case 'e':
+ break;
+ default:
+ return;
+ }
+ break;
+ default:
+ return;
+ }
+ break;
+ default:
+ if (isalpha((unsigned char)*cp))
+ tag_put(cp, prio, p->line);
+ return;
+ }
+ }
+}
diff --git a/usr.bin/mandoc/tag.c b/usr.bin/mandoc/tag.c
index 2541a02415b..2d70e52db9d 100644
--- a/usr.bin/mandoc/tag.c
+++ b/usr.bin/mandoc/tag.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tag.c,v 1.23 2019/07/19 20:25:21 schwarze Exp $ */
+/* $OpenBSD: tag.c,v 1.24 2019/07/22 03:20:55 schwarze Exp $ */
/*
* Copyright (c) 2015, 2016, 2018, 2019 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -149,11 +149,11 @@ tag_put(const char *s, int prio, size_t line)
s += 2;
/*
- * Skip whitespace and whatever follows it,
+ * Skip whitespace and escapes and whatever follows,
* and if there is any, downgrade the priority.
*/
- len = strcspn(s, " \t");
+ len = strcspn(s, " \t\\");
if (len == 0)
return;