aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2019-07-22 03:21:49 +0000
committerIngo Schwarze <schwarze@openbsd.org>2019-07-22 03:21:49 +0000
commit72cf85a98bb1b2a6ef04b580cfa7c6a0d5ae1b24 (patch)
tree7c7db3ec0c82618c4252ee155b51afe44c029836
parentf3471bbe850e1ceab86fe35bf08aed11dfa7a465 (diff)
downloadmandoc-72cf85a98bb1b2a6ef04b580cfa7c6a0d5ae1b24.tar.gz
mandoc-72cf85a98bb1b2a6ef04b580cfa7c6a0d5ae1b24.tar.zst
mandoc-72cf85a98bb1b2a6ef04b580cfa7c6a0d5ae1b24.zip
Slowly start implementing tagging support for man(7) pages, even
though it is obvious that this can never become as good as for mdoc(7) pages. As a first step, tag alphabetic arguments of .IP macros, which are often used for lists of options and keywords. Try "man -O tag=g as" to get the point. Thanks to Leah Neukirchen for recently reminding me that exploring how much can be done in this respect may be worthwhile: it is likely to slightly improve usability while adding only small amounts of relatively straightforward code.
-rw-r--r--Makefile.depend2
-rw-r--r--man_term.c67
-rw-r--r--tag.c6
3 files changed, 69 insertions, 6 deletions
diff --git a/Makefile.depend b/Makefile.depend
index 81f632d0..3540aeda 100644
--- a/Makefile.depend
+++ b/Makefile.depend
@@ -37,7 +37,7 @@ main.o: main.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h man.h ma
man.o: man.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
man_html.o: man_html.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h html.h main.h
man_macro.o: man_macro.c config.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
-man_term.o: man_term.c config.h mandoc_aux.h roff.h man.h out.h term.h main.h
+man_term.o: man_term.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h term.h tag.h main.h
man_validate.o: man_validate.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
mandoc.o: mandoc.c config.h mandoc_aux.h mandoc.h roff.h libmandoc.h roff_int.h
mandoc_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h
diff --git a/man_term.c b/man_term.c
index bb4851e9..b051b2ec 100644
--- a/man_term.c
+++ b/man_term.c
@@ -1,4 +1,4 @@
-/* $Id: man_term.c,v 1.230 2019/07/01 22:56:24 schwarze Exp $ */
+/* $Id: man_term.c,v 1.231 2019/07/22 03:21:49 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
@@ -27,10 +27,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 */
@@ -92,6 +94,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 */
@@ -534,8 +538,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;
@@ -1148,3 +1154,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/tag.c b/tag.c
index 43571c7f..d5e7f89c 100644
--- a/tag.c
+++ b/tag.c
@@ -1,4 +1,4 @@
-/* $Id: tag.c,v 1.23 2019/07/19 20:27:25 schwarze Exp $ */
+/* $Id: tag.c,v 1.24 2019/07/22 03:21:50 schwarze Exp $ */
/*
* Copyright (c) 2015, 2016, 2018, 2019 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -151,11 +151,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;