tech@mandoc.bsd.lv
 help / color / mirror / Atom feed
From: Joerg Sonnenberger <joerg@britannica.bec.de>
To: tech@mdocml.bsd.lv
Subject: .SH + .SS spacing, 2nd try
Date: Sat, 22 May 2010 23:26:27 +0200	[thread overview]
Message-ID: <20100522212627.GA12303@britannica.bec.de> (raw)

[-- Attachment #1: Type: text/plain, Size: 371 bytes --]

Hi guys,
this is the second try of getting the .SH and .SS vertical space
correct.  Basically three things need to be done:
- handle trailing .SS without body as last node
- handle sections / header that only only .AT, .UC or empty paragraphs
- handle empty paragraphs following paragraphs

This doesn't seem to add any regressions from what I can tell. Comments?

Joerg

[-- Attachment #2: ss+sh-spacing.diff --]
[-- Type: text/plain, Size: 3984 bytes --]

Index: man_term.c
===================================================================
RCS file: /home/joerg/cvsroot/mdocml/man_term.c,v
retrieving revision 1.71
diff -u -p -r1.71 man_term.c
--- man_term.c	17 May 2010 22:11:42 -0000	1.71
+++ man_term.c	22 May 2010 21:11:47 -0000
@@ -78,7 +78,7 @@ static	void		  print_man_head(struct ter
 static	void		  print_man_nodelist(DECL_ARGS);
 static	void		  print_man_node(DECL_ARGS);
 static	void		  print_man_foot(struct termp *, 
-				const struct man_meta *);
+				const struct man_meta *, const struct man *);
 static	void		  print_bvspace(struct termp *, 
 				const struct man_node *);
 
@@ -183,7 +183,7 @@ terminal_man(void *arg, const struct man
 
 	if (n->child)
 		print_man_nodelist(p, &mt, n->child, m);
-	print_man_foot(p, m);
+	print_man_foot(p, m, man);
 }
 
 
@@ -227,6 +227,9 @@ print_bvspace(struct termp *p, const str
 		return;
 	if (MAN_SH == n->prev->tok)
 		return;
+	if (MAN_PP == n->tok && MAN_PP == n->prev->tok &&
+	    NULL == n->body->child)
+		return;
 
 	term_vspace(p);
 }
@@ -641,6 +644,57 @@ post_TP(DECL_ARGS)
 }
 
 
+static void
+print_section_vspace(struct termp *p, const struct man_node *n)
+{
+	const struct man_node *nn;
+
+	nn = n->prev;
+	/* If there is no previous siblings, there is no need for vspace. */
+	if (n->prev == NULL)
+		return;
+
+	/*
+	 * The previous silbing is normally .SH or .SS.  It is possible
+	 * to be another block-level macro at the beginning of the file.
+	 *
+	 * No vspace is needed if the previous sibling of the same type
+	 * (.SH or .SS) without content.  If that sibling is not a .SH or
+	 * .SS, the vspace is not needed if all previous nodes are without
+	 * content.
+	 * 
+	 * .AT, .UC and .PP without children don't count as content.
+	 */
+	if (MAN_SH == nn->tok || MAN_SS == nn->tok) {
+		if (n->tok != nn->tok) {
+			term_vspace(p);
+			return;
+		}
+		if (NULL == nn->body->child)
+			return;
+		nn = nn->body->child;
+	} else {
+		nn = nn->parent->child;
+	}
+
+	for (; nn && n != nn; nn = nn->next) {
+		switch (nn->tok) {
+		case MAN_AT:
+			continue;
+		case MAN_UC:
+			continue;
+		case MAN_PP:
+			if (NULL == nn->body->child)
+				continue;
+			/* FALLTHRU */
+		default:
+			term_vspace(p);
+			return;
+		}
+	}
+}
+
+
 /* ARGSUSED */
 static int
 pre_SS(DECL_ARGS)
@@ -650,13 +704,7 @@ pre_SS(DECL_ARGS)
 	case (MAN_BLOCK):
 		mt->lmargin = INDENT;
 		mt->offset = INDENT;
-		/* If following a prior empty `SS', no vspace. */
-		if (n->prev && MAN_SS == n->prev->tok)
-			if (NULL == n->prev->body->child)
-				break;
-		if (NULL == n->prev)
-			break;
-		term_vspace(p);
+		print_section_vspace(p, n);
 		break;
 	case (MAN_HEAD):
 		term_fontrepl(p, TERMFONT_BOLD);
@@ -700,14 +748,7 @@ pre_SH(DECL_ARGS)
 	case (MAN_BLOCK):
 		mt->lmargin = INDENT;
 		mt->offset = INDENT;
-		/* If following a prior empty `SH', no vspace. */
-		if (n->prev && MAN_SH == n->prev->tok)
-			if (NULL == n->prev->body->child)
-				break;
-		/* If the first macro, no vspae. */
-		if (NULL == n->prev)
-			break;
-		term_vspace(p);
+		print_section_vspace(p, n);
 		break;
 	case (MAN_HEAD):
 		term_fontrepl(p, TERMFONT_BOLD);
@@ -858,17 +899,33 @@ print_man_nodelist(DECL_ARGS)
 
 
 static void
-print_man_foot(struct termp *p, const struct man_meta *meta)
+print_man_foot(struct termp *p, const struct man_meta *meta,
+    const struct man *m)
 {
 	char		buf[DATESIZ];
+	const struct man_node	*n;
 
 	term_fontrepl(p, TERMFONT_NONE);
 
 	time2a(meta->date, buf, DATESIZ);
 
-	term_vspace(p);
-	term_vspace(p);
-	term_vspace(p);
+	/*
+	 * Check if the last node is a .SS without body.
+	 * In that case, no vspace is asserted.
+	 */
+	n = man_node(m);
+	for (;;) {
+		while (n->next)
+			n = n->next;
+		if (NULL == n->child)
+			break;
+		n = n->child;
+	}
+	if (MAN_SS != n->tok || MAN_BODY != n->type) {
+		term_vspace(p);
+		term_vspace(p);
+		term_vspace(p);
+	}
 
 	p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
 	p->rmargin = p->maxrmargin - strlen(buf);

             reply	other threads:[~2010-05-22 21:28 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-22 21:26 Joerg Sonnenberger [this message]
2010-05-24 12:01 ` Ingo Schwarze

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100522212627.GA12303@britannica.bec.de \
    --to=joerg@britannica.bec.de \
    --cc=tech@mdocml.bsd.lv \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).