EDIT: simplified patch a lot by inserting the manwidth option right after the /usr/bin/mandoc
command.
kamil How would you like to see it implemented?
The way I've done it now is in the patch at the end. It inserts a -O width=NN
option to the _build
tags where-ever /usr/bin/mandoc
is present. It's a bit kludgey, but it is the least intrusive way. No other commands which read /etc/man.conf
are affected.
Another, cleaner, but more intrusive, way is to add a new tag _fmt
, then use that in the _build
tags. Eg.
_build .[1-9][a-z]* %_fmt% %s
...
_fmt /usr/bin/mandoc -O width=$((`tput cols` - 3))
OR
_build .[1-9][a-z]* %_fmt% %s
...
_fmt /usr/bin/mandoc
Here, a patch can simply append the -O width=NN
option to the _fmt
tag instead of inserting it into the _build
tags.
But, doing it this way means changes to all the commands: apropos
, whatis
, ..., to recognize the new tag.
A third method would be, as you proposed, to add a wrapper around mandoc
which calls it with the -O width
option set. This wrapper can then be used in the _build
tags. Again, no source changes would be needed; only man.conf
changes.
I'm OK with any of the 3 methods.
Patch
diff -urN a/man/man.c b/man/man.c
--- a/man/man.c 2020-04-09 11:28:32.000000000 +0000
+++ b/man/man.c 2020-11-14 08:21:48.576113574 +0000
@@ -44,6 +44,7 @@
#endif
#endif /* not lint */
+#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/stat.h>
@@ -51,6 +52,7 @@
#include <ctype.h>
#include <err.h>
+#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <glob.h>
@@ -101,6 +103,7 @@
/* other misc stuff */
const char *pager; /* pager to use */
size_t pagerlen; /* length of the above */
+ int manwidth; /* pass -O width= to mandoc(1) if > RMRG */
const char *machine; /* machine */
const char *machclass; /* machine class */
};
@@ -120,6 +123,9 @@
static void addpath(struct manstate *, const char *, size_t, const char *);
static const char *getclass(const char *);
static void printmanpath(struct manstate *);
+static int get_mw(void);
+static char *ins_mw(const char *, const char *, struct manstate *);
+
/*
* main function
@@ -222,6 +228,7 @@
else
m.pager = _PATH_PAGER;
m.pagerlen = strlen(m.pager);
+ m.manwidth = get_mw();
}
}
@@ -804,8 +811,11 @@
(void)cleanup();
exit(EXIT_FAILURE);
}
+ if ((b = ins_mw(fmt, "/usr/bin/mandoc", mp)) != NULL)
+ fmt = b;
(void)snprintf(buf, sizeof(buf), "%s > %s", fmt, tpath);
(void)snprintf(cmd, sizeof(cmd), fmtcheck_ok(buf, "%s"), p);
+ free(b);
(void)system(cmd);
(void)close(fd);
if ((*pathp = strdup(tpath)) == NULL) {
@@ -1077,3 +1087,61 @@
globfree(&pg);
}
}
+
+/*
+ * get_mw --
+ * Return a user-defined MANWIDTH or determine one if set to "tty",
+ * or -1 on errors.
+ */
+int
+get_mw(void)
+{
+ char *p, *ep;
+ int wid;
+
+ if ((p = getenv("MANWIDTH")) == NULL)
+ return -1;
+ if (strcmp(p, "tty") == 0) {
+ struct winsize ws;
+ if (!isatty(STDOUT_FILENO) ||
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0)
+ return -1;
+ return ws.ws_col;
+ }
+ errno = 0;
+ wid = (int)strtol(p, &ep, 10);
+ if (ep == p || *ep != '\0' || errno)
+ return -1;
+ return wid;
+}
+
+/*
+ * ins_mw --
+ * Insert a " -O width=NN " option right after the "/usr/bin/mandoc"
+ * command.
+ * Turns:
+ * 1. _build stuff /usr/bin/mandoc ->
+ * _build stuff /usr/bin/mandoc -O width=NN
+ * 2. _build stuff /usr/bin/mandoc stuff %s ->
+ * _build stuff /usr/bin/mandoc -O width=NN stuff %s
+ * etc.
+ * We do it this way because mandoc(1) doesn't allow options after
+ * filenames, so a simple append won't work.
+ */
+static char*
+ins_mw(const char* line, const char* s, struct manstate* mp)
+{
+ enum { RMRG = 3 }; /* Right margin to match mandoc's LHS */
+ const char* p;
+ char* ret;
+
+ if (mp->manwidth <= RMRG)
+ return NULL;
+ if ((p = strstr(line, s)) == NULL)
+ return NULL; /* not mandoc */
+ p += strlen(s);
+ if (asprintf(&ret, "%.*s -O width=%d %s",
+ (int)(p - line), line, mp->manwidth - RMRG, p) == -1)
+ return NULL;
+ return ret;
+}