Hi Theo, Theo de Raadt wrote on Sun, Jul 21, 2019 at 02:00:20PM -0600:
> Nice rant. Now get back to work. :) As you wish, Your Grace. =;c) Ingo Log Message: ----------- 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. Modified Files: -------------- mandoc: Makefile.depend man_term.c tag.c Revision Data ------------- Index: tag.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/tag.c,v retrieving revision 1.23 retrieving revision 1.24 diff -Ltag.c -Ltag.c -u -p -r1.23 -r1.24 --- tag.c +++ tag.c @@ -151,11 +151,11 @@ tag_put(const char *s, int prio, size_t 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; Index: Makefile.depend =================================================================== RCS file: /home/cvs/mandoc/mandoc/Makefile.depend,v retrieving revision 1.44 retrieving revision 1.45 diff -LMakefile.depend -LMakefile.depend -u -p -r1.44 -r1.45 --- Makefile.depend +++ Makefile.depend @@ -37,7 +37,7 @@ main.o: main.c config.h mandoc_aux.h man 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: man_term.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/man_term.c,v retrieving revision 1.230 retrieving revision 1.231 diff -Lman_term.c -Lman_term.c -u -p -r1.230 -r1.231 --- man_term.c +++ man_term.c @@ -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; @@ -1147,4 +1153,61 @@ print_man_head(struct termp *p, const st term_vspace(p); } 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; + } + } }