comparison src/tutorial.sml @ 1494:9ef6dd0df7a0

Beautified tutorial HTML
author Adam Chlipala <adam@chlipala.net>
date Fri, 15 Jul 2011 17:16:39 -0400
parents 9cb923efea4d
children af0d4d11c5d7
comparison
equal deleted inserted replaced
1493:9cb923efea4d 1494:9ef6dd0df7a0
25 * POSSIBILITY OF SUCH DAMAGE. 25 * POSSIBILITY OF SUCH DAMAGE.
26 *) 26 *)
27 27
28 structure Tutorial :> TUTORIAL = struct 28 structure Tutorial :> TUTORIAL = struct
29 29
30 fun readAll' inf = 30 fun readAll inf =
31 let 31 let
32 fun loop acc = 32 fun loop acc =
33 case TextIO.inputLine inf of 33 case TextIO.inputLine inf of
34 NONE => Substring.full (String.concat (rev acc)) 34 NONE => Substring.full (String.concat (rev acc))
35 | SOME line => loop (line :: acc) 35 | SOME line => loop (line :: acc)
36 in 36 in
37 loop [] 37 loop []
38 before TextIO.closeIn inf 38 before TextIO.closeIn inf
39 end 39 end
40 40
41 fun readAll fname = readAll' (TextIO.openIn fname) 41 val readAllFile = readAll o TextIO.openIn
42
43 fun fixupFile (fname, title) =
44 let
45 val source = readAllFile "/tmp/final.html"
46 val outf = TextIO.openOut (OS.Path.mkAbsolute {relativeTo = OS.FileSys.getDir (),
47 path = OS.Path.joinBaseExt {base = OS.Path.base fname, ext = SOME "html"}})
48
49 val (befor, after) = Substring.position "<title>" source
50
51 fun loop source =
52 let
53 val (befor, after) = Substring.position "<span class=\"comment-delimiter\">(* </span><span class=\"comment\">" source
54 in
55 if Substring.isEmpty after then
56 TextIO.outputSubstr (outf, source)
57 else
58 let
59 val (befor', after) = Substring.position " </span><span class=\"comment-delimiter\">*)</span>"
60 (Substring.slice (after, 64, NONE))
61 in
62 if Substring.isEmpty after then
63 TextIO.outputSubstr (outf, source)
64 else
65 (TextIO.outputSubstr (outf, befor);
66 TextIO.output (outf, "<div class=\"prose\">");
67 TextIO.outputSubstr (outf, befor');
68 TextIO.output (outf, "</div>");
69 loop (Substring.slice (after, 49, NONE)))
70 end
71 end
72 in
73 if Substring.isEmpty after then
74 raise Fail ("Missing <title> for " ^ title)
75 else
76 (TextIO.outputSubstr (outf, befor);
77 TextIO.output (outf, "<style type=\"text/css\">\n");
78 TextIO.output (outf, "<!--\n");
79 TextIO.output (outf, "\tdiv.prose {\n");
80 TextIO.output (outf, "\t\tfont-family: Arial;\n");
81 TextIO.output (outf, "\t\tbackground-color: #CCFFCC;\n");
82 TextIO.output (outf, "\t\tborder-style: solid;\n");
83 TextIO.output (outf, "\t\tpadding: 5px;\n");
84 TextIO.output (outf, "\t\tfont-size: larger;\n");
85 TextIO.output (outf, "\t}\n");
86 TextIO.output (outf, "-->\n");
87 TextIO.output (outf, "</style>\n");
88 TextIO.output (outf, "<title>");
89 TextIO.output (outf, title);
90 let
91 val (befor, after) = Substring.position "</title>" after
92 in
93 if Substring.isEmpty after then
94 raise Fail ("Missing </title> for " ^ title)
95 else
96 let
97 val (befor, after) = Substring.position "<body>" after
98 in
99 if Substring.isEmpty after then
100 raise Fail ("Missing <body> for " ^ title)
101 else
102 (TextIO.outputSubstr (outf, befor);
103 TextIO.output (outf, "<body><h1>");
104 TextIO.output (outf, title);
105 TextIO.output (outf, "</h1>");
106 loop (Substring.slice (after, 6, NONE)))
107 end
108 end;
109 TextIO.closeOut outf)
110 end
42 111
43 fun doUr fname = 112 fun doUr fname =
44 let 113 let
114 val inf = TextIO.openIn fname
115
116 val title = case TextIO.inputLine inf of
117 NONE => raise Fail ("No title comment at start of " ^ fname)
118 | SOME title => title
119
120 val title = String.substring (title, 3, size title - 7)
121
45 val eval = TextIO.openOut "/tmp/eval.ur" 122 val eval = TextIO.openOut "/tmp/eval.ur"
46 val gen = TextIO.openOut "/tmp/gen.ur" 123 val gen = TextIO.openOut "/tmp/gen.ur"
47 124
48 fun untilEnd source = 125 fun untilEnd source =
49 let 126 let
113 end 190 end
114 end 191 end
115 end 192 end
116 end 193 end
117 in 194 in
118 doDirectives (0, readAll fname); 195 doDirectives (0, readAll inf);
119 TextIO.closeOut gen; 196 TextIO.closeOut gen;
120 197
121 TextIO.output (eval, "\n\nfun main () : transaction page =\nreturn <xml><body>"); 198 TextIO.output (eval, "\n\nfun main () : transaction page =\nreturn <xml><body>");
122 TextIO.outputSubstr (eval, readAll "/tmp/gen.ur"); 199 TextIO.outputSubstr (eval, readAllFile "/tmp/gen.ur");
123 TextIO.output (eval, "</body></xml>"); 200 TextIO.output (eval, "</body></xml>");
124 TextIO.closeOut eval; 201 TextIO.closeOut eval;
125 202
126 if Compiler.compile "/tmp/eval" then 203 if Compiler.compile "/tmp/eval" then
127 let 204 let
128 val proc = Unix.execute ("/bin/sh", ["-c", "/tmp/eval.exe /main"]) 205 val proc = Unix.execute ("/bin/sh", ["-c", "/tmp/eval.exe /main"])
129 val inf = Unix.textInstreamOf proc 206 val inf = Unix.textInstreamOf proc
130 val s = readAll' inf 207 val s = readAll inf
131 val _ = Unix.reap proc 208 val _ = Unix.reap proc
132 209
133 val (befor, after) = Substring.position "<sc>" s 210 val (befor, after) = Substring.position "<sc>" s
134 in 211 in
135 if Substring.isEmpty after then 212 if Substring.isEmpty after then
163 ^ "/\\\") " 240 ^ "/\\\") "
164 ^ "(load \\\"urweb-mode-startup\\\") " 241 ^ "(load \\\"urweb-mode-startup\\\") "
165 ^ "(urweb-mode) " 242 ^ "(urweb-mode) "
166 ^ "(find-file \\\"/tmp/final.ur\\\") " 243 ^ "(find-file \\\"/tmp/final.ur\\\") "
167 ^ "(switch-to-buffer (htmlize-buffer)) " 244 ^ "(switch-to-buffer (htmlize-buffer)) "
168 ^ "(write-file \\\"" 245 ^ "(write-file \\\"/tmp/final.html\\\") "
169 ^ OS.Path.mkAbsolute {relativeTo = OS.FileSys.getDir (),
170 path = OS.Path.joinBaseExt {base = OS.Path.base fname, ext = SOME "html"}}
171 ^ "\\\") "
172 ^ "(kill-emacs))\"" 246 ^ "(kill-emacs))\""
173 in 247 in
174 eatNls befor; 248 eatNls befor;
175 TextIO.closeOut outf; 249 TextIO.closeOut outf;
176 ignore (OS.Process.system cmd) 250 ignore (OS.Process.system cmd);
251 fixupFile (fname, title)
177 end 252 end
178 end 253 end
179 end 254 end
180 else 255 else
181 () 256 ()