1 /*
2  * Copyright (C) 1991,1992 NEC Corporation.
3  */
4 #ifndef lint
5 static char rcsid[] =
6 	"$Id: section.c,v 2.10 1994/04/19 10:17:04 uchida Exp $ (NEC)";
7 #endif
8 
9 #include <stdio.h>
10 #include <ctype.h>
11 #include "plain2.h"
12 #include "macro.h"
13 /*
14  * Section number match
15  *	2.4.	<-+ level 2
16  *	2.4.1   <-
17  */
secNumMatch(s1,s2,d)18 secNumMatch(s1, s2, d)
19 char	*s1;
20 char	*s2;
21 int	d;
22 {
23 	int	n1, n2;
24 	if (d == 0)
25 		return 1;
26 	s1 = strNum(s1, &n1);
27 	s2 = strNum(s2, &n2);
28 	if (n1 != n2)
29 		return 0;
30 	else
31 		return secNumMatch(s1, s2, d - 1);
32 }
33 /*
34  * Section numbers are continuous
35  *	1.3.5	<- continuous
36  *	1.3.6
37  */
secNumCont(s1,s2,d)38 secNumCont(s1, s2, d)
39 char	*s1;
40 char	*s2;
41 int	d;
42 {
43 	int	n1, n2;
44 	s1 = strNum(s1, &n1);
45 	s2 = strNum(s2, &n2);
46 	if (d == 1) {
47 		if (n2 == n1 + 1)
48 			return 1;
49 		else
50 			return 0;
51 	}
52 	return secNumCont(s1, s2, d - 1);
53 }
secNumIsOne(s1,d)54 secNumIsOne(s1, d)
55 char	*s1;
56 int	d;
57 {
58 	int	n1;
59 	s1 = strNum(s1, &n1);
60 	if (d == 1) {
61 		if (n1 == 1)
62 			return 1;
63 		else
64 			return 0;
65 	}
66 	return secNumIsOne(s1, d - 1);
67 
68 }
69 /*
70  * Two text lines have continuous section numbers
71  */
72 secCnctable(cur, prev)
73 struct	text	*cur;
74 struct	text	*prev;
75 {
76 	int	depth1, depth2;
77 
78 	if (prev == NULL)
79 		return secNumIsOne(cur->body + cur->indent, 1);
80 
81 	depth1 = prev->secDepth;
82 	depth2 = cur->secDepth;
83 
84 	if (depth1 == depth2) {
85 		/* depth - 1 number is same	*/
86 		if (!secNumMatch(prev->body + prev->indent,
87 				 cur->body + cur->indent, depth1 - 1))
88 			return 0;
89 		/* last number is continuous	*/
90 		if (!secNumCont(prev->body + prev->indent,
91 				cur->body + cur->indent, depth1))
92 			return 0;
93 	}
94 	else if (depth1 < depth2) {
95 		/* depth1 number is same	*/
96 		if (!secNumMatch(prev->body + prev->indent,
97 				 cur->body + cur->indent, depth1))
98 			return 0;
99 		/* depth2 last number is "1"	*/
100 		if (!secNumIsOne(cur->body + cur->indent, depth2))
101 			return 0;
102 	}
103 	else /* depth1 > depth2 */{
104 		/* depth2 - 1 number is same	*/
105 		if (!secNumMatch(prev->body + prev->indent,
106 				 cur->body + cur->indent, depth2 - 1))
107 			return 0;
108 		/* depth2 number is continuous	*/
109 		if (!secNumCont(prev->body + prev->indent,
110 				cur->body + cur->indent, depth2))
111 			return 0;
112 	}
113 	return 1;
114 }
115 /*
116  */
section(begin,end,phase)117 section(begin, end, phase)
118 int	begin;
119 int	end;
120 int	phase;
121 {
122 	int	l;
123 	char	p;
124 	struct	text	*prevSectxt = NULL;
125 	struct	textBlock	*tbp;
126 	DBG2(7, "section (%d-%d)\n", begin, end);
127 	for (l = begin; l < end; l++) {
128 		if (texts[l]->block) {
129 			if (phase == 1 && texts[l]->block->type == TB_SECNUM)
130 				prevSectxt = texts[l];
131 			l = texts[l]->block->rend - 1;
132 			continue;
133 		}
134 		if (texts[l]->pSecNum == NEVER || !prevLine(l)->blank)
135 			continue;
136 		if (nextLine(l)->blank)
137 			p = DEFINITELY;
138 		else
139 			p = texts[l]->pSecNum;
140 
141 		if (p == AMBIGUOUS && !phase
142 		    && !(prevSectxt && secCnctable(texts[l], prevSectxt)))
143 			continue;
144 		MSG1("%d ", l);
145 		if (!secCnctable(texts[l], prevSectxt)) {
146 			MSG1("\nWarning[%d] Section number\n", l);
147 			if (prevSectxt)
148 				MSG1("\t%s\n", codeCvt(prevSectxt->body));
149 			MSG1("\t%s\n", codeCvt(texts[l]->body));
150 		}
151 		tbp = newTextBlock(l, l + 1, TB_SECNUM);
152 		texts[l]->block = tbp;
153 		prevSectxt      = texts[l];
154 	}
155 }
156 /*
157  * Initiate section number
158  */
159 setSnumFor(textp)
160 struct	text	*textp;
161 {
162 	char	*snumStr;
163 	int	i, num;
164 	snumStr = textp->body + textp->indent;
165 	for (i = 1; i <= textp->secDepth; i++){
166 		snumStr = strNum(snumStr, &num);
167 		if (num != 1
168 		    || textp->secDepth != 1) {
169 			if (i == textp->secDepth)
170 				num--;
171 			if (putMacro(M_SETSEC_1 + i - 1, num) < 0)
172 				putMacro(M_SETSEC, i, num);
173 		}
174 	}
175 }
outputSetSnum(begin,end)176 outputSetSnum(begin, end)
177 int	begin;
178 int	end;
179 {
180 	int	l;
181 	for (l = begin; l < end; ) {
182 		if (texts[l]->block) {
183 			if (texts[l]->block->type == TB_SECNUM) {
184 				setSnumFor(texts[l]);
185 				return;
186 			}
187 			l = texts[l]->block->rend;
188 		}
189 		else
190 			l++;
191 	}
192 }
193 /*
194  * Appendix
195  */
appendix(begin,end)196 appendix(begin, end)
197 int	begin;
198 int	end;
199 {
200 	int	l, apnum;
201 	int	hlen;
202 	register struct	text	*textp;
203 	DBG2(7, "appendix (%d-%d)\n", begin, end);
204 	for (l = begin; l < end; l++) {
205 		textp = texts[l];
206 		if (textp->block) {
207 			l = textp->block->rend - 1;
208 			continue;
209 		}
210 		if (textp->blank
211 		    || (!indentedSecnum && textp->indent != 0)
212 		    || !prevLine(l)->blank
213 		    || !nextLine(l)->blank)
214 			continue;
215 		if ((hlen =
216 		     checkIfAppendix(textp->body + textp->indent, &apnum))
217 		    && prevLine(l)->blank) {
218 			textp->headLen = hlen;
219 			textp->block = newTextBlock(l, l + 1, TB_APPENDIX);
220 		}
221 	}
222 }
223