From 72cf85a98bb1b2a6ef04b580cfa7c6a0d5ae1b24 Mon Sep 17 00:00:00 2001 From: Ingo Schwarze Date: Mon, 22 Jul 2019 03:21:49 +0000 Subject: 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. --- Makefile.depend | 2 +- man_term.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- tag.c | 6 +++--- 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 * Copyright (c) 2010-2015, 2017-2019 Ingo Schwarze @@ -27,10 +27,12 @@ #include #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 * @@ -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; -- cgit v1.2.3-56-ge451