site.cd 5.09 KB
Newer Older
1
2
include "xhtml-strict.cd";;  (* XHTML 1 Strict DTD *)
include "xhtml-categ.cd";;   (* Categories (Inline, ...) from this DTD *)
3

4
5
6
7
type SitePage = 
   <page {|input=String; output=String|}>[]
 | <external {|href=String; title=String|}>[];;
type Site = <site>[ SitePage* ];;
8

9
10
11
12
13
type Page = 
  <page>[
    <title>String
    <banner>[InlineText*]
    <navig>[ NavigBox* ] <main>[ Box* ] ];;
14
15
16

type Author = <author>String;;
type Paper = 
17
18
19
20
21
22
  <paper file=?String>[ 
    <title>String 
    Author+ 
    <comment>[InlineText*] 
    <abstract>Content ];;

23
type Slides = 
24
25
26
27
  <slides file=String>[ 
   <title>String 
   Author+ 
   <comment>[InlineText*] ];;
28
29

type Link =
30
  <link url=String; title=String>[ InlineText* ];;
31
32
33
34
35

type Content =      
   [ ( <p {||}>[InlineText*]
     | <ul {||}>[<li {||}>Content +]
     | <section title=String>Content
36
     | Xtable
37
38
39
     | Paper | Slides | Link 
     | <include-verbatim file=String>[]
     | InlineText )* ];;
40
41
42
43

type InlineText =
     Char
   | <(`b|`i) {||}>[InlineText*]
44
   | <duce>[InlineText*]
45
   | Xa
46
   | Ximg | Xbr ;;
47
48
49
50
51
52
53
54
55
56

type Box = <box title=String; subtitle=?String; link=String>Content
         | <meta>Content;;
type NavigBox = <box>Content | <toc>[];;

let fun authors ([Author+] -> String)
   | [ <author>a ] -> a
   | [ <author>a1 <author>a2 ] -> a1 @ ", and " @ a2
   | [ <author>a; rem ] -> a @ ", " @ authors rem;;

57
58
59
60
61
62
63
let fun text (t : [InlineText*]) : Inlines =
 map t with
   <duce>x -> <b>[ <tt>(text x) ]
 | <b>x -> <b>(text x)
 | <i>x -> <i>(text x)
 | z -> z;;

64
65
66
67
68
69
70
71
72
73
let fun content (t : Content) : Flow =
  transform t with
   | <section title=title>c -> [ <h4>title !(content c) ]
   | <paper (r)>[ <title>tit aut::Author* <comment>com <abstract>ab  ]  ->
         [ 
           (match r with 
             | { file = f } -> <a href=f>tit
	     | _ -> <b>tit
           ) '. '
           !(authors aut) '. '
74
	   !(text com)
75
76
77
           <div class="abstract">[ 'Abstract:' !(content ab) ]
         ]
   | <slides file=f>[ <title>tit aut::Author* <comment>com ]  ->
78
        [ <a href=f>tit '. ' !(authors aut) '. ' !(text com) ]
79
80
81
82
83
84
85
86
87
88
   | <include-verbatim file=f>[] ->
       let code = load_file f in
(*       let code = transform code with 
         | '\n' -> [ '\n' <br>[] ]  
         | ' ' -> "\160" 
         | c -> [c] in *)
     [
        <div class="code">[ <pre>code ]
     ]
   | <link url=url; title=title>com -> [ <a href=url>title '. ' !(text com) ]
89
   | <ul>lis -> [ <ul>(map lis with <li>x -> <li>(content x)) ]
90
   | Xtable & x -> [ x ]
91
92
93
   | <p>x -> [ <p>(text x) ]
   | <ul>x -> [ <ul>(text x) ]
   | x -> text [ x ];;
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

let fun main2html (Box -> Flow)
  <box (r)>c ->
   [ <div class="box">[
       <h2>(r.title)
        !(match r with { subtitle = t } -> [<b>t] | _ -> [])
       <a name=r.link>[] 
       !(content c)  ] ]
| <meta>c -> [ <div class="meta">(content c) ];;


let fun page2html (Page -> Xhtml)
<page>[ <title>title <banner>banner <navig>navig <main>main ] ->
 let toc = 
   transform main with <box title=t; link=l>_ -> [ <li>[ <a href=('#',l)>t ] ] in
 let toc = match toc with [] -> [] | lis -> [ <ul>lis ] in
 let navig : Flow = transform navig with
  | <box>c -> [ <div class="box">(content c) ]
  | <toc>[] -> [ <div class="box">toc ]
 in
 <html>[
  <head>[ 
   <title>title
   <meta content="text/html; charset=iso-8859-1"; http-equiv="Content-Type">[]
   <link rel="stylesheet"; href="cduce.css"; type="text/css"> []
  ]
  <body>[ 
121
   <div class="title">[ <h1>(text banner) ]
122
123
124
125
126
   <div id="Sidelog">navig
   <div id="Content">(transform main with b -> main2html b)
  ]
 ];;

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
type P = (String,<title>String);;
let fun make_plan (l : [ P+ ]) : Page =
<page>[ <title>"CDuce site"
        <banner>"CDuce site"
        <navig>[ <box>[ <a href="/">"Home" ] ]
         <main>[ 
          <box title="Pages"; link="pages">[
           <ul>(map l with (file,<title>t) -> <li>[<a href=file>t]) ]
          <meta>[
           'This page was automatically generated by a CDuce program.'
          ]
        ]
      ];;

let fun do_page((Page,String) -> [])
 (page,outf) ->
143
144
145
146
147
148
149
150
    let _ = print [ 'Generating html ... ' ] in
    let html : String = 
       [ '<?xml version="1.0" encoding="iso-8859-1"?>'
         '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"'
         '  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
         !(print_xml (page2html page)) ] in
    let _ = print [ 'Saving to ' !outf '...\n' ] in
    dump_to_file outf html;;
151
152
153
154
155
156
157
158
159
160
 
let fun do_file((String,String) -> P)
 (inf,outf) -> 
    let _ = print [ 'Loading ' !inf '... ' ] in
    let page = match load_xml inf with 
      | Page & p -> p
      | _ -> raise ("Invalid input document: " @ inf) in
    let _ = do_page (page,outf) in
    let tit = match [page]/<title>_ with [t] -> t in
    (outf, tit);;
161
162


163
164
165
166
let site =     
 let _ = print [ 'Loading site.xml ...\n' ] in
 match load_xml "site.xml" with
 | Site & <site>s ->
167
168
169
170
171
172
     let ts = map s with 
             | <page input=inf; output=outf>_ -> do_file(inf,outf)
             | <external href=url; title=t>_ -> (url,<title>t) in
     let _ = print [ 'Create plan... ' ] in
     let plan = make_plan (ts @ [("plan.html", <title>"CDuce site")]) in
     do_page(plan,"plan.html")
173
 | _ -> raise "Invalid site.xml";;