summaryrefslogtreecommitdiffstats
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
commit28bf3097cb23e1f811b5273cd04e16d309f04607 (patch)
tree38ecfdeb14b8bad014fc814155f7a1dd2f311e86
parent7f62257df910dabf75acbc931ba339de0abde743 (diff)
downloadmandoc-28bf3097cb23e1f811b5273cd04e16d309f04607.tar.gz
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.c25
-rw-r--r--html.h2
-rw-r--r--man_html.c22
-rw-r--r--mandoc_html.329
-rw-r--r--mdoc_html.c33
5 files changed, 76 insertions, 35 deletions
diff --git a/html.c b/html.c
index c477fd1b..ed076eaa 100644
--- a/html.c
+++ b/html.c
@@ -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 29e5e868..e228be5d 100644
--- a/html.h
+++ b/html.h
@@ -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 7db71e2a..cc3fc761 100644
--- a/man_html.c
+++ b/man_html.c
@@ -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 deae701b..f675d400 100644
--- a/mandoc_html.3
+++ b/mandoc_html.3
@@ -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 3a0b774b..eda5ce41 100644
--- a/mdoc_html.c
+++ b/mdoc_html.c
@@ -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);