src/Pure/Isar/isar_document.scala
author wenzelm
Sat, 07 Aug 2010 22:09:52 +0200
changeset 38230 ed147003de4b
parent 38150 67fc24df3721
child 38231 968844caaff9
permissions -rw-r--r--
simplified type XML.Tree: embed Markup directly, avoid slightly odd triple; XML.cache_tree: actually store XML.Text as well; added Isabelle_Process.Result.properties;

/*  Title:      Pure/Isar/isar_document.scala
    Author:     Makarius

Interactive Isar documents.
*/

package isabelle


object Isar_Document
{
  /* reports */

  object Assign {
    def unapply(msg: XML.Tree): Option[List[XML.Tree]] =
      msg match {
        case XML.Elem(Markup(Markup.ASSIGN, Nil), edits) => Some(edits)
        case _ => None
      }
  }

  object Edit {
    def unapply(msg: XML.Tree): Option[(Document.Command_ID, Document.State_ID)] =
      msg match {
        case XML.Elem(Markup(Markup.EDIT, List((Markup.ID, cmd_id), (Markup.STATE, state_id))), Nil) =>
          Some(cmd_id, state_id)
        case _ => None
      }
  }
}


trait Isar_Document extends Isabelle_Process
{
  import Isar_Document._


  /* commands */

  def define_command(id: Document.Command_ID, text: String) {
    output_sync("Isar.define_command " + Isabelle_Syntax.encode_string(id) + " " +
      Isabelle_Syntax.encode_string(text))
  }


  /* documents */

  def edit_document(old_id: Document.Version_ID, new_id: Document.Version_ID,
      edits: List[Document.Edit[Document.Command_ID]])
  {
    def append_edit(
        edit: (Option[Document.Command_ID], Option[Document.Command_ID]), result: StringBuilder)
    {
      Isabelle_Syntax.append_string(edit._1 getOrElse Document.NO_ID, result)
      edit._2 match {
        case None =>
        case Some(id2) =>
          result.append(" ")
          Isabelle_Syntax.append_string(id2, result)
      }
    }

    def append_node_edit(
        edit: (String, Option[List[(Option[Document.Command_ID], Option[Document.Command_ID])]]),
        result: StringBuilder)
    {
      Isabelle_Syntax.append_string(edit._1, result)
      edit._2 match {
        case None =>
        case Some(eds) =>
          result.append(" ")
          Isabelle_Syntax.append_list(append_edit, eds, result)
      }
    }

    val buf = new StringBuilder(40)
    buf.append("Isar.edit_document ")
    Isabelle_Syntax.append_string(old_id, buf)
    buf.append(" ")
    Isabelle_Syntax.append_string(new_id, buf)
    buf.append(" ")
    Isabelle_Syntax.append_list(append_node_edit, edits, buf)
    output_sync(buf.toString)
  }
}