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