Blob


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