xref: /csrg-svn/old/roff/common_source/n7.c (revision 40363)
1 #ifndef lint
2 static char sccsid[] = "@(#)n7.c	4.4 03/07/90";
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 	}else if(opn == pto || v.pn > pto){
442 		print = 0;
443 		chkpn();
444 		goto nlpn;
445 		}
446 	if(stop && print){
447 		dpn++;
448 		if(dpn >= stop){
449 			dpn = 0;
450 			dostop();
451 		}
452 	}
453 nl2:
454 	trap = 0;
455 	if(v.nl == 0){
456 		if((j = findn(0)) != NTRAP)
457 			trap = control(mlist[j],0);
458 	} else if((i = findt(v.nl-nlss)) <= nlss){
459 		if((j = findn1(v.nl-nlss+i)) == NTRAP){
460 			prstrfl("Trap botch.\n");
461 			done2(-5);
462 		}
463 		trap = control(mlist[j],0);
464 	}
465 }
466 findn1(a)
467 int a;
468 {
469 	register i, j;
470 
471 	for(i=0; i<NTRAP; i++){
472 		if(mlist[i]){
473 			if((j = nlist[i]) < 0)j += pl;
474 			if(j == a)break;
475 		}
476 	}
477 	return(i);
478 }
479 chkpn(){
480 	pfrom = pto = *(pnp++);
481 	if(pto == -1){
482 		flusho();
483 		done1(0);
484 	}
485 	if(pto == -2){
486 		print++;
487 		pfrom = 0;
488 		pto = 10000;
489 	}
490 	else if(pto & MOT){
491 		print++;
492 		pto &= ~MOT;
493 		pfrom = 0;
494 	}
495 }
496 findt(a)
497 int a;
498 {
499 	register i, j, k;
500 
501 	k = 32767;
502 	if(dip != d){
503 		if(dip->dimac && ((i = dip->ditrap -a) > 0))k = i;
504 		return(k);
505 	}
506 	for(i=0; i<NTRAP; i++){
507 		if(mlist[i]){
508 			if((j = nlist[i]) < 0)j += pl;
509 			if((j -= a)  <=  0)continue;
510 			if(j < k)k = j;
511 		}
512 	}
513 	i = pl - a;
514 	if(k > i)k = i;
515 	return(k);
516 }
517 findt1(){
518 	register i;
519 
520 	if(dip != d)i = dip->dnl;
521 		else i = v.nl;
522 	return(findt(i));
523 }
524 eject(a)
525 struct s *a;
526 {
527 	register savlss;
528 
529 	if(dip != d)return;
530 	ejf++;
531 	if(a)ejl = a;
532 		else ejl = frame;
533 	if(trap)return;
534 e1:
535 	savlss = lss;
536 	lss = findt(v.nl);
537 	newline(0);
538 	lss = savlss;
539 	if(v.nl && !trap)goto e1;
540 }
541 movword(){
542 	register i, w, *wp;
543 	int savwch, hys;
544 
545 	over = 0;
546 	wp = wordp;
547 	if(!nwd){
548 		while(((i = *wp++) & CMASK) == ' '){
549 			wch--;
550 			wne -= width(i);
551 		}
552 		wp--;
553 	}
554 	if((wne > nel) &&
555 	   !hyoff && hyf &&
556 	   (!nwd || (nel > 3*sps)) &&
557 	   (!(hyf & 02) || (findt1() > lss))
558 	  )hyphen(wp);
559 	savwch = wch;
560 	hyp = hyptr;
561 	nhyp = 0;
562 	while(*hyp && (*hyp <= wp))hyp++;
563 	while(wch){
564 		if((hyoff != 1) && (*hyp == wp)){
565 			hyp++;
566 			if(!wdstart ||
567 			   ((wp > (wdstart+1)) &&
568 			    (wp < wdend) &&
569 			    (!(hyf & 04) || (wp < (wdend-1))) &&
570 			    (!(hyf & 010) || (wp > (wdstart+2)))
571 			   )
572 			  ){
573 				nhyp++;
574 				storeline(IMP,0);
575 			}
576 		}
577 		i = *wp++;
578 		w = width(i);
579 		wne -= w;
580 		wch--;
581 		storeline(i,w);
582 	}
583 	if(nel >= 0){
584 		nwd++;
585 		return(0);
586 	}
587 	xbitf = 1;
588 	hys = width(0200); /*hyphen*/
589 m1:
590 	if(!nhyp){
591 		if(!nwd)goto m3;
592 		if(wch == savwch)goto m4;
593 	}
594 	if(*--linep != IMP)goto m5;
595 	if(!(--nhyp))
596 		if(!nwd)goto m2;
597 	if(nel < hys){
598 		nc--;
599 		goto m1;
600 	}
601 m2:
602 	if(((i = *(linep-1) & CMASK) != '-') &&
603 	   (i != 0203)
604 	  ){
605 	*linep = (*(linep-1) & ~CMASK) | 0200;
606 	w = width(*linep);
607 	nel -= w;
608 	ne += w;
609 	linep++;
610 /*
611 	hsend();
612 */
613 	}
614 m3:
615 	nwd++;
616 m4:
617 	wordp = wp;
618 	return(1);
619 m5:
620 	nc--;
621 	w = width(*linep);
622 	ne -= w;
623 	nel += w;
624 	wne += w;
625 	wch++;
626 	wp--;
627 	goto m1;
628 }
629 horiz(i)
630 int i;
631 {
632 	vflag = 0;
633 	if(i)pchar(makem(i));
634 }
635 setnel(){
636 	if(!nc){
637 		linep = line;
638 		if(un1 >= 0){
639 			un = un1;
640 			un1 = -1;
641 		}
642 		nel = ll - un;
643 		ne = adsp = adrem = 0;
644 	}
645 }
646 getword(x)
647 int x;
648 {
649 	register i, j, swp;
650 	int noword;
651 
652 	noword = 0;
653 	if(x)if(pendw){
654 		*pendw = 0;
655 		goto rtn;
656 	}
657 	if(wordp = pendw)goto g1;
658 	hyp = hyptr;
659 	wordp = word;
660 	over = wne = wch = 0;
661 	hyoff = 0;
662 	while(1){
663 		j = (i = GETCH()) & CMASK;
664 		if(j == '\n'){
665 			wne = wch = 0;
666 			noword = 1;
667 			goto rtn;
668 		}
669 		if(j == ohc){
670 			hyoff = 1;
671 			continue;
672 		}
673 		if(j == ' '){
674 			storeword(i,width(i));	/* XXX */
675 			continue;
676 		}
677 		break;
678 	}
679 	swp = widthp;
680 	storeword(' ' | chbits, -1);
681 	if(spflg){
682 		storeword(' ' | chbits, -1);
683 		spflg = 0;
684 	}
685 	widthp = swp;
686 g0:
687 	if(j == CONT){
688 		pendw = wordp;
689 		nflush = 0;
690 		flushi();
691 		return(1);
692 	}
693 	if(hyoff != 1){
694 		if(j == ohc){
695 			hyoff = 2;
696 			*hyp++ = wordp;
697 			if(hyp > (hyptr+NHYP-1))hyp = hyptr+NHYP-1;
698 			goto g1;
699 		}
700 		if((j == '-') ||
701 		   (j == 0203) /*3/4 Em dash*/
702 		  )if(wordp > word+1){
703 			hyoff = 2;
704 			*hyp++ = wordp + 1;
705 			if(hyp > (hyptr+NHYP-1))hyp = hyptr+NHYP-1;
706 		}
707 	}
708 	storeword(i,width(i));	/* XXX */
709 g1:
710 	j = (i = GETCH()) & CMASK;
711 	if(j != ' '){
712 		if(j != '\n')goto g0;
713 		j = *(wordp-1) & CMASK;
714 		if((j == '.') ||
715 		   (j == '!') ||
716 		   (j == '?'))spflg++;
717 	}
718 	*wordp = 0;
719 rtn:
720 	wdstart = 0;
721 	wordp = word;
722 	pendw = 0;
723 	*hyp++ = 0;
724 	setnel();
725 	return(noword);
726 }
727 storeword(c,w)
728 int c, w;
729 {
730 
731 	if(wordp >= &word[WDSIZE - 1]){
732 		if(!over){
733 			prstrfl("Word overflow.\n");
734 			over++;
735 			c = 0343;
736 			w = -1;
737 		goto s1;
738 		}
739 		return;
740 	}
741 s1:
742 	if(w == -1)w = width(c);
743 	wne += w;
744 	*wordp++ = c;
745 	wch++;
746 }
747 #ifdef NROFF
748 extern char trtab[];
749 gettch(){
750 	register int i, j;
751 
752 	if(!((i = getch()) & MOT) && (i & ulbit)){
753 		j = i&CMASK;
754 		if(cu && (trtab[j] == ' '))
755 			i = ((i & ~ulbit)& ~CMASK) | '_';
756 		if(!cu && (j>32) && (j<0370) && !(*t.codetab[j-32] & 0200))
757 			i &= ~ulbit;
758 	}
759 	return(i);
760 }
761 #endif
762