-/* $Id: mdoc_term.c,v 1.249 2013/06/02 18:16:57 schwarze Exp $ */
+/* $Id: mdoc_term.c,v 1.280 2014/08/21 12:57:17 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010, 2012 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif
#include <sys/types.h>
#include <string.h>
#include "mandoc.h"
+#include "mandoc_aux.h"
#include "out.h"
#include "term.h"
#include "mdoc.h"
#define DECL_ARGS struct termp *p, \
struct termpair *pair, \
- const struct mdoc_meta *meta, \
+ const struct mdoc_meta *meta, \
struct mdoc_node *n
struct termact {
static void print_bvspace(struct termp *,
const struct mdoc_node *,
const struct mdoc_node *);
-static void print_mdoc_node(DECL_ARGS);
+static void print_mdoc_node(DECL_ARGS);
static void print_mdoc_nodelist(DECL_ARGS);
static void print_mdoc_head(struct termp *, const void *);
static void print_mdoc_foot(struct termp *, const void *);
-static void synopsis_pre(struct termp *,
+static void synopsis_pre(struct termp *,
const struct mdoc_node *);
static void termp____post(DECL_ARGS);
static int termp_bx_pre(DECL_ARGS);
static int termp_cd_pre(DECL_ARGS);
static int termp_d1_pre(DECL_ARGS);
+static int termp_es_pre(DECL_ARGS);
static int termp_ex_pre(DECL_ARGS);
static int termp_fa_pre(DECL_ARGS);
static int termp_fd_pre(DECL_ARGS);
static int termp_fn_pre(DECL_ARGS);
static int termp_fo_pre(DECL_ARGS);
static int termp_ft_pre(DECL_ARGS);
-static int termp_igndelim_pre(DECL_ARGS);
static int termp_in_pre(DECL_ARGS);
static int termp_it_pre(DECL_ARGS);
static int termp_li_pre(DECL_ARGS);
+static int termp_ll_pre(DECL_ARGS);
static int termp_lk_pre(DECL_ARGS);
static int termp_nd_pre(DECL_ARGS);
static int termp_nm_pre(DECL_ARGS);
{ NULL, NULL }, /* Dt */
{ NULL, NULL }, /* Os */
{ termp_sh_pre, termp_sh_post }, /* Sh */
- { termp_ss_pre, termp_ss_post }, /* Ss */
- { termp_sp_pre, NULL }, /* Pp */
+ { termp_ss_pre, termp_ss_post }, /* Ss */
+ { termp_sp_pre, NULL }, /* Pp */
{ termp_d1_pre, termp_bl_post }, /* D1 */
{ termp_d1_pre, termp_bl_post }, /* Dl */
{ termp_bd_pre, termp_bd_post }, /* Bd */
{ termp_bl_pre, termp_bl_post }, /* Bl */
{ NULL, NULL }, /* El */
{ termp_it_pre, termp_it_post }, /* It */
- { termp_under_pre, NULL }, /* Ad */
+ { termp_under_pre, NULL }, /* Ad */
{ termp_an_pre, termp_an_post }, /* An */
{ termp_under_pre, NULL }, /* Ar */
{ termp_cd_pre, NULL }, /* Cd */
{ termp_bold_pre, NULL }, /* Cm */
- { NULL, NULL }, /* Dv */
- { NULL, NULL }, /* Er */
- { NULL, NULL }, /* Ev */
+ { NULL, NULL }, /* Dv */
+ { NULL, NULL }, /* Er */
+ { NULL, NULL }, /* Ev */
{ termp_ex_pre, NULL }, /* Ex */
- { termp_fa_pre, NULL }, /* Fa */
- { termp_fd_pre, termp_fd_post }, /* Fd */
+ { termp_fa_pre, NULL }, /* Fa */
+ { termp_fd_pre, termp_fd_post }, /* Fd */
{ termp_fl_pre, NULL }, /* Fl */
- { termp_fn_pre, NULL }, /* Fn */
- { termp_ft_pre, NULL }, /* Ft */
- { termp_bold_pre, NULL }, /* Ic */
- { termp_in_pre, termp_in_post }, /* In */
+ { termp_fn_pre, NULL }, /* Fn */
+ { termp_ft_pre, NULL }, /* Ft */
+ { termp_bold_pre, NULL }, /* Ic */
+ { termp_in_pre, termp_in_post }, /* In */
{ termp_li_pre, NULL }, /* Li */
- { termp_nd_pre, NULL }, /* Nd */
- { termp_nm_pre, termp_nm_post }, /* Nm */
+ { termp_nd_pre, NULL }, /* Nd */
+ { termp_nm_pre, termp_nm_post }, /* Nm */
{ termp_quote_pre, termp_quote_post }, /* Op */
- { NULL, NULL }, /* Ot */
+ { termp_ft_pre, NULL }, /* Ot */
{ termp_under_pre, NULL }, /* Pa */
{ termp_rv_pre, NULL }, /* Rv */
- { NULL, NULL }, /* St */
+ { NULL, NULL }, /* St */
{ termp_under_pre, NULL }, /* Va */
{ termp_vt_pre, NULL }, /* Vt */
{ termp_xr_pre, NULL }, /* Xr */
{ termp_quote_pre, termp_quote_post }, /* Aq */
{ NULL, NULL }, /* At */
{ NULL, NULL }, /* Bc */
- { termp_bf_pre, NULL }, /* Bf */
+ { termp_bf_pre, NULL }, /* Bf */
{ termp_quote_pre, termp_quote_post }, /* Bo */
{ termp_quote_pre, termp_quote_post }, /* Bq */
{ termp_xx_pre, NULL }, /* Bsx */
{ termp_quote_pre, termp_quote_post }, /* Dq */
{ NULL, NULL }, /* Ec */ /* FIXME: no space */
{ NULL, NULL }, /* Ef */
- { termp_under_pre, NULL }, /* Em */
+ { termp_under_pre, NULL }, /* Em */
{ termp_quote_pre, termp_quote_post }, /* Eo */
{ termp_xx_pre, NULL }, /* Fx */
{ termp_bold_pre, NULL }, /* Ms */
- { termp_igndelim_pre, NULL }, /* No */
+ { NULL, NULL }, /* No */
{ termp_ns_pre, NULL }, /* Ns */
{ termp_xx_pre, NULL }, /* Nx */
{ termp_xx_pre, NULL }, /* Ox */
{ NULL, NULL }, /* Pc */
- { termp_igndelim_pre, termp_pf_post }, /* Pf */
+ { NULL, termp_pf_post }, /* Pf */
{ termp_quote_pre, termp_quote_post }, /* Po */
{ termp_quote_pre, termp_quote_post }, /* Pq */
{ NULL, NULL }, /* Qc */
{ termp_xx_pre, NULL }, /* Ux */
{ NULL, NULL }, /* Xc */
{ NULL, NULL }, /* Xo */
- { termp_fo_pre, termp_fo_post }, /* Fo */
- { NULL, NULL }, /* Fc */
+ { termp_fo_pre, termp_fo_post }, /* Fo */
+ { NULL, NULL }, /* Fc */
{ termp_quote_pre, termp_quote_post }, /* Oo */
{ NULL, NULL }, /* Oc */
{ termp_bk_pre, termp_bk_post }, /* Bk */
{ NULL, NULL }, /* Ek */
{ termp_bt_pre, NULL }, /* Bt */
{ NULL, NULL }, /* Hf */
- { NULL, NULL }, /* Fr */
+ { termp_under_pre, NULL }, /* Fr */
{ termp_ud_pre, NULL }, /* Ud */
{ NULL, termp_lb_post }, /* Lb */
- { termp_sp_pre, NULL }, /* Lp */
- { termp_lk_pre, NULL }, /* Lk */
- { termp_under_pre, NULL }, /* Mt */
- { termp_quote_pre, termp_quote_post }, /* Brq */
- { termp_quote_pre, termp_quote_post }, /* Bro */
- { NULL, NULL }, /* Brc */
- { NULL, termp____post }, /* %C */
- { NULL, NULL }, /* Es */ /* TODO */
- { NULL, NULL }, /* En */ /* TODO */
- { termp_xx_pre, NULL }, /* Dx */
- { NULL, termp____post }, /* %Q */
+ { termp_sp_pre, NULL }, /* Lp */
+ { termp_lk_pre, NULL }, /* Lk */
+ { termp_under_pre, NULL }, /* Mt */
+ { termp_quote_pre, termp_quote_post }, /* Brq */
+ { termp_quote_pre, termp_quote_post }, /* Bro */
+ { NULL, NULL }, /* Brc */
+ { NULL, termp____post }, /* %C */
+ { termp_es_pre, NULL }, /* Es */
+ { termp_quote_pre, termp_quote_post }, /* En */
+ { termp_xx_pre, NULL }, /* Dx */
+ { NULL, termp____post }, /* %Q */
{ termp_sp_pre, NULL }, /* br */
- { termp_sp_pre, NULL }, /* sp */
- { NULL, termp____post }, /* %U */
- { NULL, NULL }, /* Ta */
+ { termp_sp_pre, NULL }, /* sp */
+ { NULL, termp____post }, /* %U */
+ { NULL, NULL }, /* Ta */
+ { termp_ll_pre, NULL }, /* ll */
};
term_begin(p, print_mdoc_head, print_mdoc_foot, meta);
- if (n->child)
+ if (n->child) {
+ if (MDOC_Sh != n->child->tok)
+ term_vspace(p);
print_mdoc_nodelist(p, NULL, meta, n->child);
+ }
term_end(p);
}
-
static void
print_mdoc_nodelist(DECL_ARGS)
{
print_mdoc_nodelist(p, pair, meta, n->next);
}
-
-/* ARGSUSED */
static void
print_mdoc_node(DECL_ARGS)
{
/*
* Keeps only work until the end of a line. If a keep was
* invoked in a prior line, revert it to PREKEEP.
- *
- * Also let SYNPRETTY sections behave as if they were wrapped
- * in a `Bk' block.
*/
- if (TERMP_KEEP & p->flags || MDOC_SYNPRETTY & n->flags) {
- if (n->prev ? (n->prev->line != n->line) :
+ if (TERMP_KEEP & p->flags) {
+ if (n->prev ? (n->prev->lastline != n->line) :
(n->parent && n->parent->line != n->line)) {
p->flags &= ~TERMP_KEEP;
p->flags |= TERMP_PREKEEP;
}
}
- /*
- * Since SYNPRETTY sections aren't "turned off" with `Ek',
- * we have to intuit whether we should disable formatting.
- */
-
- if ( ! (MDOC_SYNPRETTY & n->flags) &&
- ((n->prev && MDOC_SYNPRETTY & n->prev->flags) ||
- (n->parent && MDOC_SYNPRETTY & n->parent->flags)))
- p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
-
/*
* After the keep flags have been set up, we may now
* produce output. Note that some pre-handlers do so.
*/
switch (n->type) {
- case (MDOC_TEXT):
+ case MDOC_TEXT:
if (' ' == *n->string && MDOC_LINE & n->flags)
term_newln(p);
if (MDOC_DELIMC & n->flags)
if (MDOC_DELIMO & n->flags)
p->flags |= TERMP_NOSPACE;
break;
- case (MDOC_EQN):
+ case MDOC_EQN:
term_eqn(p, n->eqn);
break;
- case (MDOC_TBL):
+ case MDOC_TBL:
term_tbl(p, n->span);
break;
default:
(ENDBODY_NOT == n->end ? n : n->pending)->prev_font);
switch (n->type) {
- case (MDOC_TEXT):
+ case MDOC_TEXT:
break;
- case (MDOC_TBL):
+ case MDOC_TBL:
break;
- case (MDOC_EQN):
+ case MDOC_EQN:
break;
default:
if ( ! termacts[n->tok].post || MDOC_ENDED & n->flags)
if (MDOC_EOS & n->flags)
p->flags |= TERMP_SENTENCE;
- p->offset = offset;
- p->rmargin = rmargin;
+ if (MDOC_ll != n->tok) {
+ p->offset = offset;
+ p->rmargin = rmargin;
+ }
}
-
static void
print_mdoc_foot(struct termp *p, const void *arg)
{
term_fontrepl(p, TERMFONT_NONE);
- /*
+ /*
* Output the footer in new-groff style, that is, three columns
* with the middle being the manual date and flanking columns
* being the operating system:
term_vspace(p);
p->offset = 0;
- p->rmargin = (p->maxrmargin -
- term_strlen(p, meta->date) + term_len(p, 1)) / 2;
+ p->rmargin = (p->maxrmargin -
+ term_strlen(p, meta->date) + term_len(p, 1)) / 2;
+ p->trailspace = 1;
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
term_word(p, meta->os);
p->offset = p->rmargin;
p->rmargin = p->maxrmargin;
+ p->trailspace = 0;
p->flags &= ~TERMP_NOBREAK;
p->flags |= TERMP_NOSPACE;
p->flags = 0;
}
-
static void
print_mdoc_head(struct termp *p, const void *arg)
{
- char buf[BUFSIZ], title[BUFSIZ];
- size_t buflen, titlen;
- const struct mdoc_meta *meta;
+ const struct mdoc_meta *meta;
+ char *volume, *title;
+ size_t vollen, titlen;
meta = (const struct mdoc_meta *)arg;
p->rmargin = p->maxrmargin;
assert(meta->vol);
- strlcpy(buf, meta->vol, BUFSIZ);
- buflen = term_strlen(p, buf);
-
- if (meta->arch) {
- strlcat(buf, " (", BUFSIZ);
- strlcat(buf, meta->arch, BUFSIZ);
- strlcat(buf, ")", BUFSIZ);
- }
+ if (NULL == meta->arch)
+ volume = mandoc_strdup(meta->vol);
+ else
+ mandoc_asprintf(&volume, "%s (%s)",
+ meta->vol, meta->arch);
+ vollen = term_strlen(p, volume);
- snprintf(title, BUFSIZ, "%s(%s)", meta->title, meta->msec);
+ if (NULL == meta->msec)
+ title = mandoc_strdup(meta->title);
+ else
+ mandoc_asprintf(&title, "%s(%s)",
+ meta->title, meta->msec);
titlen = term_strlen(p, title);
p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
+ p->trailspace = 1;
p->offset = 0;
- p->rmargin = 2 * (titlen+1) + buflen < p->maxrmargin ?
- (p->maxrmargin -
- term_strlen(p, buf) + term_len(p, 1)) / 2 :
- p->maxrmargin - buflen;
+ p->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ?
+ (p->maxrmargin - vollen + term_len(p, 1)) / 2 :
+ p->maxrmargin - vollen;
term_word(p, title);
term_flushln(p);
p->flags |= TERMP_NOSPACE;
p->offset = p->rmargin;
- p->rmargin = p->offset + buflen + titlen < p->maxrmargin ?
+ p->rmargin = p->offset + vollen + titlen < p->maxrmargin ?
p->maxrmargin - titlen : p->maxrmargin;
- term_word(p, buf);
+ term_word(p, volume);
term_flushln(p);
p->flags &= ~TERMP_NOBREAK;
+ p->trailspace = 0;
if (p->rmargin + titlen <= p->maxrmargin) {
p->flags |= TERMP_NOSPACE;
p->offset = p->rmargin;
p->flags &= ~TERMP_NOSPACE;
p->offset = 0;
p->rmargin = p->maxrmargin;
+ free(title);
+ free(volume);
}
-
static size_t
a2height(const struct termp *p, const char *v)
{
return(term_vspan(p, &su));
}
-
static size_t
a2width(const struct termp *p, const char *v)
{
return(term_hspan(p, &su));
}
-
static size_t
a2offs(const struct termp *p, const char *v)
{
return(term_hspan(p, &su));
}
-
/*
* Determine how much space to print out before block elements of `It'
* (and thus `Bl') and `Bd'. And then go ahead and print that space,
* too.
*/
static void
-print_bvspace(struct termp *p,
- const struct mdoc_node *bl,
- const struct mdoc_node *n)
+print_bvspace(struct termp *p,
+ const struct mdoc_node *bl,
+ const struct mdoc_node *n)
{
const struct mdoc_node *nn;
}
-/* ARGSUSED */
+static int
+termp_ll_pre(DECL_ARGS)
+{
+
+ term_setwidth(p, n->nchild ? n->child->string : NULL);
+ return(0);
+}
+
static int
termp_it_pre(DECL_ARGS)
{
const struct mdoc_node *bl, *nn;
- char buf[7];
- int i;
- size_t width, offset, ncols, dcol;
+ char buf[24];
+ int i;
+ size_t width, offset, ncols, dcol;
enum mdoc_list type;
if (MDOC_BLOCK == n->type) {
bl = n->parent->parent->parent;
type = bl->norm->Bl.type;
- /*
+ /*
* First calculate width and offset. This is pretty easy unless
* we're a -column list, in which case all prior columns must
* be accounted for.
offset = a2offs(p, bl->norm->Bl.offs);
switch (type) {
- case (LIST_column):
+ case LIST_column:
if (MDOC_HEAD == n->type)
break;
* - For more than 5 columns, add only one column.
*/
ncols = bl->norm->Bl.ncols;
-
- /* LINTED */
- dcol = ncols < 5 ? term_len(p, 4) :
- ncols == 5 ? term_len(p, 3) : term_len(p, 1);
+ dcol = ncols < 5 ? term_len(p, 4) :
+ ncols == 5 ? term_len(p, 3) : term_len(p, 1);
/*
* Calculate the offset by applying all prior MDOC_BODY,
* so we stop at the MDOC_HEAD (NULL == nn->prev).
*/
- for (i = 0, nn = n->prev;
- nn->prev && i < (int)ncols;
- nn = nn->prev, i++)
- offset += dcol + a2width
- (p, bl->norm->Bl.cols[i]);
+ for (i = 0, nn = n->prev;
+ nn->prev && i < (int)ncols;
+ nn = nn->prev, i++)
+ offset += dcol + a2width(p,
+ bl->norm->Bl.cols[i]);
/*
* When exceeding the declared number of columns, leave
if (NULL == bl->norm->Bl.width)
break;
- /*
+ /*
* Note: buffer the width by 2, which is groff's magic
* number for buffering single arguments. See the above
* handling for column for how this changes.
break;
}
- /*
+ /*
* List-type can override the width in the case of fixed-head
* values (bullet, dash/hyphen, enum). Tags need a non-zero
* offset.
*/
switch (type) {
- case (LIST_bullet):
+ case LIST_bullet:
/* FALLTHROUGH */
- case (LIST_dash):
+ case LIST_dash:
/* FALLTHROUGH */
- case (LIST_hyphen):
+ case LIST_hyphen:
/* FALLTHROUGH */
- case (LIST_enum):
+ case LIST_enum:
if (width < term_len(p, 2))
width = term_len(p, 2);
break;
- case (LIST_hang):
+ case LIST_hang:
if (0 == width)
width = term_len(p, 8);
break;
- case (LIST_column):
+ case LIST_column:
/* FALLTHROUGH */
- case (LIST_tag):
+ case LIST_tag:
if (0 == width)
width = term_len(p, 10);
break;
break;
}
- /*
+ /*
* Whitespace control. Inset bodies need an initial space,
* while diagonal bodies need two.
*/
p->flags |= TERMP_NOSPACE;
switch (type) {
- case (LIST_diag):
+ case LIST_diag:
if (MDOC_BODY == n->type)
term_word(p, "\\ \\ ");
break;
- case (LIST_inset):
- if (MDOC_BODY == n->type)
+ case LIST_inset:
+ if (MDOC_BODY == n->type && n->parent->head->nchild)
term_word(p, "\\ ");
break;
default:
p->flags |= TERMP_NOSPACE;
switch (type) {
- case (LIST_diag):
+ case LIST_diag:
if (MDOC_HEAD == n->type)
term_fontpush(p, TERMFONT_BOLD);
break;
*/
switch (type) {
- case (LIST_enum):
+ case LIST_enum:
/*
* Weird special case.
* Very narrow enum lists actually hang.
if (width == term_len(p, 2))
p->flags |= TERMP_HANG;
/* FALLTHROUGH */
- case (LIST_bullet):
+ case LIST_bullet:
/* FALLTHROUGH */
- case (LIST_dash):
+ case LIST_dash:
/* FALLTHROUGH */
- case (LIST_hyphen):
- if (MDOC_HEAD == n->type)
- p->flags |= TERMP_NOBREAK;
+ case LIST_hyphen:
+ if (MDOC_HEAD != n->type)
+ break;
+ p->flags |= TERMP_NOBREAK;
+ p->trailspace = 1;
break;
- case (LIST_hang):
- if (MDOC_HEAD == n->type)
- p->flags |= TERMP_NOBREAK;
- else
+ case LIST_hang:
+ if (MDOC_HEAD != n->type)
break;
/*
* the "overstep" effect in term_flushln() and treat
* this as a `-ohang' list instead.
*/
- if (n->next->child &&
- (MDOC_Bl == n->next->child->tok ||
- MDOC_Bd == n->next->child->tok))
- p->flags &= ~TERMP_NOBREAK;
- else
- p->flags |= TERMP_HANG;
- break;
- case (LIST_tag):
- if (MDOC_HEAD == n->type)
- p->flags |= TERMP_NOBREAK | TERMP_TWOSPACE;
+ if (NULL != n->next &&
+ NULL != n->next->child &&
+ (MDOC_Bl == n->next->child->tok ||
+ MDOC_Bd == n->next->child->tok))
+ break;
+ p->flags |= TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG;
+ p->trailspace = 1;
+ break;
+ case LIST_tag:
if (MDOC_HEAD != n->type)
break;
+
+ p->flags |= TERMP_NOBREAK | TERMP_BRIND;
+ p->trailspace = 2;
+
if (NULL == n->next || NULL == n->next->child)
p->flags |= TERMP_DANGLE;
break;
- case (LIST_column):
+ case LIST_column:
if (MDOC_HEAD == n->type)
break;
- if (NULL == n->next)
+ if (NULL == n->next) {
p->flags &= ~TERMP_NOBREAK;
- else
+ p->trailspace = 0;
+ } else {
p->flags |= TERMP_NOBREAK;
+ p->trailspace = 1;
+ }
break;
- case (LIST_diag):
- if (MDOC_HEAD == n->type)
- p->flags |= TERMP_NOBREAK;
+ case LIST_diag:
+ if (MDOC_HEAD != n->type)
+ break;
+ p->flags |= TERMP_NOBREAK | TERMP_BRIND;
+ p->trailspace = 1;
break;
default:
break;
}
- /*
+ /*
* Margin control. Set-head-width lists have their right
* margins shortened. The body for these lists has the offset
* necessarily lengthened. Everybody gets the offset.
p->offset += offset;
switch (type) {
- case (LIST_hang):
+ case LIST_hang:
/*
* Same stipulation as above, regarding `-hang'. We
* don't want to recalculate rmargin and offsets when
* using `Bd' or `Bl' within `-hang' overstep lists.
*/
- if (MDOC_HEAD == n->type && n->next->child &&
- (MDOC_Bl == n->next->child->tok ||
- MDOC_Bd == n->next->child->tok))
+ if (MDOC_HEAD == n->type &&
+ NULL != n->next &&
+ NULL != n->next->child &&
+ (MDOC_Bl == n->next->child->tok ||
+ MDOC_Bd == n->next->child->tok))
break;
/* FALLTHROUGH */
- case (LIST_bullet):
+ case LIST_bullet:
/* FALLTHROUGH */
- case (LIST_dash):
+ case LIST_dash:
/* FALLTHROUGH */
- case (LIST_enum):
+ case LIST_enum:
/* FALLTHROUGH */
- case (LIST_hyphen):
+ case LIST_hyphen:
/* FALLTHROUGH */
- case (LIST_tag):
+ case LIST_tag:
assert(width);
if (MDOC_HEAD == n->type)
p->rmargin = p->offset + width;
- else
+ else {
p->offset += width;
+ if (p->rmargin < p->offset)
+ p->rmargin = p->offset;
+ }
break;
- case (LIST_column):
+ case LIST_column:
assert(width);
p->rmargin = p->offset + width;
- /*
+ /*
* XXX - this behaviour is not documented: the
* right-most column is filled to the right margin.
*/
break;
}
- /*
+ /*
* The dash, hyphen, bullet and enum lists all have a special
- * HEAD character (temporarily bold, in some cases).
+ * HEAD character (temporarily bold, in some cases).
*/
if (MDOC_HEAD == n->type)
switch (type) {
- case (LIST_bullet):
+ case LIST_bullet:
term_fontpush(p, TERMFONT_BOLD);
term_word(p, "\\[bu]");
term_fontpop(p);
break;
- case (LIST_dash):
+ case LIST_dash:
/* FALLTHROUGH */
- case (LIST_hyphen):
+ case LIST_hyphen:
term_fontpush(p, TERMFONT_BOLD);
term_word(p, "\\(hy");
term_fontpop(p);
break;
- case (LIST_enum):
+ case LIST_enum:
(pair->ppair->ppair->count)++;
- snprintf(buf, sizeof(buf), "%d.",
- pair->ppair->ppair->count);
+ (void)snprintf(buf, sizeof(buf), "%d.",
+ pair->ppair->ppair->count);
term_word(p, buf);
break;
default:
break;
}
- /*
+ /*
* If we're not going to process our children, indicate so here.
*/
switch (type) {
- case (LIST_bullet):
+ case LIST_bullet:
/* FALLTHROUGH */
- case (LIST_item):
+ case LIST_item:
/* FALLTHROUGH */
- case (LIST_dash):
+ case LIST_dash:
/* FALLTHROUGH */
- case (LIST_hyphen):
+ case LIST_hyphen:
/* FALLTHROUGH */
- case (LIST_enum):
+ case LIST_enum:
if (MDOC_HEAD == n->type)
return(0);
break;
- case (LIST_column):
+ case LIST_column:
if (MDOC_HEAD == n->type)
return(0);
break;
return(1);
}
-
-/* ARGSUSED */
static void
termp_it_post(DECL_ARGS)
{
type = n->parent->parent->parent->norm->Bl.type;
switch (type) {
- case (LIST_item):
+ case LIST_item:
/* FALLTHROUGH */
- case (LIST_diag):
+ case LIST_diag:
/* FALLTHROUGH */
- case (LIST_inset):
+ case LIST_inset:
if (MDOC_BODY == n->type)
term_newln(p);
break;
- case (LIST_column):
+ case LIST_column:
if (MDOC_BODY == n->type)
term_flushln(p);
break;
break;
}
- /*
+ /*
* Now that our output is flushed, we can reset our tags. Since
* only `It' sets these flags, we're free to assume that nobody
* has munged them in the meanwhile.
*/
- p->flags &= ~TERMP_DANGLE;
- p->flags &= ~TERMP_NOBREAK;
- p->flags &= ~TERMP_TWOSPACE;
- p->flags &= ~TERMP_HANG;
+ p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND |
+ TERMP_DANGLE | TERMP_HANG);
+ p->trailspace = 0;
}
-
-/* ARGSUSED */
static int
termp_nm_pre(DECL_ARGS)
{
- if (MDOC_BLOCK == n->type)
+ if (MDOC_BLOCK == n->type) {
+ p->flags |= TERMP_PREKEEP;
return(1);
+ }
if (MDOC_BODY == n->type) {
if (NULL == n->child)
MDOC_TEXT == n->prev->child->type ?
term_strlen(p, n->prev->child->string) :
term_len(p, 5));
+ if (p->rmargin < p->offset)
+ p->rmargin = p->offset;
return(1);
}
if (MDOC_HEAD == n->type)
synopsis_pre(p, n->parent);
- if (MDOC_HEAD == n->type && n->next->child) {
- p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
+ if (MDOC_HEAD == n->type &&
+ NULL != n->next && NULL != n->next->child) {
+ p->flags |= TERMP_NOSPACE | TERMP_NOBREAK | TERMP_BRIND;
+ p->trailspace = 1;
p->rmargin = p->offset + term_len(p, 1);
if (NULL == n->child) {
p->rmargin += term_strlen(p, meta->name);
return(1);
}
-
-/* ARGSUSED */
static void
termp_nm_post(DECL_ARGS)
{
- if (MDOC_HEAD == n->type && n->next->child) {
+ if (MDOC_BLOCK == n->type) {
+ p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
+ } else if (MDOC_HEAD == n->type &&
+ NULL != n->next && NULL != n->next->child) {
term_flushln(p);
- p->flags &= ~(TERMP_NOBREAK | TERMP_HANG);
+ p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG);
+ p->trailspace = 0;
} else if (MDOC_BODY == n->type && n->child)
term_flushln(p);
}
-
-/* ARGSUSED */
static int
termp_fl_pre(DECL_ARGS)
{
term_fontpush(p, TERMFONT_BOLD);
term_word(p, "\\-");
- if (n->child)
- p->flags |= TERMP_NOSPACE;
- else if (n->next && n->next->line == n->line)
+ if ( ! (n->nchild == 0 &&
+ (n->next == NULL ||
+ n->next->type == MDOC_TEXT ||
+ n->next->flags & MDOC_LINE)))
p->flags |= TERMP_NOSPACE;
return(1);
}
-
-/* ARGSUSED */
static int
termp__a_pre(DECL_ARGS)
{
return(1);
}
-
-/* ARGSUSED */
static int
termp_an_pre(DECL_ARGS)
{
* with other macros/text, are split. -split, in this case,
* will override the condition of the implied first -nosplit.
*/
-
+
if (n->sec == SEC_AUTHORS) {
if ( ! (TERMP_ANPREC & p->flags)) {
if (TERMP_SPLIT & p->flags)
return(1);
}
-
-/* ARGSUSED */
static void
termp_an_post(DECL_ARGS)
{
}
-
-/* ARGSUSED */
static int
termp_ns_pre(DECL_ARGS)
{
return(1);
}
-
-/* ARGSUSED */
static int
termp_rs_pre(DECL_ARGS)
{
return(1);
}
-
-/* ARGSUSED */
static int
termp_rv_pre(DECL_ARGS)
{
int nchild;
term_newln(p);
- term_word(p, "The");
nchild = n->nchild;
- for (n = n->child; n; n = n->next) {
- term_fontpush(p, TERMFONT_BOLD);
- term_word(p, n->string);
- term_fontpop(p);
+ if (nchild > 0) {
+ term_word(p, "The");
- p->flags |= TERMP_NOSPACE;
- term_word(p, "()");
+ for (n = n->child; n; n = n->next) {
+ term_fontpush(p, TERMFONT_BOLD);
+ term_word(p, n->string);
+ term_fontpop(p);
- if (nchild > 2 && n->next) {
p->flags |= TERMP_NOSPACE;
- term_word(p, ",");
+ term_word(p, "()");
+
+ if (n->next == NULL)
+ continue;
+
+ if (nchild > 2) {
+ p->flags |= TERMP_NOSPACE;
+ term_word(p, ",");
+ }
+ if (n->next->next == NULL)
+ term_word(p, "and");
}
- if (n->next && NULL == n->next->next)
- term_word(p, "and");
- }
+ if (nchild > 1)
+ term_word(p, "functions return");
+ else
+ term_word(p, "function returns");
- if (nchild > 1)
- term_word(p, "functions return");
- else
- term_word(p, "function returns");
+ term_word(p, "the value\\~0 if successful;");
+ } else
+ term_word(p, "Upon successful completion,"
+ " the value\\~0 is returned;");
- term_word(p, "the value 0 if successful; otherwise the value "
- "-1 is returned and the global variable");
+ term_word(p, "otherwise the value\\~\\-1 is returned"
+ " and the global variable");
term_fontpush(p, TERMFONT_UNDER);
term_word(p, "errno");
term_fontpop(p);
- term_word(p, "is set to indicate the error.");
+ term_word(p, "is set to indicate the error.");
p->flags |= TERMP_SENTENCE;
return(0);
}
-
-/* ARGSUSED */
static int
termp_ex_pre(DECL_ARGS)
{
}
if (nchild > 1)
- term_word(p, "utilities exit");
+ term_word(p, "utilities exit\\~0");
else
- term_word(p, "utility exits");
+ term_word(p, "utility exits\\~0");
- term_word(p, "0 on success, and >0 if an error occurs.");
+ term_word(p, "on success, and\\~>0 if an error occurs.");
p->flags |= TERMP_SENTENCE;
return(0);
}
-
-/* ARGSUSED */
static int
termp_nd_pre(DECL_ARGS)
{
return(1);
}
-
-/* ARGSUSED */
static int
termp_bl_pre(DECL_ARGS)
{
return(MDOC_HEAD != n->type);
}
-
-/* ARGSUSED */
static void
termp_bl_post(DECL_ARGS)
{
term_newln(p);
}
-/* ARGSUSED */
static int
termp_xr_pre(DECL_ARGS)
{
assert(MDOC_TEXT == n->type);
term_word(p, n->string);
- if (NULL == (n = n->next))
+ if (NULL == (n = n->next))
return(0);
p->flags |= TERMP_NOSPACE;
static void
synopsis_pre(struct termp *p, const struct mdoc_node *n)
{
- /*
+ /*
* Obviously, if we're not in a SYNOPSIS or no prior macros
* exist, do nothing.
*/
* newline and return. UNLESS we're `Fo', `Fn', `Fn', in which
* case we soldier on.
*/
- if (n->prev->tok == n->tok &&
- MDOC_Ft != n->tok &&
- MDOC_Fo != n->tok &&
- MDOC_Fn != n->tok) {
+ if (n->prev->tok == n->tok &&
+ MDOC_Ft != n->tok &&
+ MDOC_Fo != n->tok &&
+ MDOC_Fn != n->tok) {
term_newln(p);
return;
}
* vertical space, else only newline and move on.
*/
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:
term_vspace(p);
break;
- case (MDOC_Ft):
+ case MDOC_Ft:
if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) {
term_vspace(p);
break;
}
}
-
static int
termp_vt_pre(DECL_ARGS)
{
return(termp_under_pre(p, pair, meta, n));
}
-
-/* ARGSUSED */
static int
termp_bold_pre(DECL_ARGS)
{
return(1);
}
-
-/* ARGSUSED */
static int
termp_fd_pre(DECL_ARGS)
{
return(termp_bold_pre(p, pair, meta, n));
}
-
-/* ARGSUSED */
static void
termp_fd_post(DECL_ARGS)
{
term_newln(p);
}
-
-/* ARGSUSED */
static int
termp_sh_pre(DECL_ARGS)
{
/* No vspace between consecutive `Sh' calls. */
switch (n->type) {
- case (MDOC_BLOCK):
+ case MDOC_BLOCK:
if (n->prev && MDOC_Sh == n->prev->tok)
if (NULL == n->prev->body->child)
break;
term_vspace(p);
break;
- case (MDOC_HEAD):
+ case MDOC_HEAD:
term_fontpush(p, TERMFONT_BOLD);
break;
- case (MDOC_BODY):
+ case MDOC_BODY:
p->offset = term_len(p, p->defindent);
if (SEC_AUTHORS == n->sec)
p->flags &= ~(TERMP_SPLIT|TERMP_NOSPLIT);
return(1);
}
-
-/* ARGSUSED */
static void
termp_sh_post(DECL_ARGS)
{
switch (n->type) {
- case (MDOC_HEAD):
+ case MDOC_HEAD:
term_newln(p);
break;
- case (MDOC_BODY):
+ case MDOC_BODY:
term_newln(p);
p->offset = 0;
break;
}
}
-
-/* ARGSUSED */
static int
termp_bt_pre(DECL_ARGS)
{
return(0);
}
-
-/* ARGSUSED */
static void
termp_lb_post(DECL_ARGS)
{
term_newln(p);
}
-
-/* ARGSUSED */
static int
termp_ud_pre(DECL_ARGS)
{
return(0);
}
-
-/* ARGSUSED */
static int
termp_d1_pre(DECL_ARGS)
{
return(1);
}
-
-/* ARGSUSED */
static int
termp_ft_pre(DECL_ARGS)
{
return(1);
}
-
-/* ARGSUSED */
static int
termp_fn_pre(DECL_ARGS)
{
+ size_t rmargin = 0;
int pretty;
pretty = MDOC_SYNPRETTY & n->flags;
if (NULL == (n = n->child))
return(0);
+ if (pretty) {
+ rmargin = p->rmargin;
+ p->rmargin = p->offset + term_len(p, 4);
+ p->flags |= TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG;
+ }
+
assert(MDOC_TEXT == n->type);
term_fontpush(p, TERMFONT_BOLD);
term_word(p, n->string);
term_fontpop(p);
+ if (pretty) {
+ term_flushln(p);
+ p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG);
+ p->offset = p->rmargin;
+ p->rmargin = rmargin;
+ }
+
p->flags |= TERMP_NOSPACE;
term_word(p, "(");
p->flags |= TERMP_NOSPACE;
for (n = n->next; n; n = n->next) {
assert(MDOC_TEXT == n->type);
term_fontpush(p, TERMFONT_UNDER);
+ if (pretty)
+ p->flags |= TERMP_NBRWORD;
term_word(p, n->string);
term_fontpop(p);
if (pretty) {
p->flags |= TERMP_NOSPACE;
term_word(p, ";");
+ term_flushln(p);
}
return(0);
}
-
-/* ARGSUSED */
static int
termp_fa_pre(DECL_ARGS)
{
for (nn = n->child; nn; nn = nn->next) {
term_fontpush(p, TERMFONT_UNDER);
+ p->flags |= TERMP_NBRWORD;
term_word(p, nn->string);
term_fontpop(p);
- if (nn->next) {
+ if (nn->next || (n->next && n->next->tok == MDOC_Fa)) {
p->flags |= TERMP_NOSPACE;
term_word(p, ",");
}
}
- if (n->child && n->next && n->next->tok == MDOC_Fa) {
- p->flags |= TERMP_NOSPACE;
- term_word(p, ",");
- }
-
return(0);
}
-
-/* ARGSUSED */
static int
termp_bd_pre(DECL_ARGS)
{
- size_t tabwidth, rm, rmax;
+ size_t tabwidth, lm, len, rm, rmax;
struct mdoc_node *nn;
if (MDOC_BLOCK == n->type) {
* for macro lines, a newline is appended to the line. Blank
* lines are allowed.
*/
-
- if (DISP_literal != n->norm->Bd.type &&
- DISP_unfilled != n->norm->Bd.type)
+
+ if (DISP_literal != n->norm->Bd.type &&
+ DISP_unfilled != n->norm->Bd.type &&
+ DISP_centered != n->norm->Bd.type)
return(1);
tabwidth = p->tabwidth;
if (DISP_literal == n->norm->Bd.type)
p->tabwidth = term_len(p, 8);
+ lm = p->offset;
rm = p->rmargin;
rmax = p->maxrmargin;
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
for (nn = n->child; nn; nn = nn->next) {
+ if (DISP_centered == n->norm->Bd.type) {
+ if (MDOC_TEXT == nn->type) {
+ len = term_strlen(p, nn->string);
+ p->offset = len >= rm ? 0 :
+ lm + len >= rm ? rm - len :
+ (lm + rm - len) / 2;
+ } else
+ p->offset = lm;
+ }
print_mdoc_node(p, pair, meta, nn);
/*
* If the printed node flushes its own line, then we
* anyway, so don't sweat it.
*/
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;
default:
break;
return(0);
}
-
-/* ARGSUSED */
static void
termp_bd_post(DECL_ARGS)
{
size_t rm, rmax;
- if (MDOC_BODY != n->type)
+ if (MDOC_BODY != n->type)
return;
rm = p->rmargin;
rmax = p->maxrmargin;
- if (DISP_literal == n->norm->Bd.type ||
- DISP_unfilled == n->norm->Bd.type)
+ if (DISP_literal == n->norm->Bd.type ||
+ DISP_unfilled == n->norm->Bd.type)
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
p->flags |= TERMP_NOSPACE;
p->maxrmargin = rmax;
}
-
-/* ARGSUSED */
static int
termp_bx_pre(DECL_ARGS)
{
return(0);
}
-
-/* ARGSUSED */
static int
termp_xx_pre(DECL_ARGS)
{
pp = NULL;
switch (n->tok) {
- case (MDOC_Bsx):
+ case MDOC_Bsx:
pp = "BSD/OS";
break;
- case (MDOC_Dx):
+ case MDOC_Dx:
pp = "DragonFly";
break;
- case (MDOC_Fx):
+ case MDOC_Fx:
pp = "FreeBSD";
break;
- case (MDOC_Nx):
+ case MDOC_Nx:
pp = "NetBSD";
break;
- case (MDOC_Ox):
+ case MDOC_Ox:
pp = "OpenBSD";
break;
- case (MDOC_Ux):
+ case MDOC_Ux:
pp = "UNIX";
break;
default:
return(0);
}
-
-/* ARGSUSED */
-static int
-termp_igndelim_pre(DECL_ARGS)
-{
-
- p->flags |= TERMP_IGNDELIM;
- return(1);
-}
-
-
-/* ARGSUSED */
static void
termp_pf_post(DECL_ARGS)
{
p->flags |= TERMP_NOSPACE;
}
-
-/* ARGSUSED */
static int
termp_ss_pre(DECL_ARGS)
{
switch (n->type) {
- case (MDOC_BLOCK):
+ case MDOC_BLOCK:
term_newln(p);
if (n->prev)
term_vspace(p);
break;
- case (MDOC_HEAD):
+ case MDOC_HEAD:
term_fontpush(p, TERMFONT_BOLD);
p->offset = term_len(p, (p->defindent+1)/2);
break;
+ case MDOC_BODY:
+ p->offset = term_len(p, p->defindent);
+ break;
default:
break;
}
return(1);
}
-
-/* ARGSUSED */
static void
termp_ss_post(DECL_ARGS)
{
- if (MDOC_HEAD == n->type)
+ if (n->type == MDOC_HEAD || n->type == MDOC_BODY)
term_newln(p);
}
-
-/* ARGSUSED */
static int
termp_cd_pre(DECL_ARGS)
{
return(1);
}
-
-/* ARGSUSED */
static int
termp_in_pre(DECL_ARGS)
{
return(1);
}
-
-/* ARGSUSED */
static void
termp_in_post(DECL_ARGS)
{
term_fontpop(p);
}
-
-/* ARGSUSED */
static int
termp_sp_pre(DECL_ARGS)
{
size_t i, len;
switch (n->tok) {
- case (MDOC_sp):
+ case MDOC_sp:
len = n->child ? a2height(p, n->child->string) : 1;
break;
- case (MDOC_br):
+ case MDOC_br:
len = 0;
break;
default:
return(0);
}
+static int
+termp_es_pre(DECL_ARGS)
+{
+
+ return(0);
+}
-/* ARGSUSED */
static int
termp_quote_pre(DECL_ARGS)
{
return(1);
switch (n->tok) {
- case (MDOC_Ao):
+ case MDOC_Ao:
/* FALLTHROUGH */
- case (MDOC_Aq):
+ case MDOC_Aq:
term_word(p, "<");
break;
- case (MDOC_Bro):
+ case MDOC_Bro:
/* FALLTHROUGH */
- case (MDOC_Brq):
+ case MDOC_Brq:
term_word(p, "{");
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:
term_word(p, "[");
break;
- case (MDOC_Do):
+ case MDOC_Do:
/* FALLTHROUGH */
- case (MDOC_Dq):
+ case MDOC_Dq:
term_word(p, "\\(lq");
break;
- case (MDOC_Eo):
+ case MDOC_En:
+ if (NULL == n->norm->Es ||
+ NULL == n->norm->Es->child)
+ return(1);
+ term_word(p, n->norm->Es->child->string);
+ break;
+ case MDOC_Eo:
break;
- case (MDOC_Po):
+ case MDOC_Po:
/* FALLTHROUGH */
- case (MDOC_Pq):
+ case MDOC_Pq:
term_word(p, "(");
break;
- case (MDOC__T):
+ case MDOC__T:
/* FALLTHROUGH */
- case (MDOC_Qo):
+ case MDOC_Qo:
/* FALLTHROUGH */
- case (MDOC_Qq):
+ case MDOC_Qq:
term_word(p, "\"");
break;
- case (MDOC_Ql):
+ case MDOC_Ql:
/* FALLTHROUGH */
- case (MDOC_So):
+ case MDOC_So:
/* FALLTHROUGH */
- case (MDOC_Sq):
+ case MDOC_Sq:
term_word(p, "\\(oq");
break;
default:
return(1);
}
-
-/* ARGSUSED */
static void
termp_quote_post(DECL_ARGS)
{
if (MDOC_BODY != n->type && MDOC_ELEM != n->type)
return;
- p->flags |= TERMP_NOSPACE;
+ if (MDOC_En != n->tok)
+ p->flags |= TERMP_NOSPACE;
switch (n->tok) {
- case (MDOC_Ao):
+ case MDOC_Ao:
/* FALLTHROUGH */
- case (MDOC_Aq):
+ case MDOC_Aq:
term_word(p, ">");
break;
- case (MDOC_Bro):
+ case MDOC_Bro:
/* FALLTHROUGH */
- case (MDOC_Brq):
+ case MDOC_Brq:
term_word(p, "}");
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:
term_word(p, "]");
break;
- case (MDOC_Do):
+ case MDOC_Do:
/* FALLTHROUGH */
- case (MDOC_Dq):
+ case MDOC_Dq:
term_word(p, "\\(rq");
break;
- case (MDOC_Eo):
+ case MDOC_En:
+ if (NULL != n->norm->Es &&
+ NULL != n->norm->Es->child &&
+ NULL != n->norm->Es->child->next) {
+ p->flags |= TERMP_NOSPACE;
+ term_word(p, n->norm->Es->child->next->string);
+ }
+ break;
+ case MDOC_Eo:
break;
- case (MDOC_Po):
+ case MDOC_Po:
/* FALLTHROUGH */
- case (MDOC_Pq):
+ case MDOC_Pq:
term_word(p, ")");
break;
- case (MDOC__T):
+ case MDOC__T:
/* FALLTHROUGH */
- case (MDOC_Qo):
+ case MDOC_Qo:
/* FALLTHROUGH */
- case (MDOC_Qq):
+ case MDOC_Qq:
term_word(p, "\"");
break;
- case (MDOC_Ql):
+ case MDOC_Ql:
/* FALLTHROUGH */
- case (MDOC_So):
+ case MDOC_So:
/* FALLTHROUGH */
- case (MDOC_Sq):
+ case MDOC_Sq:
term_word(p, "\\(cq");
break;
default:
}
}
-
-/* ARGSUSED */
static int
termp_fo_pre(DECL_ARGS)
{
+ size_t rmargin = 0;
+ int pretty;
+
+ pretty = MDOC_SYNPRETTY & n->flags;
if (MDOC_BLOCK == n->type) {
synopsis_pre(p, n);
return(1);
} else if (MDOC_BODY == n->type) {
+ if (pretty) {
+ rmargin = p->rmargin;
+ p->rmargin = p->offset + term_len(p, 4);
+ p->flags |= TERMP_NOBREAK | TERMP_BRIND |
+ TERMP_HANG;
+ }
p->flags |= TERMP_NOSPACE;
term_word(p, "(");
p->flags |= TERMP_NOSPACE;
+ if (pretty) {
+ term_flushln(p);
+ p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND |
+ TERMP_HANG);
+ p->offset = p->rmargin;
+ p->rmargin = rmargin;
+ }
return(1);
- }
+ }
if (NULL == n->child)
return(0);
return(0);
}
-
-/* ARGSUSED */
static void
termp_fo_post(DECL_ARGS)
{
- if (MDOC_BODY != n->type)
+ if (MDOC_BODY != n->type)
return;
p->flags |= TERMP_NOSPACE;
if (MDOC_SYNPRETTY & n->flags) {
p->flags |= TERMP_NOSPACE;
term_word(p, ";");
+ term_flushln(p);
}
}
-
-/* ARGSUSED */
static int
termp_bf_pre(DECL_ARGS)
{
else if (MDOC_BODY != n->type)
return(1);
- if (FONT_Em == n->norm->Bf.font)
+ if (FONT_Em == n->norm->Bf.font)
term_fontpush(p, TERMFONT_UNDER);
- else if (FONT_Sy == n->norm->Bf.font)
+ else if (FONT_Sy == n->norm->Bf.font)
term_fontpush(p, TERMFONT_BOLD);
- else
+ else
term_fontpush(p, TERMFONT_NONE);
return(1);
}
-
-/* ARGSUSED */
static int
termp_sm_pre(DECL_ARGS)
{
- assert(n->child && MDOC_TEXT == n->child->type);
- if (0 == strcmp("on", n->child->string)) {
- if (p->col)
- p->flags &= ~TERMP_NOSPACE;
+ if (NULL == n->child)
+ p->flags ^= TERMP_NONOSPACE;
+ else if (0 == strcmp("on", n->child->string))
p->flags &= ~TERMP_NONOSPACE;
- } else
+ else
p->flags |= TERMP_NONOSPACE;
+ if (p->col && ! (TERMP_NONOSPACE & p->flags))
+ p->flags &= ~TERMP_NOSPACE;
+
return(0);
}
-
-/* ARGSUSED */
static int
termp_ap_pre(DECL_ARGS)
{
return(1);
}
-
-/* ARGSUSED */
static void
termp____post(DECL_ARGS)
{
term_word(p, ",");
}
-
-/* ARGSUSED */
static int
termp_li_pre(DECL_ARGS)
{
return(1);
}
-
-/* ARGSUSED */
static int
termp_lk_pre(DECL_ARGS)
{
return(0);
}
-
-/* ARGSUSED */
static int
termp_bk_pre(DECL_ARGS)
{
switch (n->type) {
- case (MDOC_BLOCK):
+ case MDOC_BLOCK:
break;
- case (MDOC_HEAD):
+ case MDOC_HEAD:
return(0);
- case (MDOC_BODY):
+ case MDOC_BODY:
if (n->parent->args || 0 == n->prev->nchild)
p->flags |= TERMP_PREKEEP;
break;
return(1);
}
-
-/* ARGSUSED */
static void
termp_bk_post(DECL_ARGS)
{
- if (MDOC_BODY == n->type && ! (MDOC_SYNPRETTY & n->flags))
+ if (MDOC_BODY == n->type)
p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
}
-/* ARGSUSED */
static void
termp__t_post(DECL_ARGS)
{
* us instead of underlining us (for disambiguation).
*/
if (n->parent && MDOC_Rs == n->parent->tok &&
- n->parent->norm->Rs.quote_T)
+ n->parent->norm->Rs.quote_T)
termp_quote_post(p, pair, meta, n);
termp____post(p, pair, meta, n);
}
-/* ARGSUSED */
static int
termp__t_pre(DECL_ARGS)
{
* us instead of underlining us (for disambiguation).
*/
if (n->parent && MDOC_Rs == n->parent->tok &&
- n->parent->norm->Rs.quote_T)
+ n->parent->norm->Rs.quote_T)
return(termp_quote_pre(p, pair, meta, n));
term_fontpush(p, TERMFONT_UNDER);
return(1);
}
-/* ARGSUSED */
static int
termp_under_pre(DECL_ARGS)
{