tech@mandoc.bsd.lv
 help / color / mirror / Atom feed
From: Ingo Schwarze <schwarze@usta.de>
To: tech@mdocml.bsd.lv
Subject: do not handle vertical lines as additional tbl(7) columns
Date: Sat, 26 May 2012 22:07:17 +0200	[thread overview]
Message-ID: <20120526200717.GB31629@iris.usta.de> (raw)

You want this refactoring, too?

----- Forwarded message from Ingo Schwarze <schwarze@cvs.openbsd.org> -----

From: Ingo Schwarze <schwarze@cvs.openbsd.org>
Date: Sat, 26 May 2012 14:03:34 -0600 (MDT)
To: source-changes@cvs.openbsd.org

CVSROOT:	/cvs
Module name:	src
Changes by:	schwarze@cvs.openbsd.org	2012/05/26 14:03:34

Modified files:
	usr.bin/mandoc : mandoc.h out.c tbl_data.c tbl_html.c 
	                 tbl_layout.c tbl_term.c 

Log message:
Do not handle vertical lines as additional tbl(7) columns,
instead save their properties with the following column.
This simplifies layout parsing and saves a lot of code
related to column handling.

At output time, print all white space and vertical lines
separating columns before printing the following column,
and none after printing the preceding column, considerably
simplifying white space handling and width calculations.

No functional change, but it saves 150 lines of code,
and it allows the next patch to tbl_term.c, tbl_literal().

----- End forwarded message -----

Index: mandoc.h
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/mandoc.h,v
retrieving revision 1.44
diff -u -p -r1.44 mandoc.h
--- mandoc.h	24 May 2012 23:33:23 -0000	1.44
+++ mandoc.h	26 May 2012 19:56:42 -0000
@@ -175,20 +175,14 @@ struct	tbl {
 	int		  cols; /* number of columns */
 };
 
-enum	tbl_headt {
-	TBL_HEAD_DATA, /* plug in data from tbl_dat */
-	TBL_HEAD_VERT, /* vertical spacer */
-	TBL_HEAD_DVERT  /* double-vertical spacer */
-};
-
 /*
  * The head of a table specifies all of its columns.  When formatting a
  * tbl_span, iterate over these and plug in data from the tbl_span when
  * appropriate, using tbl_cell as a guide to placement.
  */
 struct	tbl_head {
-	enum tbl_headt	  pos;
 	int		  ident; /* 0 <= unique id < cols */
+	int		  vert; /* width of preceding vertical line */
 	struct tbl_head	 *next;
 	struct tbl_head	 *prev;
 };
@@ -203,8 +197,6 @@ enum	tbl_cellt {
 	TBL_CELL_DOWN, /* ^ */
 	TBL_CELL_HORIZ, /* _, - */
 	TBL_CELL_DHORIZ, /* = */
-	TBL_CELL_VERT, /* | */
-	TBL_CELL_DVERT, /* || */
 	TBL_CELL_MAX
 };
 
@@ -213,6 +205,7 @@ enum	tbl_cellt {
  */
 struct	tbl_cell {
 	struct tbl_cell	 *next;
+	int		  vert; /* width of preceding vertical line */
 	enum tbl_cellt	  pos;
 	size_t		  spacing;
 	int		  flags;
Index: out.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/out.c,v
retrieving revision 1.16
diff -u -p -r1.16 out.c
--- out.c	20 Sep 2011 23:05:46 -0000	1.16
+++ out.c	26 May 2012 19:56:42 -0000
@@ -174,25 +174,6 @@ tblcalc(struct rofftbl *tbl, const struc
 			tblcalc_data(tbl, col, sp->tbl, dp);
 		}
 	}
-
-	/* 
-	 * Calculate width of the spanners.  These get one space for a
-	 * vertical line, two for a double-vertical line. 
-	 */
-
-	for ( ; hp; hp = hp->next) {
-		col = &tbl->cols[hp->ident];
-		switch (hp->pos) {
-		case (TBL_HEAD_VERT):
-			col->width = (*tbl->len)(1, tbl->arg);
-			break;
-		case (TBL_HEAD_DVERT):
-			col->width = (*tbl->len)(2, tbl->arg);
-			break;
-		default:
-			break;
-		}
-	}
 }
 
 static void
Index: tbl_data.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/tbl_data.c,v
retrieving revision 1.11
diff -u -p -r1.11 tbl_data.c
--- tbl_data.c	24 Apr 2011 16:22:02 -0000	1.11
+++ tbl_data.c	26 May 2012 19:56:42 -0000
@@ -45,13 +45,11 @@ data(struct tbl_node *tbl, struct tbl_sp
 		cp = dp->layout->first;
 
 	/* 
-	 * Skip over spanners and vertical lines to data formats, since
+	 * Skip over spanners, since
 	 * we want to match data with data layout cells in the header.
 	 */
 
-	while (cp && (TBL_CELL_VERT == cp->pos || 
-				TBL_CELL_DVERT == cp->pos ||
-				TBL_CELL_SPAN == cp->pos))
+	while (cp && TBL_CELL_SPAN == cp->pos)
 		cp = cp->next;
 
 	/*
Index: tbl_html.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/tbl_html.c,v
retrieving revision 1.5
diff -u -p -r1.5 tbl_html.c
--- tbl_html.c	18 Sep 2011 15:54:48 -0000	1.5
+++ tbl_html.c	26 May 2012 19:56:42 -0000
@@ -119,20 +119,12 @@ print_tbl(struct html *h, const struct t
 			print_stagq(h, tt);
 			print_otag(h, TAG_TD, 0, NULL);
 
-			switch (hp->pos) {
-			case (TBL_HEAD_VERT):
-				/* FALLTHROUGH */
-			case (TBL_HEAD_DVERT):
-				continue;
-			case (TBL_HEAD_DATA):
-				if (NULL == dp)
-					break;
-				if (TBL_CELL_DOWN != dp->layout->pos)
-					if (dp->string)
-						print_text(h, dp->string);
-				dp = dp->next;
+			if (NULL == dp)
 				break;
-			}
+			if (TBL_CELL_DOWN != dp->layout->pos)
+				if (dp->string)
+					print_text(h, dp->string);
+			dp = dp->next;
 		}
 		break;
 	}
Index: tbl_layout.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/tbl_layout.c,v
retrieving revision 1.10
diff -u -p -r1.10 tbl_layout.c
--- tbl_layout.c	18 Sep 2011 15:54:48 -0000	1.10
+++ tbl_layout.c	26 May 2012 19:56:43 -0000
@@ -1,6 +1,7 @@
 /*	$Id: tbl_layout.c,v 1.10 2011/09/18 15:54:48 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2012 Ingo Schwarze <schwarze@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -47,8 +48,7 @@ static	const struct tbl_phrase keys[KEYS
 	{ '^',		 TBL_CELL_DOWN },
 	{ '-',		 TBL_CELL_HORIZ },
 	{ '_',		 TBL_CELL_HORIZ },
-	{ '=',		 TBL_CELL_DHORIZ },
-	{ '|',		 TBL_CELL_VERT }
+	{ '=',		 TBL_CELL_DHORIZ }
 };
 
 static	int		 mods(struct tbl_node *, struct tbl_cell *, 
@@ -56,10 +56,8 @@ static	int		 mods(struct tbl_node *, str
 static	int		 cell(struct tbl_node *, struct tbl_row *, 
 				int, const char *, int *);
 static	void		 row(struct tbl_node *, int, const char *, int *);
-static	struct tbl_cell *cell_alloc(struct tbl_node *, 
-				struct tbl_row *, enum tbl_cellt);
-static	void		 head_adjust(const struct tbl_cell *, 
-				struct tbl_head *);
+static	struct tbl_cell *cell_alloc(struct tbl_node *, struct tbl_row *,
+				enum tbl_cellt, int vert);
 
 static int
 mods(struct tbl_node *tbl, struct tbl_cell *cp, 
@@ -76,10 +74,6 @@ mods(struct tbl_node *tbl, struct tbl_ce
 	case (TBL_CELL_HORIZ):
 		/* FALLTHROUGH */
 	case (TBL_CELL_DHORIZ):
-		/* FALLTHROUGH */
-	case (TBL_CELL_VERT):
-		/* FALLTHROUGH */
-	case (TBL_CELL_DVERT):
 		return(1);
 	default:
 		break;
@@ -210,10 +204,17 @@ static int
 cell(struct tbl_node *tbl, struct tbl_row *rp, 
 		int ln, const char *p, int *pos)
 {
-	int		 i;
+	int		 vert, i;
 	enum tbl_cellt	 c;
 
-	/* Parse the column position (`r', `R', `|', ...). */
+	/* Handle vertical lines. */
+
+	for (vert = 0; '|' == p[*pos]; ++*pos)
+		vert++;
+	while (' ' == p[*pos])
+		(*pos)++;
+
+	/* Parse the column position (`c', `l', `r', ...). */
 
 	for (i = 0; i < KEYS_MAX; i++)
 		if (tolower((unsigned char)p[*pos]) == keys[i].name)
@@ -242,8 +243,6 @@ cell(struct tbl_node *tbl, struct tbl_ro
 			return(0);
 		} else if (rp->last)
 			switch (rp->last->pos) {
-			case (TBL_CELL_VERT):
-			case (TBL_CELL_DVERT):
 			case (TBL_CELL_HORIZ):
 			case (TBL_CELL_DHORIZ):
 				mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse,
@@ -266,25 +265,16 @@ cell(struct tbl_node *tbl, struct tbl_ro
 
 	(*pos)++;
 
-	/* Extra check for the double-vertical. */
-
-	if (TBL_CELL_VERT == c && '|' == p[*pos]) {
-		(*pos)++;
-		c = TBL_CELL_DVERT;
-	} 
-	
 	/* Disallow adjacent spacers. */
 
-	if (rp->last && (TBL_CELL_VERT == c || TBL_CELL_DVERT == c) &&
-			(TBL_CELL_VERT == rp->last->pos || 
-			 TBL_CELL_DVERT == rp->last->pos)) {
+	if (vert > 2) {
 		mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse, ln, *pos - 1, NULL);
 		return(0);
 	}
 
 	/* Allocate cell then parse its modifiers. */
 
-	return(mods(tbl, cell_alloc(tbl, rp, c), ln, p, pos));
+	return(mods(tbl, cell_alloc(tbl, rp, c, vert), ln, p, pos));
 }
 
 
@@ -304,11 +294,11 @@ row:	/*
 	 */
 
 	rp = mandoc_calloc(1, sizeof(struct tbl_row));
-	if (tbl->last_row) {
+	if (tbl->last_row)
 		tbl->last_row->next = rp;
-		tbl->last_row = rp;
-	} else
-		tbl->last_row = tbl->first_row = rp;
+	else
+		tbl->first_row = rp;
+	tbl->last_row = rp;
 
 cell:
 	while (isspace((unsigned char)p[*pos]))
@@ -353,7 +343,8 @@ tbl_layout(struct tbl_node *tbl, int ln,
 }
 
 static struct tbl_cell *
-cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos)
+cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos,
+		int vert)
 {
 	struct tbl_cell	*p, *pp;
 	struct tbl_head	*h, *hp;
@@ -361,108 +352,35 @@ cell_alloc(struct tbl_node *tbl, struct 
 	p = mandoc_calloc(1, sizeof(struct tbl_cell));
 
 	if (NULL != (pp = rp->last)) {
-		rp->last->next = p;
-		rp->last = p;
-	} else
-		rp->last = rp->first = p;
+		pp->next = p;
+		h = pp->head->next;
+	} else {
+		rp->first = p;
+		h = tbl->first_head;
+	}
+	rp->last = p;
 
 	p->pos = pos;
+	p->vert = vert;
 
-	/*
-	 * This is a little bit complicated.  Here we determine the
-	 * header the corresponds to a cell.  We add headers dynamically
-	 * when need be or re-use them, otherwise.  As an example, given
-	 * the following:
-	 *
-	 * 	1  c || l 
-	 * 	2  | c | l
-	 * 	3  l l
-	 * 	3  || c | l |.
-	 *
-	 * We first add the new headers (as there are none) in (1); then
-	 * in (2) we insert the first spanner (as it doesn't match up
-	 * with the header); then we re-use the prior data headers,
-	 * skipping over the spanners; then we re-use everything and add
-	 * a last spanner.  Note that VERT headers are made into DVERT
-	 * ones.
-	 */
-
-	h = pp ? pp->head->next : tbl->first_head;
+	/* Re-use header. */
 
 	if (h) {
-		/* Re-use data header. */
-		if (TBL_HEAD_DATA == h->pos && 
-				(TBL_CELL_VERT != p->pos &&
-				 TBL_CELL_DVERT != p->pos)) {
-			p->head = h;
-			return(p);
-		}
-
-		/* Re-use spanner header. */
-		if (TBL_HEAD_DATA != h->pos && 
-				(TBL_CELL_VERT == p->pos ||
-				 TBL_CELL_DVERT == p->pos)) {
-			head_adjust(p, h);
-			p->head = h;
-			return(p);
-		}
-
-		/* Right-shift headers with a new spanner. */
-		if (TBL_HEAD_DATA == h->pos && 
-				(TBL_CELL_VERT == p->pos ||
-				 TBL_CELL_DVERT == p->pos)) {
-			hp = mandoc_calloc(1, sizeof(struct tbl_head));
-			hp->ident = tbl->opts.cols++;
-			hp->prev = h->prev;
-			if (h->prev)
-				h->prev->next = hp;
-			if (h == tbl->first_head)
-				tbl->first_head = hp;
-			h->prev = hp;
-			hp->next = h;
-			head_adjust(p, hp);
-			p->head = hp;
-			return(p);
-		}
-
-		if (NULL != (h = h->next)) {
-			head_adjust(p, h);
-			p->head = h;
-			return(p);
-		}
-
-		/* Fall through to default case... */
+		p->head = h;
+		return(p);
 	}
 
 	hp = mandoc_calloc(1, sizeof(struct tbl_head));
 	hp->ident = tbl->opts.cols++;
+	hp->vert = vert;
 
 	if (tbl->last_head) {
 		hp->prev = tbl->last_head;
 		tbl->last_head->next = hp;
-		tbl->last_head = hp;
 	} else
-		tbl->last_head = tbl->first_head = hp;
+		tbl->first_head = hp;
+	tbl->last_head = hp;
 
-	head_adjust(p, hp);
 	p->head = hp;
 	return(p);
 }
-
-static void
-head_adjust(const struct tbl_cell *cellp, struct tbl_head *head)
-{
-	if (TBL_CELL_VERT != cellp->pos &&
-			TBL_CELL_DVERT != cellp->pos) {
-		head->pos = TBL_HEAD_DATA;
-		return;
-	}
-
-	if (TBL_CELL_VERT == cellp->pos)
-		if (TBL_HEAD_DVERT != head->pos)
-			head->pos = TBL_HEAD_VERT;
-
-	if (TBL_CELL_DVERT == cellp->pos)
-		head->pos = TBL_HEAD_DVERT;
-}
-
Index: tbl_term.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/tbl_term.c,v
retrieving revision 1.10
diff -u -p -r1.10 tbl_term.c
--- tbl_term.c	20 Sep 2011 23:05:46 -0000	1.10
+++ tbl_term.c	26 May 2012 19:56:43 -0000
@@ -122,50 +122,24 @@ term_tbl(struct termp *tp, const struct 
 		dp = sp->first;
 		spans = 0;
 		for (hp = sp->head; hp; hp = hp->next) {
+
 			/* 
 			 * If the current data header is invoked during
 			 * a spanner ("spans" > 0), don't emit anything
 			 * at all.
 			 */
-			switch (hp->pos) {
-			case (TBL_HEAD_VERT):
-				/* FALLTHROUGH */
-			case (TBL_HEAD_DVERT):
-				if (spans <= 0)
-					tbl_vrule(tp, hp);
-				continue;
-			case (TBL_HEAD_DATA):
-				break;
-			}
 
 			if (--spans >= 0)
 				continue;
 
-			/*
-			 * All cells get a leading blank, except the
-			 * first one and those after double rulers.
-			 */
+			/* Separate columns. */
 
-			if (hp->prev && TBL_HEAD_DVERT != hp->prev->pos)
-				tbl_char(tp, ASCII_NBRSP, 1);
+			if (NULL != hp->prev)
+				tbl_vrule(tp, hp);
 
 			col = &tp->tbl.cols[hp->ident];
 			tbl_data(tp, sp->tbl, dp, col);
 
-			/* No trailing blanks. */
-
-			if (NULL == hp->next)
-				break;
-
-			/*
-			 * Add another blank between cells,
-			 * or two when there is no vertical ruler.
-			 */
-
-			tbl_char(tp, ASCII_NBRSP,
-			    TBL_HEAD_VERT  == hp->next->pos ||
-			    TBL_HEAD_DVERT == hp->next->pos ? 1 : 2);
-
 			/* 
 			 * Go to the next data cell and assign the
 			 * number of subsequent spans, if applicable.
@@ -218,17 +192,14 @@ tbl_rulewidth(struct termp *tp, const st
 	size_t		 width;
 
 	width = tp->tbl.cols[hp->ident].width;
-	if (TBL_HEAD_DATA == hp->pos) {
-		/* Account for leading blanks. */
-		if (hp->prev && TBL_HEAD_DVERT != hp->prev->pos)
-			width++;
-		/* Account for trailing blanks. */
-		width++;
-		if (hp->next &&
-		    TBL_HEAD_VERT  != hp->next->pos &&
-		    TBL_HEAD_DVERT != hp->next->pos)
-			width++;
-	}
+
+	/* Account for leading blanks. */
+	if (hp->prev)
+		width += 2 - hp->vert;
+
+	/* Account for trailing blank. */
+	width++;
+
 	return(width);
 }
 
@@ -246,10 +217,11 @@ tbl_hrule(struct termp *tp, const struct
 	if (TBL_SPAN_DHORIZ == sp->pos)
 		c = '=';
 
-	for (hp = sp->head; hp; hp = hp->next)
-		tbl_char(tp,
-		    TBL_HEAD_DATA == hp->pos ? c : '+',
-		    tbl_rulewidth(tp, hp));
+	for (hp = sp->head; hp; hp = hp->next) {
+		if (hp->prev && hp->vert)
+			tbl_char(tp, '+', hp->vert);
+		tbl_char(tp, c, tbl_rulewidth(tp, hp));
+	}
 }
 
 /*
@@ -264,10 +236,11 @@ tbl_hframe(struct termp *tp, const struc
 	const struct tbl_head *hp;
 
 	term_word(tp, "+");
-	for (hp = sp->head; hp; hp = hp->next)
-		tbl_char(tp,
-		    outer || TBL_HEAD_DATA == hp->pos ? '-' : '+',
-		    tbl_rulewidth(tp, hp));
+	for (hp = sp->head; hp; hp = hp->next) {
+		if (hp->prev && hp->vert)
+			tbl_char(tp, (outer ? '-' : '+'), hp->vert);
+		tbl_char(tp, '-', tbl_rulewidth(tp, hp));
+	}
 	term_word(tp, "+");
 	term_flushln(tp);
 }
@@ -334,16 +307,11 @@ static void
 tbl_vrule(struct termp *tp, const struct tbl_head *hp)
 {
 
-	switch (hp->pos) {
-	case (TBL_HEAD_VERT):
-		term_word(tp, "|");
-		break;
-	case (TBL_HEAD_DVERT):
-		term_word(tp, "||");
-		break;
-	default:
-		break;
-	}
+	tbl_char(tp, ASCII_NBRSP, 1);
+	if (0 < hp->vert)
+		tbl_char(tp, '|', hp->vert);
+	if (2 > hp->vert)
+		tbl_char(tp, ASCII_NBRSP, 2 - hp->vert);
 }
 
 static void
--
 To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv

                 reply	other threads:[~2012-05-26 20:07 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20120526200717.GB31629@iris.usta.de \
    --to=schwarze@usta.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).