src/Pure/Thy/thy_syntax.scala
changeset 44157 a21d3e1e64fd
parent 44156 6aa25b80e1a5
child 44160 8848867501fb
equal deleted inserted replaced
44156:6aa25b80e1a5 44157:a21d3e1e64fd
   100   /** text edits **/
   100   /** text edits **/
   101 
   101 
   102   def text_edits(
   102   def text_edits(
   103       syntax: Outer_Syntax,
   103       syntax: Outer_Syntax,
   104       previous: Document.Version,
   104       previous: Document.Version,
   105       edits: List[Document.Edit_Text],
   105       edits: List[Document.Edit_Text])
   106       headers: List[(String, Document.Node.Header)])
   106     : (List[Document.Edit_Command], Document.Version) =
   107     : (List[Document.Edit_Command], List[(String, Thy_Header.Header)], Document.Version) =
       
   108   {
   107   {
   109     /* phase 1: edit individual command source */
   108     /* phase 1: edit individual command source */
   110 
   109 
   111     @tailrec def edit_text(eds: List[Text.Edit], commands: Linear_Set[Command])
   110     @tailrec def edit_text(eds: List[Text.Edit], commands: Linear_Set[Command])
   112         : Linear_Set[Command] =
   111         : Linear_Set[Command] =
   171         case None => commands
   170         case None => commands
   172       }
   171       }
   173     }
   172     }
   174 
   173 
   175 
   174 
   176     /* node header */
       
   177 
       
   178     def node_header(name: String, node: Document.Node)
       
   179         : (List[(String, Thy_Header.Header)], Document.Node.Header) =
       
   180       (node.header.thy_header, headers.find(p => p._1 == name).map(_._2)) match {
       
   181         case (Exn.Res(thy_header0), Some(header @ Document.Node.Header(_, Exn.Res(thy_header))))
       
   182         if thy_header0 != thy_header =>
       
   183           (List((name, thy_header)), header)
       
   184         case (Exn.Exn(_), Some(header @ Document.Node.Header(_, Exn.Res(thy_header)))) =>
       
   185           (List((name, thy_header)), header)
       
   186         case _ => (Nil, node.header)
       
   187       }
       
   188 
       
   189 
       
   190     /* resulting document edits */
   175     /* resulting document edits */
   191 
   176 
   192     {
   177     {
   193       val doc_edits = new mutable.ListBuffer[Document.Edit_Command]
   178       val doc_edits = new mutable.ListBuffer[Document.Edit_Command]
   194       val header_edits = new mutable.ListBuffer[(String, Thy_Header.Header)]
       
   195       var nodes = previous.nodes
   179       var nodes = previous.nodes
   196 
   180 
   197       edits foreach {
   181       edits foreach {
   198         case (name, Document.Node.Remove()) =>
   182         case (name, Document.Node.Remove()) =>
   199           doc_edits += (name -> Document.Node.Remove())
   183           doc_edits += (name -> Document.Node.Remove())
   211           val cmd_edits =
   195           val cmd_edits =
   212             removed_commands.reverse.map(cmd => (commands0.prev(cmd), None)) :::
   196             removed_commands.reverse.map(cmd => (commands0.prev(cmd), None)) :::
   213             inserted_commands.map(cmd => (commands2.prev(cmd), Some(cmd)))
   197             inserted_commands.map(cmd => (commands2.prev(cmd), Some(cmd)))
   214 
   198 
   215           doc_edits += (name -> Document.Node.Edits(cmd_edits))
   199           doc_edits += (name -> Document.Node.Edits(cmd_edits))
   216 
   200           nodes += (name -> node.copy(commands = commands2))
   217           val (new_headers, new_header) = node_header(name, node)
   201 
   218           header_edits ++= new_headers
   202         case (name, Document.Node.Update_Header(header)) =>
   219 
   203           val node = nodes(name)
   220           nodes += (name -> Document.Node(new_header, node.blobs, commands2))
   204           val update_header =
   221       }
   205             (node.header.thy_header, header) match {
   222       (doc_edits.toList, header_edits.toList, Document.Version(Document.new_id(), nodes))
   206               case (Exn.Res(thy_header0), Document.Node.Header(_, Exn.Res(thy_header)))
       
   207               if thy_header0 != thy_header => true
       
   208               case (Exn.Exn(_), Document.Node.Header(_, Exn.Res(thy_header))) => true
       
   209             }
       
   210           if (update_header) doc_edits += (name -> Document.Node.Update_Header(header))
       
   211       }
       
   212       (doc_edits.toList, Document.Version(Document.new_id(), nodes))
   223     }
   213     }
   224   }
   214   }
   225 }
   215 }