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