Hi again,
I have added the modifications I think you told me.
Also I changed the extension of the tmp file then it can be interpreted
as HTML by any browser used as pager. The extension is set when using
html format.
Now this works: MANPAGER="lynx" ./man -T html -O tag=k pfctl (no need to
force_html also)
Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/main.c,v
retrieving revision 1.252
diff -u -p -r1.252 main.c
--- main.c 11 Jun 2020 16:12:14 -0000 1.252
+++ main.c 15 Jun 2020 10:30:38 -0000
@@ -107,8 +107,8 @@ static void parse(struct mparse *, in
static void passthrough(int, int);
static void process_onefile(struct mparse *, struct manpage *,
int, struct outstate *, struct manconf *);
-static void run_pager(struct tag_files *, char *);
-static pid_t spawn_pager(struct tag_files *, char *);
+static void run_pager(struct outstate, char *);
+static pid_t spawn_pager(struct outstate, char *);
static void usage(enum argmode) __attribute__((__noreturn__));
static int woptions(char *, enum mandoc_os *, int *);
@@ -621,7 +621,7 @@ out:
if (outst.tag_files != NULL) {
if (term_tag_close() != -1)
- run_pager(outst.tag_files, conf.output.tag);
+ run_pager(outst, conf.output.tag);
term_tag_unlink();
} else if (outst.had_output && outst.outtype != OUTT_LINT)
mandoc_msg_summary();
@@ -815,7 +815,10 @@ process_onefile(struct mparse *mp, struc
if (outst->use_pager) {
outst->use_pager = 0;
- outst->tag_files = term_tag_init();
+ if (outst->outtype == OUTT_HTML)
+ outst->tag_files = term_tag_init("html");
+ else
+ outst->tag_files = term_tag_init(NULL);
}
if (outst->had_output && outst->outtype <= OUTT_UTF8) {
if (outst->outdata == NULL)
@@ -1122,14 +1125,14 @@ woptions(char *arg, enum mandoc_os *os_e
* then fork the pager and wait for the user to close it.
*/
static void
-run_pager(struct tag_files *tag_files, char *tag_target)
+run_pager(struct outstate outst, char *tag_target)
{
int signum, status;
pid_t man_pgid, tc_pgid;
pid_t pager_pid, wait_pid;
man_pgid = getpgid(0);
- tag_files->tcpgid = man_pgid == getpid() ? getpgid(getppid()) :
+ outst.tag_files->tcpgid = man_pgid == getpid() ? getpgid(getppid()) :
man_pgid;
pager_pid = 0;
signum = SIGSTOP;
@@ -1144,7 +1147,7 @@ run_pager(struct tag_files *tag_files, c
if (signum == SIGTTIN)
continue;
} else
- tag_files->tcpgid = tc_pgid;
+ outst.tag_files->tcpgid = tc_pgid;
kill(0, signum);
continue;
}
@@ -1155,7 +1158,7 @@ run_pager(struct tag_files *tag_files, c
(void)tcsetpgrp(STDOUT_FILENO, pager_pid);
kill(pager_pid, SIGCONT);
} else
- pager_pid = spawn_pager(tag_files, tag_target);
+ pager_pid = spawn_pager(outst, tag_target);
/* Wait for the pager to stop or exit. */
@@ -1176,19 +1179,20 @@ run_pager(struct tag_files *tag_files, c
}
static pid_t
-spawn_pager(struct tag_files *tag_files, char *tag_target)
+spawn_pager(struct outstate outst, char *tag_target)
{
const struct timespec timeout = { 0, 100000000 }; /* 0.1s */
#define MAX_PAGER_ARGS 16
char *argv[MAX_PAGER_ARGS];
+ char *ofurl;
const char *pager;
char *cp;
size_t cmdlen;
int argc, use_ofn;
pid_t pager_pid;
- assert(tag_files->ofd == -1);
- assert(tag_files->tfs == NULL);
+ assert(outst.tag_files->ofd == -1);
+ assert(outst.tag_files->tfs == NULL);
pager = getenv("MANPAGER");
if (pager == NULL || *pager == '\0')
@@ -1218,11 +1222,11 @@ spawn_pager(struct tag_files *tag_files,
/* For more(1) and less(1), use the tag file. */
use_ofn = 1;
- if (*tag_files->tfn != '\0' && (cmdlen = strlen(argv[0])) >= 4) {
+ if (*outst.tag_files->tfn != '\0' && (cmdlen = strlen(argv[0])) >= 4) {
cp = argv[0] + cmdlen - 4;
if (strcmp(cp, "less") == 0 || strcmp(cp, "more") == 0) {
argv[argc++] = mandoc_strdup("-T");
- argv[argc++] = tag_files->tfn;
+ argv[argc++] = outst.tag_files->tfn;
if (tag_target != NULL) {
argv[argc++] = mandoc_strdup("-t");
argv[argc++] = tag_target;
@@ -1230,8 +1234,19 @@ spawn_pager(struct tag_files *tag_files,
}
}
}
- if (use_ofn)
- argv[argc++] = tag_files->ofn;
+
+ if (use_ofn) {
+ /* Use file:///tmp/man.XXXXXXXX.html URL scheme */
+ if (outst.outtype == OUTT_HTML) {
+ if (tag_target == NULL)
+ mandoc_asprintf(&ofurl, "file://%s",
outst.tag_files->ofn);
+ else
+ mandoc_asprintf(&ofurl, "file://%s#%s", outst.tag_files->ofn,
tag_target);
+ argv[argc++] = ofurl;
+ } else
+ argv[argc++] = outst.tag_files->ofn;
+ }
+
argv[argc] = NULL;
switch (pager_pid = fork()) {
@@ -1248,7 +1263,7 @@ spawn_pager(struct tag_files *tag_files,
"%s", strerror(errno));
exit(mandoc_msg_getrc());
}
- tag_files->pager_pid = pager_pid;
+ outst.tag_files->pager_pid = pager_pid;
return pager_pid;
}
Index: term_tag.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/term_tag.c,v
retrieving revision 1.4
diff -u -p -r1.4 term_tag.c
--- term_tag.c 18 Apr 2020 20:28:46 -0000 1.4
+++ term_tag.c 15 Jun 2020 10:30:38 -0000
@@ -28,6 +28,7 @@
#include <unistd.h>
#include "mandoc.h"
+#include "mandoc_aux.h"
#include "roff.h"
#include "roff_int.h"
#include "tag.h"
@@ -44,7 +45,7 @@ static struct tag_files tag_files;
* but for simplicity, create it anyway.
*/
struct tag_files *
-term_tag_init(void)
+term_tag_init(const char *out_fext)
{
struct sigaction sa;
int ofd; /* In /tmp/, dup(2)ed to stdout. */
@@ -81,20 +82,25 @@ term_tag_init(void)
/* Create both temporary output files. */
- (void)strlcpy(tag_files.ofn, "/tmp/man.XXXXXXXXXX",
- sizeof(tag_files.ofn));
- (void)strlcpy(tag_files.tfn, "/tmp/man.XXXXXXXXXX",
- sizeof(tag_files.tfn));
- if ((ofd = mkstemp(tag_files.ofn)) == -1) {
+ mandoc_asprintf(&tag_files.ofn, out_fext == NULL ?
+ "/tmp/man.XXXXXXXXXX" : "/tmp/man.XXXXXXXXXX.%s", out_fext);
+ mandoc_asprintf(&tag_files.tfn, out_fext == NULL ?
+ "/tmp/man.XXXXXXXXXX" : "/tmp/man.XXXXXXXXXX.%s", out_fext);
+
+ if ((ofd = mkstemps(tag_files.ofn, out_fext == NULL ? 0 :
+ strlen(out_fext) + 1)) == -1) {
mandoc_msg(MANDOCERR_MKSTEMP, 0, 0,
"%s: %s", tag_files.ofn, strerror(errno));
goto fail;
}
- if ((tfd = mkstemp(tag_files.tfn)) == -1) {
- mandoc_msg(MANDOCERR_MKSTEMP, 0, 0,
- "%s: %s", tag_files.tfn, strerror(errno));
+
+ if ((tfd = mkstemps(tag_files.tfn, out_fext == NULL ? 0 :
+ strlen(out_fext) + 1)) == -1) {
+ mandoc_msg(MANDOCERR_MKSTEMP, 0, 0,
+ "%s: %s", tag_files.tfn, strerror(errno));
goto fail;
}
+
if ((tag_files.tfs = fdopen(tfd, "w")) == NULL) {
mandoc_msg(MANDOCERR_FDOPEN, 0, 0, "%s", strerror(errno));
goto fail;
Index: term_tag.h
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/term_tag.h,v
retrieving revision 1.2
diff -u -p -r1.2 term_tag.h
--- term_tag.h 2 Apr 2020 22:10:27 -0000 1.2
+++ term_tag.h 15 Jun 2020 10:30:38 -0000
@@ -19,8 +19,8 @@
*/
struct tag_files {
- char ofn[20]; /* Output file name. */
- char tfn[20]; /* Tag file name. */
+ char *ofn; /* Output file name. */
+ char *tfn; /* Tag file name. */
FILE *tfs; /* Tag file object. */
int ofd; /* Original output file descriptor. */
pid_t tcpgid; /* Process group controlling the terminal. */
@@ -28,7 +28,7 @@ struct tag_files {
};
-struct tag_files *term_tag_init(void);
+struct tag_files *term_tag_init(const char *);
void term_tag_write(struct roff_node *, size_t);
int term_tag_close(void);
void term_tag_unlink(void);
On 2020-06-15 10:58, Romero Pérez, Abel wrote:
Thanks for the handy answer, Ingo.
I am going to develop it better.
On 2020-06-15 04:13, Ingo Schwarze wrote:
Hi Abel,
Romero Perez, Abel wrote on Mon, Jun 15, 2020 at 03:06:26AM +0200:
Romero Perez, Abel wrote:
I tried to view the manuals in HTML format with lynx, but I couldn't
I assume what you mean is that you could, but the "-O tag" option had
no effect.
because lynx and links can't accept the /tmp/man.XXXXXX... file as
an URL...
In "-T html" output mode, the tag file isn't even written in the first
place. Only the terminal formatter writes a tag file.
then I decided to add a new parameter (-U)
Absolutely not. Adding new options to man(1) is completely out of
the question. Option space is almost full and very messy already:
https://mandoc.bsd.lv/man/man.options.1.html
It hardly matters that -U is already taken:
https://mandoc.bsd.lv/man/man.options.1.html#U
You certainly can't take an option that is still free for this
purpose, either.
to pass the pager a formal file URL scheme as follows:
file:///tmp/man.XXXXXXX#tag
Then man spawns the pager (lynx for my case):
lynx -force_html file:///tmp/man.XXXXXXX#tag
That's an interesting idea.
It needs to be done by default when -T html -O tag is given, just
like tagging is enabled by default when the pager is less(1).
The testing command is:
PAGER="" MANPAGER="lynx -force_html" ./man -U -T html -O tag=k pfctl
The PAGER="" variable has no effect when MANPAGER is set,
see the man(1) manual.
So the goal is to make this work:
MANPAGER="lynx -force_html" ./man -T html -O tag=k pfctl
Sorry, I didn't reviewed the code well. The first diff has some bugs.
As follows the stable diff (please, review):
I didn't review the diff closely, yet.
Obviously, using strncpy(3) or strncat(3) is not permitted,
but those should be easy to replace, perhaps with mandoc_asprintf(),
not sure yet.
It looks like you will have to pass outst into run_pager() and
spawn_pager() rather than outst.tag_files, such that you can check
for outst.outtype == OUTT_HTML inside spawn_pager().
In any case, thanks for the nice idea!
Yours,
Ingo