src/Pure/Build/file_format.scala
changeset 79502 c7a98469c0e7
parent 76860 f95ed5a0600c
equal deleted inserted replaced
79501:bce98b5dfec6 79502:c7a98469c0e7
       
     1 /*  Title:      Pure/Build/file_format.scala
       
     2     Author:     Makarius
       
     3 
       
     4 Support for user-defined file formats, associated with active session.
       
     5 */
       
     6 
       
     7 package isabelle
       
     8 
       
     9 
       
    10 object File_Format {
       
    11   object No_Data extends AnyRef {
       
    12     override def toString: String = "File_Format.No_Data"
       
    13   }
       
    14 
       
    15   sealed case class Theory_Context(name: Document.Node.Name, content: String)
       
    16 
       
    17 
       
    18   /* registry */
       
    19 
       
    20   lazy val registry: Registry =
       
    21     new Registry(Isabelle_System.make_services(classOf[File_Format]))
       
    22 
       
    23   final class Registry private [File_Format](file_formats: List[File_Format]) {
       
    24     override def toString: String = file_formats.mkString("File_Format.Environment(", ",", ")")
       
    25 
       
    26     def get(name: String): Option[File_Format] = file_formats.find(_.detect(name))
       
    27     def get(name: Document.Node.Name): Option[File_Format] = get(name.node)
       
    28     def get_theory(name: Document.Node.Name): Option[File_Format] = get(name.theory)
       
    29     def is_theory(name: Document.Node.Name): Boolean = get_theory(name).isDefined
       
    30 
       
    31     def theory_excluded(name: String): Boolean = file_formats.exists(_.theory_excluded(name))
       
    32 
       
    33     def parse_data(name: String, text: String): AnyRef =
       
    34       get(name) match {
       
    35         case Some(file_format) => file_format.parse_data(name, text)
       
    36         case None => No_Data
       
    37       }
       
    38     def parse_data(name: Document.Node.Name, text: String): AnyRef = parse_data(name.node, text)
       
    39 
       
    40     def start_session(session: isabelle.Session): Session =
       
    41       new Session(file_formats.map(_.start(session)).filterNot(_ == No_Agent))
       
    42   }
       
    43 
       
    44 
       
    45   /* session */
       
    46 
       
    47   final class Session private[File_Format](agents: List[Agent]) {
       
    48     override def toString: String =
       
    49       agents.mkString("File_Format.Session(", ", ", ")")
       
    50 
       
    51     def prover_options(options: Options): Options =
       
    52       agents.foldLeft(options) { case (opts, agent) => agent.prover_options(opts) }
       
    53 
       
    54     def stop_session(): Unit = agents.foreach(_.stop())
       
    55   }
       
    56 
       
    57   trait Agent {
       
    58     def prover_options(options: Options): Options = options
       
    59     def stop(): Unit = {}
       
    60   }
       
    61 
       
    62   object No_Agent extends Agent
       
    63 }
       
    64 
       
    65 abstract class File_Format extends Isabelle_System.Service {
       
    66   def format_name: String
       
    67   override def toString: String = "File_Format(" + format_name + ")"
       
    68 
       
    69   def file_ext: String
       
    70   def detect(name: String): Boolean = name.endsWith("." + file_ext)
       
    71 
       
    72   def parse_data(name: String, text: String): AnyRef = File_Format.No_Data
       
    73 
       
    74 
       
    75   /* implicit theory context: name and content */
       
    76 
       
    77   def theory_suffix: String = ""
       
    78   def theory_content(name: String): String = ""
       
    79   def theory_excluded(name: String): Boolean = false
       
    80 
       
    81   def make_theory_name(
       
    82     resources: Resources,
       
    83     name: Document.Node.Name
       
    84   ): Option[Document.Node.Name] = {
       
    85     for {
       
    86       theory <- Url.get_base_name(name.node)
       
    87       if detect(name.node) && theory_suffix.nonEmpty
       
    88     }
       
    89     yield {
       
    90       val node = resources.append_path(name.node, Path.explode(theory_suffix))
       
    91       Document.Node.Name(node, theory = theory)
       
    92     }
       
    93   }
       
    94 
       
    95   def make_theory_content(resources: Resources, thy_name: Document.Node.Name): Option[String] = {
       
    96     for {
       
    97       prefix <- Url.strip_base_name(thy_name.node)
       
    98       suffix <- Url.get_base_name(thy_name.node)
       
    99       if detect(prefix) && suffix == theory_suffix
       
   100       thy <- Url.get_base_name(prefix)
       
   101       s <- proper_string(theory_content(thy))
       
   102     } yield s
       
   103   }
       
   104 
       
   105   def html_document(snapshot: Document.Snapshot): Option[Browser_Info.HTML_Document] = None
       
   106 
       
   107 
       
   108   /* PIDE session agent */
       
   109 
       
   110   def start(session: isabelle.Session): File_Format.Agent = File_Format.No_Agent
       
   111 }