xref: /plan9-contrib/sys/src/cmd/tbl/tu.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier /* tu.c: draws horizontal lines */
23e12c5d1SDavid du Colombier # include "t.h"
33e12c5d1SDavid du Colombier 
43e12c5d1SDavid du Colombier void
makeline(int i,int c,int lintype)53e12c5d1SDavid du Colombier makeline(int i, int c, int lintype)
63e12c5d1SDavid du Colombier {
73e12c5d1SDavid du Colombier 	int	cr, type, shortl;
83e12c5d1SDavid du Colombier 
93e12c5d1SDavid du Colombier 	type = thish(i, c);
103e12c5d1SDavid du Colombier 	if (type == 0)
113e12c5d1SDavid du Colombier 		return;
123e12c5d1SDavid du Colombier 	shortl = (table[i][c].col[0] == '\\');
133e12c5d1SDavid du Colombier 	if (c > 0 && !shortl && thish(i, c - 1) == type)
143e12c5d1SDavid du Colombier 		return;
153e12c5d1SDavid du Colombier 	if (shortl == 0)
163e12c5d1SDavid du Colombier 		for (cr = c; cr < ncol && (ctype(i, cr) == 's' || type == thish(i, cr)); cr++)
173e12c5d1SDavid du Colombier 			;
183e12c5d1SDavid du Colombier 	else
193e12c5d1SDavid du Colombier 		for (cr = c + 1; cr < ncol && ctype(i, cr) == 's'; cr++)
203e12c5d1SDavid du Colombier 			;
213e12c5d1SDavid du Colombier 	drawline(i, c, cr - 1, lintype, 0, shortl);
223e12c5d1SDavid du Colombier }
233e12c5d1SDavid du Colombier 
243e12c5d1SDavid du Colombier 
253e12c5d1SDavid du Colombier void
fullwide(int i,int lintype)263e12c5d1SDavid du Colombier fullwide(int i, int lintype)
273e12c5d1SDavid du Colombier {
283e12c5d1SDavid du Colombier 	int	cr, cl;
293e12c5d1SDavid du Colombier 
303e12c5d1SDavid du Colombier 	if (!pr1403)
31*219b2ee8SDavid du Colombier 		Bprint(&tabout, ".nr %d \\n(.v\n.vs \\n(.vu-\\n(.sp\n", SVS);
323e12c5d1SDavid du Colombier 	cr = 0;
333e12c5d1SDavid du Colombier 	while (cr < ncol) {
343e12c5d1SDavid du Colombier 		cl = cr;
353e12c5d1SDavid du Colombier 		while (i > 0 && vspand(prev(i), cl, 1))
363e12c5d1SDavid du Colombier 			cl++;
373e12c5d1SDavid du Colombier 		for (cr = cl; cr < ncol; cr++)
383e12c5d1SDavid du Colombier 			if (i > 0 && vspand(prev(i), cr, 1))
393e12c5d1SDavid du Colombier 				break;
403e12c5d1SDavid du Colombier 		if (cl < ncol)
413e12c5d1SDavid du Colombier 			drawline(i, cl, (cr < ncol ? cr - 1 : cr), lintype, 1, 0);
423e12c5d1SDavid du Colombier 	}
43*219b2ee8SDavid du Colombier 	Bprint(&tabout, "\n");
443e12c5d1SDavid du Colombier 	if (!pr1403)
45*219b2ee8SDavid du Colombier 		Bprint(&tabout, ".vs \\n(%du\n", SVS);
463e12c5d1SDavid du Colombier }
473e12c5d1SDavid du Colombier 
483e12c5d1SDavid du Colombier 
493e12c5d1SDavid du Colombier void
drawline(int i,int cl,int cr,int lintype,int noheight,int shortl)503e12c5d1SDavid du Colombier drawline(int i, int cl, int cr, int lintype, int noheight, int shortl)
513e12c5d1SDavid du Colombier {
523e12c5d1SDavid du Colombier 	char	*exhr, *exhl, *lnch;
533e12c5d1SDavid du Colombier 	int	lcount, ln, linpos, oldpos, nodata;
543e12c5d1SDavid du Colombier 
553e12c5d1SDavid du Colombier 	lcount = 0;
563e12c5d1SDavid du Colombier 	exhr = exhl = "";
573e12c5d1SDavid du Colombier 	switch (lintype) {
583e12c5d1SDavid du Colombier 	case '-':
593e12c5d1SDavid du Colombier 		lcount = 1;
603e12c5d1SDavid du Colombier 		break;
613e12c5d1SDavid du Colombier 	case '=':
623e12c5d1SDavid du Colombier 		lcount = pr1403 ? 1 : 2;
633e12c5d1SDavid du Colombier 		break;
643e12c5d1SDavid du Colombier 	case SHORTLINE:
653e12c5d1SDavid du Colombier 		lcount = 1;
663e12c5d1SDavid du Colombier 		break;
673e12c5d1SDavid du Colombier 	}
683e12c5d1SDavid du Colombier 	if (lcount <= 0)
693e12c5d1SDavid du Colombier 		return;
703e12c5d1SDavid du Colombier 	nodata = cr - cl >= ncol || noheight || allh(i);
713e12c5d1SDavid du Colombier 	if (!nodata)
72*219b2ee8SDavid du Colombier 		Bprint(&tabout, "\\v'-.5m'");
733e12c5d1SDavid du Colombier 	for (ln = oldpos = 0; ln < lcount; ln++) {
743e12c5d1SDavid du Colombier 		linpos = 2 * ln - lcount + 1;
753e12c5d1SDavid du Colombier 		if (linpos != oldpos)
76*219b2ee8SDavid du Colombier 			Bprint(&tabout, "\\v'%dp'", linpos - oldpos);
773e12c5d1SDavid du Colombier 		oldpos = linpos;
783e12c5d1SDavid du Colombier 		if (shortl == 0) {
793e12c5d1SDavid du Colombier 			tohcol(cl);
803e12c5d1SDavid du Colombier 			if (lcount > 1) {
813e12c5d1SDavid du Colombier 				switch (interv(i, cl)) {
823e12c5d1SDavid du Colombier 				case TOP:
833e12c5d1SDavid du Colombier 					exhl = ln == 0 ? "1p" : "-1p";
843e12c5d1SDavid du Colombier 					break;
853e12c5d1SDavid du Colombier 				case BOT:
863e12c5d1SDavid du Colombier 					exhl = ln == 1 ? "1p" : "-1p";
873e12c5d1SDavid du Colombier 					break;
883e12c5d1SDavid du Colombier 				case THRU:
893e12c5d1SDavid du Colombier 					exhl = "1p";
903e12c5d1SDavid du Colombier 					break;
913e12c5d1SDavid du Colombier 				}
923e12c5d1SDavid du Colombier 				if (exhl[0])
93*219b2ee8SDavid du Colombier 					Bprint(&tabout, "\\h'%s'", exhl);
943e12c5d1SDavid du Colombier 			} else if (lcount == 1) {
953e12c5d1SDavid du Colombier 				switch (interv(i, cl)) {
963e12c5d1SDavid du Colombier 				case TOP:
973e12c5d1SDavid du Colombier 				case BOT:
983e12c5d1SDavid du Colombier 					exhl = "-1p";
993e12c5d1SDavid du Colombier 					break;
1003e12c5d1SDavid du Colombier 				case THRU:
1013e12c5d1SDavid du Colombier 					exhl = "1p";
1023e12c5d1SDavid du Colombier 					break;
1033e12c5d1SDavid du Colombier 				}
1043e12c5d1SDavid du Colombier 				if (exhl[0])
105*219b2ee8SDavid du Colombier 					Bprint(&tabout, "\\h'%s'", exhl);
1063e12c5d1SDavid du Colombier 			}
1073e12c5d1SDavid du Colombier 			if (lcount > 1) {
1083e12c5d1SDavid du Colombier 				switch (interv(i, cr + 1)) {
1093e12c5d1SDavid du Colombier 				case TOP:
1103e12c5d1SDavid du Colombier 					exhr = ln == 0 ? "-1p" : "+1p";
1113e12c5d1SDavid du Colombier 					break;
1123e12c5d1SDavid du Colombier 				case BOT:
1133e12c5d1SDavid du Colombier 					exhr = ln == 1 ? "-1p" : "+1p";
1143e12c5d1SDavid du Colombier 					break;
1153e12c5d1SDavid du Colombier 				case THRU:
1163e12c5d1SDavid du Colombier 					exhr = "-1p";
1173e12c5d1SDavid du Colombier 					break;
1183e12c5d1SDavid du Colombier 				}
1193e12c5d1SDavid du Colombier 			} else if (lcount == 1) {
1203e12c5d1SDavid du Colombier 				switch (interv(i, cr + 1)) {
1213e12c5d1SDavid du Colombier 				case TOP:
1223e12c5d1SDavid du Colombier 				case BOT:
1233e12c5d1SDavid du Colombier 					exhr = "+1p";
1243e12c5d1SDavid du Colombier 					break;
1253e12c5d1SDavid du Colombier 				case THRU:
1263e12c5d1SDavid du Colombier 					exhr = "-1p";
1273e12c5d1SDavid du Colombier 					break;
1283e12c5d1SDavid du Colombier 				}
1293e12c5d1SDavid du Colombier 			}
1303e12c5d1SDavid du Colombier 		} else
131*219b2ee8SDavid du Colombier 			Bprint(&tabout, "\\h'|\\n(%2su'", reg(cl, CLEFT));
132*219b2ee8SDavid du Colombier 		Bprint(&tabout, "\\s\\n(%d", LSIZE);
1333e12c5d1SDavid du Colombier 		if (linsize)
134*219b2ee8SDavid du Colombier 			Bprint(&tabout, "\\v'-\\n(%dp/6u'", LSIZE);
1353e12c5d1SDavid du Colombier 		if (shortl)
136*219b2ee8SDavid du Colombier 			Bprint(&tabout, "\\l'|\\n(%2su'", reg(cr, CRIGHT));
1373e12c5d1SDavid du Colombier 		else
1383e12c5d1SDavid du Colombier 		 {
1393e12c5d1SDavid du Colombier 			lnch = "\\(ul";
1403e12c5d1SDavid du Colombier 			if (pr1403)
1413e12c5d1SDavid du Colombier 				lnch = lintype == 2 ? "=" : "\\(ru";
1423e12c5d1SDavid du Colombier 			if (cr + 1 >= ncol)
143*219b2ee8SDavid du Colombier 				Bprint(&tabout, "\\l'|\\n(TWu%s%s'", exhr, lnch);
1443e12c5d1SDavid du Colombier 			else
145*219b2ee8SDavid du Colombier 				Bprint(&tabout, "\\l'(|\\n(%2su+|\\n(%2su)/2u%s%s'", reg(cr, CRIGHT),
1463e12c5d1SDavid du Colombier 				    reg(cr + 1, CLEFT), exhr, lnch);
1473e12c5d1SDavid du Colombier 		}
1483e12c5d1SDavid du Colombier 		if (linsize)
149*219b2ee8SDavid du Colombier 			Bprint(&tabout, "\\v'\\n(%dp/6u'", LSIZE);
150*219b2ee8SDavid du Colombier 		Bprint(&tabout, "\\s0");
1513e12c5d1SDavid du Colombier 	}
1523e12c5d1SDavid du Colombier 	if (oldpos != 0)
153*219b2ee8SDavid du Colombier 		Bprint(&tabout, "\\v'%dp'", -oldpos);
1543e12c5d1SDavid du Colombier 	if (!nodata)
155*219b2ee8SDavid du Colombier 		Bprint(&tabout, "\\v'+.5m'");
1563e12c5d1SDavid du Colombier }
1573e12c5d1SDavid du Colombier 
1583e12c5d1SDavid du Colombier 
1593e12c5d1SDavid du Colombier void
getstop(void)1603e12c5d1SDavid du Colombier getstop(void)
1613e12c5d1SDavid du Colombier {
1623e12c5d1SDavid du Colombier 	int	i, c, k, junk, stopp;
1633e12c5d1SDavid du Colombier 
1643e12c5d1SDavid du Colombier 	stopp = 1;
1653e12c5d1SDavid du Colombier 	for (i = 0; i < MAXLIN; i++)
1663e12c5d1SDavid du Colombier 		linestop[i] = 0;
1673e12c5d1SDavid du Colombier 	for (i = 0; i < nlin; i++)
1683e12c5d1SDavid du Colombier 		for (c = 0; c < ncol; c++) {
1693e12c5d1SDavid du Colombier 			k = left(i, c, &junk);
1703e12c5d1SDavid du Colombier 			if (k >= 0 && linestop[k] == 0)
1713e12c5d1SDavid du Colombier 				linestop[k] = ++stopp;
1723e12c5d1SDavid du Colombier 		}
1733e12c5d1SDavid du Colombier 	if (boxflg || allflg || dboxflg)
1743e12c5d1SDavid du Colombier 		linestop[0] = 1;
1753e12c5d1SDavid du Colombier }
1763e12c5d1SDavid du Colombier 
1773e12c5d1SDavid du Colombier 
1783e12c5d1SDavid du Colombier int
left(int i,int c,int * lwidp)1793e12c5d1SDavid du Colombier left(int i, int c, int *lwidp)
1803e12c5d1SDavid du Colombier {
1813e12c5d1SDavid du Colombier 	int	kind, li, lj;
1823e12c5d1SDavid du Colombier 					/* returns -1 if no line to left */
1833e12c5d1SDavid du Colombier 					/* returns number of line where it starts */
1843e12c5d1SDavid du Colombier 					/* stores into lwid the kind of line */
1853e12c5d1SDavid du Colombier 	*lwidp = 0;
1863e12c5d1SDavid du Colombier 	if (i < 0)
1873e12c5d1SDavid du Colombier 		return(-1);
1883e12c5d1SDavid du Colombier 	kind = lefdata(i, c);
1893e12c5d1SDavid du Colombier 	if (kind == 0)
1903e12c5d1SDavid du Colombier 		return(-1);
1913e12c5d1SDavid du Colombier 	if (i + 1 < nlin)
1923e12c5d1SDavid du Colombier 		if (lefdata(next(i), c) == kind)
1933e12c5d1SDavid du Colombier 			return(-1);
1943e12c5d1SDavid du Colombier 	li = i;
1953e12c5d1SDavid du Colombier 	while (i >= 0 && lefdata(i, c) == kind)
1963e12c5d1SDavid du Colombier 		i = prev(li = i);
1973e12c5d1SDavid du Colombier 	if (prev(li) == -1)
1983e12c5d1SDavid du Colombier 		li = 0;
1993e12c5d1SDavid du Colombier 	*lwidp = kind;
2003e12c5d1SDavid du Colombier 	for (lj = i + 1; lj < li; lj++)
2013e12c5d1SDavid du Colombier 		if (instead[lj] && strcmp(instead[lj], ".TH") == 0)
2023e12c5d1SDavid du Colombier 			return(li);
2033e12c5d1SDavid du Colombier 	for (i = i + 1; i < li; i++)
2043e12c5d1SDavid du Colombier 		if (fullbot[i])
2053e12c5d1SDavid du Colombier 			li = i;
2063e12c5d1SDavid du Colombier 	return(li);
2073e12c5d1SDavid du Colombier }
2083e12c5d1SDavid du Colombier 
2093e12c5d1SDavid du Colombier 
2103e12c5d1SDavid du Colombier int
lefdata(int i,int c)2113e12c5d1SDavid du Colombier lefdata(int i, int c)
2123e12c5d1SDavid du Colombier {
2133e12c5d1SDavid du Colombier 	int	ck;
2143e12c5d1SDavid du Colombier 
2153e12c5d1SDavid du Colombier 	if (i >= nlin)
2163e12c5d1SDavid du Colombier 		i = nlin - 1;
2173e12c5d1SDavid du Colombier 	if (ctype(i, c) == 's') {
2183e12c5d1SDavid du Colombier 		for (ck = c; ctype(i, ck) == 's'; ck--)
2193e12c5d1SDavid du Colombier 			;
2203e12c5d1SDavid du Colombier 		if (thish(i, ck) == 0)
2213e12c5d1SDavid du Colombier 			return(0);
2223e12c5d1SDavid du Colombier 	}
2233e12c5d1SDavid du Colombier 	i = stynum[i];
2243e12c5d1SDavid du Colombier 	i = lefline[c][i];
2253e12c5d1SDavid du Colombier 	if (i > 0)
2263e12c5d1SDavid du Colombier 		return(i);
2273e12c5d1SDavid du Colombier 	if (dboxflg && c == 0)
2283e12c5d1SDavid du Colombier 		return(2);
2293e12c5d1SDavid du Colombier 	if (allflg)
2303e12c5d1SDavid du Colombier 		return(1);
2313e12c5d1SDavid du Colombier 	if (boxflg && c == 0)
2323e12c5d1SDavid du Colombier 		return(1);
2333e12c5d1SDavid du Colombier 	return(0);
2343e12c5d1SDavid du Colombier }
2353e12c5d1SDavid du Colombier 
2363e12c5d1SDavid du Colombier 
2373e12c5d1SDavid du Colombier int
next(int i)2383e12c5d1SDavid du Colombier next(int i)
2393e12c5d1SDavid du Colombier {
2403e12c5d1SDavid du Colombier 	while (i + 1 < nlin) {
2413e12c5d1SDavid du Colombier 		i++;
2423e12c5d1SDavid du Colombier 		if (!fullbot[i] && !instead[i])
2433e12c5d1SDavid du Colombier 			break;
2443e12c5d1SDavid du Colombier 	}
2453e12c5d1SDavid du Colombier 	return(i);
2463e12c5d1SDavid du Colombier }
2473e12c5d1SDavid du Colombier 
2483e12c5d1SDavid du Colombier 
2493e12c5d1SDavid du Colombier int
prev(int i)2503e12c5d1SDavid du Colombier prev(int i)
2513e12c5d1SDavid du Colombier {
2523e12c5d1SDavid du Colombier 	while (--i >= 0  && (fullbot[i] || instead[i]))
2533e12c5d1SDavid du Colombier 		;
2543e12c5d1SDavid du Colombier 	return(i);
2553e12c5d1SDavid du Colombier }
2563e12c5d1SDavid du Colombier 
2573e12c5d1SDavid du Colombier 
258