/[svn]/web/site.cd
ViewVC logotype

Contents of /web/site.cd

Parent Directory Parent Directory | Revision Log Revision Log


Revision 777 - (show annotations)
Tue Jul 10 18:02:24 2007 UTC (5 years, 10 months ago) by abate
File size: 12502 byte(s)
[r2003-11-20 11:23:27 by szach] added support for unnamed boxes

Original author: szach
Date: 2003-11-20 11:23:27+00:00
1 (* This CDuce script produces CDuce web site. *)
2
3 (** Command line **)
4
5 let input =
6 match argv with
7 | [ s ] -> s
8 | _ -> raise "Please use --arg to specify an input file on the command line"
9
10 (** Output types **)
11
12 using H = "xhtml"
13
14 (** Input types **)
15
16 type Page = <page name=String new=?Any>[ <title>String <banner>[InlineText*]? Item* ]
17 type External = <external {|href=String; title=String; name=String |}>[]
18
19 type Item =
20 <box noindex=?String title=String link=String>Content
21 | <meta>Content
22 | <left>Content
23 | Page
24 | External
25
26 type Author = <author>String
27 type Paper =
28 <paper file=?String old=?String>[
29 <title>String Author+ <comment>[InlineText*] <abstract>Content ]
30
31 type Slides =
32 <slides file=String>[ <title>String Author+ <comment>[InlineText*] ]
33
34 type Link =
35 <link url=String title=String>[ InlineText* ]
36
37 type Content =
38 [ ( <p {|style=?String|}>[InlineText*]
39 | <ul {||}>[<li {||}>Content +]
40 | <section title=String>Content
41 | <sample highlight=?"true"|"false">String
42 | H:Xtable
43 | Paper | Slides | Link
44 | <boxes-toc sections=?"">[] (* the presence optional "section" attr produces *)
45 | <pages-toc sections=?"">[] (* a two-level depth toc to include also sections *)
46 | <site-toc>[]
47 | <local-links href=String>[]
48 | <two-columns>[ <left>Content <right>Content ]
49 | InlineText
50 )* ]
51
52 type InlineText =
53 Char
54 | <(`b|`i|`tt|`em) {| style=?String |}>[InlineText*]
55 | <code>String
56 | <local href=String>String
57 | <footnote>[InlineText*]
58 | H:Xa | H:Ximg | H:Xbr
59
60 (** Generic purpose functions **)
61
62 (* Recursive inclusion of XML files and verbatim text files *)
63
64 let load_include (String -> [Any*])
65 name ->
66 (* let _ = print [ 'Loading ' !name '... \n' ] in *)
67 xtransform [ (load_xml name) ] with
68 | <include file=(s & String)>[] -> load_include s
69 | <include-verbatim file=(s & String)>[] -> load_file s
70
71 (* Highlighting text between {{...}} *)
72
73 let highlight (String -> [ (Char | H:Xvar | H:Xi)* ] )
74 | [ '{{' h ::(Char *?) '}}' ; rest ] ->
75 [ <var class="highlight">h; highlight rest ]
76 | [ '%%' h ::(Char *?) '%%' ; rest ] ->
77 [ <i>h; highlight rest ]
78 | [ c; rest ] -> [ c; highlight rest ]
79 | [] -> []
80
81 (* Split a comma-separated string *)
82
83 let split_comma (String -> [String*])
84 | [ x::(Char*?) ',' ; rest ] -> (x, split_comma rest)
85 | s -> [ s ]
86
87
88 (** Internal types **)
89
90 type Path = [ { url = String; title = String }* ]
91 type Tree = { name = String; url = String; title = String;
92 children = [Tree*] }
93
94 let url_of_name (String -> String)
95 "index" -> "/"
96 | s -> s @ ".html"
97
98 let authors ([Author+] -> String)
99 | [ <author>a ] -> a
100 | [ <author>a1 <author>a2 ] -> a1 @ ", and " @ a2
101 | [ <author>a; rem ] -> a @ ", " @ authors rem
102
103 let find_local_link (sitemap : [Tree*], l : String) : Tree =
104 match sitemap with
105 | (h,t) ->
106 if (h . name = l) then h
107 else
108 (try find_local_link (t,l) with `Not_found ->
109 find_local_link (h . children,l))
110 | [] -> raise `Not_found
111
112 let local_link (sitemap : Tree, l : String, txt : String) : H:Inline =
113 try
114 let h = find_local_link ([sitemap],l) in
115 let txt = if txt = "" then h . title else txt in
116 <a href=(h . url)>txt
117 with `Not_found -> raise [ 'Local link not found: ' !l ]
118
119 let compute_sitemap ((Page|External) -> Tree)
120 <page name=name>[ <title>title (c::(Page|External) | _)* ] ->
121 let children = map c with p -> compute_sitemap p in
122 { name = name; url = (url_of_name name); title = title; children =children }
123 |<external name=name href=h title=t>[] ->
124 { name = name; url = h; title = t; children = [] }
125
126 let display_sitemap (h : Tree) : H:Xli =
127 let ch = map h . children with x -> display_sitemap x in
128 let ch = match ch with [] -> [] | l -> [ <ul>l ] in
129 <li>[ <a href=(h . url)>(h . title); ch ]
130
131
132 let boxes_of (Page -> [H:Xul?])
133 <page name=n>[ (items::Item | _)*] ->
134 let toc =
135 transform items with
136 | <box noindex=_>_ -> []
137 | <box title=t link=l>_ -> [ <li>[ <a href=((url_of_name n)@('#',l))>t ] ] in
138 (match toc with [] -> [] | lis -> [ <ul>lis ])
139
140 let link_to (Page -> H:Xa)
141 <page name=n new=_>[<title>t ; _ ] ->
142 <a href=(url_of_name n)>[!t
143 <img src="img/new.gif" alt="(new)" style="border:0">[]]
144 | <page name=n>[<title>t ; _ ] -> <a href=(url_of_name n)>t
145
146 let box (x : H:Flow) : H:Block =
147 <table cellpadding="2"
148 style="font-size:11px ; font-family:arial,sans-serif;
149 border: solid 2px black; background: #ffffff" width="100%">
150 [ <tr> [<td>x] ]
151
152 let meta (x : H:Flow) : H:Block =
153 <table cellpadding="2"
154 style="border: solid 1px #b0b0b0; background: #e0e0e0; font-size: 80%"
155 width="100%">
156 [ <tr> [<td>x] ]
157
158 let box_title (x : H:Flow, t : String) : H:Block =
159 <table cellpadding="5"
160 style="border: solid 2px black; background: #ffffff" width="100%">
161 [ <tr>[ <td style="background: #fff0f0; color: #0000ff; font: bold
162 100% helvetica">t ] <tr> [<td>x] ]
163
164 let style = "
165 a:link:hover, a:visited:hover {
166 text-decoration: none;
167 background: #FFFFD0;
168 color: #FF0000;
169 }
170 a.old, a.old:hover, a.old:visited:hover {
171 text-decoration: line-through;
172 }
173 p {
174 text-align: justify;
175 margin: 1ex 1em 0 1em;
176 }
177 pre {
178 margin: 1ex 1em 0 1em;
179 }
180 var.highlight {
181 color: #FF0000;
182 }
183 img.icon {
184 border: 0;
185 }
186 div.code {
187 background: #E0E0E0;
188 margin: 0.5ex 0.5em 0 0.5em;
189 padding: 0.2ex;
190 }
191 div.abstract {
192 font: bold helvetica;
193 margin: 1ex 1em 1ex 1em;
194 padding: 1ex 1em 1ex 1em;
195 background: #F0F0F0;
196 }
197 div.abstract p {
198 font: sans-serif;
199 }
200 "
201
202 (* Main transformation function *)
203
204 (* returns the last page of the descendance *)
205 let gen_page (prev : Page|[], page : Page, next : Page|[],
206 path : Path, sitemap : Tree) : (Page|[]) =
207 match page with
208 <page name=name>[
209 <title>title <banner>banner | <title>(title & banner); items ] ->
210
211 let footnote_counter = ref Int 0 in
212 let footnotes = ref H:Flow [] in
213
214 let text (t : [InlineText*]) : H:Inlines =
215 transform t with
216 | <code>x -> [ <b>[ <tt>(highlight x) ] ]
217 | <local href=l>txt -> [ (local_link (sitemap,l,txt)) ]
218 | <(tag & (`b|`i|`tt|`em)) (attr)>x -> [ <(tag) (attr)>(text x) ]
219 (* | <a href=url>_ & z -> let [] = print [ 'Link: ' !url '\n'] in [z] *)
220 | <footnote>c ->
221 footnote_counter := !footnote_counter + 1;
222 let n = string_of !footnote_counter in
223 let fn = !footnotes in
224 footnotes := [];
225 let c = <p>[ <a name=[ 'note' !n ]>[]
226 <a href=[ '#bnote' !n ]>[ '[' !n ']' ]
227 ' ' ; text c ] in
228 footnotes := fn @ [ c ] @ !footnotes;
229 [ <a name=[ 'bnote' !n ]>[]
230 <a href=[ '#note' !n ]>[ '[' !n ']' ] ]
231 | z -> [ z ]
232 in
233
234 let content (t : Content) : H:Flow =
235 transform t with
236 | <section title=title>c ->
237 [ <p>[ <b style="color: #008000">title ] !(content c) ]
238 | <paper (r)>[ <title>tit aut::Author* <comment>com <abstract>ab ] ->
239 [ (match r with
240 | { file = f; old = "true" } -> <a class="old" href=f>tit
241 | { file = f } -> <a href=f>tit
242 | _ -> <b>tit) '. '
243 !(authors aut) '. '
244 !(text com)
245 <div class="abstract">[ 'Abstract:' !(content ab) ]
246 ]
247 | <slides file=f>[ <title>tit aut::Author* <comment>com ] ->
248 [ <a href=f>tit '. ' !(authors aut) '. ' !(text com) ]
249 | <sample highlight="false">s ->
250 [ <div class="code">[ <pre>s ] ]
251 | <sample>s ->
252 [ <div class="code">[ <pre>(highlight s) ] ]
253 | <link url=url title=title>com ->
254 [ <a href=url>title '. ' !(text com) ]
255 | <ul>lis ->
256 [ <ul>(map lis with <li>x -> <li>(content x)) ]
257 | H:Xtable & x ->
258 [ x ]
259 | <p (attr)>x -> [ <p (attr)>(text x) ]
260 | <pages-toc (a)>[] ->
261 let toc =
262 transform items with
263 | Page & p -> [ <li>[ (link_to p)
264 !(match a with {|sections=_|} -> (boxes_of p) | _ -> [])] ]
265 | <external href=l title=t>[] -> [ <li>[ <a href=l>t ] ] in
266 (match toc with [] -> [] | lis -> [ <ul>lis ])
267 | <boxes-toc (a)>[] ->
268 let toc =
269 transform items with
270 | <box noindex=_>_ -> []
271 | <box title=t link=l>b -> [ <li>[ <a href=('#',l)>t
272 !(match a with
273 | {|sections=_|} ->
274 (transform b with <section title=t>_ -> [<br>[] '-' !t])
275 | _ ->[])]]
276 in (match toc with [] -> [] | lis -> [ <ul>lis ])
277 | <site-toc>[] ->
278 [ <ul>[ (display_sitemap sitemap) ] ]
279 | <local-links href=s>[] ->
280 (match (split_comma s) with
281 | [] -> []
282 | l -> let l = map l with x -> <li>[ (local_link(sitemap,x,"")) ]
283 in [ <ul>l ])
284 | <two-columns>[ <left>x <right>y ] ->
285 [ <table width="100%">[
286 <tr>[
287 <td valign="top">(content x)
288 <td valign="top">(content y) ] ] ]
289 | t -> text [ t ]
290 in
291
292 (* Preparing left panel *)
293
294 let navig = transform items with <left>c -> [ c ] in
295 let left = match navig with [] -> [ [<boxes-toc>[]] ] | n -> n in
296 let left =
297 <td valign="top" align="left">[
298 <table cellpadding="0" cellspacing="15"
299 width="200"
300 style="font-size:80%; border: 1px dashed black;
301 background: #ffcd72">
302 (map left with x -> <tr>[ <td>[ (box (content x)) ] ]) ] in
303
304 let dpath : H:Inlines = transform path with
305 | { url = f; title = t } -> [ <a href=f>t ': ']
306 in
307 let npath = path @ [ { url = (url_of_name name); title = title } ] in
308 let subpages = transform items with p & Page -> [ p ] in
309 let (next,last) = gen_page_seq (page, subpages, next, npath, sitemap) in
310 let next = match next with [] -> []
311 | <page name=n>[ <title>t; _ ] ->
312 [ <a href=(url_of_name n)>[
313 <img width="16" height="16" class="icon" alt="Next page:"
314 src="img/right.gif">[]
315 ' ' !t
316 ] ] in
317 let prev = match prev with [] -> []
318 | <page name=n>[ <title>t; _ ] ->
319 [ <a href=(url_of_name n)>[
320 <img width="16" height="16" class="icon"
321 alt="Previous page:" src="img/left.gif">[]
322 ' ' !t
323 ] ] in
324 let navig =
325 if prev = [] then [] else
326 [ (box [
327 <p>[ !dpath !title ]
328 <p>[ !prev ' ' !next ] ]) ] in
329
330 (* Preparing main panel *)
331 let main = transform items with
332 | <box (r)>c ->
333 let b = [
334 <a name=(r . link)>[]
335 !(content c) ] in
336 [ (box_title (b,r . title)) ]
337 | <meta>c -> [ (meta (content c)) ]
338 in
339 let notes = match !footnotes with
340 | [] -> []
341 | n -> [ (meta n) ] in
342 let main = match (navig @ main @ notes @ navig) with
343 | [] -> raise "Empty page !"
344 | x -> x in
345
346 let right : H:Xtd =
347 <td valign="top" align="left" style="width:100%">[
348 <table width="100%">[
349 <tr>[ <td valign="top" align="left"
350 style="border: 2px solid black; background: #ffffff;
351 text-align:center; color: #aa0000; font: bold 200% helvetica" >
352 (text banner)
353 ]
354
355 <tr>[
356 <td valign="top" align="left"
357 style="border: 1px solid black; background: #fccead">[
358 <table width="100%" cellpadding="0" cellspacing="17">
359 (map main with x -> <tr>[ <td>[x] ])
360 ] ]
361 ] ] in
362
363 let html : H:Xhtml =
364 <html>[
365 <head>[
366 <title>[ 'CDuce: ' !title ]
367 <meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type">[]
368 <style type="text/css">style
369 ]
370 <body style="margin: 0; padding : 0; background: #fcb333">[
371 <table cellspacing="10" cellpadding="0" width="100%" border="0">[
372 <tr>[ left right ]
373 ]
374 ]
375 ]
376 in
377 let txt : Latin1 =
378 [ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"'
379 ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
380 !(print_xml html) ] in
381 let fn = "www/" @ name @ ".html" in
382 dump_to_file fn txt;
383 last
384
385
386 let gen_page_seq
387 (prev : Page|[], pages : [Page*], next : Page|[],
388 path : Path, sitemap : Tree) : (Page|[], Page|[]) =
389 match pages with
390 | [ p1 p2 ; _ ] & [ _; rest ] ->
391 let last = gen_page (prev,p1,p2, path, sitemap) in
392 let (_,last) = gen_page_seq (last, rest, next, path, sitemap) in
393 (p1,last)
394 | [ p ] ->
395 let last = gen_page (prev,p,next, path, sitemap) in (p,last)
396 | [] -> (next,prev)
397
398
399 ;;
400
401 match load_include input with
402 | [ Page & p ] -> let _ = gen_page ([],p,[], [], compute_sitemap p) in []
403 | _ -> raise ("Invalid input document " @ input)
404
405

CVS Admin">CVS Admin
ViewVC Help
Powered by ViewVC 1.1.5