summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2018-10-02 14:56:47 +0000
committerIngo Schwarze <schwarze@openbsd.org>2018-10-02 14:56:47 +0000
commit1a292c4956427312d2ebea2becc01a2861e089fc (patch)
treed767b2200fd77455d1c7f9c1ef1ec6648d1750b0
parent9e238facdedce54e6eeccb030929d4b3893df873 (diff)
downloadmandoc-1a292c4956427312d2ebea2becc01a2861e089fc.tar.gz
Add an option -T html -O toc to add a brief table of contents near
the top of HTML pages containing at least two non-standard sections. Suggested by Adam Kalisz and discussed with kristaps@ during EuroBSDCon 2018.
-rw-r--r--TODO5
-rw-r--r--html.c2
-rw-r--r--html.h2
-rw-r--r--man.conf.53
-rw-r--r--manconf.h3
-rw-r--r--mandoc.13
-rw-r--r--manpath.c7
-rw-r--r--mdoc_html.c32
8 files changed, 47 insertions, 10 deletions
diff --git a/TODO b/TODO
index 4aded6d4..6a0e735b 100644
--- a/TODO
+++ b/TODO
@@ -390,11 +390,6 @@ are mere guesses, and some may be wrong.
--- HTML issues --------------------------------------------------------
-- table of content at the top of HTML (and perhaps ps/pdf) pages
- only if there are at least two (or three?) non-standard sections
- only if the new option -O toc is given
- suggested by Adam Kalisz during EuroBSDCon 2018
-
- wrap Sh and Ss content into <div>
Laura Morales <lauretas at mail dot com> 21 Apr 2018 18:10:48 +0200
(Evaluate whether this is really useful and has no adverse
diff --git a/html.c b/html.c
index d0c2b656..8926ca2b 100644
--- a/html.c
+++ b/html.c
@@ -136,6 +136,8 @@ html_alloc(const struct manoutput *outopts)
h->base_includes = outopts->includes;
if (outopts->fragment)
h->oflags |= HTML_FRAGMENT;
+ if (outopts->toc)
+ h->oflags |= HTML_TOC;
mandoc_ohash_init(&id_unique, 4, 0);
diff --git a/html.h b/html.h
index 4b3e3df1..46f9cebd 100644
--- a/html.h
+++ b/html.h
@@ -93,6 +93,7 @@ struct html {
#define HTML_SPLIT (1 << 8) /* break line before .An */
#define HTML_NONEWLINE (1 << 9) /* No line break in nofill mode. */
#define HTML_BUFFER (1 << 10) /* Collect a word to see if it fits. */
+#define HTML_TOCDONE (1 << 11) /* The TOC was already written. */
size_t indent; /* current output indentation level */
int noindent; /* indent disabled by <pre> */
size_t col; /* current output byte position */
@@ -110,6 +111,7 @@ struct html {
enum htmlfont metac; /* current font mode */
int oflags; /* output options */
#define HTML_FRAGMENT (1 << 0) /* don't emit HTML/HEAD/BODY */
+#define HTML_TOC (1 << 1) /* emit a table of contents */
};
diff --git a/man.conf.5 b/man.conf.5
index 0645aa6d..989c4169 100644
--- a/man.conf.5
+++ b/man.conf.5
@@ -1,6 +1,6 @@
.\" $Id$
.\"
-.\" Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
+.\" Copyright (c) 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -98,6 +98,7 @@ manual.
.It Ic man Ta string Ta Cm html Ta path for \&Xr links
.It Ic paper Ta string Ta Cm ps , pdf Ta paper size
.It Ic style Ta string Ta Cm html Ta CSS file
+.It Ic toc Ta none Ta Cm html Ta print table of contents
.It Ic width Ta integer Ta Cm ascii , utf8 Ta right margin
.El
.It Ic _whatdb Ar path Ns Cm /whatis.db
diff --git a/manconf.h b/manconf.h
index cb3a883a..20973366 100644
--- a/manconf.h
+++ b/manconf.h
@@ -34,8 +34,9 @@ struct manoutput {
size_t width;
int fragment;
int mdoc;
- int synopsisonly;
int noval;
+ int synopsisonly;
+ int toc;
};
struct manconf {
diff --git a/mandoc.1 b/mandoc.1
index afea0a1b..466cbeb2 100644
--- a/mandoc.1
+++ b/mandoc.1
@@ -371,6 +371,9 @@ The file
is used for an external style-sheet.
This must be a valid absolute or
relative URI.
+.It Cm toc
+If an input file contains at least two non-standard sections,
+print a table of contents near the beginning of the output.
.El
.Ss Locale Output
By default,
diff --git a/manpath.c b/manpath.c
index 7b6f0c1a..24f57598 100644
--- a/manpath.c
+++ b/manpath.c
@@ -1,6 +1,6 @@
/* $Id$ */
/*
- * Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -233,7 +233,7 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
{
const char *const toks[] = {
"includes", "man", "paper", "style",
- "indent", "width", "fragment", "mdoc", "noval"
+ "indent", "width", "fragment", "mdoc", "noval", "toc"
};
const char *errstr;
@@ -320,6 +320,9 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
case 8:
conf->noval = 1;
return 0;
+ case 9:
+ conf->toc = 1;
+ return 0;
default:
if (fromfile)
warnx("-O %s: Bad argument", cp);
diff --git a/mdoc_html.c b/mdoc_html.c
index c66160df..8e5ce783 100644
--- a/mdoc_html.c
+++ b/mdoc_html.c
@@ -507,9 +507,39 @@ cond_id(const struct roff_node *n)
static int
mdoc_sh_pre(MDOC_ARGS)
{
- char *id;
+ struct roff_node *sn;
+ struct tag *t, *tt;
+ char *id;
+ int sc;
switch (n->type) {
+ case ROFFT_BLOCK:
+ if ((h->oflags & HTML_TOC) == 0 ||
+ h->flags & HTML_TOCDONE ||
+ n->sec <= SEC_SYNOPSIS)
+ break;
+ h->flags |= HTML_TOCDONE;
+ sc = 0;
+ for (sn = n->next; sn != NULL; sn = sn->next)
+ if (sn->sec == SEC_CUSTOM)
+ if (++sc == 2)
+ break;
+ if (sc < 2)
+ break;
+ t = print_otag(h, TAG_H1, "c", "Sh");
+ print_text(h, "TABLE OF CONTENTS");
+ print_tagq(h, t);
+ t = print_otag(h, TAG_UL, "c", "Bl-compact");
+ for (sn = n->next; sn != NULL; sn = sn->next) {
+ id = html_make_id(sn->head, 0);
+ tt = print_otag(h, TAG_LI, "");
+ print_otag(h, TAG_A, "hR", id);
+ print_mdoc_nodelist(meta, sn->head->child, h);
+ print_tagq(h, tt);
+ free(id);
+ }
+ print_tagq(h, t);
+ break;
case ROFFT_HEAD:
id = html_make_id(n, 1);
print_otag(h, TAG_H1, "cTi", "Sh", id);