| author | wenzelm | 
| Wed, 02 Jan 2002 21:53:50 +0100 | |
| changeset 12618 | 43a97a2155d0 | 
| parent 12311 | ce5f9e61c037 | 
| child 12632 | 3d3e356778b5 | 
| permissions | -rw-r--r-- | 
| 6203 | 1 | (* Title: Pure/Thy/present.ML | 
| 2 | ID: $Id$ | |
| 9416 | 3 | Author: Markus Wenzel and Stefan Berghofer, TU Muenchen | 
| 8808 | 4 | License: GPL (GNU GENERAL PUBLIC LICENSE) | 
| 6203 | 5 | |
| 9416 | 6 | Theory presentation: HTML, graph files, (PDF)LaTeX documents. | 
| 6203 | 7 | *) | 
| 8 | ||
| 9 | signature BASIC_PRESENT = | |
| 10 | sig | |
| 11057 | 11 |   val no_document: ('a -> 'b) -> 'a -> 'b
 | 
| 7727 | 12 | val section: string -> unit | 
| 6203 | 13 | end; | 
| 14 | ||
| 15 | signature PRESENT = | |
| 16 | sig | |
| 7727 | 17 | include BASIC_PRESENT | 
| 9452 | 18 |   val write_graph: {name: string, ID: string, dir: string, unfold: bool,
 | 
| 19 | path: string, parents: string list} list -> Path.T -> unit | |
| 11911 
6533ceee4cd7
build option enables most basic browser info (for proper recording of session);
 wenzelm parents: 
11856diff
changeset | 20 | val init: bool -> bool -> string -> bool -> string list -> string -> Path.T option | 
| 11580 | 21 | -> Url.T option * bool -> bool -> unit | 
| 7727 | 22 | val finish: unit -> unit | 
| 23 | val init_theory: string -> unit | |
| 8192 | 24 | val verbatim_source: string -> (unit -> Symbol.symbol list) -> unit | 
| 25 | val old_symbol_source: string -> (unit -> Symbol.symbol list) -> unit | |
| 9136 | 26 | val theory_output: string -> string -> unit | 
| 7727 | 27 | val begin_theory: string -> string list -> (Path.T * bool) list -> theory -> theory | 
| 12151 | 28 | val multi_result: string * (string * thm list) list -> unit | 
| 7727 | 29 | val results: string -> string -> thm list -> unit | 
| 30 | val theorem: string -> thm -> unit | |
| 31 | val theorems: string -> thm list -> unit | |
| 8088 | 32 | val chapter: string -> unit | 
| 7727 | 33 | val subsection: string -> unit | 
| 34 | val subsubsection: string -> unit | |
| 35 | val setup: (theory -> theory) list | |
| 9416 | 36 |   val get_info: theory -> {name: string, session: string list, is_local: bool}
 | 
| 6203 | 37 | end; | 
| 38 | ||
| 7685 | 39 | structure Present: PRESENT = | 
| 40 | struct | |
| 41 | ||
| 7727 | 42 | |
| 43 | (** paths **) | |
| 44 | ||
| 45 | val output_path = Path.variable "ISABELLE_BROWSER_INFO"; | |
| 46 | ||
| 47 | val tex_ext = Path.ext "tex"; | |
| 48 | val tex_path = tex_ext o Path.basic; | |
| 49 | val html_ext = Path.ext "html"; | |
| 50 | val html_path = html_ext o Path.basic; | |
| 51 | val index_path = Path.basic "index.html"; | |
| 11856 | 52 | val readme_html_path = Path.basic "README.html"; | 
| 53 | val readme_path = Path.basic "README"; | |
| 7727 | 54 | val doc_path = Path.basic "document"; | 
| 8196 | 55 | val doc_indexN = "session"; | 
| 11856 | 56 | val graph_path = Path.basic "session.graph"; | 
| 57 | val graph_pdf_path = Path.basic "session_graph.pdf"; | |
| 58 | val graph_eps_path = Path.basic "session_graph.eps"; | |
| 7727 | 59 | |
| 60 | val session_path = Path.basic ".session"; | |
| 61 | val session_entries_path = Path.unpack ".session/entries"; | |
| 62 | val pre_index_path = Path.unpack ".session/pre-index"; | |
| 63 | ||
| 9044 | 64 | fun mk_rel_path [] ys = Path.make ys | 
| 65 | | mk_rel_path xs [] = Path.appends (replicate (length xs) Path.parent) | |
| 9416 | 66 | | mk_rel_path (ps as x :: xs) (qs as y :: ys) = if x = y then mk_rel_path xs ys else | 
| 9044 | 67 | Path.appends (replicate (length ps) Path.parent @ [Path.make qs]); | 
| 7727 | 68 | |
| 11856 | 69 | fun show_path path = Path.pack (Path.append (File.pwd ()) path); | 
| 70 | ||
| 7727 | 71 | |
| 72 | (** additional theory data **) | |
| 73 | ||
| 74 | structure BrowserInfoArgs = | |
| 75 | struct | |
| 76 | val name = "Pure/browser_info"; | |
| 9416 | 77 |   type T = {name: string, session: string list, is_local: bool};
 | 
| 7727 | 78 | |
| 9416 | 79 |   val empty = {name = "Pure", session = [], is_local = false};
 | 
| 7727 | 80 | val copy = I; | 
| 9452 | 81 |   fun prep_ext _ = {name = "", session = [], is_local = false};
 | 
| 7727 | 82 | fun merge _ = empty; | 
| 83 | fun print _ _ = (); | |
| 84 | end; | |
| 85 | ||
| 86 | structure BrowserInfoData = TheoryDataFun(BrowserInfoArgs); | |
| 87 | ||
| 88 | fun get_info thy = | |
| 89 | if Theory.eq_thy (thy, ProtoPure.thy) then BrowserInfoArgs.empty | |
| 90 | else BrowserInfoData.get thy; | |
| 91 | ||
| 92 | ||
| 93 | ||
| 94 | (** graphs **) | |
| 95 | ||
| 96 | type graph_node = | |
| 97 |   {name: string, ID: string, dir: string, unfold: bool,
 | |
| 98 | path: string, parents: string list}; | |
| 99 | ||
| 9416 | 100 | fun write_graph gr path = | 
| 101 |   File.write path (cat_lines (map (fn {name, ID, dir, unfold, path, parents} =>
 | |
| 102 | "\"" ^ name ^ "\" \"" ^ ID ^ "\" \"" ^ dir ^ (if unfold then "\" + \"" else "\" \"") ^ | |
| 103 | path ^ "\" > " ^ space_implode " " (map quote parents) ^ " ;") gr)); | |
| 7727 | 104 | |
| 9416 | 105 | fun ID_of sess s = space_implode "/" (sess @ [s]); | 
| 7727 | 106 | |
| 9416 | 107 | (*retrieve graph data from initial theory loader database*) | 
| 108 | fun init_graph remote_path curr_sess = map (fn name => | |
| 7727 | 109 | let | 
| 9416 | 110 |     val {name = sess_name, session, is_local} = get_info (ThyInfo.theory name);
 | 
| 111 | val path' = Path.append (Path.make session) (html_path name); | |
| 7727 | 112 | in | 
| 9416 | 113 |    {name = name, ID = ID_of session name, dir = sess_name,
 | 
| 114 | path = | |
| 115 | if null session then "" else | |
| 116 | if is_some remote_path andalso not is_local then | |
| 117 | Url.pack (Url.append (the remote_path) (Url.file | |
| 118 | (Path.append (Path.make session) (html_path name)))) | |
| 119 | else Path.pack (Path.append (mk_rel_path curr_sess session) (html_path name)), | |
| 120 | unfold = false, | |
| 121 | parents = | |
| 122 | map (fn s => ID_of (#session (get_info (ThyInfo.theory s))) s) (ThyInfo.get_preds name)} | |
| 7727 | 123 | end) (ThyInfo.names ()); | 
| 124 | ||
| 9416 | 125 | fun ins_graph_entry (entry as {ID, ...}) (gr: graph_node list) =
 | 
| 7727 | 126 | filter_out (fn entry' => #ID entry' = ID) gr @ [entry]; | 
| 127 | ||
| 128 | ||
| 129 | ||
| 130 | (** global browser info state **) | |
| 131 | ||
| 132 | (* type theory_info *) | |
| 133 | ||
| 134 | type theory_info = {tex_source: Buffer.T, html_source: Buffer.T, html: Buffer.T};
 | |
| 135 | ||
| 136 | fun make_theory_info (tex_source, html_source, html) = | |
| 137 |   {tex_source = tex_source, html_source = html_source, html = html}: theory_info;
 | |
| 138 | ||
| 139 | val empty_theory_info = make_theory_info (Buffer.empty, Buffer.empty, Buffer.empty); | |
| 140 | ||
| 141 | fun map_theory_info f {tex_source, html_source, html} =
 | |
| 142 | make_theory_info (f (tex_source, html_source, html)); | |
| 143 | ||
| 144 | ||
| 145 | (* type browser_info *) | |
| 146 | ||
| 11856 | 147 | type browser_info = {theories: theory_info Symtab.table, files: (Path.T * string) list,
 | 
| 148 | tex_index: Buffer.T, html_index: Buffer.T, graph: graph_node list}; | |
| 7727 | 149 | |
| 11856 | 150 | fun make_browser_info (theories, files, tex_index, html_index, graph) = | 
| 151 |   {theories = theories, files = files, tex_index = tex_index, html_index = html_index,
 | |
| 9416 | 152 | graph = graph}: browser_info; | 
| 7727 | 153 | |
| 11856 | 154 | val empty_browser_info = make_browser_info (Symtab.empty, [], Buffer.empty, Buffer.empty, []); | 
| 7727 | 155 | |
| 9416 | 156 | fun init_browser_info remote_path curr_sess = make_browser_info | 
| 11856 | 157 | (Symtab.empty, [], Buffer.empty, Buffer.empty, init_graph remote_path curr_sess); | 
| 7727 | 158 | |
| 11856 | 159 | fun map_browser_info f {theories, files, tex_index, html_index, graph} =
 | 
| 160 | make_browser_info (f (theories, files, tex_index, html_index, graph)); | |
| 7727 | 161 | |
| 162 | ||
| 163 | (* state *) | |
| 164 | ||
| 165 | val browser_info = ref empty_browser_info; | |
| 11057 | 166 | fun change_browser_info f = browser_info := map_browser_info f (! browser_info); | 
| 7727 | 167 | |
| 11057 | 168 | val suppress_tex_source = ref false; | 
| 169 | fun no_document f x = Library.setmp suppress_tex_source true f x; | |
| 7727 | 170 | |
| 171 | fun init_theory_info name info = | |
| 11856 | 172 | change_browser_info (fn (theories, files, tex_index, html_index, graph) => | 
| 173 | (Symtab.update ((name, info), theories), files, tex_index, html_index, graph)); | |
| 7727 | 174 | |
| 175 | fun change_theory_info name f = | |
| 11856 | 176 | change_browser_info (fn (info as (theories, files, tex_index, html_index, graph)) => | 
| 7727 | 177 | (case Symtab.lookup (theories, name) of | 
| 178 |       None => (warning ("Browser info: cannot access theory document " ^ quote name); info)
 | |
| 11856 | 179 | | Some info => (Symtab.update ((name, map_theory_info f info), theories), files, | 
| 9416 | 180 | tex_index, html_index, graph))); | 
| 7727 | 181 | |
| 182 | ||
| 11856 | 183 | fun add_file file = | 
| 184 | change_browser_info (fn (theories, files, tex_index, html_index, graph) => | |
| 185 | (theories, file :: files, tex_index, html_index, graph)); | |
| 186 | ||
| 7727 | 187 | fun add_tex_index txt = | 
| 11856 | 188 | change_browser_info (fn (theories, files, tex_index, html_index, graph) => | 
| 189 | (theories, files, Buffer.add txt tex_index, html_index, graph)); | |
| 7727 | 190 | |
| 191 | fun add_html_index txt = | |
| 11856 | 192 | change_browser_info (fn (theories, files, tex_index, html_index, graph) => | 
| 193 | (theories, files, tex_index, Buffer.add txt html_index, graph)); | |
| 7727 | 194 | |
| 195 | fun add_graph_entry e = | |
| 11856 | 196 | change_browser_info (fn (theories, files, tex_index, html_index, graph) => | 
| 197 | (theories, files, tex_index, html_index, ins_graph_entry e graph)); | |
| 7727 | 198 | |
| 11057 | 199 | fun add_tex_source name txt = | 
| 200 | if ! suppress_tex_source then () | |
| 201 | else change_theory_info name (fn (tex_source, html_source, html) => | |
| 202 | (Buffer.add txt tex_source, html_source, html)); | |
| 7727 | 203 | |
| 204 | fun add_html_source name txt = change_theory_info name (fn (tex_source, html_source, html) => | |
| 205 | (tex_source, Buffer.add txt html_source, html)); | |
| 206 | ||
| 207 | fun add_html name txt = change_theory_info name (fn (tex_source, html_source, html) => | |
| 208 | (tex_source, html_source, Buffer.add txt html)); | |
| 209 | ||
| 210 | ||
| 211 | ||
| 212 | (** global session state **) | |
| 213 | ||
| 214 | (* session_info *) | |
| 215 | ||
| 216 | type session_info = | |
| 217 |   {name: string, parent: string, session: string, path: string list, html_prefix: Path.T,
 | |
| 11856 | 218 | info: bool, doc_format: string, doc_graph: bool, doc_prefix1: Path.T option, | 
| 219 | doc_prefix2: Path.T option, remote_path: Url.T option, verbose: bool, readme: Path.T option}; | |
| 7727 | 220 | |
| 9416 | 221 | fun make_session_info | 
| 11856 | 222 | (name, parent, session, path, html_prefix, info, doc_format, doc_graph, doc_prefix1, | 
| 223 | doc_prefix2, remote_path, verbose, readme) = | |
| 7802 | 224 |   {name = name, parent = parent, session = session, path = path, html_prefix = html_prefix,
 | 
| 11856 | 225 | info = info, doc_format = doc_format, doc_graph = doc_graph, doc_prefix1 = doc_prefix1, | 
| 226 | doc_prefix2 = doc_prefix2, remote_path = remote_path, verbose = verbose, | |
| 227 | readme = readme}: session_info; | |
| 7685 | 228 | |
| 229 | ||
| 7727 | 230 | (* state *) | 
| 231 | ||
| 232 | val session_info = ref (None: session_info option); | |
| 233 | ||
| 234 | fun with_session x f = (case ! session_info of None => x | Some info => f info); | |
| 235 | fun with_context f = f (PureThy.get_name (Context.the_context ())); | |
| 236 | ||
| 237 | ||
| 238 | ||
| 239 | (** HTML output **) | |
| 240 | ||
| 241 | (* maintain index *) | |
| 242 | ||
| 243 | val session_entries = | |
| 244 | HTML.session_entries o | |
| 245 | map (fn name => (Url.file (Path.append (Path.basic name) index_path), name)); | |
| 246 | ||
| 247 | fun get_entries dir = | |
| 248 | split_lines (File.read (Path.append dir session_entries_path)); | |
| 249 | ||
| 250 | fun put_entries entries dir = | |
| 251 | File.write (Path.append dir session_entries_path) (cat_lines entries); | |
| 252 | ||
| 253 | ||
| 254 | fun create_index dir = | |
| 255 | File.read (Path.append dir pre_index_path) ^ | |
| 256 | session_entries (get_entries dir) ^ HTML.end_index | |
| 257 | |> File.write (Path.append dir index_path); | |
| 258 | ||
| 259 | fun update_index dir name = | |
| 260 | (case try get_entries dir of | |
| 261 |     None => warning ("Browser info: cannot access session index of " ^ quote (Path.pack dir))
 | |
| 262 | | Some es => (put_entries ((es \ name) @ [name]) dir; create_index dir)); | |
| 263 | ||
| 264 | ||
| 265 | (* init session *) | |
| 266 | ||
| 267 | fun name_of_session elems = space_implode "/" ("Isabelle" :: elems);
 | |
| 268 | ||
| 9044 | 269 | fun copy_files path1 path2 = | 
| 270 | (File.mkdir path2; | |
| 9795 | 271 | File.system_command (*FIXME: quote paths!?*) | 
| 272 |      ("cp " ^ File.sysify_path path1 ^ " " ^ File.sysify_path path2));
 | |
| 9044 | 273 | |
| 9416 | 274 | |
| 11911 
6533ceee4cd7
build option enables most basic browser info (for proper recording of session);
 wenzelm parents: 
11856diff
changeset | 275 | fun init build info doc doc_graph path name doc_prefix2 (remote_path, first_time) verbose = | 
| 
6533ceee4cd7
build option enables most basic browser info (for proper recording of session);
 wenzelm parents: 
11856diff
changeset | 276 | if not build andalso not info andalso doc = "" andalso is_none doc_prefix2 then | 
| 11856 | 277 | (browser_info := empty_browser_info; session_info := None) | 
| 278 | else | |
| 279 | let | |
| 280 | val parent_name = name_of_session (Library.take (length path - 1, path)); | |
| 281 | val session_name = name_of_session path; | |
| 282 | val sess_prefix = Path.make path; | |
| 283 | val html_prefix = Path.append (Path.expand output_path) sess_prefix; | |
| 7727 | 284 | |
| 11856 | 285 | val (doc_prefix1, document_path) = | 
| 286 | if doc = "" then (None, None) | |
| 287 | else if not (File.exists doc_path) then (conditional verbose (fn () => | |
| 288 | std_error "Warning: missing document directory\n"); (None, None)) | |
| 289 | else (Some (Path.append html_prefix doc_path), Some (Path.ext doc doc_path)); | |
| 7727 | 290 | |
| 11856 | 291 | val parent_index_path = Path.append Path.parent index_path; | 
| 292 | val index_up_lnk = if first_time then | |
| 293 | Url.append (the remote_path) (Url.file (Path.append sess_prefix parent_index_path)) | |
| 294 | else Url.file parent_index_path; | |
| 295 | val readme = | |
| 296 | if File.exists readme_html_path then Some readme_html_path | |
| 297 | else if File.exists readme_path then Some readme_path | |
| 298 | else None; | |
| 7727 | 299 | |
| 11856 | 300 | val index_text = HTML.begin_index (index_up_lnk, parent_name) | 
| 301 | (Url.file index_path, session_name) (apsome Url.file readme) | |
| 302 | (apsome Url.file document_path) (Url.unpack "medium.html"); | |
| 303 | in | |
| 304 | session_info := Some (make_session_info (name, parent_name, session_name, path, html_prefix, | |
| 305 | info, doc, doc_graph, doc_prefix1, doc_prefix2, remote_path, verbose, readme)); | |
| 306 | browser_info := init_browser_info remote_path path; | |
| 307 | add_html_index index_text | |
| 308 | end; | |
| 7727 | 309 | |
| 310 | ||
| 11856 | 311 | (* finish session -- output all generated text *) | 
| 312 | ||
| 313 | fun write_tex src name path = Buffer.write (Path.append path (tex_path name)) src; | |
| 7685 | 314 | |
| 11856 | 315 | fun isatool_document doc_format path = | 
| 316 | let val s = "\"$ISATOOL\" document -c -o '" ^ doc_format ^ "' " ^ File.quote_sysify_path path in | |
| 317 | writeln s; | |
| 318 | if system s <> 0 orelse not (File.exists (Path.ext doc_format path)) then | |
| 8646 
1a2c5ccebfdb
isatool document: check output file (workaround PolyML problem with RC);
 wenzelm parents: 
8499diff
changeset | 319 | error "Failed to build document" | 
| 
1a2c5ccebfdb
isatool document: check output file (workaround PolyML problem with RC);
 wenzelm parents: 
8499diff
changeset | 320 | else () | 
| 
1a2c5ccebfdb
isatool document: check output file (workaround PolyML problem with RC);
 wenzelm parents: 
8499diff
changeset | 321 | end; | 
| 7802 | 322 | |
| 11856 | 323 | fun isatool_browser graph = | 
| 324 | let | |
| 325 | val pdfpath = File.tmp_path graph_pdf_path; | |
| 326 | val epspath = File.tmp_path graph_eps_path; | |
| 327 | val gpath = File.tmp_path graph_path; | |
| 328 | val s = "\"$ISATOOL\" browser -o " ^ File.quote_sysify_path pdfpath ^ " " ^ | |
| 329 | File.quote_sysify_path gpath; | |
| 330 | in | |
| 331 | write_graph graph gpath; | |
| 332 | if system s <> 0 orelse not (File.exists epspath) orelse not (File.exists pdfpath) then | |
| 333 | error "Failed to prepare dependency graph" | |
| 334 | else | |
| 335 | let val pdf = File.read pdfpath and eps = File.read epspath | |
| 336 | in File.rm pdfpath; File.rm epspath; File.rm gpath; (pdf, eps) end | |
| 337 | end; | |
| 8196 | 338 | |
| 11856 | 339 | fun finish () = with_session () (fn {name, info, html_prefix, doc_format, doc_graph,
 | 
| 340 | doc_prefix1, doc_prefix2, path, verbose, readme, ...} => | |
| 7727 | 341 | let | 
| 11856 | 342 |     val {theories, files, tex_index, html_index, graph} = ! browser_info;
 | 
| 343 | val thys = Symtab.dest theories; | |
| 9416 | 344 | val parent_html_prefix = Path.append html_prefix Path.parent; | 
| 7727 | 345 | |
| 11856 | 346 |     fun finish_tex path (a, {tex_source, ...}: theory_info) = write_tex tex_source a path;
 | 
| 347 |     fun finish_html (a, {html, ...}: theory_info) =
 | |
| 348 | Buffer.write (Path.append html_prefix (html_path a)) (Buffer.add HTML.end_theory html); | |
| 349 | ||
| 350 | val opt_graphs = | |
| 351 | if doc_graph andalso (is_some doc_prefix1 orelse is_some doc_prefix2) then | |
| 352 | Some (isatool_browser graph) | |
| 353 | else None; | |
| 354 | ||
| 355 | fun doc_common path = | |
| 356 | ((case opt_graphs of None => () | Some (pdf, eps) => | |
| 357 | (File.write (Path.append path graph_pdf_path) pdf; | |
| 358 | File.write (Path.append path graph_eps_path) eps)); | |
| 359 | write_tex (Buffer.add Latex.tex_trailer tex_index) doc_indexN path; | |
| 360 | seq (finish_tex path) thys); | |
| 7727 | 361 | in | 
| 11856 | 362 | conditional info (fn () => | 
| 363 | (File.mkdir (Path.append html_prefix session_path); | |
| 364 | Buffer.write (Path.append html_prefix pre_index_path) html_index; | |
| 365 | File.write (Path.append html_prefix session_entries_path) ""; | |
| 366 | create_index html_prefix; | |
| 367 | if length path > 1 then update_index parent_html_prefix name else (); | |
| 368 | (case readme of None => () | Some path => File.copy path (Path.append html_prefix path)); | |
| 369 | write_graph graph (Path.append html_prefix graph_path); | |
| 370 | copy_files (Path.unpack "~~/lib/browser/awtUtilities/*.class") | |
| 371 | (Path.append html_prefix (Path.basic "awtUtilities")); | |
| 372 | copy_files (Path.unpack "~~/lib/browser/GraphBrowser/*.class") | |
| 373 | (Path.append html_prefix (Path.basic "GraphBrowser")); | |
| 374 | seq (fn (a, txt) => File.write (Path.append html_prefix (Path.basic a)) txt) | |
| 375 | (HTML.applet_pages name (Url.file index_path, name)); | |
| 376 | seq finish_html thys; | |
| 377 | seq (uncurry File.write) files; | |
| 378 | conditional verbose (fn () => | |
| 379 |         std_error ("Browser info at " ^ show_path html_prefix ^ "\n"))));
 | |
| 380 | ||
| 381 | (case doc_prefix1 of None => () | Some path => | |
| 382 | (File.mkdir html_prefix; | |
| 383 | File.copy_all doc_path html_prefix; | |
| 384 | doc_common path; | |
| 385 | isatool_document doc_format path; | |
| 386 | conditional verbose (fn () => | |
| 387 |         std_error ("Document at " ^ show_path (Path.ext doc_format path) ^ "\n"))));
 | |
| 388 | ||
| 389 | (case doc_prefix2 of None => () | Some path => | |
| 390 | (File.mkdir path; | |
| 391 | copy_files (Path.unpack "~~/lib/texinputs/*.sty") path; | |
| 392 | doc_common path; | |
| 393 |       conditional verbose (fn () => std_error ("Document sources at " ^ show_path path ^ "\n"))));
 | |
| 394 | ||
| 7727 | 395 | browser_info := empty_browser_info; | 
| 396 | session_info := None | |
| 397 | end); | |
| 398 | ||
| 399 | ||
| 400 | (* theory elements *) | |
| 401 | ||
| 402 | fun init_theory name = with_session () (fn _ => init_theory_info name empty_theory_info); | |
| 403 | ||
| 404 | fun verbatim_source name mk_text = | |
| 405 | with_session () (fn _ => add_html_source name (HTML.verbatim_source (mk_text ()))); | |
| 406 | ||
| 8192 | 407 | fun old_symbol_source name mk_text = | 
| 8499 | 408 | with_session () (fn _ => add_tex_source name (Latex.old_symbol_source name (mk_text ()))); | 
| 8192 | 409 | |
| 9136 | 410 | fun theory_output name s = | 
| 9917 | 411 | with_session () (fn _ => add_tex_source name (Latex.isabelle_file name s)); | 
| 7727 | 412 | |
| 413 | ||
| 414 | fun parent_link remote_path curr_session name = | |
| 9416 | 415 |   let val {name = _, session, is_local} = get_info (ThyInfo.theory name)
 | 
| 7727 | 416 | in (if null session then None else | 
| 417 | Some (if is_some remote_path andalso not is_local then | |
| 9044 | 418 | Url.append (the remote_path) (Url.file | 
| 419 | (Path.append (Path.make session) (html_path name))) | |
| 420 | else Url.file (Path.append (mk_rel_path curr_session session) | |
| 421 | (html_path name))), name) | |
| 7727 | 422 | end; | 
| 423 | ||
| 424 | fun begin_theory name raw_parents orig_files thy = | |
| 9416 | 425 |     with_session thy (fn {name = sess_name, session, path, html_prefix, remote_path, ...} =>
 | 
| 7727 | 426 | let | 
| 427 | val parents = map (parent_link remote_path path) raw_parents; | |
| 428 | val ml_path = ThyLoad.ml_path name; | |
| 429 | val files = map (apsnd Some) orig_files @ | |
| 430 | (if is_some (ThyLoad.check_file ml_path) then [(ml_path, None)] else []); | |
| 431 | ||
| 432 | fun prep_file (raw_path, loadit) = | |
| 433 | (case ThyLoad.check_file raw_path of | |
| 434 | Some (path, _) => | |
| 435 | let | |
| 436 | val base = Path.base path; | |
| 437 | val base_html = html_ext base; | |
| 438 | in | |
| 11856 | 439 | add_file (Path.append html_prefix base_html, | 
| 440 | HTML.ml_file (Url.file base) (File.read path)); | |
| 7727 | 441 | (Some (Url.file base_html), Url.file raw_path, loadit) | 
| 442 | end | |
| 443 |       | None => (warning ("Browser info: expected to find ML file" ^ quote (Path.pack raw_path));
 | |
| 444 | (None, Url.file raw_path, loadit))); | |
| 445 | ||
| 446 | val files_html = map prep_file files; | |
| 447 | ||
| 448 | fun prep_html_source (tex_source, html_source, html) = | |
| 449 | let | |
| 450 | val txt = HTML.begin_theory (Url.file index_path, session) | |
| 451 | name parents files_html (Buffer.content html_source) | |
| 452 | in (tex_source, Buffer.empty, Buffer.add txt html) end; | |
| 453 | ||
| 9416 | 454 | val entry = | 
| 455 |      {name = name, ID = ID_of path name, dir = sess_name, unfold = true,
 | |
| 456 | path = Path.pack (html_path name), | |
| 457 | parents = map (fn s => ID_of (#session (get_info (ThyInfo.theory s))) s) raw_parents}; | |
| 7727 | 458 | |
| 459 | in | |
| 460 | change_theory_info name prep_html_source; | |
| 9416 | 461 | add_graph_entry entry; | 
| 7727 | 462 | add_html_index (HTML.theory_entry (Url.file (html_path name), name)); | 
| 463 | add_tex_index (Latex.theory_entry name); | |
| 9416 | 464 |     BrowserInfoData.put {name = sess_name, session = path, is_local = is_some remote_path} thy
 | 
| 7727 | 465 | end); | 
| 466 | ||
| 467 | ||
| 12151 | 468 | fun multi_result res = with_session () (fn _ => with_context add_html (HTML.multi_result res)); | 
| 7727 | 469 | fun results k a thms = with_session () (fn _ => with_context add_html (HTML.results k a thms)); | 
| 470 | fun theorem a thm = with_session () (fn _ => with_context add_html (HTML.theorem a thm)); | |
| 471 | fun theorems a thms = with_session () (fn _ => with_context add_html (HTML.theorems a thms)); | |
| 8088 | 472 | fun chapter s = with_session () (fn _ => with_context add_html (HTML.chapter s)); | 
| 7727 | 473 | fun section s = with_session () (fn _ => with_context add_html (HTML.section s)); | 
| 474 | fun subsection s = with_session () (fn _ => with_context add_html (HTML.subsection s)); | |
| 475 | fun subsubsection s = with_session () (fn _ => with_context add_html (HTML.subsubsection s)); | |
| 476 | ||
| 477 | ||
| 478 | ||
| 479 | (** theory setup **) | |
| 480 | ||
| 481 | val setup = [BrowserInfoData.init]; | |
| 7685 | 482 | |
| 483 | ||
| 484 | end; | |
| 485 | ||
| 6203 | 486 | |
| 487 | structure BasicPresent: BASIC_PRESENT = Present; | |
| 488 | open BasicPresent; |