-/* $Id: mdoc_html.c,v 1.202 2014/09/27 09:05:57 kristaps Exp $ */
+/* $Id: mdoc_html.c,v 1.219 2015/01/23 14:21:01 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2014, 2015 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
#include <string.h>
#include <unistd.h>
-#include "mandoc.h"
#include "mandoc_aux.h"
+#include "mdoc.h"
#include "out.h"
#include "html.h"
-#include "mdoc.h"
#include "main.h"
#define INDENT 5
const struct mdoc_node *);
static void a2width(const char *, struct roffsu *);
-static void a2offs(const char *, struct roffsu *);
static void mdoc_root_post(MDOC_ARGS);
static int mdoc_root_pre(MDOC_ARGS);
static int mdoc_ms_pre(MDOC_ARGS);
static int mdoc_nd_pre(MDOC_ARGS);
static int mdoc_nm_pre(MDOC_ARGS);
+static int mdoc_no_pre(MDOC_ARGS);
static int mdoc_ns_pre(MDOC_ARGS);
static int mdoc_pa_pre(MDOC_ARGS);
static void mdoc_pf_post(MDOC_ARGS);
{mdoc_quote_pre, mdoc_quote_post}, /* Bq */
{mdoc_xx_pre, NULL}, /* Bsx */
{mdoc_bx_pre, NULL}, /* Bx */
- {NULL, NULL}, /* Db */
+ {mdoc_skip_pre, NULL}, /* Db */
{NULL, NULL}, /* Dc */
{mdoc_quote_pre, mdoc_quote_post}, /* Do */
{mdoc_quote_pre, mdoc_quote_post}, /* Dq */
{mdoc_quote_pre, mdoc_quote_post}, /* Eo */
{mdoc_xx_pre, NULL}, /* Fx */
{mdoc_ms_pre, NULL}, /* Ms */
- {mdoc_igndelim_pre, NULL}, /* No */
+ {mdoc_no_pre, NULL}, /* No */
{mdoc_ns_pre, NULL}, /* Ns */
{mdoc_xx_pre, NULL}, /* Nx */
{mdoc_xx_pre, NULL}, /* Ox */
a2width(const char *p, struct roffsu *su)
{
- if ( ! a2roffsu(p, su, SCALE_MAX)) {
- su->unit = SCALE_BU;
+ if (a2roffsu(p, su, SCALE_MAX) < 2) {
+ su->unit = SCALE_EN;
su->scale = html_strlen(p);
- }
+ } else if (su->scale < 0.0)
+ su->scale = 0.0;
}
/*
case MDOC_In:
/* FALLTHROUGH */
case MDOC_Vt:
- print_otag(h, TAG_P, 0, NULL);
+ print_paragraph(h);
break;
case MDOC_Ft:
if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) {
- print_otag(h, TAG_P, 0, NULL);
+ print_paragraph(h);
break;
}
/* FALLTHROUGH */
}
}
-/*
- * Calculate the scaling unit passed in an `-offset' argument. This
- * uses either a native scaling unit (e.g., 1i, 2m), one of a set of
- * predefined strings (indent, etc.), or the string length of the value.
- */
-static void
-a2offs(const char *p, struct roffsu *su)
-{
-
- /* FIXME: "right"? */
-
- if (0 == strcmp(p, "left"))
- SCALE_HS_INIT(su, 0);
- else if (0 == strcmp(p, "indent"))
- SCALE_HS_INIT(su, INDENT);
- else if (0 == strcmp(p, "indent-two"))
- SCALE_HS_INIT(su, INDENT * 2);
- else if ( ! a2roffsu(p, su, SCALE_MAX))
- SCALE_HS_INIT(su, html_strlen(p));
-}
-
static void
print_mdoc(MDOC_ARGS)
{
* the "meta" table state. This will be reopened on the
* next table element.
*/
- if (h->tblt) {
+ if (h->tblt != NULL) {
print_tblclose(h);
t = h->tags.head;
}
-
- assert(NULL == h->tblt);
- if (mdocs[n->tok].pre && ENDBODY_NOT == n->end)
+ assert(h->tblt == NULL);
+ if (mdocs[n->tok].pre && (n->end == ENDBODY_NOT || n->child))
child = (*mdocs[n->tok].pre)(meta, n, h);
break;
}
case MDOC_EQN:
break;
default:
- if (mdocs[n->tok].post && ENDBODY_NOT == n->end)
- (*mdocs[n->tok].post)(meta, n, h);
+ if ( ! mdocs[n->tok].post || n->flags & MDOC_ENDED)
+ break;
+ (*mdocs[n->tok].post)(meta, n, h);
+ if (n->end != ENDBODY_NOT)
+ n->pending->flags |= MDOC_ENDED;
+ if (n->end == ENDBODY_NOSPACE)
+ h->flags |= HTML_NOSPACE;
break;
}
}
static void
mdoc_root_post(MDOC_ARGS)
{
- struct htmlpair tag[2];
+ struct htmlpair tag;
struct tag *t, *tt;
- PAIR_CLASS_INIT(&tag[0], "foot");
- t = print_otag(h, TAG_TABLE, 1, tag);
- PAIR_INIT(&tag[0], ATTR_WIDTH, "50%");
- print_otag(h, TAG_COL, 1, tag);
- print_otag(h, TAG_COL, 1, tag);
+ PAIR_CLASS_INIT(&tag, "foot");
+ t = print_otag(h, TAG_TABLE, 1, &tag);
print_otag(h, TAG_TBODY, 0, NULL);
tt = print_otag(h, TAG_TR, 0, NULL);
- PAIR_CLASS_INIT(&tag[0], "foot-date");
- print_otag(h, TAG_TD, 1, tag);
+ PAIR_CLASS_INIT(&tag, "foot-date");
+ print_otag(h, TAG_TD, 1, &tag);
print_text(h, meta->date);
print_stagq(h, tt);
- PAIR_CLASS_INIT(&tag[0], "foot-os");
- PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
- print_otag(h, TAG_TD, 2, tag);
+ PAIR_CLASS_INIT(&tag, "foot-os");
+ print_otag(h, TAG_TD, 1, &tag);
print_text(h, meta->os);
print_tagq(h, t);
}
static int
mdoc_root_pre(MDOC_ARGS)
{
- struct htmlpair tag[2];
+ struct htmlpair tag;
struct tag *t, *tt;
char *volume, *title;
mandoc_asprintf(&title, "%s(%s)",
meta->title, meta->msec);
- PAIR_CLASS_INIT(&tag[0], "head");
- t = print_otag(h, TAG_TABLE, 1, tag);
- PAIR_INIT(&tag[0], ATTR_WIDTH, "30%");
- print_otag(h, TAG_COL, 1, tag);
- print_otag(h, TAG_COL, 1, tag);
- print_otag(h, TAG_COL, 1, tag);
+ PAIR_CLASS_INIT(&tag, "head");
+ t = print_otag(h, TAG_TABLE, 1, &tag);
print_otag(h, TAG_TBODY, 0, NULL);
tt = print_otag(h, TAG_TR, 0, NULL);
- PAIR_CLASS_INIT(&tag[0], "head-ltitle");
- print_otag(h, TAG_TD, 1, tag);
+ PAIR_CLASS_INIT(&tag, "head-ltitle");
+ print_otag(h, TAG_TD, 1, &tag);
print_text(h, title);
print_stagq(h, tt);
- PAIR_CLASS_INIT(&tag[0], "head-vol");
- PAIR_INIT(&tag[1], ATTR_ALIGN, "center");
- print_otag(h, TAG_TD, 2, tag);
+ PAIR_CLASS_INIT(&tag, "head-vol");
+ print_otag(h, TAG_TD, 1, &tag);
print_text(h, volume);
print_stagq(h, tt);
- PAIR_CLASS_INIT(&tag[0], "head-rtitle");
- PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
- print_otag(h, TAG_TD, 2, tag);
+ PAIR_CLASS_INIT(&tag, "head-rtitle");
+ print_otag(h, TAG_TD, 1, &tag);
print_text(h, title);
print_tagq(h, t);
/* Set the block's left-hand margin. */
if (n->norm->Bl.offs) {
- a2offs(n->norm->Bl.offs, &su);
+ a2width(n->norm->Bl.offs, &su);
bufcat_su(h, "margin-left", &su);
}
break;
}
if ( ! comp)
- print_otag(h, TAG_P, 0, NULL);
+ print_paragraph(h);
return(1);
}
- SCALE_HS_INIT(&su, 0);
- if (n->norm->Bd.offs)
- a2offs(n->norm->Bd.offs, &su);
+ /* Handle the -offset argument. */
+
+ if (n->norm->Bd.offs == NULL ||
+ ! strcmp(n->norm->Bd.offs, "left"))
+ SCALE_HS_INIT(&su, 0);
+ else if ( ! strcmp(n->norm->Bd.offs, "indent"))
+ SCALE_HS_INIT(&su, INDENT);
+ else if ( ! strcmp(n->norm->Bd.offs, "indent-two"))
+ SCALE_HS_INIT(&su, INDENT * 2);
+ else
+ a2width(n->norm->Bd.offs, &su);
bufinit(h);
bufcat_su(h, "margin-left", &su);
default:
break;
}
- if (nn->next && nn->next->line == nn->line)
+ if (h->flags & HTML_NONEWLINE ||
+ (nn->next && ! (nn->next->flags & MDOC_LINE)))
continue;
else if (nn->next)
print_text(h, "\n");
mdoc_pp_pre(MDOC_ARGS)
{
- print_otag(h, TAG_P, 0, NULL);
+ print_paragraph(h);
return(0);
}
SCALE_VS_INIT(&su, 1);
if (MDOC_sp == n->tok) {
- if (NULL != (n = n->child))
+ if (NULL != (n = n->child)) {
if ( ! a2roffsu(n->string, &su, SCALE_VS))
- SCALE_VS_INIT(&su, atoi(n->string));
+ su.scale = 1.0;
+ else if (su.scale < 0.0)
+ su.scale = 0.0;
+ }
} else
su.scale = 0.0;
mdoc_pf_post(MDOC_ARGS)
{
- h->flags |= HTML_NOSPACE;
+ if ( ! (n->next == NULL || n->next->flags & MDOC_LINE))
+ h->flags |= HTML_NOSPACE;
}
static int
return(1);
if (n->prev && SEC_SEE_ALSO == n->sec)
- print_otag(h, TAG_P, 0, NULL);
+ print_paragraph(h);
PAIR_CLASS_INIT(&tag, "ref");
print_otag(h, TAG_SPAN, 1, &tag);
return(1);
}
+static int
+mdoc_no_pre(MDOC_ARGS)
+{
+ struct htmlpair tag;
+
+ PAIR_CLASS_INIT(&tag, "none");
+ print_otag(h, TAG_CODE, 1, &tag);
+ return(1);
+}
+
static int
mdoc_li_pre(MDOC_ARGS)
{
case MDOC_Ao:
/* FALLTHROUGH */
case MDOC_Aq:
- print_text(h, "\\(la");
+ print_text(h, n->nchild == 1 &&
+ n->child->tok == MDOC_Mt ? "<" : "\\(la");
break;
case MDOC_Bro:
/* FALLTHROUGH */
mdoc_quote_post(MDOC_ARGS)
{
- if (MDOC_BODY != n->type)
+ if (n->type != MDOC_BODY && n->type != MDOC_ELEM)
return;
- if (MDOC_En != n->tok)
+ if ( ! (n->tok == MDOC_En ||
+ (n->tok == MDOC_Eo && n->end == ENDBODY_SPACE)))
h->flags |= HTML_NOSPACE;
switch (n->tok) {
case MDOC_Ao:
/* FALLTHROUGH */
case MDOC_Aq:
- print_text(h, "\\(ra");
+ print_text(h, n->nchild == 1 &&
+ n->child->tok == MDOC_Mt ? ">" : "\\(ra");
break;
case MDOC_Bro:
/* FALLTHROUGH */