9acba6243b6c2a378eb6033963fdcb51f65826ba
[c-standard] / ann2html.sh
1 #!/bin/sh
2
3 export LC_ALL=C
4 awk '
5 BEGIN {
6         noteid = 1
7         sid = 1
8         ss[sid] = "<pre>"
9 }
10
11 function esc() {
12         gsub(/\&/, "\\&amp;")
13         gsub(/</, "\\&lt;")
14         gsub(/>/, "\\&gt;")
15 }
16
17 {
18         esc()
19 }
20
21 !title && /^[^@]/ {
22         title = $0
23         gsub(/  +/, "  ", title)
24         gsub(/Committee Draft --/, "", title)
25 }
26
27 /^@sect Contents/ {
28         ss[sid] = ss[sid] "</pre>\n"
29         seencontents = 1
30         level = 0
31 }
32
33 seencontents && !seenfore && /^[^@]/ {
34         id = $1
35         if (id ~ /Annex/)
36                 id = $2
37         sub(/\.$/, "", id)
38
39         s = $0
40         if (!sub(/ +\. .*/, "", s)) {
41                 getline
42                 esc()
43                 sub(/^ */, " ")
44                 s = s $0
45                 sub(/ +\. .*/, "", s)
46         }
47
48         if (match(s, /&lt;[a-zA-Z0-9_]*\.h&gt;/)) {
49                 h = substr($0,RSTART,RLENGTH)
50                 if (!(h in header))
51                         header[h] = id
52         }
53
54         s = "<a href=\"#" id "\">" s "</a>\n"
55
56         s = "<li>" s
57         n = split(id, a, /\./)
58         while (n > level) {
59                 s = "<ul>\n" s
60                 level++
61         }
62         while (n < level) {
63                 s = "</ul>\n" s
64                 level--
65         }
66         ss[sid] = ss[sid] s
67         next
68 }
69
70 /^@sect Foreword/ {
71         while (level--)
72                 ss[sid] = ss[sid] "</ul>\n"
73         seenfore = 1
74 }
75
76 /^@sect Index/ {
77         seenindex = 1
78 }
79
80 /^@title/ {
81         if (!seencontents) {
82                 ss[sid] = ss[sid] "</pre>\n"
83         }
84         sid++
85         getline
86         esc()
87         ss[sid] = ss[sid] "<h1>" $0 "</h1>\n"
88         if (!seencontents) {
89                 ss[sid] = ss[sid] "<pre>\n"
90         }
91         next
92 }
93
94 /^@sect 3\./ {
95         markdef = 1
96 }
97
98 /^@sect/ {
99         sid++
100         slevel = split($2,a,/\./)+1
101         if (slevel > 5)
102                 slevel = 5
103         sect = $2
104         getline
105         esc()
106         # todo hX, back to top
107         ss[sid] = sprintf("<h%s><a name=\"%s\" href=\"#%s\">%s</a></h%s>\n", slevel, sect, sect, $0, slevel)
108         if ($0 == "Index")
109                 ss[sid] = ss[sid] "<pre>\n"
110         next
111 }
112
113 /^@ul/ {
114         ss[sid] = ss[sid] "<ul>\n"
115         next
116 }
117 /^@end ul/ {
118         ss[sid] = ss[sid] "</ul>\n"
119         next
120 }
121 /^@ol/ {
122         ss[sid] = ss[sid] "<ol>\n"
123         next
124 }
125 /^@end ol/ {
126         ss[sid] = ss[sid] "</ol>\n"
127         next
128 }
129
130 /^@li/ {
131         ss[sid] = ss[sid] "<li>"
132         next
133 }
134
135 /^@pre/ {
136         pre = "<pre>"
137         next
138 }
139
140 /^@end pre/ {
141         if (!pre)
142                 next
143         pre = pre "\n</pre>\n"
144         if (nn)
145                 note[nn] = note[nn] "\n" pre
146         else
147                 ss[sid] = ss[sid] pre
148         pre = ""
149         next
150 }
151
152 /^@note/ {
153         nn = $2+0
154         note[nn] = ""
155         next
156 }
157
158 /^@page/ {
159         nn = 0
160         p = $2
161         getline
162         ss[sid] = ss[sid] "<!--page " p " -->\n"
163         next
164 }
165
166 /^@para/ {
167         ss[sid] = ss[sid] "<p><!--para " $2 " -->\n"
168         next
169 }
170
171 /^ ?(Syntax|Semantics|Description|Constraints|Synopsis|Returns|Recommended practice|Implementation limits|Environmental limits)$/ {
172         ss[sid] = ss[sid] "<p><b>" $0 "</b>\n"
173         next
174 }
175
176 !seenfore {
177         ss[sid] = ss[sid] $0 "\n"
178         next
179 }
180
181 {
182         s = $0
183         p = ""
184         if (seenindex)
185                 r = " [A-Z1-9][0-9.]*"
186         else
187                 r = "[ ([][A-Z1-9]\\.[0-9.]*[0-9]"
188         # hack
189         s = " " s
190         while (match(s, r)) {
191                 p = p substr(s,1,RSTART)
192                 m = substr(s,RSTART+1,RLENGTH-1)
193                 if (m ~ /\.0$/ || m ~ /[4-9][0-9]/ || m ~ /[0-3][0-9][0-9]/ ||
194                     substr(s,RSTART+RLENGTH,1) ~ /[a-zA-Z_\-]/)
195                         p = p m
196                 else
197                         p = p "<a href=\"#" m "\">" m "</a>"
198                 s = substr(s,RSTART+RLENGTH)
199         }
200         s = p s
201         p = ""
202         while (match(s, /[Aa]nnex [A-Z]/)) {
203                 p = p substr(s,1,RSTART-1)
204                 m = substr(s,RSTART,RLENGTH)
205                 p = p "<a href=\"#" substr(m,RLENGTH,1) "\">" m "</a>"
206                 s = substr(s,RSTART+RLENGTH)
207         }
208         s = p s
209         p = ""
210         while (match(s, /&lt;[a-zA-Z0-9_]*\.h&gt;/)) {
211                 p = p substr(s,1,RSTART-1)
212                 m = substr(s,RSTART,RLENGTH)
213                 if (m in header)
214                         p = p "<a href=\"#" header[m] "\">" m "</a>"
215                 else
216                         p = p m
217                 s = substr(s,RSTART+RLENGTH)
218         }
219         s = p s
220         p = ""
221         # TODO: false positives..
222         while (match(s, /[a-z]opt[ )"]/))
223                 s = substr(s,1,RSTART) "<sub>opt</sub>" substr(s,RSTART+RLENGTH-1)
224         if (match(s, /[a-z]opt$/))
225                 s = substr(s,1,RSTART) "<sub>opt</sub>"
226         for (;;) {
227                 while (match(s, noteid-1 "\\)")) {
228                         p = p substr(s,1,RSTART-1)
229                         p = p "<sup><a href=\"#note" noteid-1 "\"><b>" noteid-1 ")</b></a></sup>"
230                         s = substr(s,RSTART+RLENGTH)
231                 }
232                 if (!match(s, noteid "\\)"))
233                         break
234                 if (noteid==1 && s !~ /\.1\)/)
235                         break
236                 p = p substr(s,1,RSTART-1)
237                 p = p "<sup><a href=\"#note" noteid "\"><b>" noteid ")</b></a></sup>"
238                 snote[sid] = snote[sid] " " noteid
239                 noteid++
240                 s = substr(s,RSTART+RLENGTH)
241         }
242         s = p s
243         sub(/^ *Forward references/, "<p><b>&</b>", s)
244         if (markdef) {
245                 s = "<b>" s "</b><br>"
246                 markdef = 0
247         }
248         if (pre)
249                 pre = pre "\n" s
250         else if (nn)
251                 note[nn] = note[nn] s "\n"
252         else
253                 ss[sid] = ss[sid] s "\n"
254 }
255
256 END {
257         ss[sid] = ss[sid] "</pre>"
258
259         print "<html><head><title>" title "</title></head><body>"
260
261         for (i = 1; i <= sid; i++) {
262                 print ss[i]
263                 n = split(snote[i],a)
264                 if (n > 0) {
265                         s = "<p><b>Footnotes</b>\n"
266                         for (j = 1; j <= n; j++) {
267                                 s = s "<p><small><a name=\"note" a[j] "\" href=\"#note" a[j] "\">" a[j] ")</a>" note[a[j]+0] "</small>\n"
268                         }
269                         print s
270                 }
271         }
272
273         print "</body></html>"
274 }'