]> git.cameronkatri.com Git - mandoc.git/commitdiff
Slowly start implementing tagging support for man(7) pages, even
authorIngo Schwarze <schwarze@openbsd.org>
Mon, 22 Jul 2019 03:21:49 +0000 (03:21 +0000)
committerIngo Schwarze <schwarze@openbsd.org>
Mon, 22 Jul 2019 03:21:49 +0000 (03:21 +0000)
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.

Makefile.depend
man_term.c
tag.c

index 81f632d0985473dd7e990ca554aaaf9aa0b1d8d8..3540aeda822ceef4111bf3f4a046222517f5e5c5 100644 (file)
@@ -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
index bb4851e9c7d561c8e6acd9d70896b5f6a528ac76..b051b2ec18b5d94c638c45250fd47a9ee72ff9ca 100644 (file)
@@ -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>
 #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 43571c7f80351185f79643d68414437069030aab..d5e7f89c1a509eb97e5e3608d46019eab4f90077 100644 (file)
--- 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;