src/Pure/Thy/presentation.scala
changeset 74770 32c2587cda4f
parent 74769 5d84f0312a3a
child 74782 0a87ea7eb76f
equal deleted inserted replaced
74769:5d84f0312a3a 74770:32c2587cda4f
    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 }