| 1 |
(* This CDuce script produces CDuce web site. *)
|
| 2 |
|
| 3 |
|
| 4 |
include "xhtml-strict.cd";; (* XHTML 1 Strict DTD *)
|
| 5 |
include "xhtml-categ.cd";; (* Categories (Inline, ...) from this DTD *)
|
| 6 |
|
| 7 |
type SitePage =
|
| 8 |
<page {|input=String; output=String|}>[]
|
| 9 |
| <external {|href=String; title=String|}>[];;
|
| 10 |
type Site = <site>[ SitePage* ];;
|
| 11 |
|
| 12 |
type Page =
|
| 13 |
<page>[
|
| 14 |
<title>String
|
| 15 |
<banner>[InlineText*]
|
| 16 |
<navig>[ NavigBox* ] <main>[ Box* ] ];;
|
| 17 |
|
| 18 |
type Author = <author>String;;
|
| 19 |
type Paper =
|
| 20 |
<paper file=?String>[
|
| 21 |
<title>String
|
| 22 |
Author+
|
| 23 |
<comment>[InlineText*]
|
| 24 |
<abstract>Content ];;
|
| 25 |
|
| 26 |
type Slides =
|
| 27 |
<slides file=String>[
|
| 28 |
<title>String
|
| 29 |
Author+
|
| 30 |
<comment>[InlineText*] ];;
|
| 31 |
|
| 32 |
type Link =
|
| 33 |
<link url=String; title=String>[ InlineText* ];;
|
| 34 |
|
| 35 |
type Content =
|
| 36 |
[ ( <p {||}>[InlineText*]
|
| 37 |
| <ul {||}>[<li {||}>Content +]
|
| 38 |
| <section title=String>Content
|
| 39 |
| Xtable
|
| 40 |
| Paper | Slides | Link
|
| 41 |
| <include-verbatim file=String>[]
|
| 42 |
| InlineText )* ];;
|
| 43 |
|
| 44 |
type InlineText =
|
| 45 |
Char
|
| 46 |
| <(`b|`i|`tt) {||}>[InlineText*]
|
| 47 |
| <duce>[InlineText*]
|
| 48 |
| Xa
|
| 49 |
| Ximg | Xbr ;;
|
| 50 |
|
| 51 |
type Box = <box title=String; subtitle=?String; link=String>Content
|
| 52 |
| <meta>Content;;
|
| 53 |
type NavigBox = <box>Content | <toc>[];;
|
| 54 |
|
| 55 |
let fun authors ([Author+] -> String)
|
| 56 |
| [ <author>a ] -> a
|
| 57 |
| [ <author>a1 <author>a2 ] -> a1 @ ", and " @ a2
|
| 58 |
| [ <author>a; rem ] -> a @ ", " @ authors rem;;
|
| 59 |
|
| 60 |
let fun text (t : [InlineText*]) : Inlines =
|
| 61 |
map t with
|
| 62 |
| <duce>x -> <b>[ <tt>(text x) ]
|
| 63 |
| <(tag & (`b|`i|`tt))>x -> <(tag)>(text x)
|
| 64 |
| z -> z;;
|
| 65 |
|
| 66 |
let fun content (t : Content) : Flow =
|
| 67 |
transform t with
|
| 68 |
| <section title=title>c ->
|
| 69 |
[ <h4>title !(content c) ]
|
| 70 |
| <paper (r)>[ <title>tit aut::Author* <comment>com <abstract>ab ] ->
|
| 71 |
[ (match r with { file = f } -> <a href=f>tit | _ -> <b>tit) '. '
|
| 72 |
!(authors aut) '. '
|
| 73 |
!(text com)
|
| 74 |
<div class="abstract">[ 'Abstract:' !(content ab) ]
|
| 75 |
]
|
| 76 |
| <slides file=f>[ <title>tit aut::Author* <comment>com ] ->
|
| 77 |
[ <a href=f>tit '. ' !(authors aut) '. ' !(text com) ]
|
| 78 |
| <include-verbatim file=f>[] ->
|
| 79 |
[ <div class="code">[ <pre>(load_file f) ] ]
|
| 80 |
| <link url=url; title=title>com ->
|
| 81 |
[ <a href=url>title '. ' !(text com) ]
|
| 82 |
| <ul>lis ->
|
| 83 |
[ <ul>(map lis with <li>x -> <li>(content x)) ]
|
| 84 |
| Xtable & x ->
|
| 85 |
[ x ]
|
| 86 |
| <p>x -> [ <p>(text x) ]
|
| 87 |
| x -> text [ x ];;
|
| 88 |
|
| 89 |
let fun main2html (Box -> Flow)
|
| 90 |
<box (r)>c ->
|
| 91 |
[ <div class="box">[
|
| 92 |
<h2>(r . title)
|
| 93 |
!(match r with { subtitle = t } -> [<b>t] | _ -> [])
|
| 94 |
<a name=r . link>[]
|
| 95 |
!(content c) ] ]
|
| 96 |
| <meta>c -> [ <div class="meta">(content c) ];;
|
| 97 |
|
| 98 |
|
| 99 |
(* Ugly hack to introduce PHP code ...
|
| 100 |
The idea is to produce first an XML document with a distinguished element.
|
| 101 |
The function patch_css search for the textual representation of this
|
| 102 |
element and replace it with the PHP code. *)
|
| 103 |
|
| 104 |
let php_css : String =
|
| 105 |
[' <?php
|
| 106 |
$browser = getenv("HTTP_USER_AGENT");
|
| 107 |
if (preg_match("/MSIE/i", "$browser")) {
|
| 108 |
$css = "<link rel=\\"stylesheet\\" href=\\"cduce.css\\"
|
| 109 |
type=\\"text/css\\">";
|
| 110 |
} elseif (preg_match("/Mozilla/i", "$browser")) {
|
| 111 |
$css = "<blink>For better presentation use a more recent version
|
| 112 |
of your browser, like Netscape 6</blink>";
|
| 113 |
} if (preg_match("/Mozilla\\/5.0/i", "$browser")) {
|
| 114 |
$css = "<link rel=\\"stylesheet\\" href=\\"cduce.css\\"
|
| 115 |
type=\\"text/css\\">";
|
| 116 |
} elseif (preg_match("/opera/i", "$browser")) {
|
| 117 |
$css = "<link rel=\\"stylesheet\\" href=\\"cduce.css\\"
|
| 118 |
type=\\"text/css\\">";
|
| 119 |
}
|
| 120 |
echo "$css";
|
| 121 |
?> '];;
|
| 122 |
|
| 123 |
|
| 124 |
let fun patch_css (String -> String)
|
| 125 |
| [ a::_*? '<meta content="css"/>'; rem ] -> a @ php_css @ rem
|
| 126 |
| s -> s;;
|
| 127 |
|
| 128 |
let fun page2html (Page -> Xhtml)
|
| 129 |
<page>[ <title>title <banner>banner <navig>navig <main>main ] ->
|
| 130 |
let toc =
|
| 131 |
transform main with <box title=t; link=l>_ -> [ <li>[ <a href=('#',l)>t ] ] in
|
| 132 |
let toc = match toc with [] -> [] | lis -> [ <ul>lis ] in
|
| 133 |
let navig : Flow = transform navig with
|
| 134 |
| <box>c -> [ <div class="box">(content c) ]
|
| 135 |
| <toc>[] -> [ <div class="box">toc ]
|
| 136 |
in
|
| 137 |
<html>[
|
| 138 |
<head>[
|
| 139 |
<title>title
|
| 140 |
<meta content="text/html; charset=iso-8859-1"; http-equiv="Content-Type">[]
|
| 141 |
<meta content="css">[] (* Placeholder for PHP code *)
|
| 142 |
]
|
| 143 |
<body>[
|
| 144 |
<div class="title">[ <h1>(text banner) ]
|
| 145 |
<div id="Sidelog">navig
|
| 146 |
<div id="Content">(transform main with b -> main2html b)
|
| 147 |
]
|
| 148 |
];;
|
| 149 |
|
| 150 |
type P = (String,<title>String);;
|
| 151 |
|
| 152 |
let fun make_plan (l : [ P+ ]) : Page =
|
| 153 |
<page>[
|
| 154 |
<title>"CDuce site"
|
| 155 |
<banner>"CDuce site"
|
| 156 |
<navig>[ <box>[ <a href="/">"Home" ] ]
|
| 157 |
<main>[
|
| 158 |
<box title="Pages"; link="pages">[
|
| 159 |
<ul>(map l with (file,<title>t) -> <li>[<a href=file>t])
|
| 160 |
]
|
| 161 |
<meta>[ 'This page was automatically generated by a CDuce program.' ]
|
| 162 |
]
|
| 163 |
];;
|
| 164 |
|
| 165 |
let fun do_page((Page,String) -> [])
|
| 166 |
(page,outf) ->
|
| 167 |
let _ = print [ 'Generating html ... ' ] in
|
| 168 |
let html : String =
|
| 169 |
[ (* '<?xml version="1.0" encoding="iso-8859-1"?>' *)
|
| 170 |
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"'
|
| 171 |
' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
|
| 172 |
!(patch_css (print_xml (page2html page))) ] in
|
| 173 |
let _ = print [ 'Saving to ' !outf '...\n' ] in
|
| 174 |
dump_to_file outf html;;
|
| 175 |
|
| 176 |
let fun do_file((String,String) -> P)
|
| 177 |
(inf,outf) ->
|
| 178 |
let _ = print [ 'Loading ' !inf '... ' ] in
|
| 179 |
let page = match load_xml inf with
|
| 180 |
| Page & p -> p
|
| 181 |
| _ -> raise ("Invalid input document: " @ inf) in
|
| 182 |
let _ = do_page (page,outf) in
|
| 183 |
let tit = match [page]/<title>_ with [t] -> t in
|
| 184 |
(outf, tit);;
|
| 185 |
|
| 186 |
|
| 187 |
let site =
|
| 188 |
let _ = print [ 'Loading site.xml ...\n' ] in
|
| 189 |
match load_xml "site.xml" with
|
| 190 |
| Site & <site>s ->
|
| 191 |
let ts = map s with
|
| 192 |
| <page input=inf; output=outf>_ -> do_file(inf,outf)
|
| 193 |
| <external href=url; title=t>_ -> (url,<title>t) in
|
| 194 |
let _ = print [ 'Create plan... ' ] in
|
| 195 |
let plan = make_plan (ts @ [("plan.php", <title>"CDuce site")]) in
|
| 196 |
do_page(plan,"plan.php")
|
| 197 |
| _ -> raise "Invalid site.xml";;
|