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