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