summaryrefslogtreecommitdiffstats
path: root/mdoc_term.c
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2010-06-07 11:01:15 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2010-06-07 11:01:15 +0000
commit34f23714ec5c9661110c828a4b433def8d068bd8 (patch)
treeb12adeaa4f81681b934c24bfd9fcad086ff064b1 /mdoc_term.c
parentf841f3b77ee7f43443d4bc40a1e8da0ca81dfed7 (diff)
downloadmandoc-34f23714ec5c9661110c828a4b433def8d068bd8.tar.gz
Normalise SYNOPSIS behaviour after I gave up on following groff's
inconsistent behaviour. In short: Some macros are displayed differently in the SYNOPSIS section, particularly Nm, Cd, Fd, Fn, Fo, In, Vt, and Ft. All of these macros are output on their own line. If two such dissimilar macros are pair-wise invoked (except for Ft before Fo or Fn), they are separated by a vertical space, unless in the case of Fo, Fn, and Ft, which are always separated by vertical space. Behaviour ok Jason McIntyre, ingo@. Fallout will be treated case-by-case. I had to clear out some regressions that were testing against groff's stranger behaviours: these will now break, as we don't care about such invocations. Also removed the newline for `Cd' invocation in a non-SYNOPSIS context.
Diffstat (limited to 'mdoc_term.c')
-rw-r--r--mdoc_term.c166
1 files changed, 90 insertions, 76 deletions
diff --git a/mdoc_term.c b/mdoc_term.c
index e62d7219..84583caf 100644
--- a/mdoc_term.c
+++ b/mdoc_term.c
@@ -68,6 +68,8 @@ static void print_mdoc_node(DECL_ARGS);
static void print_mdoc_head(DECL_ARGS);
static void print_mdoc_nodelist(DECL_ARGS);
static void print_foot(DECL_ARGS);
+static void synopsis_pre(struct termp *,
+ const struct mdoc_node *);
static void termp____post(DECL_ARGS);
static void termp_an_post(DECL_ARGS);
@@ -79,8 +81,7 @@ static void termp_brq_post(DECL_ARGS);
static void termp_bx_post(DECL_ARGS);
static void termp_d1_post(DECL_ARGS);
static void termp_dq_post(DECL_ARGS);
-static void termp_fd_post(DECL_ARGS);
-static void termp_fn_post(DECL_ARGS);
+static int termp_fd_pre(DECL_ARGS);
static void termp_fo_post(DECL_ARGS);
static void termp_in_post(DECL_ARGS);
static void termp_it_post(DECL_ARGS);
@@ -92,7 +93,6 @@ static void termp_qq_post(DECL_ARGS);
static void termp_sh_post(DECL_ARGS);
static void termp_sq_post(DECL_ARGS);
static void termp_ss_post(DECL_ARGS);
-static void termp_vt_post(DECL_ARGS);
static int termp_an_pre(DECL_ARGS);
static int termp_ap_pre(DECL_ARGS);
@@ -162,9 +162,9 @@ static const struct termact termacts[MDOC_MAX] = {
{ NULL, NULL }, /* Ev */
{ termp_ex_pre, NULL }, /* Ex */
{ termp_fa_pre, NULL }, /* Fa */
- { termp_bold_pre, termp_fd_post }, /* Fd */
+ { termp_fd_pre, NULL }, /* Fd */
{ termp_fl_pre, NULL }, /* Fl */
- { termp_fn_pre, termp_fn_post }, /* Fn */
+ { termp_fn_pre, NULL }, /* Fn */
{ termp_ft_pre, NULL }, /* Ft */
{ termp_bold_pre, NULL }, /* Ic */
{ termp_in_pre, termp_in_post }, /* In */
@@ -177,7 +177,7 @@ static const struct termact termacts[MDOC_MAX] = {
{ termp_rv_pre, NULL }, /* Rv */
{ NULL, NULL }, /* St */
{ termp_under_pre, NULL }, /* Va */
- { termp_vt_pre, termp_vt_post }, /* Vt */
+ { termp_vt_pre, NULL }, /* Vt */
{ termp_xr_pre, NULL }, /* Xr */
{ NULL, termp____post }, /* %A */
{ termp_under_pre, termp____post }, /* %B */
@@ -1055,14 +1055,11 @@ termp_nm_pre(DECL_ARGS)
if (NULL == n->child && NULL == m->name)
return(1);
- if (SEC_SYNOPSIS == n->sec && MDOC_LINE & n->flags)
- term_newln(p);
+ synopsis_pre(p, n);
term_fontpush(p, TERMFONT_BOLD);
-
if (NULL == n->child)
term_word(p, m->name);
-
return(1);
}
@@ -1313,32 +1310,78 @@ termp_xr_pre(DECL_ARGS)
}
-static int
-termp_vt_pre(DECL_ARGS)
+/*
+ * This decides how to assert whitespace before any of the SYNOPSIS set
+ * of macros (which, as in the case of Ft/Fo and Ft/Fn, may contain
+ * macro combos).
+ */
+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.
+ */
+ if (NULL == n->prev || SEC_SYNOPSIS != n->sec)
+ return;
- if (MDOC_ELEM == n->type)
- return(termp_under_pre(p, pair, m, n));
- else if (MDOC_HEAD == n->type)
- return(0);
- else if (MDOC_BLOCK == n->type)
- return(1);
+ /*
+ * If we're the second in a pair of like elements, emit our
+ * 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) {
+ term_newln(p);
+ return;
+ }
- return(termp_under_pre(p, pair, m, n));
+ /*
+ * If we're one of the SYNOPSIS set and non-like pair-wise after
+ * another (or Fn/Fo, which we've let slip through) then assert
+ * vertical space, else only newline and move on.
+ */
+ switch (n->prev->tok) {
+ case (MDOC_Fd):
+ /* FALLTHROUGH */
+ case (MDOC_Fn):
+ /* FALLTHROUGH */
+ case (MDOC_Fo):
+ /* FALLTHROUGH */
+ case (MDOC_In):
+ /* FALLTHROUGH */
+ case (MDOC_Vt):
+ term_vspace(p);
+ break;
+ case (MDOC_Ft):
+ if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) {
+ term_vspace(p);
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ term_newln(p);
+ break;
+ }
}
-/* ARGSUSED */
-static void
-termp_vt_post(DECL_ARGS)
+static int
+termp_vt_pre(DECL_ARGS)
{
- if (MDOC_BLOCK != n->type)
- return;
- if (n->next && MDOC_Vt == n->next->tok)
- term_newln(p);
- else if (n->next)
- term_vspace(p);
+ if (MDOC_ELEM == n->type) {
+ synopsis_pre(p, n);
+ return(termp_under_pre(p, pair, m, n));
+ } else if (MDOC_BLOCK == n->type) {
+ synopsis_pre(p, n);
+ return(1);
+ } else if (MDOC_HEAD == n->type)
+ return(0);
+
+ return(termp_under_pre(p, pair, m, n));
}
@@ -1353,11 +1396,12 @@ termp_bold_pre(DECL_ARGS)
/* ARGSUSED */
-static void
-termp_fd_post(DECL_ARGS)
+static int
+termp_fd_pre(DECL_ARGS)
{
- term_newln(p);
+ synopsis_pre(p, n);
+ return(termp_bold_pre(p, pair, m, n));
}
@@ -1511,9 +1555,7 @@ termp_ft_pre(DECL_ARGS)
{
/* NB: MDOC_LINE does not effect this! */
- if (SEC_SYNOPSIS == n->sec && n->prev)
- term_vspace(p);
-
+ synopsis_pre(p, n);
term_fontpush(p, TERMFONT_UNDER);
return(1);
}
@@ -1525,13 +1567,7 @@ termp_fn_pre(DECL_ARGS)
{
const struct mdoc_node *nn;
- /* NB: MDOC_LINE has no effect on this macro! */
- if (SEC_SYNOPSIS == n->sec) {
- if (n->prev && MDOC_Ft == n->prev->tok)
- term_newln(p);
- else if (n->prev)
- term_vspace(p);
- }
+ synopsis_pre(p, n);
term_fontpush(p, TERMFONT_BOLD);
term_word(p, n->child->string);
@@ -1559,17 +1595,6 @@ termp_fn_pre(DECL_ARGS)
/* ARGSUSED */
-static void
-termp_fn_post(DECL_ARGS)
-{
-
- /* NB: MDOC_LINE has no effect on this macro! */
- if (SEC_SYNOPSIS == n->sec)
- term_newln(p);
-}
-
-
-/* ARGSUSED */
static int
termp_fa_pre(DECL_ARGS)
{
@@ -1834,8 +1859,8 @@ static int
termp_cd_pre(DECL_ARGS)
{
+ synopsis_pre(p, n);
term_fontpush(p, TERMFONT_BOLD);
- term_newln(p);
return(1);
}
@@ -1845,8 +1870,7 @@ static int
termp_in_pre(DECL_ARGS)
{
- if (SEC_SYNOPSIS == n->sec && n->prev && MDOC_In != n->prev->tok)
- term_vspace(p);
+ synopsis_pre(p, n);
if (SEC_SYNOPSIS == n->sec && MDOC_LINE & n->flags) {
term_fontpush(p, TERMFONT_BOLD);
@@ -1867,16 +1891,14 @@ static void
termp_in_post(DECL_ARGS)
{
- if (SEC_SYNOPSIS == n->sec && MDOC_LINE & n->flags)
+ if (SEC_SYNOPSIS == n->sec)
term_fontpush(p, TERMFONT_BOLD);
p->flags |= TERMP_NOSPACE;
term_word(p, ">");
- if (SEC_SYNOPSIS == n->sec && MDOC_LINE & n->flags) {
+ if (SEC_SYNOPSIS == n->sec)
term_fontpop(p);
- term_newln(p);
- }
}
@@ -1987,13 +2009,7 @@ termp_fo_pre(DECL_ARGS)
{
if (MDOC_BLOCK == n->type) {
- /* NB: MDOC_LINE has no effect on this macro! */
- if (SEC_SYNOPSIS != n->sec)
- return(1);
- if (n->prev && MDOC_Ft == n->prev->tok)
- term_newln(p);
- else if (n->prev)
- term_vspace(p);
+ synopsis_pre(p, n);
return(1);
} else if (MDOC_BODY == n->type) {
p->flags |= TERMP_NOSPACE;
@@ -2017,17 +2033,15 @@ static void
termp_fo_post(DECL_ARGS)
{
- if (MDOC_BLOCK == n->type) {
- /* NB: MDOC_LINE has no effect on this macro! */
- if (SEC_SYNOPSIS == n->sec)
- term_newln(p);
- } else if (MDOC_BODY == n->type) {
+ if (MDOC_BODY != n->type)
+ return;
+
+ p->flags |= TERMP_NOSPACE;
+ term_word(p, ")");
+
+ if (SEC_SYNOPSIS == n->sec) {
p->flags |= TERMP_NOSPACE;
- term_word(p, ")");
- if (SEC_SYNOPSIS == n->sec) {
- p->flags |= TERMP_NOSPACE;
- term_word(p, ";");
- }
+ term_word(p, ";");
}
}