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