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