Blob


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