X-Git-Url: https://git.cameronkatri.com/mandoc.git/blobdiff_plain/f633d3ad738687c0ad18d8ce9fb451cdffce7a3c..5851ee4d2b64ce06c48c8cfb740d681250066ca5:/mdocterm.c

diff --git a/mdocterm.c b/mdocterm.c
index b79904cc..9a344639 100644
--- a/mdocterm.c
+++ b/mdocterm.c
@@ -1,4 +1,4 @@
-/* $Id: mdocterm.c,v 1.11 2009/02/25 13:30:53 kristaps Exp $ */
+/* $Id: mdocterm.c,v 1.13 2009/02/25 17:02:47 kristaps Exp $ */
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -44,6 +44,7 @@ enum	termstyle {
 };
 
 static	void		  body(struct termp *,
+				struct termpair *,
 				const struct mdoc_meta *,
 				const struct mdoc_node *);
 static	void		  header(struct termp *,
@@ -54,6 +55,8 @@ static	void		  footer(struct termp *,
 static	void		  pword(struct termp *, const char *, size_t);
 static	void		  pescape(struct termp *, 
 				const char *, size_t *, size_t);
+static	void		  nescape(struct termp *, 
+				const char *, size_t);
 static	void		  chara(struct termp *, char);
 static	void		  stringa(struct termp *, const char *);
 static	void		  style(struct termp *, enum termstyle);
@@ -89,7 +92,7 @@ main(int argc, char *argv[])
 		err(1, "malloc");
 
 	header(&termp, mdoc_meta(mdoc));
-	body(&termp, mdoc_meta(mdoc), mdoc_node(mdoc));
+	body(&termp, NULL, mdoc_meta(mdoc), mdoc_node(mdoc));
 	footer(&termp, mdoc_meta(mdoc));
 
 	free(termp.buf);
@@ -218,8 +221,10 @@ newln(struct termp *p)
 	 * vertical space.
 	 */
 	p->flags |= TERMP_NOSPACE;
-	if (0 == p->col) 
+	if (0 == p->col) {
+		p->flags &= ~TERMP_NOLPAD;
 		return;
+	}
 	flushln(p);
 	p->flags &= ~TERMP_NOLPAD;
 }
@@ -286,9 +291,37 @@ style(struct termp *p, enum termstyle esc)
 }
 
 
+static void
+nescape(struct termp *p, const char *word, size_t len)
+{
+
+	switch (len) {
+	case (2):
+		if ('r' == word[0] && 'B' == word[1])
+			chara(p, ']');
+		else if ('l' == word[0] && 'B' == word[1])
+			chara(p, '[');
+		else if ('<' == word[0] && '-' == word[1])
+			stringa(p, "<-");
+		else if ('-' == word[0] && '>' == word[1])
+			stringa(p, "->");
+		else if ('l' == word[0] && 'q' == word[1])
+			chara(p, '\"');
+		else if ('r' == word[0] && 'q' == word[1])
+			chara(p, '\"');
+		else if ('b' == word[0] && 'u' == word[1])
+			chara(p, 'o');
+		break;
+	default:
+		break;
+	}
+}
+
+
 static void
 pescape(struct termp *p, const char *word, size_t *i, size_t len)
 {
+	size_t		 j;
 
 	(*i)++;
 	assert(*i < len);
@@ -297,20 +330,7 @@ pescape(struct termp *p, const char *word, size_t *i, size_t len)
 		/* Two-character escapes. */
 		(*i)++;
 		assert(*i + 1 < len);
-
-		if ('r' == word[*i] && 'B' == word[*i + 1])
-			chara(p, ']');
-		else if ('l' == word[*i] && 'B' == word[*i + 1])
-			chara(p, '[');
-		else if ('<' == word[*i] && '-' == word[*i + 1])
-			stringa(p, "<-");
-		else if ('-' == word[*i] && '>' == word[*i + 1])
-			stringa(p, "->");
-		else if ('l' == word[*i] && 'q' == word[*i + 1])
-			chara(p, '\"');
-		else if ('r' == word[*i] && 'q' == word[*i + 1])
-			chara(p, '\"');
-
+		nescape(p, &word[*i], 2);
 		(*i)++;
 		return;
 
@@ -325,6 +345,8 @@ pescape(struct termp *p, const char *word, size_t *i, size_t len)
 			/* FALLTHROUGH */
 		case ('-'):
 			/* FALLTHROUGH */
+		case (' '):
+			/* FALLTHROUGH */
 		case ('.'):
 			chara(p, word[*i]);
 		default:
@@ -332,7 +354,12 @@ pescape(struct termp *p, const char *word, size_t *i, size_t len)
 		}
 		return;
 	}
-	/* n-character escapes. */
+
+	(*i)++;
+	for (j = 0; word[*i] && ']' != word[*i]; (*i)++, j++)
+		/* Loop... */ ;
+
+	nescape(p, &word[*i - j], j);
 }
 
 
@@ -347,7 +374,8 @@ pword(struct termp *p, const char *word, size_t len)
 			! (p->flags & TERMP_LITERAL))
 		chara(p, ' ');
 
-	p->flags &= ~TERMP_NOSPACE;
+	if ( ! (p->flags & TERMP_NONOSPACE))
+		p->flags &= ~TERMP_NOSPACE;
 
 	if (p->flags & TERMP_BOLD)
 		style(p, STYLE_BOLD);
@@ -407,7 +435,8 @@ word(struct termp *p, const char *word)
 
 
 static void
-body(struct termp *p, const struct mdoc_meta *meta,
+body(struct termp *p, struct termpair *ppair,
+		const struct mdoc_meta *meta,
 		const struct mdoc_node *node)
 {
 	int		 dochild;
@@ -416,9 +445,11 @@ body(struct termp *p, const struct mdoc_meta *meta,
 	/* Pre-processing. */
 
 	dochild = 1;
+	pair.ppair = ppair;
 	pair.type = 0;
 	pair.offset = pair.rmargin = 0;
 	pair.flag = 0;
+	pair.count = 0;
 
 	if (MDOC_TEXT != node->type) {
 		if (termacts[node->tok].pre)
@@ -433,7 +464,7 @@ body(struct termp *p, const struct mdoc_meta *meta,
 		p->flags |= pair.flag;
 
 	if (dochild && node->child)
-		body(p, meta, node->child);
+		body(p, &pair, meta, node->child);
 
 	if (TERMPAIR_FLAG & pair.type)
 		p->flags &= ~pair.flag;
@@ -447,7 +478,7 @@ body(struct termp *p, const struct mdoc_meta *meta,
 	/* Siblings. */
 
 	if (node->next)
-		body(p, meta, node->next);
+		body(p, ppair, meta, node->next);
 }
 
 
@@ -502,8 +533,7 @@ static void
 header(struct termp *p, const struct mdoc_meta *meta)
 {
 	char		*buf, *title;
-	const char	*pp, *msec;
-	size_t		 ssz, tsz, ttsz, i;;
+	const char	*pp;
 
 	if (NULL == (buf = malloc(p->rmargin)))
 		err(1, "malloc");
@@ -540,50 +570,44 @@ header(struct termp *p, const struct mdoc_meta *meta)
 				pp = mdoc_msec2a(MSEC_local);
 			break;
 		}
-	assert(pp);
-
-	tsz = strlcpy(buf, pp, p->rmargin);
-	assert(tsz < p->rmargin);
-
-	if ((pp = mdoc_arch2a(meta->arch))) {
-		tsz = strlcat(buf, " (", p->rmargin);
-		assert(tsz < p->rmargin);
-		tsz = strlcat(buf, pp, p->rmargin);
-		assert(tsz < p->rmargin);
-		tsz = strlcat(buf, ")", p->rmargin);
-		assert(tsz < p->rmargin);
-	}
 
-	ttsz = strlcpy(title, meta->title, p->rmargin);
+	if (mdoc_arch2a(meta->arch))
+		(void)snprintf(buf, p->rmargin, "%s(%s)",
+				pp, mdoc_arch2a(meta->arch));
+	else
+		(void)strlcpy(buf, pp, p->rmargin);
 
-	if (NULL == (msec = mdoc_msec2a(meta->msec)))
-		msec = "";
+	pp = mdoc_msec2a(meta->msec);
 
-	ssz = (2 * (ttsz + 2 + strlen(msec))) + tsz + 2;
+	(void)snprintf(title, p->rmargin, "%s(%s)",
+			meta->title, pp ? pp : "");
 
-	if (ssz > p->rmargin) {
-		if ((ssz -= p->rmargin) % 2)
-			ssz++;
-		ssz /= 2;
-	
-		assert(ssz <= ttsz);
-		title[ttsz - ssz] = 0;
-		ssz = 1;
-	} else
-		ssz = ((p->rmargin - ssz) / 2) + 1;
+	p->offset = 0;
+	p->rmargin = (p->maxrmargin - strlen(buf)) / 2;
+	p->flags |= TERMP_NOBREAK;
+	p->flags |= TERMP_NOSPACE;
 
-	printf("%s(%s)", title, msec);
+	word(p, title);
+	flushln(p);
 
-	for (i = 0; i < ssz; i++)
-		printf(" ");
+	p->offset = p->rmargin;
+	p->rmargin += strlen(buf);
 
-	printf("%s", buf);
+	word(p, buf);
+	flushln(p);
 
-	for (i = 0; i < ssz; i++)
-		printf(" ");
+	exit(1);
 
-	printf("%s(%s)\n", title, msec);
-	fflush(stdout);
+	p->offset = p->rmargin;
+	p->rmargin = p->maxrmargin;
+	p->flags &= ~TERMP_NOBREAK;
+
+	word(p, title);
+	flushln(p);
+
+	p->rmargin = p->maxrmargin;
+	p->offset = 0;
+	p->flags &= ~TERMP_NOSPACE;
 
 	free(title);
 	free(buf);