summaryrefslogtreecommitdiff
path: root/tbl/tu.c
diff options
context:
space:
mode:
Diffstat (limited to 'tbl/tu.c')
-rw-r--r--tbl/tu.c401
1 files changed, 401 insertions, 0 deletions
diff --git a/tbl/tu.c b/tbl/tu.c
new file mode 100644
index 0000000000000..d8756b0d2e4aa
--- /dev/null
+++ b/tbl/tu.c
@@ -0,0 +1,401 @@
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+/*
+ * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc.
+ * All Rights Reserved.
+ */
+
+/* from OpenSolaris "tu.c 1.3 05/06/02 SMI" SVr4.0 1.1 */
+
+/*
+ * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany
+ * Portions Copyright (c) 2015 Carsten Kunze
+ *
+ * Sccsid @(#)tu.c 1.4 (gritter) 9/8/06
+ */
+
+ /* tu.c: draws horizontal lines */
+# include "t..c"
+# include <string.h>
+
+/* 0 1 2
+ * lintype - =
+ * tl | ||
+ * bl | ||
+ * c |< ~ >| */
+
+static char *udbdc[2][3][3][3] = { /* vs. uhbdc */
+ { { { NULL , /* 0000 */
+ NULL , /* 0001 */
+ NULL } , /* 0002 */
+ { "\\U'250C'" /* ┌ */ , /* 0010 */
+ "\\U'252C'" /* ┬ */ , /* 0011 */
+ "\\U'2510'" /* ┐ */ } , /* 0012 */
+ { "\\U'2553'" /* ╓ */ , /* 0020 */
+ "\\U'2565'" /* ╥ */ , /* 0021 */
+ "\\U'2556'" /* ╖ */ } } , /* 0022 */
+ { { "\\U'2514'" /* └ */ , /* 0100 */
+ "\\U'2534'" /* ┴ */ , /* 0101 */
+ "\\U'2518'" /* ┘ */ } , /* 0102 */
+ { "\\U'251c'" /* ├ */ , /* 0110 */
+ "\\U'253c'" /* ┼ */ , /* 0111 */
+ "\\U'2524'" /* ┤ */ } , /* 0112 */
+ { "\\U'2553'" /* ╓ */ , /* 0120 ! */
+ "\\U'2565'" /* ╥ */ , /* 0121 ! */
+ "\\U'2556'" /* ╖ */ } } , /* 0122 ! */
+ { { "\\U'2559'" /* ╙ */ , /* 0200 */
+ "\\U'2568'" /* ╨ */ , /* 0201 */
+ "\\U'255C'" /* ╜ */ } , /* 0202 */
+ { "\\U'2559'" /* ╙ */ , /* 0210 ! */
+ "\\U'2568'" /* ╨ */ , /* 0211 ! */
+ "\\U'255C'" /* ╜ */ } , /* 0212 ! */
+ { "\\U'255F'" /* ╟ */ , /* 0220 */
+ "\\U'256B'" /* ╫ */ , /* 0221 */
+ "\\U'2562'" /* ╢ */ } } } , /* 0222 */
+ { { { NULL , /* 1000 */
+ NULL , /* 1001 */
+ NULL } , /* 1002 */
+ { "\\U'2552'" /* ╒ */ , /* 1010 */
+ "\\U'2564'" /* ╤ */ , /* 1011 */
+ "\\U'2555'" /* ╕ */ } , /* 1012 */
+ { "\\U'2554'" /* ╔ */ , /* 1020 */
+ "\\U'2566'" /* ╦ */ , /* 1021 */
+ "\\U'2557'" /* ╗ */ } } , /* 1022 */
+ { { "\\U'2558'" /* ╘ */ , /* 1100 */
+ "\\U'2567'" /* ╧ */ , /* 1101 */
+ "\\U'255B'" /* ╛ */ } , /* 1102 */
+ { "\\U'255E'" /* ╞ */ , /* 1110 */
+ "\\U'256A'" /* ╪ */ , /* 1111 */
+ "\\U'2561'" /* ╡ */ } , /* 1112 */
+ { "\\U'2554'" /* ╔ */ , /* 1120 ! */
+ "\\U'2566'" /* ╦ */ , /* 1121 ! */
+ "\\U'2557'" /* ╗ */ } } , /* 1122 ! */
+ { { "\\U'255A'" /* ╚ */ , /* 1200 */
+ "\\U'2569'" /* ╩ */ , /* 1201 */
+ "\\U'255D'" /* ╝ */ } , /* 1202 */
+ { "\\U'255A'" /* ╚ */ , /* 1210 ! */
+ "\\U'2569'" /* ╩ */ , /* 1211 ! */
+ "\\U'255D'" /* ╝ */ } , /* 1212 ! */
+ { "\\U'2560'" /* ╠ */ , /* 1220 */
+ "\\U'256C'" /* ╬ */ , /* 1221 */
+ "\\U'2563'" /* ╣ */ } } } /* 1222 */
+};
+
+static char *grbe(int i, int lintype);
+static char *glibe(int, int, int, int, int);
+
+void
+makeline(int i, int c, int lintype)
+{
+ int cr, type, shortl;
+ type = thish(i,c);
+ if (type==0) return;
+ cr=c;
+ shortl = (table[i][c].col[0]=='\\');
+ if (c>0 && !shortl && thish(i,c-1) == type)return;
+ if (shortl==0)
+ for(cr=c; cr < ncol && (ctype(i,cr)=='s'||type==thish(i,cr)); cr++);
+ else
+ for(cr=c+1; cr<ncol && ctype(i,cr)=='s'; cr++);
+ drawline(i, c, cr-1, lintype, 0, shortl);
+}
+void
+fullwide(int i, int lintype)
+{
+ int cr, cl;
+ if (!nflm)
+ fprintf(tabout, ".nr %d \\n(.v\n.vs \\n(.vu-\\n(.sp\n", SVS);
+ cr= 0;
+ while (cr<ncol)
+ {
+ cl=cr;
+ while (i>0 && vspand(prev(i),cl,1))
+ cl++;
+ for(cr=cl; cr<ncol; cr++)
+ if (i>0 && vspand(prev(i),cr,1))
+ break;
+ if (cl<ncol)
+ drawline(i,cl,(cr<ncol?cr-1:cr),lintype,1,0);
+ }
+ fprintf(tabout, "\n");
+ if (!nflm)
+ fprintf(tabout, ".vs \\n(%du\n", SVS);
+}
+
+void
+drawline(int i, int cl, int cr, int lintype, int noheight, int shortl)
+{
+ char *exhr, *exhl, *lnch;
+ int lcount, ln, linpos, oldpos, nodata;
+ lcount=0;
+ exhr=exhl= "";
+ switch(lintype)
+ {
+ case '-': lcount=1;break;
+ case '=': lcount = nflm ? 1 : 2; break;
+ case SHORTLINE: lcount=1; break;
+ }
+ if (lcount<=0) return;
+ nodata = cr-cl>=ncol || noheight || allh(i);
+ if (!nflm) {
+ if (!nodata)
+ fprintf(tabout, "\\v'-.5m'");
+ if (graphics)
+ fprintf(tabout, "\\v'\\n(#Du'");
+ }
+ for(ln=oldpos=0; ln<lcount; ln++)
+ {
+ linpos = 2*ln - lcount +1;
+ if (linpos != oldpos)
+ fprintf(tabout, "\\v'%dp'", linpos-oldpos);
+ oldpos=linpos;
+ if (shortl==0)
+ {
+ tohcol(cl);
+ if (lcount>1)
+ {
+ switch(interv(i,cl))
+ {
+ case TOP: exhl = ln==0 ? "1p" : "-1p"; break;
+ case BOT: exhl = ln==1 ? "1p" : "-1p"; break;
+ case THRU: exhl = "1p"; break;
+ }
+ if (exhl[0])
+ fprintf(tabout, "\\h'%s'", exhl);
+ }
+ else if (lcount==1)
+ {
+ switch(interv(i,cl))
+ {
+ case TOP: case BOT: exhl = "-1p"; break;
+ case THRU: exhl = "1p"; break;
+ }
+ if (exhl[0])
+ fprintf(tabout, "\\h'%s'", exhl);
+ }
+ if (lcount>1)
+ {
+ switch(interv(i,cr+1))
+ {
+ case TOP: exhr = ln==0 ? "-1p" : "+1p"; break;
+ case BOT: exhr = ln==1 ? "-1p" : "+1p"; break;
+ case THRU: exhr = "-1p"; break;
+ }
+ }
+ else if (lcount==1)
+ {
+ switch(interv(i,cr+1))
+ {
+ case TOP: case BOT: exhr = "+1p"; break;
+ case THRU: exhr = "-1p"; break;
+ }
+ }
+ }
+ else
+ fprintf(tabout, "\\h'|\\n(%du'", cl+CLEFT);
+ if (!graphics)
+ fprintf(tabout, "\\s\\n(%d",LSIZE);
+ if (linsize)
+ fprintf(tabout, "\\v'-\\n(%dp/6u'", LSIZE);
+ if (shortl) {
+ if (graphics)
+ fprintf(tabout, "\\D'l |\\n(%du 0'", cr+CRIGHT);
+ else
+ fprintf(tabout, "\\l'|\\n(%du%s'", cr+CRIGHT,
+ utf8 ? "\\U'2500'" : /* ─ */
+ tlp ? "\\-" :
+ "");
+ }
+ else if (graphics) {
+ if (cr+1>=ncol)
+ fprintf(tabout, "\\D'l |\\n(TWu%s 0'", exhr);
+ else
+ fprintf(tabout, "\\D'l (|\\n(%du+|\\n(%du)/2u%s 0'",
+ cr+CRIGHT, cr+1+CLEFT, exhr);
+ }
+ else
+ {
+ lnch = "\\(ul";
+ if (utf8)
+ lnch = lintype == '=' ? "\\U'2550'" : /* ═ */
+ "\\U'2500'" ; /* ─ */
+ else if (tlp)
+ lnch = lintype == '=' ? "\\&=" : "\\-";
+ else
+ if (pr1403)
+ lnch = lintype == '=' ? "\\&=" : "\\(ru";
+ if (cr+1>=ncol)
+ fprintf(tabout, "\\l'|\\n(TWu%s%s'", exhr,lnch);
+ else
+ fprintf(tabout, "\\l'(|\\n(%du+|\\n(%du)/2u%s%s'", cr+CRIGHT,
+ cr+1+CLEFT, exhr, lnch);
+ }
+ if (linsize)
+ fprintf(tabout, "\\v'\\n(%dp/6u'", LSIZE);
+ if (!graphics)
+ fprintf(tabout, "\\s0");
+ }
+ if (oldpos!=0)
+ fprintf(tabout, "\\v'%dp'", -oldpos);
+ if (graphics)
+ fprintf(tabout, "\\v'-\\n(#Du'");
+ if (!nodata)
+ fprintf(tabout, "\\v'+.5m'");
+ if (!shortl && (utf8 || tlp)) {
+ int corred, c, ccr, licr;
+ char *s;
+ ccr = cr;
+ if (ccr == cl) ccr++;
+ corred = 0;
+ if (ccr == ncol && (boxflg || allflg || dboxflg) &&
+ (s = grbe(i, lintype))) {
+ fprintf(tabout, "\n.sp -1\n");
+ corred = 1;
+ fprintf(tabout, "\\h'|\\n(TWu'");
+ fprintf(tabout, "%s", s);
+ }
+ licr = ccr;
+ if (licr == ncol) {
+ licr--;
+ if (!(boxflg || allflg || dboxflg)) ccr--;
+ }
+ for(c = cl; c <= licr; c++) {
+ if ((s = glibe(i, c, cl, ccr, lintype))) {
+ if (!corred) {
+ fprintf(tabout, "\n.sp -1\n");
+ corred = 1;
+ }
+ tohcol(c);
+ fprintf(tabout, "%s", s);
+ }
+ }
+ }
+}
+
+static char *glibe(int i, int c, int cl, int cr, int lintype) {
+ char *s = NULL;
+ int tl, bl;
+ int cx = c == cl ? 0 :
+ c == cr ? 2 : 1 ;
+ lintype = lintype == '=' ? 1 : 0;
+ if (!i) {
+ bl = lefdata(1, c);
+ if (bl >= 1 && bl <= 2)
+ s = tlp ? "+" :
+ udbdc[lintype][0][bl][cx];
+ } else if (i < nlin - 1) {
+ tl = lefdata(i - 1, c);
+ bl = lefdata(i + 1, c);
+ if (tl >= 0 && tl <= 2 && bl >= 0 && bl <= 2)
+ {
+ if (tlp) {
+ if (tl || bl) s = "+";
+ } else
+ s = udbdc[lintype][tl][bl][cx];
+ }
+ } else {
+ tl = lefdata(i - 1, c);
+ if (tl >= 1 && tl <= 2)
+ s = tlp ? "+" :
+ udbdc[lintype][tl][0][cx];
+ }
+ return s;
+}
+
+static char *grbe(int i, int lintype) {
+ int tl, bl;
+ lintype = lintype == '=' ? 1 : 0;
+ tl = !i ? 0 :
+ dboxflg ? 2 : 1;
+ bl = i && i >= nlin - 1 ? 0 :
+ dboxflg ? 2 : 1;
+ if (utf8) return udbdc[lintype][tl][bl][2];
+ else if (tl || bl) return "+";
+ else return NULL;
+}
+
+void
+getstop(void)
+{
+int i,c,k,junk, stopp;
+stopp=1;
+for(i=0; i<MAXLIN; i++)
+ linestop[i]=0;
+for(i=0; i<nlin; i++)
+ for(c=0; c<ncol; c++)
+ {
+ k = left(i,c,&junk);
+ if (k>=0 && linestop[k]==0)
+ linestop[k]= ++stopp;
+ }
+if (boxflg || allflg || dboxflg)
+ linestop[0]=1;
+}
+int
+left(int i, int c, int *lwidp)
+{
+ int kind, li = 0, lj;
+ /* returns -1 if no line to left */
+ /* returns number of line where it starts */
+ /* stores into lwid the kind of line */
+ *lwidp=0;
+ kind = lefdata(i,c);
+ if (kind==0) return(-1);
+ if (i+1<nlin)
+ if (lefdata(next(i),c)== kind) return(-1);
+ while (i>=0 && lefdata(i,c)==kind)
+ i=prev(li=i);
+ if (prev(li)== -1) li=0;
+ *lwidp=kind;
+ for(lj= i+1; lj<li; lj++)
+ if (instead[lj] && strcmp(instead[lj], ".TH")==0)
+ return(li);
+ for(i= i+1; i<li; i++)
+ if (fullbot[i])
+ li=i;
+ return(li);
+}
+int
+lefdata(int i, int c)
+{
+ int ck;
+ if (i>=nlin) i=nlin-1;
+ if (ctype(i,c) == 's')
+ {
+ for(ck=c; ctype(i,ck)=='s'; ck--);
+ if (thish(i,ck)==0)
+ return(0);
+ }
+ i =stynum[i];
+ i = lefline[i][c];
+ if (i>0) return(i);
+ if (dboxflg && c==0) return(2);
+ if (allflg)return(1);
+ if (boxflg && c==0) return(1);
+ return(0);
+}
+int
+next(int i)
+{
+while (i+1 <nlin)
+ {
+ i++;
+ if (!fullbot[i] && !instead[i]) break;
+ }
+return(i);
+}
+int
+prev(int i)
+{
+while (--i >=0 && (fullbot[i] || instead[i]))
+ ;
+return(i);
+}