|
|
1.1 root 1: #include "tdef.h"
2: #include "fns.h"
3: #include "ext.h"
4:
5: #define GETCH gettch
6: Tchar gettch(void);
7:
8:
9: /*
10: * troff7.c
11: *
12: * text
13: */
14:
15: int brflg;
16:
17: void tbreak(void)
18: {
19: int pad, k;
20: Tchar *i, j;
21: int resol;
22: int un0 = un;
23:
24: trap = 0;
25: if (nb)
26: return;
27: if (dip == d && numtab[NL].val == -1) {
28: newline(1);
29: return;
30: }
31: if (!nc) {
32: setnel();
33: if (!wch)
34: return;
35: if (pendw)
36: getword(1);
37: movword();
38: } else if (pendw && !brflg) {
39: getword(1);
40: movword();
41: }
42: *linep = dip->nls = 0;
43: if (NROFF && dip == d)
44: horiz(po);
45: if (lnmod)
46: donum();
47: lastl = ne;
48: if (brflg != 1) {
49: totout = 0;
50: } else if (ad) {
51: if ((lastl = ll - un) < ne)
52: lastl = ne;
53: }
54: if (admod && ad && (brflg != 2)) {
55: lastl = ne;
56: adsp = adrem = 0;
57: if (admod == 1)
58: un += quant(nel / 2, HOR);
59: else if (admod == 2)
60: un += nel;
61: }
62: totout++;
63: brflg = 0;
64: if (lastl + un > dip->maxl)
65: dip->maxl = lastl + un;
66: horiz(un);
67: if (NROFF) {
68: if (adrem % t.Adj)
69: resol = t.Hor;
70: else
71: resol = t.Adj;
72: } else
73: resol = HOR;
74:
75: lastl = ne + (nwd-1) * adsp + adrem;
76: for (i = line; nc > 0; ) {
77: if ((cbits(j = *i++)) == ' ') {
78: pad = 0;
79: do {
80: pad += width(j);
81: nc--;
82: } while ((cbits(j = *i++)) == ' ');
83: i--;
84: pad += adsp;
85: --nwd;
86: if (adrem) {
87: if (adrem < 0) {
88: pad -= resol;
89: adrem += resol;
90: } else if ((totout & 01) || adrem / resol >= nwd) {
91: pad += resol;
92: adrem -= resol;
93: }
94: }
95: pchar((Tchar) WORDSP);
96: horiz(pad);
97: } else {
98: pchar(j);
99: nc--;
100: }
101: }
102: if (ic) {
103: if ((k = ll - un0 - lastl + ics) > 0)
104: horiz(k);
105: pchar(ic);
106: }
107: if (icf)
108: icf++;
109: else
110: ic = 0;
111: ne = nwd = 0;
112: un = in;
113: setnel();
114: newline(0);
115: if (dip != d) {
116: if (dip->dnl > dip->hnl)
117: dip->hnl = dip->dnl;
118: } else {
119: if (numtab[NL].val > dip->hnl)
120: dip->hnl = numtab[NL].val;
121: }
122: for (k = ls - 1; k > 0 && !trap; k--)
123: newline(0);
124: spread = 0;
125: }
126:
127: void donum(void)
128: {
129: int i, nw;
130: int lnv = numtab[LN].val;
131:
132: nrbits = nmbits;
133: nw = width('1' | nrbits);
134: if (nn) {
135: nn--;
136: goto d1;
137: }
138: if (lnv % ndf) {
139: numtab[LN].val++;
140: d1:
141: un += nw * (nmwid + nms + ni);
142: return;
143: }
144: i = 0;
145: do { /* count digits in numtab[LN].val */
146: i++;
147: } while ((lnv /= 10) > 0);
148: horiz(nw * (ni + max(nmwid-i, 0)));
149: nform = 0;
150: fnumb(numtab[LN].val, pchar);
151: un += nw * nms;
152: numtab[LN].val++;
153: }
154:
155:
156: void text(void)
157: {
158: Tchar i;
159: static int spcnt;
160:
161: nflush++;
162: numtab[HP].val = 0;
163: if ((dip == d) && (numtab[NL].val == -1)) {
164: newline(1);
165: return;
166: }
167: setnel();
168: if (ce || !fi) {
169: nofill();
170: return;
171: }
172: if (pendw)
173: goto t4;
174: if (pendt)
175: if (spcnt)
176: goto t2;
177: else
178: goto t3;
179: pendt++;
180: if (spcnt)
181: goto t2;
182: while ((cbits(i = GETCH())) == ' ') {
183: spcnt++;
184: numtab[HP].val += sps;
185: widthp = sps;
186: }
187: if (nlflg) {
188: t1:
189: nflush = pendt = ch = spcnt = 0;
190: callsp();
191: return;
192: }
193: ch = i;
194: if (spcnt) {
195: t2:
196: tbreak();
197: if (nc || wch)
198: goto rtn;
199: un += spcnt * sps;
200: spcnt = 0;
201: setnel();
202: if (trap)
203: goto rtn;
204: if (nlflg)
205: goto t1;
206: }
207: t3:
208: if (spread)
209: goto t5;
210: if (pendw || !wch)
211: t4:
212: if (getword(0))
213: goto t6;
214: if (!movword())
215: goto t3;
216: t5:
217: if (nlflg)
218: pendt = 0;
219: adsp = adrem = 0;
220: if (ad) {
221: if (nwd == 1)
222: adsp = nel;
223: else
224: adsp = nel / (nwd - 1);
225: adsp = (adsp / HOR) * HOR;
226: adrem = nel - adsp*(nwd-1);
227: }
228: brflg = 1;
229: tbreak();
230: spread = 0;
231: if (!trap)
232: goto t3;
233: if (!nlflg)
234: goto rtn;
235: t6:
236: pendt = 0;
237: ckul();
238: rtn:
239: nflush = 0;
240: }
241:
242:
243: void nofill(void)
244: {
245: int j;
246: Tchar i;
247:
248: if (!pendnf) {
249: over = 0;
250: tbreak();
251: if (trap)
252: goto rtn;
253: if (nlflg) {
254: ch = nflush = 0;
255: callsp();
256: return;
257: }
258: adsp = adrem = 0;
259: nwd = 10000;
260: }
261: while ((j = (cbits(i = GETCH()))) != '\n') {
262: if (j == ohc)
263: continue;
264: if (j == CONT) {
265: pendnf++;
266: nflush = 0;
267: flushi();
268: ckul();
269: return;
270: }
271: j = width(i);
272: widthp = j;
273: numtab[HP].val += j;
274: storeline(i, j);
275: }
276: if (ce) {
277: ce--;
278: if ((i = quant(nel / 2, HOR)) > 0)
279: un += i;
280: }
281: if (!nc)
282: storeline((Tchar)FILLER, 0);
283: brflg = 2;
284: tbreak();
285: ckul();
286: rtn:
287: pendnf = nflush = 0;
288: }
289:
290:
291: void callsp(void)
292: {
293: int i;
294:
295: if (flss)
296: i = flss;
297: else
298: i = lss;
299: flss = 0;
300: casesp1(i);
301: }
302:
303:
304: void ckul(void)
305: {
306: if (ul && (--ul == 0)) {
307: cu = 0;
308: font = sfont;
309: mchbits();
310: }
311: if (it && --it == 0 && itmac)
312: control(itmac, 0);
313: }
314:
315:
316: void storeline(Tchar c, int w)
317: {
318: if (linep >= line + lnsize - 2) {
319: if (!over) {
320: flusho();
321: ERROR "Line overflow." WARN;
322: over++;
323: c = LEFTHAND;
324: w = -1;
325: *linep++ = c;
326: *linep++ = '\n'; nc++; /* other one comes later */
327: goto s1;
328: }
329: return;
330: }
331: *linep++ = c;
332: s1:
333: if (w == -1)
334: w = width(c);
335: ne += w;
336: nel -= w;
337: nc++;
338: }
339:
340:
341: void newline(int a)
342: {
343: int i, j, nlss;
344: int opn;
345:
346: if (a)
347: goto nl1;
348: if (dip != d) {
349: j = lss;
350: pchar1((Tchar)FLSS);
351: if (flss)
352: lss = flss;
353: i = lss + dip->blss;
354: dip->dnl += i;
355: pchar1((Tchar)i);
356: pchar1((Tchar)'\n');
357: lss = j;
358: dip->blss = flss = 0;
359: if (dip->alss) {
360: pchar1((Tchar)FLSS);
361: pchar1((Tchar)dip->alss);
362: pchar1((Tchar)'\n');
363: dip->dnl += dip->alss;
364: dip->alss = 0;
365: }
366: if (dip->ditrap && !dip->ditf && dip->dnl >= dip->ditrap && dip->dimac)
367: if (control(dip->dimac, 0)) {
368: trap++;
369: dip->ditf++;
370: }
371: return;
372: }
373: j = lss;
374: if (flss)
375: lss = flss;
376: nlss = dip->alss + dip->blss + lss;
377: numtab[NL].val += nlss;
378: if (TROFF && ascii) {
379: dip->alss = dip->blss = 0;
380: }
381: pchar1((Tchar)'\n');
382: flss = 0;
383: lss = j;
384: if (numtab[NL].val < pl)
385: goto nl2;
386: nl1:
387: ejf = dip->hnl = numtab[NL].val = 0;
388: ejl = frame;
389: if (donef) {
390: if ((!nc && !wch) || ndone)
391: done1(0);
392: ndone++;
393: donef = 0;
394: if (frame == stk)
395: nflush++;
396: }
397: opn = numtab[PN].val;
398: numtab[PN].val++;
399: if (npnflg) {
400: numtab[PN].val = npn;
401: npn = npnflg = 0;
402: }
403: nlpn:
404: if (numtab[PN].val == pfrom) {
405: print++;
406: pfrom = -1;
407: } else if (opn == pto) {
408: print = 0;
409: opn = -1;
410: chkpn();
411: goto nlpn;
412: }
413: if (print)
414: ptpage(numtab[PN].val); /* supposedly in a clean state so can pause */
415: if (stop && print) {
416: dpn++;
417: if (dpn >= stop) {
418: dpn = 0;
419: ptpause();
420: }
421: }
422: nl2:
423: trap = 0;
424: if (numtab[NL].val == 0) {
425: if ((j = findn(0)) != NTRAP)
426: trap = control(mlist[j], 0);
427: } else if ((i = findt(numtab[NL].val - nlss)) <= nlss) {
428: if ((j = findn1(numtab[NL].val - nlss + i)) == NTRAP) {
429: flusho();
430: ERROR "Trap botch." WARN;
431: done2(-5);
432: }
433: trap = control(mlist[j], 0);
434: }
435: }
436:
437:
438: findn1(int a)
439: {
440: int i, j;
441:
442: for (i = 0; i < NTRAP; i++) {
443: if (mlist[i]) {
444: if ((j = nlist[i]) < 0)
445: j += pl;
446: if (j == a)
447: break;
448: }
449: }
450: return(i);
451: }
452:
453:
454: void chkpn(void)
455: {
456: pto = *(pnp++);
457: pfrom = pto>=0 ? pto : -pto;
458: if (pto == -INT_MAX) {
459: flusho();
460: done1(0);
461: }
462: if (pto < 0) {
463: pto = -pto;
464: print++;
465: pfrom = 0;
466: }
467: }
468:
469:
470: findt(int a)
471: {
472: int i, j, k;
473:
474: k = INT_MAX;
475: if (dip != d) {
476: if (dip->dimac && (i = dip->ditrap - a) > 0)
477: k = i;
478: return(k);
479: }
480: for (i = 0; i < NTRAP; i++) {
481: if (mlist[i]) {
482: if ((j = nlist[i]) < 0)
483: j += pl;
484: if ((j -= a) <= 0)
485: continue;
486: if (j < k)
487: k = j;
488: }
489: }
490: i = pl - a;
491: if (k > i)
492: k = i;
493: return(k);
494: }
495:
496:
497: findt1(void)
498: {
499: int i;
500:
501: if (dip != d)
502: i = dip->dnl;
503: else
504: i = numtab[NL].val;
505: return(findt(i));
506: }
507:
508:
509: void eject(Stack *a)
510: {
511: int savlss;
512:
513: if (dip != d)
514: return;
515: ejf++;
516: if (a)
517: ejl = a;
518: else
519: ejl = frame;
520: if (trap)
521: return;
522: e1:
523: savlss = lss;
524: lss = findt(numtab[NL].val);
525: newline(0);
526: lss = savlss;
527: if (numtab[NL].val && !trap)
528: goto e1;
529: }
530:
531:
532: movword(void)
533: {
534: int w;
535: Tchar i, *wp;
536: int savwch, hys;
537:
538: over = 0;
539: wp = wordp;
540: if (!nwd) {
541: while (cbits(*wp++) == ' ') {
542: wch--;
543: wne -= sps;
544: }
545: wp--;
546: }
547: if (wne > nel && !hyoff && hyf && (!nwd || nel > 3 * sps) &&
548: (!(hyf & 02) || (findt1() > lss)))
549: hyphen(wp);
550: savwch = wch;
551: hyp = hyptr;
552: nhyp = 0;
553: while (*hyp && *hyp <= wp)
554: hyp++;
555: while (wch) {
556: if (hyoff != 1 && *hyp == wp) {
557: hyp++;
558: if (!wdstart || (wp > wdstart + 1 && wp < wdend &&
559: (!(hyf & 04) || wp < wdend - 1) && /* 04 => last 2 */
560: (!(hyf & 010) || wp > wdstart + 2))) { /* 010 => 1st 2 */
561: nhyp++;
562: storeline((Tchar)IMP, 0);
563: }
564: }
565: i = *wp++;
566: w = width(i);
567: wne -= w;
568: wch--;
569: storeline(i, w);
570: }
571: if (nel >= 0) {
572: nwd++;
573: return(0); /* line didn't fill up */
574: }
575: if (TROFF)
576: xbits((Tchar)HYPHEN, 1);
577: hys = width((Tchar)HYPHEN);
578: m1:
579: if (!nhyp) {
580: if (!nwd)
581: goto m3;
582: if (wch == savwch)
583: goto m4;
584: }
585: if (*--linep != IMP)
586: goto m5;
587: if (!(--nhyp))
588: if (!nwd)
589: goto m2;
590: if (nel < hys) {
591: nc--;
592: goto m1;
593: }
594: m2:
595: if ((i = cbits(*(linep - 1))) != '-' && i != EMDASH) {
596: *linep = (*(linep - 1) & SFMASK) | HYPHEN;
597: w = width(*linep);
598: nel -= w;
599: ne += w;
600: linep++;
601: }
602: m3:
603: nwd++;
604: m4:
605: wordp = wp;
606: return(1); /* line filled up */
607: m5:
608: nc--;
609: w = width(*linep);
610: ne -= w;
611: nel += w;
612: wne += w;
613: wch++;
614: wp--;
615: goto m1;
616: }
617:
618:
619: void horiz(int i)
620: {
621: vflag = 0;
622: if (i)
623: pchar(makem(i));
624: }
625:
626:
627: void setnel(void)
628: {
629: if (!nc) {
630: linep = line;
631: if (un1 >= 0) {
632: un = un1;
633: un1 = -1;
634: }
635: nel = ll - un;
636: ne = adsp = adrem = 0;
637: }
638: }
639:
640:
641: getword(int x)
642: {
643: int j, k;
644: Tchar i, *wp;
645: int noword;
646: int obits;
647:
648: noword = 0;
649: if (x)
650: if (pendw) {
651: *pendw = 0;
652: goto rtn;
653: }
654: if (wordp = pendw)
655: goto g1;
656: hyp = hyptr;
657: wordp = word;
658: over = wne = wch = 0;
659: hyoff = 0;
660: obits = chbits;
661: while (1) { /* picks up 1st char of word */
662: j = cbits(i = GETCH());
663: if (j == '\n') {
664: wne = wch = 0;
665: noword = 1;
666: goto rtn;
667: }
668: if (j == ohc) {
669: hyoff = 1; /* 1 => don't hyphenate */
670: continue;
671: }
672: if (j == ' ') {
673: numtab[HP].val += sps;
674: widthp = sps;
675: storeword(i, sps);
676: continue;
677: }
678: break;
679: }
680: storeword(' ' | obits, sps);
681: if (spflg) {
682: storeword(' ' | obits, sps);
683: spflg = 0;
684: }
685: g0:
686: if (j == CONT) {
687: pendw = wordp;
688: nflush = 0;
689: flushi();
690: return(1);
691: }
692: if (hyoff != 1) {
693: if (j == ohc) {
694: hyoff = 2;
695: *hyp++ = wordp;
696: if (hyp > hyptr + NHYP - 1)
697: hyp = hyptr + NHYP - 1;
698: goto g1;
699: }
700: if (((j == '-' || j == EMDASH)) && !(i & ZBIT)) /* zbit avoids \X */
701: if (wordp > word + 1) {
702: hyoff = 2;
703: *hyp++ = wordp + 1;
704: if (hyp > hyptr + NHYP - 1)
705: hyp = hyptr + NHYP - 1;
706: }
707: }
708: j = width(i);
709: numtab[HP].val += j;
710: storeword(i, j);
711: g1:
712: j = cbits(i = GETCH());
713: if (j != ' ') {
714: static char *sentchar = ".?!"; /* sentence terminators */
715: if (j != '\n')
716: goto g0;
717: wp = wordp-1; /* handle extra space at end of sentence */
718: while (wp >= word) {
719: j = cbits(*wp--);
720: if (j=='"' || j=='\'' || j==')' || j==']' || j=='*' || j==DAGGER)
721: continue;
722: for (k = 0; sentchar[k]; k++)
723: if (j == sentchar[k]) {
724: spflg++;
725: break;
726: }
727: break;
728: }
729: }
730: *wordp = 0;
731: numtab[HP].val += sps;
732: rtn:
733: for (wp = word; *wp; wp++) {
734: if (ismot(j))
735: break; /* drechsler */
736: j = cbits(*wp);
737: if (j == ' ')
738: continue;
739: if (!isdigit(j) && j != '-')
740: break;
741: }
742: if (*wp == 0) /* all numbers, so don't hyphenate */
743: hyoff = 1;
744: wdstart = 0;
745: wordp = word;
746: pendw = 0;
747: *hyp++ = 0;
748: setnel();
749: return(noword);
750: }
751:
752:
753: void storeword(Tchar c, int w)
754: {
755: if (wordp >= &word[WDSIZE - 3]) {
756: if (!over) {
757: flusho();
758: ERROR "Word overflow." WARN;
759: over++;
760: c = LEFTHAND;
761: w = -1;
762: goto s1;
763: }
764: return;
765: }
766: s1:
767: if (w == -1)
768: w = width(c);
769: widthp = w;
770: wne += w;
771: *wordp++ = c;
772: wch++;
773: }
774:
775:
776: Tchar gettch(void)
777: {
778: extern int c_isalnum;
779: Tchar i;
780: int j;
781:
782: if (TROFF)
783: return getch();
784:
785: i = getch();
786: j = cbits(i);
787: if (ismot(i) || fbits(i) != ulfont)
788: return(i);
789: if (cu) {
790: if (trtab[j] == ' ') {
791: setcbits(i, '_');
792: setfbits(i, FT); /* default */
793: }
794: return(i);
795: }
796: /* should test here for characters that ought to be underlined */
797: /* in the old nroff, that was the 200 bit on the width! */
798: /* for now, just do letters, digits and certain special chars */
799: if (j <= 127) {
800: if (!isalnum(j))
801: setfbits(i, FT);
802: } else {
803: if (j < c_isalnum)
804: setfbits(i, FT);
805: }
806: return(i);
807: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.