aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-03-15 11:29:53 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-03-15 11:29:53 +0000
commit4765dc18ce4546a42d3aa2ce149a3c3fb4d79b00 (patch)
tree29466681c88eea5ed0346c222603343534c49d77
parent7820a26ea52032d0330456ae02d4044b357144de (diff)
downloadmandoc-4765dc18ce4546a42d3aa2ce149a3c3fb4d79b00.tar.gz
mandoc-4765dc18ce4546a42d3aa2ce149a3c3fb4d79b00.tar.zst
mandoc-4765dc18ce4546a42d3aa2ce149a3c3fb4d79b00.zip
Minimal support for deep linking into man(7) pages.
As the man(7) language does not provide semantic markup, only .SH, .SS, and .UR become anchors for now.
-rw-r--r--html.c27
-rw-r--r--html.h4
-rw-r--r--man_html.c24
-rw-r--r--mandoc_html.333
-rw-r--r--mdoc_html.c35
5 files changed, 82 insertions, 41 deletions
diff --git a/html.c b/html.c
index 9d3ca523..e424754b 100644
--- a/html.c
+++ b/html.c
@@ -1,4 +1,4 @@
-/* $Id: html.c,v 1.209 2017/03/14 01:35:15 schwarze Exp $ */
+/* $Id: html.c,v 1.210 2017/03/15 11:29:53 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -28,8 +28,9 @@
#include <string.h>
#include <unistd.h>
-#include "mandoc.h"
#include "mandoc_aux.h"
+#include "mandoc.h"
+#include "roff.h"
#include "out.h"
#include "html.h"
#include "manconf.h"
@@ -236,6 +237,28 @@ print_metaf(struct html *h, enum mandoc_esc deco)
}
}
+char *
+html_make_id(const struct roff_node *n)
+{
+ const struct roff_node *nch;
+ char *buf, *cp;
+
+ for (nch = n->child; nch != NULL; nch = nch->next)
+ if (nch->type != ROFFT_TEXT)
+ return NULL;
+
+ buf = NULL;
+ deroff(&buf, n);
+
+ /* http://www.w3.org/TR/html5/dom.html#the-id-attribute */
+
+ for (cp = buf; *cp != '\0'; cp++)
+ if (*cp == ' ')
+ *cp = '_';
+
+ return buf;
+}
+
int
html_strlen(const char *cp)
{
diff --git a/html.h b/html.h
index 5be2f82d..02d5c57d 100644
--- a/html.h
+++ b/html.h
@@ -1,4 +1,4 @@
-/* $Id: html.h,v 1.83 2017/02/05 20:22:04 schwarze Exp $ */
+/* $Id: html.h,v 1.84 2017/03/15 11:29:53 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -112,6 +112,7 @@ struct html {
};
+struct roff_node;
struct tbl_span;
struct eqn;
@@ -127,4 +128,5 @@ void print_eqn(struct html *, const struct eqn *);
void print_paragraph(struct html *);
void print_endline(struct html *);
+char *html_make_id(const struct roff_node *);
int html_strlen(const char *);
diff --git a/man_html.c b/man_html.c
index 9151e4c7..10c544f9 100644
--- a/man_html.c
+++ b/man_html.c
@@ -1,4 +1,4 @@
-/* $Id: man_html.c,v 1.133 2017/02/05 18:15:39 schwarze Exp $ */
+/* $Id: man_html.c,v 1.134 2017/03/15 11:29:53 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -435,8 +435,14 @@ man_br_pre(MAN_ARGS)
static int
man_SH_pre(MAN_ARGS)
{
- if (n->type == ROFFT_HEAD)
- print_otag(h, TAG_H1, "c", "Sh");
+ char *id;
+
+ if (n->type == ROFFT_HEAD) {
+ id = html_make_id(n);
+ print_otag(h, TAG_H1, "cTi", "Sh", id);
+ print_otag(h, TAG_A, "chR", "selflink", id);
+ free(id);
+ }
return 1;
}
@@ -498,8 +504,14 @@ man_SM_pre(MAN_ARGS)
static int
man_SS_pre(MAN_ARGS)
{
- if (n->type == ROFFT_HEAD)
- print_otag(h, TAG_H2, "c", "Ss");
+ char *id;
+
+ if (n->type == ROFFT_HEAD) {
+ id = html_make_id(n);
+ print_otag(h, TAG_H2, "cTi", "Ss", id);
+ print_otag(h, TAG_A, "chR", "selflink", id);
+ free(id);
+ }
return 1;
}
@@ -656,7 +668,7 @@ man_UR_pre(MAN_ARGS)
assert(n->type == ROFFT_HEAD);
if (n->child != NULL) {
assert(n->child->type == ROFFT_TEXT);
- print_otag(h, TAG_A, "ch", "Lk", n->child->string);
+ print_otag(h, TAG_A, "cTh", "Lk", n->child->string);
}
assert(n->next->type == ROFFT_BODY);
diff --git a/mandoc_html.3 b/mandoc_html.3
index a274fd03..1382a2f8 100644
--- a/mandoc_html.3
+++ b/mandoc_html.3
@@ -1,4 +1,4 @@
-.\" $Id: mandoc_html.3,v 1.6 2017/03/13 19:01:38 schwarze Exp $
+.\" $Id: mandoc_html.3,v 1.7 2017/03/15 11:29:53 schwarze Exp $
.\"
.\" Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: March 13 2017 $
+.Dd $Mdocdate: March 15 2017 $
.Dt MANDOC_HTML 3
.Os
.Sh NAME
@@ -48,6 +48,14 @@
.Fa "struct html *h"
.Fa "const char *word"
.Fc
+.Ft char *
+.Fo html_make_id
+.Fa "const struct roff_node *n"
+.Fc
+.Ft int
+.Fo html_strlen
+.Fa "const char *cp"
+.Fc
.Sh DESCRIPTION
The mandoc HTML formatter is not a formal library.
However, as it is compiled into more than one program, in particular
@@ -306,8 +314,27 @@ and
.Fn print_tagq
functions.
.Pp
+The function
+.Fn html_make_id
+takes a node containing one or more text children
+and returns a newly allocated string containing the concatenation
+of the child strings, with blanks replaced by underscores.
+If the node
+.Fa n
+contains any non-text child node,
+.Fn html_make_id
+returns
+.Dv NULL
+instead.
+The caller is responsible for freeing the returned string.
+.Pp
+The function
+.Fn html_strlen
+counts the number of characters in
+.Fa cp .
+It is used as a crude estimate of the width needed to display a string.
+.Pp
The functions
-.Fn html_strlen ,
.Fn print_eqn ,
.Fn print_tbl ,
and
diff --git a/mdoc_html.c b/mdoc_html.c
index 8a0eb8dc..0f71a16b 100644
--- a/mdoc_html.c
+++ b/mdoc_html.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_html.c,v 1.276 2017/03/14 01:35:15 schwarze Exp $ */
+/* $Id: mdoc_html.c,v 1.277 2017/03/15 11:29:53 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -49,7 +49,6 @@ struct htmlmdoc {
};
static char *cond_id(const struct roff_node *);
-static char *make_id(const struct roff_node *);
static void print_mdoc_head(MDOC_ARGS);
static void print_mdoc_node(MDOC_ARGS);
static void print_mdoc_nodelist(MDOC_ARGS);
@@ -478,28 +477,6 @@ mdoc_root_pre(MDOC_ARGS)
}
static char *
-make_id(const struct roff_node *n)
-{
- const struct roff_node *nch;
- char *buf, *cp;
-
- for (nch = n->child; nch != NULL; nch = nch->next)
- if (nch->type != ROFFT_TEXT)
- return NULL;
-
- buf = NULL;
- deroff(&buf, n);
-
- /* http://www.w3.org/TR/html5/dom.html#the-id-attribute */
-
- for (cp = buf; *cp != '\0'; cp++)
- if (*cp == ' ')
- *cp = '_';
-
- return buf;
-}
-
-static char *
cond_id(const struct roff_node *n)
{
if (n->child != NULL &&
@@ -511,7 +488,7 @@ cond_id(const struct roff_node *n)
(n->parent->tok == MDOC_Xo &&
n->parent->parent->prev == NULL &&
n->parent->parent->parent->tok == MDOC_It)))
- return make_id(n);
+ return html_make_id(n);
return NULL;
}
@@ -522,7 +499,7 @@ mdoc_sh_pre(MDOC_ARGS)
switch (n->type) {
case ROFFT_HEAD:
- id = make_id(n);
+ id = html_make_id(n);
print_otag(h, TAG_H1, "cTi", "Sh", id);
print_otag(h, TAG_A, "chR", "selflink", id);
free(id);
@@ -545,7 +522,7 @@ mdoc_ss_pre(MDOC_ARGS)
if (n->type != ROFFT_HEAD)
return 1;
- id = make_id(n);
+ id = html_make_id(n);
print_otag(h, TAG_H2, "cTi", "Ss", id);
print_otag(h, TAG_A, "chR", "selflink", id);
free(id);
@@ -955,7 +932,7 @@ mdoc_sx_pre(MDOC_ARGS)
{
char *id;
- id = make_id(n);
+ id = html_make_id(n);
print_otag(h, TAG_A, "cThR", "Sx", id);
free(id);
return 1;
@@ -1128,7 +1105,7 @@ mdoc_er_pre(MDOC_ARGS)
(n->parent->tok == MDOC_It ||
(n->parent->tok == MDOC_Bq &&
n->parent->parent->parent->tok == MDOC_It)) ?
- make_id(n) : NULL;
+ html_make_id(n) : NULL;
if (id != NULL)
print_otag(h, TAG_A, "chR", "selflink", id);