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

Contents of /web/site.cd

Parent Directory Parent Directory | Revision Log Revision Log


Revision 774 - (hide annotations)
Tue Jul 10 18:02:15 2007 UTC (5 years, 11 months ago) by abate
File size: 12421 byte(s)
[r2003-11-18 23:16:09 by beppe] Empty log message

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

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