Return to mdoc_html.c CVS log | Up to [cvsweb.bsd.lv] / mandoc |
version 1.217, 2014/12/23 09:31:46 | version 1.248, 2017/01/17 01:47:51 | ||
---|---|---|---|
|
|
||
/* $Id$ */ | /* $Id$ */ | ||
/* | /* | ||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> | * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> | ||
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org> | * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org> | ||
* | * | ||
* Permission to use, copy, modify, and distribute this software for any | * Permission to use, copy, modify, and distribute this software for any | ||
* purpose with or without fee is hereby granted, provided that the above | * purpose with or without fee is hereby granted, provided that the above | ||
* copyright notice and this permission notice appear in all copies. | * copyright notice and this permission notice appear in all copies. | ||
* | * | ||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES | ||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR | ||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
|
|
||
#include <unistd.h> | #include <unistd.h> | ||
#include "mandoc_aux.h" | #include "mandoc_aux.h" | ||
#include "roff.h" | |||
#include "mdoc.h" | #include "mdoc.h" | ||
#include "out.h" | #include "out.h" | ||
#include "html.h" | #include "html.h" | ||
|
|
||
#define INDENT 5 | #define INDENT 5 | ||
#define MDOC_ARGS const struct mdoc_meta *meta, \ | #define MDOC_ARGS const struct roff_meta *meta, \ | ||
const struct mdoc_node *n, \ | struct roff_node *n, \ | ||
struct html *h | struct html *h | ||
#ifndef MIN | #ifndef MIN | ||
|
|
||
void (*post)(MDOC_ARGS); | void (*post)(MDOC_ARGS); | ||
}; | }; | ||
static void print_mdoc(MDOC_ARGS); | |||
static void print_mdoc_head(MDOC_ARGS); | static void print_mdoc_head(MDOC_ARGS); | ||
static void print_mdoc_node(MDOC_ARGS); | static void print_mdoc_node(MDOC_ARGS); | ||
static void print_mdoc_nodelist(MDOC_ARGS); | static void print_mdoc_nodelist(MDOC_ARGS); | ||
static void synopsis_pre(struct html *, | static void synopsis_pre(struct html *, | ||
const struct mdoc_node *); | const struct roff_node *); | ||
static void a2width(const char *, struct roffsu *); | |||
static void mdoc_root_post(MDOC_ARGS); | static void mdoc_root_post(MDOC_ARGS); | ||
static int mdoc_root_pre(MDOC_ARGS); | static int mdoc_root_pre(MDOC_ARGS); | ||
|
|
||
static void mdoc_bk_post(MDOC_ARGS); | static void mdoc_bk_post(MDOC_ARGS); | ||
static int mdoc_bk_pre(MDOC_ARGS); | static int mdoc_bk_pre(MDOC_ARGS); | ||
static int mdoc_bl_pre(MDOC_ARGS); | static int mdoc_bl_pre(MDOC_ARGS); | ||
static int mdoc_bt_pre(MDOC_ARGS); | |||
static int mdoc_bx_pre(MDOC_ARGS); | |||
static int mdoc_cd_pre(MDOC_ARGS); | static int mdoc_cd_pre(MDOC_ARGS); | ||
static int mdoc_d1_pre(MDOC_ARGS); | static int mdoc_d1_pre(MDOC_ARGS); | ||
static int mdoc_dv_pre(MDOC_ARGS); | static int mdoc_dv_pre(MDOC_ARGS); | ||
|
|
||
static int mdoc_fn_pre(MDOC_ARGS); | static int mdoc_fn_pre(MDOC_ARGS); | ||
static int mdoc_ft_pre(MDOC_ARGS); | static int mdoc_ft_pre(MDOC_ARGS); | ||
static int mdoc_em_pre(MDOC_ARGS); | static int mdoc_em_pre(MDOC_ARGS); | ||
static void mdoc_eo_post(MDOC_ARGS); | |||
static int mdoc_eo_pre(MDOC_ARGS); | |||
static int mdoc_er_pre(MDOC_ARGS); | static int mdoc_er_pre(MDOC_ARGS); | ||
static int mdoc_ev_pre(MDOC_ARGS); | static int mdoc_ev_pre(MDOC_ARGS); | ||
static int mdoc_ex_pre(MDOC_ARGS); | static int mdoc_ex_pre(MDOC_ARGS); | ||
|
|
||
static void mdoc_quote_post(MDOC_ARGS); | static void mdoc_quote_post(MDOC_ARGS); | ||
static int mdoc_quote_pre(MDOC_ARGS); | static int mdoc_quote_pre(MDOC_ARGS); | ||
static int mdoc_rs_pre(MDOC_ARGS); | static int mdoc_rs_pre(MDOC_ARGS); | ||
static int mdoc_rv_pre(MDOC_ARGS); | |||
static int mdoc_sh_pre(MDOC_ARGS); | static int mdoc_sh_pre(MDOC_ARGS); | ||
static int mdoc_skip_pre(MDOC_ARGS); | static int mdoc_skip_pre(MDOC_ARGS); | ||
static int mdoc_sm_pre(MDOC_ARGS); | static int mdoc_sm_pre(MDOC_ARGS); | ||
|
|
||
static int mdoc_ss_pre(MDOC_ARGS); | static int mdoc_ss_pre(MDOC_ARGS); | ||
static int mdoc_sx_pre(MDOC_ARGS); | static int mdoc_sx_pre(MDOC_ARGS); | ||
static int mdoc_sy_pre(MDOC_ARGS); | static int mdoc_sy_pre(MDOC_ARGS); | ||
static int mdoc_ud_pre(MDOC_ARGS); | |||
static int mdoc_va_pre(MDOC_ARGS); | static int mdoc_va_pre(MDOC_ARGS); | ||
static int mdoc_vt_pre(MDOC_ARGS); | static int mdoc_vt_pre(MDOC_ARGS); | ||
static int mdoc_xr_pre(MDOC_ARGS); | static int mdoc_xr_pre(MDOC_ARGS); | ||
|
|
||
{mdoc_quote_pre, mdoc_quote_post}, /* Op */ | {mdoc_quote_pre, mdoc_quote_post}, /* Op */ | ||
{mdoc_ft_pre, NULL}, /* Ot */ | {mdoc_ft_pre, NULL}, /* Ot */ | ||
{mdoc_pa_pre, NULL}, /* Pa */ | {mdoc_pa_pre, NULL}, /* Pa */ | ||
{mdoc_rv_pre, NULL}, /* Rv */ | {mdoc_ex_pre, NULL}, /* Rv */ | ||
{NULL, NULL}, /* St */ | {NULL, NULL}, /* St */ | ||
{mdoc_va_pre, NULL}, /* Va */ | {mdoc_va_pre, NULL}, /* Va */ | ||
{mdoc_vt_pre, NULL}, /* Vt */ | {mdoc_vt_pre, NULL}, /* Vt */ | ||
|
|
||
{mdoc_quote_pre, mdoc_quote_post}, /* Bo */ | {mdoc_quote_pre, mdoc_quote_post}, /* Bo */ | ||
{mdoc_quote_pre, mdoc_quote_post}, /* Bq */ | {mdoc_quote_pre, mdoc_quote_post}, /* Bq */ | ||
{mdoc_xx_pre, NULL}, /* Bsx */ | {mdoc_xx_pre, NULL}, /* Bsx */ | ||
{mdoc_bx_pre, NULL}, /* Bx */ | {mdoc_xx_pre, NULL}, /* Bx */ | ||
{mdoc_skip_pre, NULL}, /* Db */ | {mdoc_skip_pre, NULL}, /* Db */ | ||
{NULL, NULL}, /* Dc */ | {NULL, NULL}, /* Dc */ | ||
{mdoc_quote_pre, mdoc_quote_post}, /* Do */ | {mdoc_quote_pre, mdoc_quote_post}, /* Do */ | ||
|
|
||
{NULL, NULL}, /* Ec */ /* FIXME: no space */ | {NULL, NULL}, /* Ec */ /* FIXME: no space */ | ||
{NULL, NULL}, /* Ef */ | {NULL, NULL}, /* Ef */ | ||
{mdoc_em_pre, NULL}, /* Em */ | {mdoc_em_pre, NULL}, /* Em */ | ||
{mdoc_quote_pre, mdoc_quote_post}, /* Eo */ | {mdoc_eo_pre, mdoc_eo_post}, /* Eo */ | ||
{mdoc_xx_pre, NULL}, /* Fx */ | {mdoc_xx_pre, NULL}, /* Fx */ | ||
{mdoc_ms_pre, NULL}, /* Ms */ | {mdoc_ms_pre, NULL}, /* Ms */ | ||
{mdoc_no_pre, NULL}, /* No */ | {mdoc_no_pre, NULL}, /* No */ | ||
|
|
||
{NULL, NULL}, /* Oc */ | {NULL, NULL}, /* Oc */ | ||
{mdoc_bk_pre, mdoc_bk_post}, /* Bk */ | {mdoc_bk_pre, mdoc_bk_post}, /* Bk */ | ||
{NULL, NULL}, /* Ek */ | {NULL, NULL}, /* Ek */ | ||
{mdoc_bt_pre, NULL}, /* Bt */ | {NULL, NULL}, /* Bt */ | ||
{NULL, NULL}, /* Hf */ | {NULL, NULL}, /* Hf */ | ||
{mdoc_em_pre, NULL}, /* Fr */ | {mdoc_em_pre, NULL}, /* Fr */ | ||
{mdoc_ud_pre, NULL}, /* Ud */ | {NULL, NULL}, /* Ud */ | ||
{mdoc_lb_pre, NULL}, /* Lb */ | {mdoc_lb_pre, NULL}, /* Lb */ | ||
{mdoc_pp_pre, NULL}, /* Lp */ | {mdoc_pp_pre, NULL}, /* Lp */ | ||
{mdoc_lk_pre, NULL}, /* Lk */ | {mdoc_lk_pre, NULL}, /* Lk */ | ||
|
|
||
}; | }; | ||
void | |||
html_mdoc(void *arg, const struct mdoc *mdoc) | |||
{ | |||
print_mdoc(mdoc_meta(mdoc), mdoc_node(mdoc), | |||
(struct html *)arg); | |||
putchar('\n'); | |||
} | |||
/* | /* | ||
* Calculate the scaling unit passed in a `-width' argument. This uses | |||
* either a native scaling unit (e.g., 1i, 2m) or the string length of | |||
* the value. | |||
*/ | |||
static void | |||
a2width(const char *p, struct roffsu *su) | |||
{ | |||
if (a2roffsu(p, su, SCALE_MAX) < 2) { | |||
su->unit = SCALE_EN; | |||
su->scale = html_strlen(p); | |||
} | |||
} | |||
/* | |||
* See the same function in mdoc_term.c for documentation. | * See the same function in mdoc_term.c for documentation. | ||
*/ | */ | ||
static void | static void | ||
synopsis_pre(struct html *h, const struct mdoc_node *n) | synopsis_pre(struct html *h, const struct roff_node *n) | ||
{ | { | ||
if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags)) | if (NULL == n->prev || ! (NODE_SYNPRETTY & n->flags)) | ||
return; | return; | ||
if (n->prev->tok == n->tok && | if (n->prev->tok == n->tok && | ||
MDOC_Fo != n->tok && | MDOC_Fo != n->tok && | ||
MDOC_Ft != n->tok && | MDOC_Ft != n->tok && | ||
MDOC_Fn != n->tok) { | MDOC_Fn != n->tok) { | ||
print_otag(h, TAG_BR, 0, NULL); | print_otag(h, TAG_BR, ""); | ||
return; | return; | ||
} | } | ||
switch (n->prev->tok) { | switch (n->prev->tok) { | ||
case MDOC_Fd: | case MDOC_Fd: | ||
/* FALLTHROUGH */ | |||
case MDOC_Fn: | case MDOC_Fn: | ||
/* FALLTHROUGH */ | |||
case MDOC_Fo: | case MDOC_Fo: | ||
/* FALLTHROUGH */ | |||
case MDOC_In: | case MDOC_In: | ||
/* FALLTHROUGH */ | |||
case MDOC_Vt: | case MDOC_Vt: | ||
print_paragraph(h); | print_paragraph(h); | ||
break; | break; | ||
|
|
||
} | } | ||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||
default: | default: | ||
print_otag(h, TAG_BR, 0, NULL); | print_otag(h, TAG_BR, ""); | ||
break; | break; | ||
} | } | ||
} | } | ||
static void | void | ||
print_mdoc(MDOC_ARGS) | html_mdoc(void *arg, const struct roff_man *mdoc) | ||
{ | { | ||
struct html *h; | |||
struct tag *t, *tt; | struct tag *t, *tt; | ||
struct htmlpair tag; | |||
PAIR_CLASS_INIT(&tag, "mandoc"); | h = (struct html *)arg; | ||
if ( ! (HTML_FRAGMENT & h->oflags)) { | if ( ! (HTML_FRAGMENT & h->oflags)) { | ||
print_gen_decls(h); | print_gen_decls(h); | ||
t = print_otag(h, TAG_HTML, 0, NULL); | t = print_otag(h, TAG_HTML, ""); | ||
tt = print_otag(h, TAG_HEAD, 0, NULL); | tt = print_otag(h, TAG_HEAD, ""); | ||
print_mdoc_head(meta, n, h); | print_mdoc_head(&mdoc->meta, mdoc->first->child, h); | ||
print_tagq(h, tt); | print_tagq(h, tt); | ||
print_otag(h, TAG_BODY, 0, NULL); | print_otag(h, TAG_BODY, ""); | ||
print_otag(h, TAG_DIV, 1, &tag); | print_otag(h, TAG_DIV, "c", "mandoc"); | ||
} else | } else | ||
t = print_otag(h, TAG_DIV, 1, &tag); | t = print_otag(h, TAG_DIV, "c", "mandoc"); | ||
print_mdoc_nodelist(meta, n, h); | mdoc_root_pre(&mdoc->meta, mdoc->first->child, h); | ||
print_mdoc_nodelist(&mdoc->meta, mdoc->first->child, h); | |||
mdoc_root_post(&mdoc->meta, mdoc->first->child, h); | |||
print_tagq(h, t); | print_tagq(h, t); | ||
putchar('\n'); | |||
} | } | ||
static void | static void | ||
|
|
||
if (meta->arch) | if (meta->arch) | ||
bufcat_fmt(h, " (%s)", meta->arch); | bufcat_fmt(h, " (%s)", meta->arch); | ||
print_otag(h, TAG_TITLE, 0, NULL); | print_otag(h, TAG_TITLE, ""); | ||
print_text(h, h->buf); | print_text(h, h->buf); | ||
} | } | ||
|
|
||
print_mdoc_nodelist(MDOC_ARGS) | print_mdoc_nodelist(MDOC_ARGS) | ||
{ | { | ||
print_mdoc_node(meta, n, h); | while (n != NULL) { | ||
if (n->next) | print_mdoc_node(meta, n, h); | ||
print_mdoc_nodelist(meta, n->next, h); | n = n->next; | ||
} | |||
} | } | ||
static void | static void | ||
|
|
||
int child; | int child; | ||
struct tag *t; | struct tag *t; | ||
if (n->flags & NODE_NOPRT) | |||
return; | |||
child = 1; | child = 1; | ||
t = h->tags.head; | t = h->tags.head; | ||
n->flags &= ~NODE_ENDED; | |||
switch (n->type) { | switch (n->type) { | ||
case MDOC_ROOT: | case ROFFT_TEXT: | ||
child = mdoc_root_pre(meta, n, h); | |||
break; | |||
case MDOC_TEXT: | |||
/* No tables in this mode... */ | /* No tables in this mode... */ | ||
assert(NULL == h->tblt); | assert(NULL == h->tblt); | ||
|
|
||
* Make sure that if we're in a literal mode already | * Make sure that if we're in a literal mode already | ||
* (i.e., within a <PRE>) don't print the newline. | * (i.e., within a <PRE>) don't print the newline. | ||
*/ | */ | ||
if (' ' == *n->string && MDOC_LINE & n->flags) | if (' ' == *n->string && NODE_LINE & n->flags) | ||
if ( ! (HTML_LITERAL & h->flags)) | if ( ! (HTML_LITERAL & h->flags)) | ||
print_otag(h, TAG_BR, 0, NULL); | print_otag(h, TAG_BR, ""); | ||
if (MDOC_DELIMC & n->flags) | if (NODE_DELIMC & n->flags) | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
print_text(h, n->string); | print_text(h, n->string); | ||
if (MDOC_DELIMO & n->flags) | if (NODE_DELIMO & n->flags) | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
return; | return; | ||
case MDOC_EQN: | case ROFFT_EQN: | ||
if (n->flags & NODE_LINE) | |||
putchar('\n'); | |||
print_eqn(h, n->eqn); | print_eqn(h, n->eqn); | ||
break; | break; | ||
case MDOC_TBL: | case ROFFT_TBL: | ||
/* | /* | ||
* This will take care of initialising all of the table | * This will take care of initialising all of the table | ||
* state data for the first table, then tearing it down | * state data for the first table, then tearing it down | ||
|
|
||
break; | break; | ||
} | } | ||
if (HTML_KEEP & h->flags) { | if (h->flags & HTML_KEEP && n->flags & NODE_LINE) { | ||
if (n->prev ? (n->prev->lastline != n->line) : | h->flags &= ~HTML_KEEP; | ||
(n->parent && n->parent->line != n->line)) { | h->flags |= HTML_PREKEEP; | ||
h->flags &= ~HTML_KEEP; | |||
h->flags |= HTML_PREKEEP; | |||
} | |||
} | } | ||
if (child && n->child) | if (child && n->child) | ||
|
|
||
print_stagq(h, t); | print_stagq(h, t); | ||
switch (n->type) { | switch (n->type) { | ||
case MDOC_ROOT: | case ROFFT_EQN: | ||
mdoc_root_post(meta, n, h); | |||
break; | break; | ||
case MDOC_EQN: | |||
break; | |||
default: | default: | ||
if ( ! mdocs[n->tok].post || n->flags & MDOC_ENDED) | if ( ! mdocs[n->tok].post || n->flags & NODE_ENDED) | ||
break; | break; | ||
(*mdocs[n->tok].post)(meta, n, h); | (*mdocs[n->tok].post)(meta, n, h); | ||
if (n->end != ENDBODY_NOT) | if (n->end != ENDBODY_NOT) | ||
n->pending->flags |= MDOC_ENDED; | n->body->flags |= NODE_ENDED; | ||
if (n->end == ENDBODY_NOSPACE) | if (n->end == ENDBODY_NOSPACE) | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
break; | break; | ||
|
|
||
static void | static void | ||
mdoc_root_post(MDOC_ARGS) | mdoc_root_post(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | |||
struct tag *t, *tt; | struct tag *t, *tt; | ||
PAIR_CLASS_INIT(&tag, "foot"); | t = print_otag(h, TAG_TABLE, "c", "foot"); | ||
t = print_otag(h, TAG_TABLE, 1, &tag); | print_otag(h, TAG_TBODY, ""); | ||
tt = print_otag(h, TAG_TR, ""); | |||
print_otag(h, TAG_TBODY, 0, NULL); | print_otag(h, TAG_TD, "c", "foot-date"); | ||
tt = print_otag(h, TAG_TR, 0, NULL); | |||
PAIR_CLASS_INIT(&tag, "foot-date"); | |||
print_otag(h, TAG_TD, 1, &tag); | |||
print_text(h, meta->date); | print_text(h, meta->date); | ||
print_stagq(h, tt); | print_stagq(h, tt); | ||
PAIR_CLASS_INIT(&tag, "foot-os"); | print_otag(h, TAG_TD, "c", "foot-os"); | ||
print_otag(h, TAG_TD, 1, &tag); | |||
print_text(h, meta->os); | print_text(h, meta->os); | ||
print_tagq(h, t); | print_tagq(h, t); | ||
} | } | ||
|
|
||
static int | static int | ||
mdoc_root_pre(MDOC_ARGS) | mdoc_root_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | |||
struct tag *t, *tt; | struct tag *t, *tt; | ||
char *volume, *title; | char *volume, *title; | ||
|
|
||
mandoc_asprintf(&title, "%s(%s)", | mandoc_asprintf(&title, "%s(%s)", | ||
meta->title, meta->msec); | meta->title, meta->msec); | ||
PAIR_CLASS_INIT(&tag, "head"); | t = print_otag(h, TAG_TABLE, "c", "head"); | ||
t = print_otag(h, TAG_TABLE, 1, &tag); | print_otag(h, TAG_TBODY, ""); | ||
tt = print_otag(h, TAG_TR, ""); | |||
print_otag(h, TAG_TBODY, 0, NULL); | print_otag(h, TAG_TD, "c", "head-ltitle"); | ||
tt = print_otag(h, TAG_TR, 0, NULL); | |||
PAIR_CLASS_INIT(&tag, "head-ltitle"); | |||
print_otag(h, TAG_TD, 1, &tag); | |||
print_text(h, title); | print_text(h, title); | ||
print_stagq(h, tt); | print_stagq(h, tt); | ||
PAIR_CLASS_INIT(&tag, "head-vol"); | print_otag(h, TAG_TD, "c", "head-vol"); | ||
print_otag(h, TAG_TD, 1, &tag); | |||
print_text(h, volume); | print_text(h, volume); | ||
print_stagq(h, tt); | print_stagq(h, tt); | ||
PAIR_CLASS_INIT(&tag, "head-rtitle"); | print_otag(h, TAG_TD, "c", "head-rtitle"); | ||
print_otag(h, TAG_TD, 1, &tag); | |||
print_text(h, title); | print_text(h, title); | ||
print_tagq(h, t); | print_tagq(h, t); | ||
free(title); | free(title); | ||
free(volume); | free(volume); | ||
return(1); | return 1; | ||
} | } | ||
static int | static int | ||
mdoc_sh_pre(MDOC_ARGS) | mdoc_sh_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | |||
switch (n->type) { | switch (n->type) { | ||
case MDOC_BLOCK: | case ROFFT_BLOCK: | ||
PAIR_CLASS_INIT(&tag, "section"); | print_otag(h, TAG_DIV, "c", "section"); | ||
print_otag(h, TAG_DIV, 1, &tag); | return 1; | ||
return(1); | case ROFFT_BODY: | ||
case MDOC_BODY: | |||
if (n->sec == SEC_AUTHORS) | if (n->sec == SEC_AUTHORS) | ||
h->flags &= ~(HTML_SPLIT|HTML_NOSPLIT); | h->flags &= ~(HTML_SPLIT|HTML_NOSPLIT); | ||
return(1); | return 1; | ||
default: | default: | ||
break; | break; | ||
} | } | ||
bufinit(h); | bufinit(h); | ||
bufcat(h, "x"); | |||
for (n = n->child; n && MDOC_TEXT == n->type; ) { | for (n = n->child; n != NULL && n->type == ROFFT_TEXT; ) { | ||
bufcat_id(h, n->string); | bufcat_id(h, n->string); | ||
if (NULL != (n = n->next)) | if (NULL != (n = n->next)) | ||
bufcat_id(h, " "); | bufcat_id(h, " "); | ||
} | } | ||
if (NULL == n) { | if (NULL == n) | ||
PAIR_ID_INIT(&tag, h->buf); | print_otag(h, TAG_H1, "i", h->buf); | ||
print_otag(h, TAG_H1, 1, &tag); | else | ||
} else | print_otag(h, TAG_H1, ""); | ||
print_otag(h, TAG_H1, 0, NULL); | |||
return(1); | return 1; | ||
} | } | ||
static int | static int | ||
mdoc_ss_pre(MDOC_ARGS) | mdoc_ss_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | if (n->type == ROFFT_BLOCK) { | ||
print_otag(h, TAG_DIV, "c", "subsection"); | |||
return 1; | |||
} else if (n->type == ROFFT_BODY) | |||
return 1; | |||
if (MDOC_BLOCK == n->type) { | |||
PAIR_CLASS_INIT(&tag, "subsection"); | |||
print_otag(h, TAG_DIV, 1, &tag); | |||
return(1); | |||
} else if (MDOC_BODY == n->type) | |||
return(1); | |||
bufinit(h); | bufinit(h); | ||
bufcat(h, "x"); | |||
for (n = n->child; n && MDOC_TEXT == n->type; ) { | for (n = n->child; n != NULL && n->type == ROFFT_TEXT; ) { | ||
bufcat_id(h, n->string); | bufcat_id(h, n->string); | ||
if (NULL != (n = n->next)) | if (NULL != (n = n->next)) | ||
bufcat_id(h, " "); | bufcat_id(h, " "); | ||
} | } | ||
if (NULL == n) { | if (NULL == n) | ||
PAIR_ID_INIT(&tag, h->buf); | print_otag(h, TAG_H2, "i", h->buf); | ||
print_otag(h, TAG_H2, 1, &tag); | else | ||
} else | print_otag(h, TAG_H2, ""); | ||
print_otag(h, TAG_H2, 0, NULL); | |||
return(1); | return 1; | ||
} | } | ||
static int | static int | ||
mdoc_fl_pre(MDOC_ARGS) | mdoc_fl_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | print_otag(h, TAG_B, "c", "flag"); | ||
PAIR_CLASS_INIT(&tag, "flag"); | |||
print_otag(h, TAG_B, 1, &tag); | |||
/* `Cm' has no leading hyphen. */ | /* `Cm' has no leading hyphen. */ | ||
if (MDOC_Cm == n->tok) | if (MDOC_Cm == n->tok) | ||
return(1); | return 1; | ||
print_text(h, "\\-"); | print_text(h, "\\-"); | ||
if ( ! (n->nchild == 0 && | if (!(n->child == NULL && | ||
(n->next == NULL || | (n->next == NULL || | ||
n->next->type == MDOC_TEXT || | n->next->type == ROFFT_TEXT || | ||
n->next->flags & MDOC_LINE))) | n->next->flags & NODE_LINE))) | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
return(1); | return 1; | ||
} | } | ||
static int | static int | ||
mdoc_nd_pre(MDOC_ARGS) | mdoc_nd_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | if (n->type != ROFFT_BODY) | ||
return 1; | |||
if (MDOC_BODY != n->type) | |||
return(1); | |||
/* XXX: this tag in theory can contain block elements. */ | /* XXX: this tag in theory can contain block elements. */ | ||
print_text(h, "\\(em"); | print_text(h, "\\(em"); | ||
PAIR_CLASS_INIT(&tag, "desc"); | print_otag(h, TAG_SPAN, "c", "desc"); | ||
print_otag(h, TAG_SPAN, 1, &tag); | return 1; | ||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_nm_pre(MDOC_ARGS) | mdoc_nm_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | |||
struct roffsu su; | |||
int len; | int len; | ||
switch (n->type) { | switch (n->type) { | ||
case MDOC_ELEM: | case ROFFT_HEAD: | ||
synopsis_pre(h, n); | print_otag(h, TAG_TD, ""); | ||
PAIR_CLASS_INIT(&tag, "name"); | /* FALLTHROUGH */ | ||
print_otag(h, TAG_B, 1, &tag); | case ROFFT_ELEM: | ||
if (NULL == n->child && meta->name) | print_otag(h, TAG_B, "c", "name"); | ||
if (n->child == NULL && meta->name != NULL) | |||
print_text(h, meta->name); | print_text(h, meta->name); | ||
return(1); | return 1; | ||
case MDOC_HEAD: | case ROFFT_BODY: | ||
print_otag(h, TAG_TD, 0, NULL); | print_otag(h, TAG_TD, ""); | ||
if (NULL == n->child && meta->name) | return 1; | ||
print_text(h, meta->name); | |||
return(1); | |||
case MDOC_BODY: | |||
print_otag(h, TAG_TD, 0, NULL); | |||
return(1); | |||
default: | default: | ||
break; | break; | ||
} | } | ||
synopsis_pre(h, n); | synopsis_pre(h, n); | ||
PAIR_CLASS_INIT(&tag, "synopsis"); | print_otag(h, TAG_TABLE, "c", "synopsis"); | ||
print_otag(h, TAG_TABLE, 1, &tag); | |||
for (len = 0, n = n->child; n; n = n->next) | for (len = 0, n = n->head->child; n; n = n->next) | ||
if (MDOC_TEXT == n->type) | if (n->type == ROFFT_TEXT) | ||
len += html_strlen(n->string); | len += html_strlen(n->string); | ||
if (0 == len && meta->name) | if (len == 0 && meta->name != NULL) | ||
len = html_strlen(meta->name); | len = html_strlen(meta->name); | ||
SCALE_HS_INIT(&su, len); | print_otag(h, TAG_COL, "shw", len); | ||
bufinit(h); | print_otag(h, TAG_COL, ""); | ||
bufcat_su(h, "width", &su); | print_otag(h, TAG_TBODY, ""); | ||
PAIR_STYLE_INIT(&tag, h); | print_otag(h, TAG_TR, ""); | ||
print_otag(h, TAG_COL, 1, &tag); | return 1; | ||
print_otag(h, TAG_COL, 0, NULL); | |||
print_otag(h, TAG_TBODY, 0, NULL); | |||
print_otag(h, TAG_TR, 0, NULL); | |||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_xr_pre(MDOC_ARGS) | mdoc_xr_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag[2]; | |||
if (NULL == n->child) | if (NULL == n->child) | ||
return(0); | return 0; | ||
PAIR_CLASS_INIT(&tag[0], "link-man"); | |||
if (h->base_man) { | if (h->base_man) { | ||
buffmt_man(h, n->child->string, | buffmt_man(h, n->child->string, | ||
n->child->next ? | n->child->next ? | ||
n->child->next->string : NULL); | n->child->next->string : NULL); | ||
PAIR_HREF_INIT(&tag[1], h->buf); | print_otag(h, TAG_A, "ch", "link-man", h->buf); | ||
print_otag(h, TAG_A, 2, tag); | |||
} else | } else | ||
print_otag(h, TAG_A, 1, tag); | print_otag(h, TAG_A, "c", "link-man"); | ||
n = n->child; | n = n->child; | ||
print_text(h, n->string); | print_text(h, n->string); | ||
if (NULL == (n = n->next)) | if (NULL == (n = n->next)) | ||
return(0); | return 0; | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
print_text(h, "("); | print_text(h, "("); | ||
|
|
||
print_text(h, n->string); | print_text(h, n->string); | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
print_text(h, ")"); | print_text(h, ")"); | ||
return(0); | return 0; | ||
} | } | ||
static int | static int | ||
mdoc_ns_pre(MDOC_ARGS) | mdoc_ns_pre(MDOC_ARGS) | ||
{ | { | ||
if ( ! (MDOC_LINE & n->flags)) | if ( ! (NODE_LINE & n->flags)) | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
return(1); | return 1; | ||
} | } | ||
static int | static int | ||
mdoc_ar_pre(MDOC_ARGS) | mdoc_ar_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | print_otag(h, TAG_I, "c", "arg"); | ||
return 1; | |||
PAIR_CLASS_INIT(&tag, "arg"); | |||
print_otag(h, TAG_I, 1, &tag); | |||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_xx_pre(MDOC_ARGS) | mdoc_xx_pre(MDOC_ARGS) | ||
{ | { | ||
const char *pp; | print_otag(h, TAG_SPAN, "c", "unix"); | ||
struct htmlpair tag; | return 1; | ||
int flags; | |||
switch (n->tok) { | |||
case MDOC_Bsx: | |||
pp = "BSD/OS"; | |||
break; | |||
case MDOC_Dx: | |||
pp = "DragonFly"; | |||
break; | |||
case MDOC_Fx: | |||
pp = "FreeBSD"; | |||
break; | |||
case MDOC_Nx: | |||
pp = "NetBSD"; | |||
break; | |||
case MDOC_Ox: | |||
pp = "OpenBSD"; | |||
break; | |||
case MDOC_Ux: | |||
pp = "UNIX"; | |||
break; | |||
default: | |||
return(1); | |||
} | |||
PAIR_CLASS_INIT(&tag, "unix"); | |||
print_otag(h, TAG_SPAN, 1, &tag); | |||
print_text(h, pp); | |||
if (n->child) { | |||
flags = h->flags; | |||
h->flags |= HTML_KEEP; | |||
print_text(h, n->child->string); | |||
h->flags = flags; | |||
} | |||
return(0); | |||
} | } | ||
static int | static int | ||
mdoc_bx_pre(MDOC_ARGS) | |||
{ | |||
struct htmlpair tag; | |||
PAIR_CLASS_INIT(&tag, "unix"); | |||
print_otag(h, TAG_SPAN, 1, &tag); | |||
if (NULL != (n = n->child)) { | |||
print_text(h, n->string); | |||
h->flags |= HTML_NOSPACE; | |||
print_text(h, "BSD"); | |||
} else { | |||
print_text(h, "BSD"); | |||
return(0); | |||
} | |||
if (NULL != (n = n->next)) { | |||
h->flags |= HTML_NOSPACE; | |||
print_text(h, "-"); | |||
h->flags |= HTML_NOSPACE; | |||
print_text(h, n->string); | |||
} | |||
return(0); | |||
} | |||
static int | |||
mdoc_it_pre(MDOC_ARGS) | mdoc_it_pre(MDOC_ARGS) | ||
{ | { | ||
struct roffsu su; | |||
enum mdoc_list type; | enum mdoc_list type; | ||
struct htmlpair tag[2]; | const struct roff_node *bl; | ||
const struct mdoc_node *bl; | |||
bl = n->parent; | bl = n->parent; | ||
while (bl && MDOC_Bl != bl->tok) | while (bl && MDOC_Bl != bl->tok) | ||
bl = bl->parent; | bl = bl->parent; | ||
assert(bl); | |||
type = bl->norm->Bl.type; | type = bl->norm->Bl.type; | ||
assert(lists[type]); | if (n->type == ROFFT_HEAD) { | ||
PAIR_CLASS_INIT(&tag[0], lists[type]); | |||
bufinit(h); | |||
if (MDOC_HEAD == n->type) { | |||
switch (type) { | switch (type) { | ||
case LIST_bullet: | case LIST_bullet: | ||
/* FALLTHROUGH */ | |||
case LIST_dash: | case LIST_dash: | ||
/* FALLTHROUGH */ | |||
case LIST_item: | case LIST_item: | ||
/* FALLTHROUGH */ | |||
case LIST_hyphen: | case LIST_hyphen: | ||
/* FALLTHROUGH */ | |||
case LIST_enum: | case LIST_enum: | ||
return(0); | return 0; | ||
case LIST_diag: | case LIST_diag: | ||
/* FALLTHROUGH */ | |||
case LIST_hang: | case LIST_hang: | ||
/* FALLTHROUGH */ | |||
case LIST_inset: | case LIST_inset: | ||
/* FALLTHROUGH */ | |||
case LIST_ohang: | case LIST_ohang: | ||
/* FALLTHROUGH */ | |||
case LIST_tag: | case LIST_tag: | ||
SCALE_VS_INIT(&su, ! bl->norm->Bl.comp); | print_otag(h, TAG_DT, "csvt", lists[type], | ||
bufcat_su(h, "margin-top", &su); | !bl->norm->Bl.comp); | ||
PAIR_STYLE_INIT(&tag[1], h); | |||
print_otag(h, TAG_DT, 2, tag); | |||
if (LIST_diag != type) | if (LIST_diag != type) | ||
break; | break; | ||
PAIR_CLASS_INIT(&tag[0], "diag"); | print_otag(h, TAG_B, "c", "diag"); | ||
print_otag(h, TAG_B, 1, tag); | |||
break; | break; | ||
case LIST_column: | case LIST_column: | ||
break; | break; | ||
default: | default: | ||
break; | break; | ||
} | } | ||
} else if (MDOC_BODY == n->type) { | } else if (n->type == ROFFT_BODY) { | ||
switch (type) { | switch (type) { | ||
case LIST_bullet: | case LIST_bullet: | ||
/* FALLTHROUGH */ | |||
case LIST_hyphen: | case LIST_hyphen: | ||
/* FALLTHROUGH */ | |||
case LIST_dash: | case LIST_dash: | ||
/* FALLTHROUGH */ | |||
case LIST_enum: | case LIST_enum: | ||
/* FALLTHROUGH */ | |||
case LIST_item: | case LIST_item: | ||
SCALE_VS_INIT(&su, ! bl->norm->Bl.comp); | print_otag(h, TAG_LI, "csvt", lists[type], | ||
bufcat_su(h, "margin-top", &su); | !bl->norm->Bl.comp); | ||
PAIR_STYLE_INIT(&tag[1], h); | |||
print_otag(h, TAG_LI, 2, tag); | |||
break; | break; | ||
case LIST_diag: | case LIST_diag: | ||
/* FALLTHROUGH */ | |||
case LIST_hang: | case LIST_hang: | ||
/* FALLTHROUGH */ | |||
case LIST_inset: | case LIST_inset: | ||
/* FALLTHROUGH */ | |||
case LIST_ohang: | case LIST_ohang: | ||
/* FALLTHROUGH */ | |||
case LIST_tag: | case LIST_tag: | ||
if (NULL == bl->norm->Bl.width) { | if (NULL == bl->norm->Bl.width) { | ||
print_otag(h, TAG_DD, 1, tag); | print_otag(h, TAG_DD, "c", lists[type]); | ||
break; | break; | ||
} | } | ||
a2width(bl->norm->Bl.width, &su); | print_otag(h, TAG_DD, "cswl", lists[type], | ||
bufcat_su(h, "margin-left", &su); | bl->norm->Bl.width); | ||
PAIR_STYLE_INIT(&tag[1], h); | |||
print_otag(h, TAG_DD, 2, tag); | |||
break; | break; | ||
case LIST_column: | case LIST_column: | ||
SCALE_VS_INIT(&su, ! bl->norm->Bl.comp); | print_otag(h, TAG_TD, "csvt", lists[type], | ||
bufcat_su(h, "margin-top", &su); | !bl->norm->Bl.comp); | ||
PAIR_STYLE_INIT(&tag[1], h); | |||
print_otag(h, TAG_TD, 2, tag); | |||
break; | break; | ||
default: | default: | ||
break; | break; | ||
|
|
||
} else { | } else { | ||
switch (type) { | switch (type) { | ||
case LIST_column: | case LIST_column: | ||
print_otag(h, TAG_TR, 1, tag); | print_otag(h, TAG_TR, "c", lists[type]); | ||
break; | break; | ||
default: | default: | ||
break; | break; | ||
} | } | ||
} | } | ||
return(1); | return 1; | ||
} | } | ||
static int | static int | ||
mdoc_bl_pre(MDOC_ARGS) | mdoc_bl_pre(MDOC_ARGS) | ||
{ | { | ||
int i; | int i; | ||
struct htmlpair tag[3]; | |||
struct roffsu su; | |||
char buf[BUFSIZ]; | char buf[BUFSIZ]; | ||
enum htmltag elemtype; | |||
if (MDOC_BODY == n->type) { | if (n->type == ROFFT_BODY) { | ||
if (LIST_column == n->norm->Bl.type) | if (LIST_column == n->norm->Bl.type) | ||
print_otag(h, TAG_TBODY, 0, NULL); | print_otag(h, TAG_TBODY, ""); | ||
return(1); | return 1; | ||
} | } | ||
if (MDOC_HEAD == n->type) { | if (n->type == ROFFT_HEAD) { | ||
if (LIST_column != n->norm->Bl.type) | if (LIST_column != n->norm->Bl.type) | ||
return(0); | return 0; | ||
/* | /* | ||
* For each column, print out the <COL> tag with our | * For each column, print out the <COL> tag with our | ||
|
|
||
* screen and we want to preserve that behaviour. | * screen and we want to preserve that behaviour. | ||
*/ | */ | ||
for (i = 0; i < (int)n->norm->Bl.ncols; i++) { | for (i = 0; i < (int)n->norm->Bl.ncols - 1; i++) | ||
bufinit(h); | print_otag(h, TAG_COL, "sww", n->norm->Bl.cols[i]); | ||
a2width(n->norm->Bl.cols[i], &su); | print_otag(h, TAG_COL, "swW", n->norm->Bl.cols[i]); | ||
if (i < (int)n->norm->Bl.ncols - 1) | |||
bufcat_su(h, "width", &su); | |||
else | |||
bufcat_su(h, "min-width", &su); | |||
PAIR_STYLE_INIT(&tag[0], h); | |||
print_otag(h, TAG_COL, 1, tag); | |||
} | |||
return(0); | return 0; | ||
} | } | ||
SCALE_VS_INIT(&su, 0); | |||
bufinit(h); | |||
bufcat_su(h, "margin-top", &su); | |||
bufcat_su(h, "margin-bottom", &su); | |||
PAIR_STYLE_INIT(&tag[0], h); | |||
assert(lists[n->norm->Bl.type]); | assert(lists[n->norm->Bl.type]); | ||
(void)strlcpy(buf, "list ", BUFSIZ); | (void)strlcpy(buf, "list ", BUFSIZ); | ||
(void)strlcat(buf, lists[n->norm->Bl.type], BUFSIZ); | (void)strlcat(buf, lists[n->norm->Bl.type], BUFSIZ); | ||
PAIR_INIT(&tag[1], ATTR_CLASS, buf); | |||
/* Set the block's left-hand margin. */ | |||
if (n->norm->Bl.offs) { | |||
a2width(n->norm->Bl.offs, &su); | |||
bufcat_su(h, "margin-left", &su); | |||
} | |||
switch (n->norm->Bl.type) { | switch (n->norm->Bl.type) { | ||
case LIST_bullet: | case LIST_bullet: | ||
/* FALLTHROUGH */ | |||
case LIST_dash: | case LIST_dash: | ||
/* FALLTHROUGH */ | |||
case LIST_hyphen: | case LIST_hyphen: | ||
/* FALLTHROUGH */ | |||
case LIST_item: | case LIST_item: | ||
print_otag(h, TAG_UL, 2, tag); | elemtype = TAG_UL; | ||
break; | break; | ||
case LIST_enum: | case LIST_enum: | ||
print_otag(h, TAG_OL, 2, tag); | elemtype = TAG_OL; | ||
break; | break; | ||
case LIST_diag: | case LIST_diag: | ||
/* FALLTHROUGH */ | |||
case LIST_hang: | case LIST_hang: | ||
/* FALLTHROUGH */ | |||
case LIST_inset: | case LIST_inset: | ||
/* FALLTHROUGH */ | |||
case LIST_ohang: | case LIST_ohang: | ||
/* FALLTHROUGH */ | |||
case LIST_tag: | case LIST_tag: | ||
print_otag(h, TAG_DL, 2, tag); | elemtype = TAG_DL; | ||
break; | break; | ||
case LIST_column: | case LIST_column: | ||
print_otag(h, TAG_TABLE, 2, tag); | elemtype = TAG_TABLE; | ||
break; | break; | ||
default: | default: | ||
abort(); | abort(); | ||
/* NOTREACHED */ | |||
} | } | ||
return(1); | if (n->norm->Bl.offs) | ||
print_otag(h, elemtype, "csvtvbwl", buf, 0, 0, | |||
n->norm->Bl.offs); | |||
else | |||
print_otag(h, elemtype, "csvtvb", buf, 0, 0); | |||
return 1; | |||
} | } | ||
static int | static int | ||
mdoc_ex_pre(MDOC_ARGS) | mdoc_ex_pre(MDOC_ARGS) | ||
{ | { | ||
struct tag *t; | |||
struct htmlpair tag; | |||
int nchild; | |||
if (n->prev) | if (n->prev) | ||
print_otag(h, TAG_BR, 0, NULL); | print_otag(h, TAG_BR, ""); | ||
return 1; | |||
PAIR_CLASS_INIT(&tag, "utility"); | |||
print_text(h, "The"); | |||
nchild = n->nchild; | |||
for (n = n->child; n; n = n->next) { | |||
assert(MDOC_TEXT == n->type); | |||
t = print_otag(h, TAG_B, 1, &tag); | |||
print_text(h, n->string); | |||
print_tagq(h, t); | |||
if (nchild > 2 && n->next) { | |||
h->flags |= HTML_NOSPACE; | |||
print_text(h, ","); | |||
} | |||
if (n->next && NULL == n->next->next) | |||
print_text(h, "and"); | |||
} | |||
if (nchild > 1) | |||
print_text(h, "utilities exit\\~0"); | |||
else | |||
print_text(h, "utility exits\\~0"); | |||
print_text(h, "on success, and\\~>0 if an error occurs."); | |||
return(0); | |||
} | } | ||
static int | static int | ||
mdoc_em_pre(MDOC_ARGS) | mdoc_em_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | print_otag(h, TAG_SPAN, "c", "emph"); | ||
return 1; | |||
PAIR_CLASS_INIT(&tag, "emph"); | |||
print_otag(h, TAG_SPAN, 1, &tag); | |||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_d1_pre(MDOC_ARGS) | mdoc_d1_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag[2]; | if (n->type != ROFFT_BLOCK) | ||
struct roffsu su; | return 1; | ||
if (MDOC_BLOCK != n->type) | print_otag(h, TAG_BLOCKQUOTE, "svtvb", 0, 0); | ||
return(1); | |||
SCALE_VS_INIT(&su, 0); | |||
bufinit(h); | |||
bufcat_su(h, "margin-top", &su); | |||
bufcat_su(h, "margin-bottom", &su); | |||
PAIR_STYLE_INIT(&tag[0], h); | |||
print_otag(h, TAG_BLOCKQUOTE, 1, tag); | |||
/* BLOCKQUOTE needs a block body. */ | /* BLOCKQUOTE needs a block body. */ | ||
PAIR_CLASS_INIT(&tag[0], "display"); | print_otag(h, TAG_DIV, "c", "display"); | ||
print_otag(h, TAG_DIV, 1, tag); | |||
if (MDOC_Dl == n->tok) { | if (MDOC_Dl == n->tok) | ||
PAIR_CLASS_INIT(&tag[0], "lit"); | print_otag(h, TAG_CODE, "c", "lit"); | ||
print_otag(h, TAG_CODE, 1, tag); | |||
} | |||
return(1); | return 1; | ||
} | } | ||
static int | static int | ||
mdoc_sx_pre(MDOC_ARGS) | mdoc_sx_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag[2]; | |||
bufinit(h); | bufinit(h); | ||
bufcat(h, "#x"); | bufcat(h, "#"); | ||
for (n = n->child; n; ) { | for (n = n->child; n; ) { | ||
bufcat_id(h, n->string); | bufcat_id(h, n->string); | ||
|
|
||
bufcat_id(h, " "); | bufcat_id(h, " "); | ||
} | } | ||
PAIR_CLASS_INIT(&tag[0], "link-sec"); | print_otag(h, TAG_I, "c", "link-sec"); | ||
PAIR_HREF_INIT(&tag[1], h->buf); | print_otag(h, TAG_A, "ch", "link-sec", h->buf); | ||
return 1; | |||
print_otag(h, TAG_I, 1, tag); | |||
print_otag(h, TAG_A, 2, tag); | |||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_bd_pre(MDOC_ARGS) | mdoc_bd_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag[2]; | int comp, offs, sv; | ||
int comp, sv; | struct roff_node *nn; | ||
const struct mdoc_node *nn; | |||
struct roffsu su; | |||
if (MDOC_HEAD == n->type) | if (n->type == ROFFT_HEAD) | ||
return(0); | return 0; | ||
if (MDOC_BLOCK == n->type) { | if (n->type == ROFFT_BLOCK) { | ||
comp = n->norm->Bd.comp; | comp = n->norm->Bd.comp; | ||
for (nn = n; nn && ! comp; nn = nn->parent) { | for (nn = n; nn && ! comp; nn = nn->parent) { | ||
if (MDOC_BLOCK != nn->type) | if (nn->type != ROFFT_BLOCK) | ||
continue; | continue; | ||
if (MDOC_Ss == nn->tok || MDOC_Sh == nn->tok) | if (MDOC_Ss == nn->tok || MDOC_Sh == nn->tok) | ||
comp = 1; | comp = 1; | ||
|
|
||
} | } | ||
if ( ! comp) | if ( ! comp) | ||
print_paragraph(h); | print_paragraph(h); | ||
return(1); | return 1; | ||
} | } | ||
/* Handle the -offset argument. */ | /* Handle the -offset argument. */ | ||
if (n->norm->Bd.offs == NULL || | if (n->norm->Bd.offs == NULL || | ||
! strcmp(n->norm->Bd.offs, "left")) | ! strcmp(n->norm->Bd.offs, "left")) | ||
SCALE_HS_INIT(&su, 0); | offs = 0; | ||
else if ( ! strcmp(n->norm->Bd.offs, "indent")) | else if ( ! strcmp(n->norm->Bd.offs, "indent")) | ||
SCALE_HS_INIT(&su, INDENT); | offs = INDENT; | ||
else if ( ! strcmp(n->norm->Bd.offs, "indent-two")) | else if ( ! strcmp(n->norm->Bd.offs, "indent-two")) | ||
SCALE_HS_INIT(&su, INDENT * 2); | offs = INDENT * 2; | ||
else | else | ||
a2width(n->norm->Bd.offs, &su); | offs = -1; | ||
bufinit(h); | if (offs == -1) | ||
bufcat_su(h, "margin-left", &su); | print_otag(h, TAG_DIV, "cswl", "display", n->norm->Bd.offs); | ||
PAIR_STYLE_INIT(&tag[0], h); | else | ||
print_otag(h, TAG_DIV, "cshl", "display", offs); | |||
if (DISP_unfilled != n->norm->Bd.type && | if (n->norm->Bd.type != DISP_unfilled && | ||
DISP_literal != n->norm->Bd.type) { | n->norm->Bd.type != DISP_literal) | ||
PAIR_CLASS_INIT(&tag[1], "display"); | return 1; | ||
print_otag(h, TAG_DIV, 2, tag); | |||
return(1); | |||
} | |||
PAIR_CLASS_INIT(&tag[1], "lit display"); | print_otag(h, TAG_PRE, "c", "lit"); | ||
print_otag(h, TAG_PRE, 2, tag); | |||
/* This can be recursive: save & set our literal state. */ | /* This can be recursive: save & set our literal state. */ | ||
|
|
||
*/ | */ | ||
switch (nn->tok) { | switch (nn->tok) { | ||
case MDOC_Sm: | case MDOC_Sm: | ||
/* FALLTHROUGH */ | |||
case MDOC_br: | case MDOC_br: | ||
/* FALLTHROUGH */ | |||
case MDOC_sp: | case MDOC_sp: | ||
/* FALLTHROUGH */ | |||
case MDOC_Bl: | case MDOC_Bl: | ||
/* FALLTHROUGH */ | |||
case MDOC_D1: | case MDOC_D1: | ||
/* FALLTHROUGH */ | |||
case MDOC_Dl: | case MDOC_Dl: | ||
/* FALLTHROUGH */ | |||
case MDOC_Lp: | case MDOC_Lp: | ||
/* FALLTHROUGH */ | |||
case MDOC_Pp: | case MDOC_Pp: | ||
continue; | continue; | ||
default: | default: | ||
break; | break; | ||
} | } | ||
if (h->flags & HTML_NONEWLINE || | if (h->flags & HTML_NONEWLINE || | ||
(nn->next && ! (nn->next->flags & MDOC_LINE))) | (nn->next && ! (nn->next->flags & NODE_LINE))) | ||
continue; | continue; | ||
else if (nn->next) | else if (nn->next) | ||
print_text(h, "\n"); | print_text(h, "\n"); | ||
|
|
||
if (0 == sv) | if (0 == sv) | ||
h->flags &= ~HTML_LITERAL; | h->flags &= ~HTML_LITERAL; | ||
return(0); | return 0; | ||
} | } | ||
static int | static int | ||
mdoc_pa_pre(MDOC_ARGS) | mdoc_pa_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | print_otag(h, TAG_I, "c", "file"); | ||
return 1; | |||
PAIR_CLASS_INIT(&tag, "file"); | |||
print_otag(h, TAG_I, 1, &tag); | |||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_ad_pre(MDOC_ARGS) | mdoc_ad_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | print_otag(h, TAG_I, "c", "addr"); | ||
return 1; | |||
PAIR_CLASS_INIT(&tag, "addr"); | |||
print_otag(h, TAG_I, 1, &tag); | |||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_an_pre(MDOC_ARGS) | mdoc_an_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | |||
if (n->norm->An.auth == AUTH_split) { | if (n->norm->An.auth == AUTH_split) { | ||
h->flags &= ~HTML_NOSPLIT; | h->flags &= ~HTML_NOSPLIT; | ||
h->flags |= HTML_SPLIT; | h->flags |= HTML_SPLIT; | ||
return(0); | return 0; | ||
} | } | ||
if (n->norm->An.auth == AUTH_nosplit) { | if (n->norm->An.auth == AUTH_nosplit) { | ||
h->flags &= ~HTML_SPLIT; | h->flags &= ~HTML_SPLIT; | ||
h->flags |= HTML_NOSPLIT; | h->flags |= HTML_NOSPLIT; | ||
return(0); | return 0; | ||
} | } | ||
if (n->child == NULL) | |||
return(0); | |||
if (h->flags & HTML_SPLIT) | if (h->flags & HTML_SPLIT) | ||
print_otag(h, TAG_BR, 0, NULL); | print_otag(h, TAG_BR, ""); | ||
if (n->sec == SEC_AUTHORS && ! (h->flags & HTML_NOSPLIT)) | if (n->sec == SEC_AUTHORS && ! (h->flags & HTML_NOSPLIT)) | ||
h->flags |= HTML_SPLIT; | h->flags |= HTML_SPLIT; | ||
PAIR_CLASS_INIT(&tag, "author"); | print_otag(h, TAG_SPAN, "c", "author"); | ||
print_otag(h, TAG_SPAN, 1, &tag); | return 1; | ||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_cd_pre(MDOC_ARGS) | mdoc_cd_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | |||
synopsis_pre(h, n); | synopsis_pre(h, n); | ||
PAIR_CLASS_INIT(&tag, "config"); | print_otag(h, TAG_B, "c", "config"); | ||
print_otag(h, TAG_B, 1, &tag); | return 1; | ||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_dv_pre(MDOC_ARGS) | mdoc_dv_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | print_otag(h, TAG_SPAN, "c", "define"); | ||
return 1; | |||
PAIR_CLASS_INIT(&tag, "define"); | |||
print_otag(h, TAG_SPAN, 1, &tag); | |||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_ev_pre(MDOC_ARGS) | mdoc_ev_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | print_otag(h, TAG_SPAN, "c", "env"); | ||
return 1; | |||
PAIR_CLASS_INIT(&tag, "env"); | |||
print_otag(h, TAG_SPAN, 1, &tag); | |||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_er_pre(MDOC_ARGS) | mdoc_er_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | print_otag(h, TAG_SPAN, "c", "errno"); | ||
return 1; | |||
PAIR_CLASS_INIT(&tag, "errno"); | |||
print_otag(h, TAG_SPAN, 1, &tag); | |||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_fa_pre(MDOC_ARGS) | mdoc_fa_pre(MDOC_ARGS) | ||
{ | { | ||
const struct mdoc_node *nn; | const struct roff_node *nn; | ||
struct htmlpair tag; | |||
struct tag *t; | struct tag *t; | ||
PAIR_CLASS_INIT(&tag, "farg"); | |||
if (n->parent->tok != MDOC_Fo) { | if (n->parent->tok != MDOC_Fo) { | ||
print_otag(h, TAG_I, 1, &tag); | print_otag(h, TAG_I, "c", "farg"); | ||
return(1); | return 1; | ||
} | } | ||
for (nn = n->child; nn; nn = nn->next) { | for (nn = n->child; nn; nn = nn->next) { | ||
t = print_otag(h, TAG_I, 1, &tag); | t = print_otag(h, TAG_I, "c", "farg"); | ||
print_text(h, nn->string); | print_text(h, nn->string); | ||
print_tagq(h, t); | print_tagq(h, t); | ||
if (nn->next) { | if (nn->next) { | ||
|
|
||
print_text(h, ","); | print_text(h, ","); | ||
} | } | ||
return(0); | return 0; | ||
} | } | ||
static int | static int | ||
mdoc_fd_pre(MDOC_ARGS) | mdoc_fd_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag[2]; | |||
char buf[BUFSIZ]; | char buf[BUFSIZ]; | ||
size_t sz; | size_t sz; | ||
int i; | |||
struct tag *t; | struct tag *t; | ||
synopsis_pre(h, n); | synopsis_pre(h, n); | ||
if (NULL == (n = n->child)) | if (NULL == (n = n->child)) | ||
return(0); | return 0; | ||
assert(MDOC_TEXT == n->type); | assert(n->type == ROFFT_TEXT); | ||
if (strcmp(n->string, "#include")) { | if (strcmp(n->string, "#include")) { | ||
PAIR_CLASS_INIT(&tag[0], "macro"); | print_otag(h, TAG_B, "c", "macro"); | ||
print_otag(h, TAG_B, 1, tag); | return 1; | ||
return(1); | |||
} | } | ||
PAIR_CLASS_INIT(&tag[0], "includes"); | print_otag(h, TAG_B, "c", "includes"); | ||
print_otag(h, TAG_B, 1, tag); | |||
print_text(h, n->string); | print_text(h, n->string); | ||
if (NULL != (n = n->next)) { | if (NULL != (n = n->next)) { | ||
assert(MDOC_TEXT == n->type); | assert(n->type == ROFFT_TEXT); | ||
/* | /* | ||
* XXX This is broken and not easy to fix. | * XXX This is broken and not easy to fix. | ||
|
|
||
if (sz && ('>' == buf[sz - 1] || '"' == buf[sz - 1])) | if (sz && ('>' == buf[sz - 1] || '"' == buf[sz - 1])) | ||
buf[sz - 1] = '\0'; | buf[sz - 1] = '\0'; | ||
PAIR_CLASS_INIT(&tag[0], "link-includes"); | |||
i = 1; | |||
if (h->base_includes) { | if (h->base_includes) { | ||
buffmt_includes(h, buf); | buffmt_includes(h, buf); | ||
PAIR_HREF_INIT(&tag[i], h->buf); | t = print_otag(h, TAG_A, "ch", "link-includes", | ||
i++; | h->buf); | ||
} | } else | ||
t = print_otag(h, TAG_A, "c", "link-includes"); | |||
t = print_otag(h, TAG_A, i, tag); | |||
print_text(h, n->string); | print_text(h, n->string); | ||
print_tagq(h, t); | print_tagq(h, t); | ||
|
|
||
} | } | ||
for ( ; n; n = n->next) { | for ( ; n; n = n->next) { | ||
assert(MDOC_TEXT == n->type); | assert(n->type == ROFFT_TEXT); | ||
print_text(h, n->string); | print_text(h, n->string); | ||
} | } | ||
return(0); | return 0; | ||
} | } | ||
static int | static int | ||
mdoc_vt_pre(MDOC_ARGS) | mdoc_vt_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | if (n->type == ROFFT_BLOCK) { | ||
if (MDOC_BLOCK == n->type) { | |||
synopsis_pre(h, n); | synopsis_pre(h, n); | ||
return(1); | return 1; | ||
} else if (MDOC_ELEM == n->type) { | } else if (n->type == ROFFT_ELEM) { | ||
synopsis_pre(h, n); | synopsis_pre(h, n); | ||
} else if (MDOC_HEAD == n->type) | } else if (n->type == ROFFT_HEAD) | ||
return(0); | return 0; | ||
PAIR_CLASS_INIT(&tag, "type"); | print_otag(h, TAG_SPAN, "c", "type"); | ||
print_otag(h, TAG_SPAN, 1, &tag); | return 1; | ||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_ft_pre(MDOC_ARGS) | mdoc_ft_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | |||
synopsis_pre(h, n); | synopsis_pre(h, n); | ||
PAIR_CLASS_INIT(&tag, "ftype"); | print_otag(h, TAG_I, "c", "ftype"); | ||
print_otag(h, TAG_I, 1, &tag); | return 1; | ||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_fn_pre(MDOC_ARGS) | mdoc_fn_pre(MDOC_ARGS) | ||
{ | { | ||
struct tag *t; | struct tag *t; | ||
struct htmlpair tag[2]; | |||
char nbuf[BUFSIZ]; | char nbuf[BUFSIZ]; | ||
const char *sp, *ep; | const char *sp, *ep; | ||
int sz, i, pretty; | int sz, pretty; | ||
pretty = MDOC_SYNPRETTY & n->flags; | pretty = NODE_SYNPRETTY & n->flags; | ||
synopsis_pre(h, n); | synopsis_pre(h, n); | ||
/* Split apart into type and name. */ | /* Split apart into type and name. */ | ||
|
|
||
ep = strchr(sp, ' '); | ep = strchr(sp, ' '); | ||
if (NULL != ep) { | if (NULL != ep) { | ||
PAIR_CLASS_INIT(&tag[0], "ftype"); | t = print_otag(h, TAG_I, "c", "ftype"); | ||
t = print_otag(h, TAG_I, 1, tag); | |||
while (ep) { | while (ep) { | ||
sz = MIN((int)(ep - sp), BUFSIZ - 1); | sz = MIN((int)(ep - sp), BUFSIZ - 1); | ||
|
|
||
print_tagq(h, t); | print_tagq(h, t); | ||
} | } | ||
PAIR_CLASS_INIT(&tag[0], "fname"); | t = print_otag(h, TAG_B, "c", "fname"); | ||
/* | |||
* FIXME: only refer to IDs that we know exist. | |||
*/ | |||
#if 0 | |||
if (MDOC_SYNPRETTY & n->flags) { | |||
nbuf[0] = '\0'; | |||
html_idcat(nbuf, sp, BUFSIZ); | |||
PAIR_ID_INIT(&tag[1], nbuf); | |||
} else { | |||
strlcpy(nbuf, "#", BUFSIZ); | |||
html_idcat(nbuf, sp, BUFSIZ); | |||
PAIR_HREF_INIT(&tag[1], nbuf); | |||
} | |||
#endif | |||
t = print_otag(h, TAG_B, 1, tag); | |||
if (sp) | if (sp) | ||
print_text(h, sp); | print_text(h, sp); | ||
|
|
||
print_text(h, "("); | print_text(h, "("); | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
PAIR_CLASS_INIT(&tag[0], "farg"); | |||
bufinit(h); | |||
bufcat_style(h, "white-space", "nowrap"); | |||
PAIR_STYLE_INIT(&tag[1], h); | |||
for (n = n->child->next; n; n = n->next) { | for (n = n->child->next; n; n = n->next) { | ||
i = 1; | if (NODE_SYNPRETTY & n->flags) | ||
if (MDOC_SYNPRETTY & n->flags) | t = print_otag(h, TAG_I, "css?", "farg", | ||
i = 2; | "white-space", "nowrap"); | ||
t = print_otag(h, TAG_I, i, tag); | else | ||
t = print_otag(h, TAG_I, "c", "farg"); | |||
print_text(h, n->string); | print_text(h, n->string); | ||
print_tagq(h, t); | print_tagq(h, t); | ||
if (n->next) { | if (n->next) { | ||
|
|
||
print_text(h, ";"); | print_text(h, ";"); | ||
} | } | ||
return(0); | return 0; | ||
} | } | ||
static int | static int | ||
|
|
||
if ( ! (HTML_NONOSPACE & h->flags)) | if ( ! (HTML_NONOSPACE & h->flags)) | ||
h->flags &= ~HTML_NOSPACE; | h->flags &= ~HTML_NOSPACE; | ||
return(0); | return 0; | ||
} | } | ||
static int | static int | ||
mdoc_skip_pre(MDOC_ARGS) | mdoc_skip_pre(MDOC_ARGS) | ||
{ | { | ||
return(0); | return 0; | ||
} | } | ||
static int | static int | ||
|
|
||
{ | { | ||
print_paragraph(h); | print_paragraph(h); | ||
return(0); | return 0; | ||
} | } | ||
static int | static int | ||
mdoc_sp_pre(MDOC_ARGS) | mdoc_sp_pre(MDOC_ARGS) | ||
{ | { | ||
struct roffsu su; | struct roffsu su; | ||
struct htmlpair tag; | |||
SCALE_VS_INIT(&su, 1); | SCALE_VS_INIT(&su, 1); | ||
if (MDOC_sp == n->tok) { | if (MDOC_sp == n->tok) { | ||
if (NULL != (n = n->child)) | if (NULL != (n = n->child)) { | ||
if ( ! a2roffsu(n->string, &su, SCALE_VS)) | if ( ! a2roffsu(n->string, &su, SCALE_VS)) | ||
su.scale = 1.0; | su.scale = 1.0; | ||
else if (su.scale < 0.0) | |||
su.scale = 0.0; | |||
} | |||
} else | } else | ||
su.scale = 0.0; | su.scale = 0.0; | ||
bufinit(h); | print_otag(h, TAG_DIV, "suh", &su); | ||
bufcat_su(h, "height", &su); | |||
PAIR_STYLE_INIT(&tag, h); | |||
print_otag(h, TAG_DIV, 1, &tag); | |||
/* So the div isn't empty: */ | /* So the div isn't empty: */ | ||
print_text(h, "\\~"); | print_text(h, "\\~"); | ||
return(0); | return 0; | ||
} | } | ||
static int | static int | ||
mdoc_lk_pre(MDOC_ARGS) | mdoc_lk_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag[2]; | |||
if (NULL == (n = n->child)) | if (NULL == (n = n->child)) | ||
return(0); | return 0; | ||
assert(MDOC_TEXT == n->type); | assert(n->type == ROFFT_TEXT); | ||
PAIR_CLASS_INIT(&tag[0], "link-ext"); | print_otag(h, TAG_A, "ch", "link-ext", n->string); | ||
PAIR_HREF_INIT(&tag[1], n->string); | |||
print_otag(h, TAG_A, 2, tag); | |||
if (NULL == n->next) | if (NULL == n->next) | ||
print_text(h, n->string); | print_text(h, n->string); | ||
for (n = n->next; n; n = n->next) | for (n = n->next; n; n = n->next) | ||
print_text(h, n->string); | print_text(h, n->string); | ||
return(0); | return 0; | ||
} | } | ||
static int | static int | ||
mdoc_mt_pre(MDOC_ARGS) | mdoc_mt_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag[2]; | |||
struct tag *t; | struct tag *t; | ||
PAIR_CLASS_INIT(&tag[0], "link-mail"); | |||
for (n = n->child; n; n = n->next) { | for (n = n->child; n; n = n->next) { | ||
assert(MDOC_TEXT == n->type); | assert(n->type == ROFFT_TEXT); | ||
bufinit(h); | bufinit(h); | ||
bufcat(h, "mailto:"); | bufcat(h, "mailto:"); | ||
bufcat(h, n->string); | bufcat(h, n->string); | ||
t = print_otag(h, TAG_A, "ch", "link-mail", h->buf); | |||
PAIR_HREF_INIT(&tag[1], h->buf); | |||
t = print_otag(h, TAG_A, 2, tag); | |||
print_text(h, n->string); | print_text(h, n->string); | ||
print_tagq(h, t); | print_tagq(h, t); | ||
} | } | ||
return(0); | return 0; | ||
} | } | ||
static int | static int | ||
mdoc_fo_pre(MDOC_ARGS) | mdoc_fo_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | |||
struct tag *t; | struct tag *t; | ||
if (MDOC_BODY == n->type) { | if (n->type == ROFFT_BODY) { | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
print_text(h, "("); | print_text(h, "("); | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
return(1); | return 1; | ||
} else if (MDOC_BLOCK == n->type) { | } else if (n->type == ROFFT_BLOCK) { | ||
synopsis_pre(h, n); | synopsis_pre(h, n); | ||
return(1); | return 1; | ||
} | } | ||
/* XXX: we drop non-initial arguments as per groff. */ | if (n->child == NULL) | ||
return 0; | |||
assert(n->child); | |||
assert(n->child->string); | assert(n->child->string); | ||
t = print_otag(h, TAG_B, "c", "fname"); | |||
PAIR_CLASS_INIT(&tag, "fname"); | |||
t = print_otag(h, TAG_B, 1, &tag); | |||
print_text(h, n->child->string); | print_text(h, n->child->string); | ||
print_tagq(h, t); | print_tagq(h, t); | ||
return(0); | return 0; | ||
} | } | ||
static void | static void | ||
mdoc_fo_post(MDOC_ARGS) | mdoc_fo_post(MDOC_ARGS) | ||
{ | { | ||
if (MDOC_BODY != n->type) | if (n->type != ROFFT_BODY) | ||
return; | return; | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
print_text(h, ")"); | print_text(h, ")"); | ||
|
|
||
mdoc_in_pre(MDOC_ARGS) | mdoc_in_pre(MDOC_ARGS) | ||
{ | { | ||
struct tag *t; | struct tag *t; | ||
struct htmlpair tag[2]; | |||
int i; | |||
synopsis_pre(h, n); | synopsis_pre(h, n); | ||
print_otag(h, TAG_B, "c", "includes"); | |||
PAIR_CLASS_INIT(&tag[0], "includes"); | |||
print_otag(h, TAG_B, 1, tag); | |||
/* | /* | ||
* The first argument of the `In' gets special treatment as | * The first argument of the `In' gets special treatment as | ||
* being a linked value. Subsequent values are printed | * being a linked value. Subsequent values are printed | ||
|
|
||
* of no children. | * of no children. | ||
*/ | */ | ||
if (MDOC_SYNPRETTY & n->flags && MDOC_LINE & n->flags) | if (NODE_SYNPRETTY & n->flags && NODE_LINE & n->flags) | ||
print_text(h, "#include"); | print_text(h, "#include"); | ||
print_text(h, "<"); | print_text(h, "<"); | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
if (NULL != (n = n->child)) { | if (NULL != (n = n->child)) { | ||
assert(MDOC_TEXT == n->type); | assert(n->type == ROFFT_TEXT); | ||
PAIR_CLASS_INIT(&tag[0], "link-includes"); | |||
i = 1; | |||
if (h->base_includes) { | if (h->base_includes) { | ||
buffmt_includes(h, n->string); | buffmt_includes(h, n->string); | ||
PAIR_HREF_INIT(&tag[i], h->buf); | t = print_otag(h, TAG_A, "ch", "link-includes", | ||
i++; | h->buf); | ||
} | } else | ||
t = print_otag(h, TAG_A, "c", "link-includes"); | |||
t = print_otag(h, TAG_A, i, tag); | |||
print_text(h, n->string); | print_text(h, n->string); | ||
print_tagq(h, t); | print_tagq(h, t); | ||
|
|
||
print_text(h, ">"); | print_text(h, ">"); | ||
for ( ; n; n = n->next) { | for ( ; n; n = n->next) { | ||
assert(MDOC_TEXT == n->type); | assert(n->type == ROFFT_TEXT); | ||
print_text(h, n->string); | print_text(h, n->string); | ||
} | } | ||
return(0); | return 0; | ||
} | } | ||
static int | static int | ||
mdoc_ic_pre(MDOC_ARGS) | mdoc_ic_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | print_otag(h, TAG_B, "c", "cmd"); | ||
return 1; | |||
PAIR_CLASS_INIT(&tag, "cmd"); | |||
print_otag(h, TAG_B, 1, &tag); | |||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_rv_pre(MDOC_ARGS) | |||
{ | |||
struct htmlpair tag; | |||
struct tag *t; | |||
int nchild; | |||
if (n->prev) | |||
print_otag(h, TAG_BR, 0, NULL); | |||
PAIR_CLASS_INIT(&tag, "fname"); | |||
nchild = n->nchild; | |||
if (nchild > 0) { | |||
print_text(h, "The"); | |||
for (n = n->child; n; n = n->next) { | |||
t = print_otag(h, TAG_B, 1, &tag); | |||
print_text(h, n->string); | |||
print_tagq(h, t); | |||
h->flags |= HTML_NOSPACE; | |||
print_text(h, "()"); | |||
if (n->next == NULL) | |||
continue; | |||
if (nchild > 2) { | |||
h->flags |= HTML_NOSPACE; | |||
print_text(h, ","); | |||
} | |||
if (n->next->next == NULL) | |||
print_text(h, "and"); | |||
} | |||
if (nchild > 1) | |||
print_text(h, "functions return"); | |||
else | |||
print_text(h, "function returns"); | |||
print_text(h, "the value\\~0 if successful;"); | |||
} else | |||
print_text(h, "Upon successful completion," | |||
" the value\\~0 is returned;"); | |||
print_text(h, "otherwise the value\\~\\-1 is returned" | |||
" and the global variable"); | |||
PAIR_CLASS_INIT(&tag, "var"); | |||
t = print_otag(h, TAG_B, 1, &tag); | |||
print_text(h, "errno"); | |||
print_tagq(h, t); | |||
print_text(h, "is set to indicate the error."); | |||
return(0); | |||
} | |||
static int | |||
mdoc_va_pre(MDOC_ARGS) | mdoc_va_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | print_otag(h, TAG_B, "c", "var"); | ||
return 1; | |||
PAIR_CLASS_INIT(&tag, "var"); | |||
print_otag(h, TAG_B, 1, &tag); | |||
return(1); | |||
} | } | ||
static int | static int | ||
|
|
||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
print_text(h, "\\(aq"); | print_text(h, "\\(aq"); | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
return(1); | return 1; | ||
} | } | ||
static int | static int | ||
mdoc_bf_pre(MDOC_ARGS) | mdoc_bf_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag[2]; | const char *cattr; | ||
struct roffsu su; | |||
if (MDOC_HEAD == n->type) | if (n->type == ROFFT_HEAD) | ||
return(0); | return 0; | ||
else if (MDOC_BODY != n->type) | else if (n->type != ROFFT_BODY) | ||
return(1); | return 1; | ||
if (FONT_Em == n->norm->Bf.font) | if (FONT_Em == n->norm->Bf.font) | ||
PAIR_CLASS_INIT(&tag[0], "emph"); | cattr = "emph"; | ||
else if (FONT_Sy == n->norm->Bf.font) | else if (FONT_Sy == n->norm->Bf.font) | ||
PAIR_CLASS_INIT(&tag[0], "symb"); | cattr = "symb"; | ||
else if (FONT_Li == n->norm->Bf.font) | else if (FONT_Li == n->norm->Bf.font) | ||
PAIR_CLASS_INIT(&tag[0], "lit"); | cattr = "lit"; | ||
else | else | ||
PAIR_CLASS_INIT(&tag[0], "none"); | cattr = "none"; | ||
/* | /* | ||
* We want this to be inline-formatted, but needs to be div to | * We want this to be inline-formatted, but needs to be div to | ||
* accept block children. | * accept block children. | ||
*/ | */ | ||
bufinit(h); | |||
bufcat_style(h, "display", "inline"); | print_otag(h, TAG_DIV, "css?hl", cattr, "display", "inline", 1); | ||
SCALE_HS_INIT(&su, 1); | return 1; | ||
/* Needs a left-margin for spacing. */ | |||
bufcat_su(h, "margin-left", &su); | |||
PAIR_STYLE_INIT(&tag[1], h); | |||
print_otag(h, TAG_DIV, 2, tag); | |||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_ms_pre(MDOC_ARGS) | mdoc_ms_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | print_otag(h, TAG_SPAN, "c", "symb"); | ||
return 1; | |||
PAIR_CLASS_INIT(&tag, "symb"); | |||
print_otag(h, TAG_SPAN, 1, &tag); | |||
return(1); | |||
} | } | ||
static int | static int | ||
|
|
||
{ | { | ||
h->flags |= HTML_IGNDELIM; | h->flags |= HTML_IGNDELIM; | ||
return(1); | return 1; | ||
} | } | ||
static void | static void | ||
mdoc_pf_post(MDOC_ARGS) | mdoc_pf_post(MDOC_ARGS) | ||
{ | { | ||
if ( ! (n->next == NULL || n->next->flags & MDOC_LINE)) | if ( ! (n->next == NULL || n->next->flags & NODE_LINE)) | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
} | } | ||
static int | static int | ||
mdoc_rs_pre(MDOC_ARGS) | mdoc_rs_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | if (n->type != ROFFT_BLOCK) | ||
return 1; | |||
if (MDOC_BLOCK != n->type) | |||
return(1); | |||
if (n->prev && SEC_SEE_ALSO == n->sec) | if (n->prev && SEC_SEE_ALSO == n->sec) | ||
print_paragraph(h); | print_paragraph(h); | ||
PAIR_CLASS_INIT(&tag, "ref"); | print_otag(h, TAG_SPAN, "c", "ref"); | ||
print_otag(h, TAG_SPAN, 1, &tag); | return 1; | ||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_no_pre(MDOC_ARGS) | mdoc_no_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | print_otag(h, TAG_SPAN, "c", "none"); | ||
return 1; | |||
PAIR_CLASS_INIT(&tag, "none"); | |||
print_otag(h, TAG_CODE, 1, &tag); | |||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_li_pre(MDOC_ARGS) | mdoc_li_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | print_otag(h, TAG_CODE, "c", "lit"); | ||
return 1; | |||
PAIR_CLASS_INIT(&tag, "lit"); | |||
print_otag(h, TAG_CODE, 1, &tag); | |||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_sy_pre(MDOC_ARGS) | mdoc_sy_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | print_otag(h, TAG_SPAN, "c", "symb"); | ||
return 1; | |||
PAIR_CLASS_INIT(&tag, "symb"); | |||
print_otag(h, TAG_SPAN, 1, &tag); | |||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc_bt_pre(MDOC_ARGS) | |||
{ | |||
print_text(h, "is currently in beta test."); | |||
return(0); | |||
} | |||
static int | |||
mdoc_ud_pre(MDOC_ARGS) | |||
{ | |||
print_text(h, "currently under development."); | |||
return(0); | |||
} | |||
static int | |||
mdoc_lb_pre(MDOC_ARGS) | mdoc_lb_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | if (SEC_LIBRARY == n->sec && NODE_LINE & n->flags && n->prev) | ||
print_otag(h, TAG_BR, ""); | |||
if (SEC_LIBRARY == n->sec && MDOC_LINE & n->flags && n->prev) | print_otag(h, TAG_SPAN, "c", "lib"); | ||
print_otag(h, TAG_BR, 0, NULL); | return 1; | ||
PAIR_CLASS_INIT(&tag, "lib"); | |||
print_otag(h, TAG_SPAN, 1, &tag); | |||
return(1); | |||
} | } | ||
static int | static int | ||
mdoc__x_pre(MDOC_ARGS) | mdoc__x_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag[2]; | const char *cattr; | ||
enum htmltag t; | enum htmltag t; | ||
t = TAG_SPAN; | t = TAG_SPAN; | ||
switch (n->tok) { | switch (n->tok) { | ||
case MDOC__A: | case MDOC__A: | ||
PAIR_CLASS_INIT(&tag[0], "ref-auth"); | cattr = "ref-auth"; | ||
if (n->prev && MDOC__A == n->prev->tok) | if (n->prev && MDOC__A == n->prev->tok) | ||
if (NULL == n->next || MDOC__A != n->next->tok) | if (NULL == n->next || MDOC__A != n->next->tok) | ||
print_text(h, "and"); | print_text(h, "and"); | ||
break; | break; | ||
case MDOC__B: | case MDOC__B: | ||
PAIR_CLASS_INIT(&tag[0], "ref-book"); | cattr = "ref-book"; | ||
t = TAG_I; | t = TAG_I; | ||
break; | break; | ||
case MDOC__C: | case MDOC__C: | ||
PAIR_CLASS_INIT(&tag[0], "ref-city"); | cattr = "ref-city"; | ||
break; | break; | ||
case MDOC__D: | case MDOC__D: | ||
PAIR_CLASS_INIT(&tag[0], "ref-date"); | cattr = "ref-date"; | ||
break; | break; | ||
case MDOC__I: | case MDOC__I: | ||
PAIR_CLASS_INIT(&tag[0], "ref-issue"); | cattr = "ref-issue"; | ||
t = TAG_I; | t = TAG_I; | ||
break; | break; | ||
case MDOC__J: | case MDOC__J: | ||
PAIR_CLASS_INIT(&tag[0], "ref-jrnl"); | cattr = "ref-jrnl"; | ||
t = TAG_I; | t = TAG_I; | ||
break; | break; | ||
case MDOC__N: | case MDOC__N: | ||
PAIR_CLASS_INIT(&tag[0], "ref-num"); | cattr = "ref-num"; | ||
break; | break; | ||
case MDOC__O: | case MDOC__O: | ||
PAIR_CLASS_INIT(&tag[0], "ref-opt"); | cattr = "ref-opt"; | ||
break; | break; | ||
case MDOC__P: | case MDOC__P: | ||
PAIR_CLASS_INIT(&tag[0], "ref-page"); | cattr = "ref-page"; | ||
break; | break; | ||
case MDOC__Q: | case MDOC__Q: | ||
PAIR_CLASS_INIT(&tag[0], "ref-corp"); | cattr = "ref-corp"; | ||
break; | break; | ||
case MDOC__R: | case MDOC__R: | ||
PAIR_CLASS_INIT(&tag[0], "ref-rep"); | cattr = "ref-rep"; | ||
break; | break; | ||
case MDOC__T: | case MDOC__T: | ||
PAIR_CLASS_INIT(&tag[0], "ref-title"); | cattr = "ref-title"; | ||
break; | break; | ||
case MDOC__U: | case MDOC__U: | ||
PAIR_CLASS_INIT(&tag[0], "link-ref"); | cattr = "link-ref"; | ||
break; | break; | ||
case MDOC__V: | case MDOC__V: | ||
PAIR_CLASS_INIT(&tag[0], "ref-vol"); | cattr = "ref-vol"; | ||
break; | break; | ||
default: | default: | ||
abort(); | abort(); | ||
/* NOTREACHED */ | |||
} | } | ||
if (MDOC__U != n->tok) { | if (MDOC__U != n->tok) { | ||
print_otag(h, t, 1, tag); | print_otag(h, t, "c", cattr); | ||
return(1); | return 1; | ||
} | } | ||
PAIR_HREF_INIT(&tag[1], n->child->string); | print_otag(h, TAG_A, "ch", cattr, n->child->string); | ||
print_otag(h, TAG_A, 2, tag); | |||
return(1); | return 1; | ||
} | } | ||
static void | static void | ||
|
|
||
{ | { | ||
switch (n->type) { | switch (n->type) { | ||
case MDOC_BLOCK: | case ROFFT_BLOCK: | ||
break; | break; | ||
case MDOC_HEAD: | case ROFFT_HEAD: | ||
return(0); | return 0; | ||
case MDOC_BODY: | case ROFFT_BODY: | ||
if (n->parent->args || 0 == n->prev->nchild) | if (n->parent->args != NULL || n->prev->child == NULL) | ||
h->flags |= HTML_PREKEEP; | h->flags |= HTML_PREKEEP; | ||
break; | break; | ||
default: | default: | ||
abort(); | abort(); | ||
/* NOTREACHED */ | |||
} | } | ||
return(1); | return 1; | ||
} | } | ||
static void | static void | ||
mdoc_bk_post(MDOC_ARGS) | mdoc_bk_post(MDOC_ARGS) | ||
{ | { | ||
if (MDOC_BODY == n->type) | if (n->type == ROFFT_BODY) | ||
h->flags &= ~(HTML_KEEP | HTML_PREKEEP); | h->flags &= ~(HTML_KEEP | HTML_PREKEEP); | ||
} | } | ||
static int | static int | ||
mdoc_quote_pre(MDOC_ARGS) | mdoc_quote_pre(MDOC_ARGS) | ||
{ | { | ||
struct htmlpair tag; | if (n->type != ROFFT_BODY) | ||
return 1; | |||
if (MDOC_BODY != n->type) | |||
return(1); | |||
switch (n->tok) { | switch (n->tok) { | ||
case MDOC_Ao: | case MDOC_Ao: | ||
/* FALLTHROUGH */ | |||
case MDOC_Aq: | case MDOC_Aq: | ||
print_text(h, n->parent->prev != NULL && | print_text(h, n->child != NULL && n->child->next == NULL && | ||
n->parent->prev->tok == MDOC_An ? "<" : "\\(la"); | n->child->tok == MDOC_Mt ? "<" : "\\(la"); | ||
break; | break; | ||
case MDOC_Bro: | case MDOC_Bro: | ||
/* FALLTHROUGH */ | |||
case MDOC_Brq: | case MDOC_Brq: | ||
print_text(h, "\\(lC"); | print_text(h, "\\(lC"); | ||
break; | break; | ||
case MDOC_Bo: | case MDOC_Bo: | ||
/* FALLTHROUGH */ | |||
case MDOC_Bq: | case MDOC_Bq: | ||
print_text(h, "\\(lB"); | print_text(h, "\\(lB"); | ||
break; | break; | ||
case MDOC_Oo: | case MDOC_Oo: | ||
/* FALLTHROUGH */ | |||
case MDOC_Op: | case MDOC_Op: | ||
print_text(h, "\\(lB"); | print_text(h, "\\(lB"); | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
PAIR_CLASS_INIT(&tag, "opt"); | print_otag(h, TAG_SPAN, "c", "opt"); | ||
print_otag(h, TAG_SPAN, 1, &tag); | |||
break; | break; | ||
case MDOC_En: | case MDOC_En: | ||
if (NULL == n->norm->Es || | if (NULL == n->norm->Es || | ||
NULL == n->norm->Es->child) | NULL == n->norm->Es->child) | ||
return(1); | return 1; | ||
print_text(h, n->norm->Es->child->string); | print_text(h, n->norm->Es->child->string); | ||
break; | break; | ||
case MDOC_Eo: | |||
break; | |||
case MDOC_Do: | case MDOC_Do: | ||
/* FALLTHROUGH */ | |||
case MDOC_Dq: | case MDOC_Dq: | ||
/* FALLTHROUGH */ | |||
case MDOC_Qo: | case MDOC_Qo: | ||
/* FALLTHROUGH */ | |||
case MDOC_Qq: | case MDOC_Qq: | ||
print_text(h, "\\(lq"); | print_text(h, "\\(lq"); | ||
break; | break; | ||
case MDOC_Po: | case MDOC_Po: | ||
/* FALLTHROUGH */ | |||
case MDOC_Pq: | case MDOC_Pq: | ||
print_text(h, "("); | print_text(h, "("); | ||
break; | break; | ||
case MDOC_Ql: | case MDOC_Ql: | ||
print_text(h, "\\(oq"); | print_text(h, "\\(oq"); | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
PAIR_CLASS_INIT(&tag, "lit"); | print_otag(h, TAG_CODE, "c", "lit"); | ||
print_otag(h, TAG_CODE, 1, &tag); | |||
break; | break; | ||
case MDOC_So: | case MDOC_So: | ||
/* FALLTHROUGH */ | |||
case MDOC_Sq: | case MDOC_Sq: | ||
print_text(h, "\\(oq"); | print_text(h, "\\(oq"); | ||
break; | break; | ||
default: | default: | ||
abort(); | abort(); | ||
/* NOTREACHED */ | |||
} | } | ||
h->flags |= HTML_NOSPACE; | h->flags |= HTML_NOSPACE; | ||
return(1); | return 1; | ||
} | } | ||
static void | static void | ||
mdoc_quote_post(MDOC_ARGS) | mdoc_quote_post(MDOC_ARGS) | ||
{ | { | ||
if (n->type != MDOC_BODY && n->type != MDOC_ELEM) | if (n->type != ROFFT_BODY && n->type != ROFFT_ELEM) | ||
return; | return; | ||
if ( ! (n->tok == MDOC_En || | h->flags |= HTML_NOSPACE; | ||
(n->tok == MDOC_Eo && n->end == ENDBODY_SPACE))) | |||
h->flags |= HTML_NOSPACE; | |||
switch (n->tok) { | switch (n->tok) { | ||
case MDOC_Ao: | case MDOC_Ao: | ||
/* FALLTHROUGH */ | |||
case MDOC_Aq: | case MDOC_Aq: | ||
print_text(h, n->parent->prev != NULL && | print_text(h, n->child != NULL && n->child->next == NULL && | ||
n->parent->prev->tok == MDOC_An ? ">" : "\\(ra"); | n->child->tok == MDOC_Mt ? ">" : "\\(ra"); | ||
break; | break; | ||
case MDOC_Bro: | case MDOC_Bro: | ||
/* FALLTHROUGH */ | |||
case MDOC_Brq: | case MDOC_Brq: | ||
print_text(h, "\\(rC"); | print_text(h, "\\(rC"); | ||
break; | break; | ||
case MDOC_Oo: | case MDOC_Oo: | ||
/* FALLTHROUGH */ | |||
case MDOC_Op: | case MDOC_Op: | ||
/* FALLTHROUGH */ | |||
case MDOC_Bo: | case MDOC_Bo: | ||
/* FALLTHROUGH */ | |||
case MDOC_Bq: | case MDOC_Bq: | ||
print_text(h, "\\(rB"); | print_text(h, "\\(rB"); | ||
break; | break; | ||
case MDOC_En: | case MDOC_En: | ||
if (NULL != n->norm->Es && | if (n->norm->Es == NULL || | ||
NULL != n->norm->Es->child && | n->norm->Es->child == NULL || | ||
NULL != n->norm->Es->child->next) { | n->norm->Es->child->next == NULL) | ||
h->flags |= HTML_NOSPACE; | h->flags &= ~HTML_NOSPACE; | ||
else | |||
print_text(h, n->norm->Es->child->next->string); | print_text(h, n->norm->Es->child->next->string); | ||
} | |||
break; | break; | ||
case MDOC_Eo: | |||
break; | |||
case MDOC_Qo: | case MDOC_Qo: | ||
/* FALLTHROUGH */ | |||
case MDOC_Qq: | case MDOC_Qq: | ||
/* FALLTHROUGH */ | |||
case MDOC_Do: | case MDOC_Do: | ||
/* FALLTHROUGH */ | |||
case MDOC_Dq: | case MDOC_Dq: | ||
print_text(h, "\\(rq"); | print_text(h, "\\(rq"); | ||
break; | break; | ||
case MDOC_Po: | case MDOC_Po: | ||
/* FALLTHROUGH */ | |||
case MDOC_Pq: | case MDOC_Pq: | ||
print_text(h, ")"); | print_text(h, ")"); | ||
break; | break; | ||
case MDOC_Ql: | case MDOC_Ql: | ||
/* FALLTHROUGH */ | |||
case MDOC_So: | case MDOC_So: | ||
/* FALLTHROUGH */ | |||
case MDOC_Sq: | case MDOC_Sq: | ||
print_text(h, "\\(cq"); | print_text(h, "\\(cq"); | ||
break; | break; | ||
default: | default: | ||
abort(); | abort(); | ||
/* NOTREACHED */ | |||
} | } | ||
} | |||
static int | |||
mdoc_eo_pre(MDOC_ARGS) | |||
{ | |||
if (n->type != ROFFT_BODY) | |||
return 1; | |||
if (n->end == ENDBODY_NOT && | |||
n->parent->head->child == NULL && | |||
n->child != NULL && | |||
n->child->end != ENDBODY_NOT) | |||
print_text(h, "\\&"); | |||
else if (n->end != ENDBODY_NOT ? n->child != NULL : | |||
n->parent->head->child != NULL && (n->child != NULL || | |||
(n->parent->tail != NULL && n->parent->tail->child != NULL))) | |||
h->flags |= HTML_NOSPACE; | |||
return 1; | |||
} | |||
static void | |||
mdoc_eo_post(MDOC_ARGS) | |||
{ | |||
int body, tail; | |||
if (n->type != ROFFT_BODY) | |||
return; | |||
if (n->end != ENDBODY_NOT) { | |||
h->flags &= ~HTML_NOSPACE; | |||
return; | |||
} | |||
body = n->child != NULL || n->parent->head->child != NULL; | |||
tail = n->parent->tail != NULL && n->parent->tail->child != NULL; | |||
if (body && tail) | |||
h->flags |= HTML_NOSPACE; | |||
else if ( ! tail) | |||
h->flags &= ~HTML_NOSPACE; | |||
} | } |