18 |
18 |
19 /* HTML context */ |
19 /* HTML context */ |
20 |
20 |
21 sealed case class HTML_Document(title: String, content: String) |
21 sealed case class HTML_Document(title: String, content: String) |
22 |
22 |
23 class HTML_Context |
23 abstract class HTML_Context |
24 { |
24 { |
|
25 /* directory structure */ |
|
26 |
|
27 def root_dir: Path |
|
28 def theory_session(name: Document.Node.Name): Sessions.Info |
|
29 |
|
30 def session_dir(info: Sessions.Info): Path = |
|
31 root_dir + Path.explode(info.chapter_session) |
|
32 def theory_path(name: Document.Node.Name): Path = |
|
33 session_dir(theory_session(name)) + Path.explode(name.theory_base_name).html |
|
34 def files_path(name: Document.Node.Name, path: Path): Path = |
|
35 theory_path(name).dir + Path.explode("files") + path.squash.html |
|
36 |
|
37 |
25 /* cached theory exports */ |
38 /* cached theory exports */ |
26 |
39 |
27 val cache: Term.Cache = Term.Cache.make() |
40 val cache: Term.Cache = Term.Cache.make() |
28 |
41 |
29 private val already_presented = Synchronized(Set.empty[String]) |
42 private val already_presented = Synchronized(Set.empty[String]) |
435 |
448 |
436 /* present session */ |
449 /* present session */ |
437 |
450 |
438 val session_graph_path = Path.explode("session_graph.pdf") |
451 val session_graph_path = Path.explode("session_graph.pdf") |
439 val readme_path = Path.explode("README.html") |
452 val readme_path = Path.explode("README.html") |
440 val files_path = Path.explode("files") |
|
441 |
453 |
442 def html_name(name: Document.Node.Name): String = Path.explode(name.theory_base_name).html.implode |
454 def html_name(name: Document.Node.Name): String = Path.explode(name.theory_base_name).html.implode |
443 def html_path(path: Path): String = (files_path + path.squash.html).implode |
455 def files_path(src_path: Path): String = (Path.explode("files") + src_path.squash.html).implode |
444 |
456 |
445 private def node_file(node: Document.Node.Name): String = |
457 private def node_file(name: Document.Node.Name): String = |
446 if (node.node.endsWith(".thy")) html_name(node) else html_path(Path.explode(node.node)) |
458 if (name.node.endsWith(".thy")) html_name(name) else files_path(name.path) |
447 |
459 |
448 private def session_relative(deps: Sessions.Deps, session0: String, session1: String): Option[String] = |
460 private def session_relative(deps: Sessions.Deps, session0: String, session1: String): Option[String] = |
449 { |
461 { |
450 for { |
462 for { |
451 info0 <- deps.sessions_structure.get(session0) |
463 info0 <- deps.sessions_structure.get(session0) |
480 deps: Sessions.Deps, |
492 deps: Sessions.Deps, |
481 db_context: Sessions.Database_Context, |
493 db_context: Sessions.Database_Context, |
482 progress: Progress = new Progress, |
494 progress: Progress = new Progress, |
483 verbose: Boolean = false, |
495 verbose: Boolean = false, |
484 html_context: HTML_Context, |
496 html_context: HTML_Context, |
485 session_elements: Elements, |
497 session_elements: Elements): Unit = |
486 presentation: Context): Unit = |
|
487 { |
498 { |
488 val hierarchy = deps.sessions_structure.hierarchy(session) |
499 val hierarchy = deps.sessions_structure.hierarchy(session) |
489 val info = deps.sessions_structure(session) |
500 val info = deps.sessions_structure(session) |
490 val options = info.options |
501 val options = info.options |
491 val base = deps(session) |
502 val base = deps(session) |
492 |
503 |
493 def make_session_dir(name: String): Path = |
504 val session_dir = Isabelle_System.make_directory(html_context.session_dir(info)) |
494 Isabelle_System.make_directory( |
|
495 presentation.dir(db_context.store, deps.sessions_structure(name))) |
|
496 |
|
497 val session_dir = make_session_dir(session) |
|
498 val presentation_dir = presentation.dir(db_context.store) |
|
499 |
505 |
500 Bytes.write(session_dir + session_graph_path, |
506 Bytes.write(session_dir + session_graph_path, |
501 graphview.Graph_File.make_pdf(options, base.session_graph_display)) |
507 graphview.Graph_File.make_pdf(options, base.session_graph_display)) |
502 |
508 |
503 val documents = |
509 val documents = |
558 Entity_Context.make(session, deps, name, theory_exports) |
564 Entity_Context.make(session, deps, name, theory_exports) |
559 |
565 |
560 val theories: List[XML.Body] = |
566 val theories: List[XML.Body] = |
561 { |
567 { |
562 sealed case class Seen_File( |
568 sealed case class Seen_File( |
563 src_path: Path, file_name: String, thy_session: String, thy_name: Document.Node.Name) |
569 src_path: Path, thy_name: Document.Node.Name, thy_session: String) |
564 { |
570 { |
565 def check(src_path1: Path, file_name1: String, thy_session1: String): Boolean = |
571 val files_path: Path = html_context.files_path(thy_name, src_path) |
566 (src_path == src_path1 || file_name == file_name1) && thy_session == thy_session1 |
572 |
|
573 def check(src_path1: Path, thy_name1: Document.Node.Name, thy_session1: String): Boolean = |
|
574 { |
|
575 val files_path1 = html_context.files_path(thy_name1, src_path1) |
|
576 (src_path == src_path1 || files_path == files_path1) && thy_session == thy_session1 |
|
577 } |
567 } |
578 } |
568 var seen_files = List.empty[Seen_File] |
579 var seen_files = List.empty[Seen_File] |
569 |
580 |
570 sealed case class Theory( |
581 sealed case class Theory( |
571 name: Document.Node.Name, |
582 name: Document.Node.Name, |
607 Theory(name, command, files_html, html) |
618 Theory(name, command, files_html, html) |
608 } |
619 } |
609 } |
620 } |
610 |
621 |
611 (for (thy <- Par_List.map(read_theory, present_theories).flatten) yield { |
622 (for (thy <- Par_List.map(read_theory, present_theories).flatten) yield { |
612 val thy_session = base.theory_qualifier(thy.name) |
623 val thy_session = html_context.theory_session(thy.name) |
613 val thy_dir = make_session_dir(thy_session) |
624 val thy_dir = Isabelle_System.make_directory(html_context.session_dir(thy_session)) |
614 val files = |
625 val files = |
615 for { (src_path, file_html) <- thy.files_html } |
626 for { (src_path, file_html) <- thy.files_html } |
616 yield { |
627 yield { |
617 val file_name = html_path(src_path) |
628 seen_files.find(_.check(src_path, thy.name, thy_session.name)) match { |
618 |
629 case None => seen_files ::= Seen_File(src_path, thy.name, thy_session.name) |
619 seen_files.find(_.check(src_path, file_name, thy_session)) match { |
|
620 case None => seen_files ::= Seen_File(src_path, file_name, thy_session, thy.name) |
|
621 case Some(seen_file) => |
630 case Some(seen_file) => |
622 error("Incoherent use of file name " + src_path + " as " + quote(file_name) + |
631 error("Incoherent use of file name " + src_path + " as " + files_path(src_path) + |
623 " in theory " + seen_file.thy_name + " vs. " + thy.name) |
632 " in theory " + seen_file.thy_name + " vs. " + thy.name) |
624 } |
633 } |
625 |
634 |
626 val file_path = thy_dir + Path.explode(file_name) |
635 val file_path = html_context.files_path(thy.name, src_path) |
627 val file_title = "File " + Symbol.cartouche_decoded(src_path.implode_short) |
636 val file_title = "File " + Symbol.cartouche_decoded(src_path.implode_short) |
628 HTML.write_document(file_path.dir, file_path.file_name, |
637 HTML.write_document(file_path.dir, file_path.file_name, |
629 List(HTML.title(file_title)), List(html_context.head(file_title), file_html), |
638 List(HTML.title(file_title)), List(html_context.head(file_title), file_html), |
630 base = Some(presentation_dir)) |
639 base = Some(html_context.root_dir)) |
631 |
640 |
632 List(HTML.link(file_name, HTML.text(file_title))) |
641 List(HTML.link(files_path(src_path), HTML.text(file_title))) |
633 } |
642 } |
634 |
643 |
635 val thy_title = "Theory " + thy.name.theory_base_name |
644 val thy_title = "Theory " + thy.name.theory_base_name |
636 |
645 |
637 HTML.write_document(thy_dir, html_name(thy.name), |
646 HTML.write_document(thy_dir, html_name(thy.name), |
638 List(HTML.title(thy_title)), List(html_context.head(thy_title), thy.html), |
647 List(HTML.title(thy_title)), List(html_context.head(thy_title), thy.html), |
639 base = Some(presentation_dir)) |
648 base = Some(html_context.root_dir)) |
640 |
649 |
641 if (thy_session == session) { |
650 if (thy_session.name == session) { |
642 Some( |
651 Some( |
643 List(HTML.link(html_name(thy.name), |
652 List(HTML.link(html_name(thy.name), |
644 HTML.text(thy.name.theory_base_name) ::: |
653 HTML.text(thy.name.theory_base_name) ::: |
645 (if (files.isEmpty) Nil else List(HTML.itemize(files)))))) |
654 (if (files.isEmpty) Nil else List(HTML.itemize(files)))))) |
646 } |
655 } |
651 val title = "Session " + session |
660 val title = "Session " + session |
652 HTML.write_document(session_dir, "index.html", |
661 HTML.write_document(session_dir, "index.html", |
653 List(HTML.title(title + Isabelle_System.isabelle_heading())), |
662 List(HTML.title(title + Isabelle_System.isabelle_heading())), |
654 html_context.head(title, List(HTML.par(view_links))) :: |
663 html_context.head(title, List(HTML.par(view_links))) :: |
655 html_context.contents("Theories", theories), |
664 html_context.contents("Theories", theories), |
656 base = Some(presentation_dir)) |
665 base = Some(html_context.root_dir)) |
657 } |
666 } |
658 } |
667 } |