| author | wenzelm | 
| Sun, 08 Aug 2010 20:03:31 +0200 | |
| changeset 38238 | 43c13eb0d842 | 
| parent 38227 | 6bbb42843b6e | 
| child 38355 | 8cb265fb12fe | 
| permissions | -rw-r--r-- | 
| 36676 | 1 | /* Title: Pure/PIDE/document.scala | 
| 2 | Author: Makarius | |
| 3 | ||
| 38150 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 4 | Document as collection of named nodes, each consisting of an editable | 
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 5 | list of commands. | 
| 36676 | 6 | */ | 
| 34407 | 7 | |
| 34871 
e596a0b71f3c
incorporate "proofdocument" part into main Isabelle/Pure.jar -- except for html_panel.scala, which depends on external library (Lobo/Cobra browser);
 wenzelm parents: 
34868diff
changeset | 8 | package isabelle | 
| 34318 
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
 wenzelm parents: diff
changeset | 9 | |
| 34760 | 10 | |
| 38150 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 11 | import scala.collection.mutable | 
| 37073 | 12 | import scala.annotation.tailrec | 
| 13 | ||
| 14 | ||
| 34823 | 15 | object Document | 
| 34483 | 16 | {
 | 
| 38227 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 17 | /* formal identifiers */ | 
| 38150 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 18 | |
| 38227 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 19 | type Version_ID = String | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 20 | type Command_ID = String | 
| 38150 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 21 | type State_ID = String | 
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 22 | |
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 23 | val NO_ID = "" | 
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 24 | |
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 25 | |
| 34818 
7df68a8f0e3e
register Proof_Document instances as session entities -- handle Markup.EDIT messages locally;
 wenzelm parents: 
34815diff
changeset | 26 | |
| 38227 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 27 | /** named document nodes **/ | 
| 38151 | 28 | |
| 29 | object Node | |
| 30 |   {
 | |
| 31 | val empty: Node = new Node(Linear_Set()) | |
| 38227 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 32 | |
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 33 | def command_starts(commands: Iterator[Command], offset: Int = 0): Iterator[(Command, Int)] = | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 34 |     {
 | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 35 | var i = offset | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 36 |       for (command <- commands) yield {
 | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 37 | val start = i | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 38 | i += command.length | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 39 | (command, start) | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 40 | } | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 41 | } | 
| 38151 | 42 | } | 
| 43 | ||
| 44 | class Node(val commands: Linear_Set[Command]) | |
| 45 |   {
 | |
| 46 | /* command ranges */ | |
| 47 | ||
| 48 | def command_starts: Iterator[(Command, Int)] = | |
| 38227 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 49 | Node.command_starts(commands.iterator) | 
| 38151 | 50 | |
| 51 | def command_start(cmd: Command): Option[Int] = | |
| 52 | command_starts.find(_._1 == cmd).map(_._2) | |
| 53 | ||
| 54 | def command_range(i: Int): Iterator[(Command, Int)] = | |
| 55 |       command_starts dropWhile { case (cmd, start) => start + cmd.length <= i }
 | |
| 56 | ||
| 57 | def command_range(i: Int, j: Int): Iterator[(Command, Int)] = | |
| 58 |       command_range(i) takeWhile { case (_, start) => start < j }
 | |
| 59 | ||
| 60 | def command_at(i: Int): Option[(Command, Int)] = | |
| 61 |     {
 | |
| 62 | val range = command_range(i) | |
| 63 | if (range.hasNext) Some(range.next) else None | |
| 64 | } | |
| 65 | ||
| 66 | def proper_command_at(i: Int): Option[Command] = | |
| 67 |       command_at(i) match {
 | |
| 68 | case Some((command, _)) => | |
| 69 | commands.reverse_iterator(command).find(cmd => !cmd.is_ignored) | |
| 70 | case None => None | |
| 71 | } | |
| 72 | } | |
| 73 | ||
| 74 | ||
| 38150 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 75 | /* initial document */ | 
| 34485 | 76 | |
| 38150 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 77 | val init: Document = | 
| 34835 
67733fd0e3fa
back to explicit management of documents -- not as generic Session.Entity -- to avoid ill-defined referencing of new states;
 wenzelm parents: 
34832diff
changeset | 78 |   {
 | 
| 38151 | 79 | val doc = new Document(NO_ID, Map().withDefaultValue(Node.empty), Map()) | 
| 34835 
67733fd0e3fa
back to explicit management of documents -- not as generic Session.Entity -- to avoid ill-defined referencing of new states;
 wenzelm parents: 
34832diff
changeset | 80 | doc.assign_states(Nil) | 
| 
67733fd0e3fa
back to explicit management of documents -- not as generic Session.Entity -- to avoid ill-defined referencing of new states;
 wenzelm parents: 
34832diff
changeset | 81 | doc | 
| 
67733fd0e3fa
back to explicit management of documents -- not as generic Session.Entity -- to avoid ill-defined referencing of new states;
 wenzelm parents: 
34832diff
changeset | 82 | } | 
| 34660 | 83 | |
| 34859 | 84 | |
| 85 | ||
| 38227 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 86 | /** changes of plain text, eventually resulting in document edits **/ | 
| 38151 | 87 | |
| 88 | type Node_Text_Edit = (String, List[Text_Edit]) // FIXME None: remove | |
| 89 | ||
| 90 | type Edit[C] = | |
| 91 | (String, // node name | |
| 92 | Option[List[(Option[C], Option[C])]]) // None: remove, Some: insert/remove commands | |
| 34859 | 93 | |
| 38227 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 94 | abstract class Snapshot | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 95 |   {
 | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 96 | val document: Document | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 97 | val node: Document.Node | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 98 | val is_outdated: Boolean | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 99 | def convert(offset: Int): Int | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 100 | def revert(offset: Int): Int | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 101 | } | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 102 | |
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 103 | object Change | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 104 |   {
 | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 105 | val init = new Change(NO_ID, None, Nil, Future.value(Nil, Document.init)) | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 106 | } | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 107 | |
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 108 | class Change( | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 109 | val id: Version_ID, | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 110 | val parent: Option[Change], | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 111 | val edits: List[Node_Text_Edit], | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 112 | val result: Future[(List[Edit[Command]], Document)]) | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 113 |   {
 | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 114 | def ancestors: Iterator[Change] = new Iterator[Change] | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 115 |     {
 | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 116 | private var state: Option[Change] = Some(Change.this) | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 117 | def hasNext = state.isDefined | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 118 | def next = | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 119 |         state match {
 | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 120 | case Some(change) => state = change.parent; change | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 121 |           case None => throw new NoSuchElementException("next on empty iterator")
 | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 122 | } | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 123 | } | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 124 | |
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 125 | def join_document: Document = result.join._2 | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 126 | def is_assigned: Boolean = result.is_finished && join_document.assignment.is_finished | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 127 | |
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 128 | def snapshot(name: String, pending_edits: List[Text_Edit]): Snapshot = | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 129 |     {
 | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 130 | val latest = Change.this | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 131 | val stable = latest.ancestors.find(_.is_assigned) | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 132 | require(stable.isDefined) | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 133 | |
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 134 | val edits = | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 135 | (pending_edits /: latest.ancestors.takeWhile(_ != stable.get))((edits, change) => | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 136 | (for ((a, eds) <- change.edits if a == name) yield eds).flatten ::: edits) | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 137 | lazy val reverse_edits = edits.reverse | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 138 | |
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 139 |       new Snapshot {
 | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 140 | val document = stable.get.join_document | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 141 | val node = document.nodes(name) | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 142 | val is_outdated = !(pending_edits.isEmpty && latest == stable.get) | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 143 | def convert(offset: Int): Int = (offset /: edits)((i, edit) => edit.convert(i)) | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 144 | def revert(offset: Int): Int = (offset /: reverse_edits)((i, edit) => edit.revert(i)) | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 145 | } | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 146 | } | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 147 | } | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 148 | |
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 149 | |
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 150 | |
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 151 | /** editing **/ | 
| 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 152 | |
| 38150 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 153 | def text_edits(session: Session, old_doc: Document, new_id: Version_ID, | 
| 38151 | 154 | edits: List[Node_Text_Edit]): (List[Edit[Command]], Document) = | 
| 34824 
ac35eee85f5c
renamed current_document to recent_document (might be a bit older than current_change);
 wenzelm parents: 
34823diff
changeset | 155 |   {
 | 
| 34840 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 156 | require(old_doc.assignment.is_finished) | 
| 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 157 | |
| 34859 | 158 | |
| 159 | /* unparsed dummy commands */ | |
| 34538 
20bfcca24658
Prover as actor managing ProofDocument-versions (removed EventBus structural_changes);
 immler@in.tum.de parents: 
34532diff
changeset | 160 | |
| 34859 | 161 | def unparsed(source: String) = | 
| 38220 | 162 | new Command(NO_ID, List(Token(Token.Kind.UNPARSED, source))) | 
| 34859 | 163 | |
| 38220 | 164 | def is_unparsed(command: Command) = command.id == NO_ID | 
| 34835 
67733fd0e3fa
back to explicit management of documents -- not as generic Session.Entity -- to avoid ill-defined referencing of new states;
 wenzelm parents: 
34832diff
changeset | 165 | |
| 34859 | 166 | |
| 167 | /* phase 1: edit individual command source */ | |
| 168 | ||
| 38150 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 169 | @tailrec def edit_text(eds: List[Text_Edit], | 
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 170 | commands: Linear_Set[Command]): Linear_Set[Command] = | 
| 34859 | 171 |     {
 | 
| 172 |       eds match {
 | |
| 173 | case e :: es => | |
| 38227 
6bbb42843b6e
concentrate structural document notions in document.scala;
 wenzelm parents: 
38220diff
changeset | 174 |           Node.command_starts(commands.iterator).find {
 | 
| 34866 
a4fe43df58b3
new unparsed span for text right after existing command;
 wenzelm parents: 
34863diff
changeset | 175 | case (cmd, cmd_start) => | 
| 37685 
305c326db33b
more efficient document model/view -- avoid repeated iteration over commands from start, prefer bulk operations;
 wenzelm parents: 
37186diff
changeset | 176 | e.can_edit(cmd.source, cmd_start) || | 
| 
305c326db33b
more efficient document model/view -- avoid repeated iteration over commands from start, prefer bulk operations;
 wenzelm parents: 
37186diff
changeset | 177 | e.is_insert && e.start == cmd_start + cmd.length | 
| 34863 | 178 |           } match {
 | 
| 34866 
a4fe43df58b3
new unparsed span for text right after existing command;
 wenzelm parents: 
34863diff
changeset | 179 | case Some((cmd, cmd_start)) if e.can_edit(cmd.source, cmd_start) => | 
| 
a4fe43df58b3
new unparsed span for text right after existing command;
 wenzelm parents: 
34863diff
changeset | 180 | val (rest, text) = e.edit(cmd.source, cmd_start) | 
| 
a4fe43df58b3
new unparsed span for text right after existing command;
 wenzelm parents: 
34863diff
changeset | 181 | val new_commands = commands.insert_after(Some(cmd), unparsed(text)) - cmd | 
| 34863 | 182 | edit_text(rest.toList ::: es, new_commands) | 
| 34318 
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
 wenzelm parents: diff
changeset | 183 | |
| 34866 
a4fe43df58b3
new unparsed span for text right after existing command;
 wenzelm parents: 
34863diff
changeset | 184 | case Some((cmd, cmd_start)) => | 
| 
a4fe43df58b3
new unparsed span for text right after existing command;
 wenzelm parents: 
34863diff
changeset | 185 | edit_text(es, commands.insert_after(Some(cmd), unparsed(e.text))) | 
| 
a4fe43df58b3
new unparsed span for text right after existing command;
 wenzelm parents: 
34863diff
changeset | 186 | |
| 34859 | 187 | case None => | 
| 34866 
a4fe43df58b3
new unparsed span for text right after existing command;
 wenzelm parents: 
34863diff
changeset | 188 | require(e.is_insert && e.start == 0) | 
| 34863 | 189 | edit_text(es, commands.insert_after(None, unparsed(e.text))) | 
| 34859 | 190 | } | 
| 34863 | 191 | case Nil => commands | 
| 34318 
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
 wenzelm parents: diff
changeset | 192 | } | 
| 
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
 wenzelm parents: diff
changeset | 193 | } | 
| 34582 | 194 | |
| 34818 
7df68a8f0e3e
register Proof_Document instances as session entities -- handle Markup.EDIT messages locally;
 wenzelm parents: 
34815diff
changeset | 195 | |
| 34866 
a4fe43df58b3
new unparsed span for text right after existing command;
 wenzelm parents: 
34863diff
changeset | 196 | /* phase 2: recover command spans */ | 
| 34859 | 197 | |
| 37073 | 198 | @tailrec def parse_spans(commands: Linear_Set[Command]): Linear_Set[Command] = | 
| 34859 | 199 |     {
 | 
| 36011 
3ff725ac13a4
adapted to Scala 2.8.0 Beta1 -- with notable changes to scala.collection;
 wenzelm parents: 
34871diff
changeset | 200 |       commands.iterator.find(is_unparsed) match {
 | 
| 34859 | 201 | case Some(first_unparsed) => | 
| 37071 
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
 wenzelm parents: 
37059diff
changeset | 202 | val first = | 
| 37072 
9105c8237c7a
renamed "rev" to "reverse" following usual Scala conventions;
 wenzelm parents: 
37071diff
changeset | 203 | commands.reverse_iterator(first_unparsed).find(_.is_command) getOrElse commands.head | 
| 37071 
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
 wenzelm parents: 
37059diff
changeset | 204 | val last = | 
| 
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
 wenzelm parents: 
37059diff
changeset | 205 | commands.iterator(first_unparsed).find(_.is_command) getOrElse commands.last | 
| 
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
 wenzelm parents: 
37059diff
changeset | 206 | val range = | 
| 
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
 wenzelm parents: 
37059diff
changeset | 207 | commands.iterator(first).takeWhile(_ != last).toList ::: List(last) | 
| 34859 | 208 | |
| 37071 
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
 wenzelm parents: 
37059diff
changeset | 209 | val sources = range.flatMap(_.span.map(_.source)) | 
| 34866 
a4fe43df58b3
new unparsed span for text right after existing command;
 wenzelm parents: 
34863diff
changeset | 210 | val spans0 = Thy_Syntax.parse_spans(session.current_syntax.scan(sources.mkString)) | 
| 34485 | 211 | |
| 34859 | 212 | val (before_edit, spans1) = | 
| 37071 
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
 wenzelm parents: 
37059diff
changeset | 213 | if (!spans0.isEmpty && first.is_command && first.span == spans0.head) | 
| 
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
 wenzelm parents: 
37059diff
changeset | 214 | (Some(first), spans0.tail) | 
| 
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
 wenzelm parents: 
37059diff
changeset | 215 | else (commands.prev(first), spans0) | 
| 34544 
56217d219e27
proofdocument-versions get id from changes
 immler@in.tum.de parents: 
34541diff
changeset | 216 | |
| 34859 | 217 | val (after_edit, spans2) = | 
| 37071 
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
 wenzelm parents: 
37059diff
changeset | 218 | if (!spans1.isEmpty && last.is_command && last.span == spans1.last) | 
| 
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
 wenzelm parents: 
37059diff
changeset | 219 | (Some(last), spans1.take(spans1.length - 1)) | 
| 
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
 wenzelm parents: 
37059diff
changeset | 220 | else (commands.next(last), spans1) | 
| 34859 | 221 | |
| 34863 | 222 | val inserted = spans2.map(span => new Command(session.create_id(), span)) | 
| 223 | val new_commands = | |
| 224 | commands.delete_between(before_edit, after_edit).append_after(before_edit, inserted) | |
| 34866 
a4fe43df58b3
new unparsed span for text right after existing command;
 wenzelm parents: 
34863diff
changeset | 225 | parse_spans(new_commands) | 
| 34485 | 226 | |
| 34863 | 227 | case None => commands | 
| 34485 | 228 | } | 
| 229 | } | |
| 34739 | 230 | |
| 34554 
7dc6c231da40
abs. stops, markup nodes depend on doc-version;
 immler@in.tum.de parents: 
34551diff
changeset | 231 | |
| 34859 | 232 | /* phase 3: resulting document edits */ | 
| 233 | ||
| 38150 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 234 |     {
 | 
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 235 | val doc_edits = new mutable.ListBuffer[Edit[Command]] | 
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 236 | var nodes = old_doc.nodes | 
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 237 | var former_states = old_doc.assignment.join | 
| 34660 | 238 | |
| 38150 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 239 |       for ((name, text_edits) <- edits) {
 | 
| 38151 | 240 | val commands0 = nodes(name).commands | 
| 38150 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 241 | val commands1 = edit_text(text_edits, commands0) | 
| 38220 | 242 | val commands2 = parse_spans(commands1) // FIXME somewhat slow | 
| 34863 | 243 | |
| 38150 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 244 | val removed_commands = commands0.iterator.filter(!commands2.contains(_)).toList | 
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 245 | val inserted_commands = commands2.iterator.filter(!commands0.contains(_)).toList | 
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 246 | |
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 247 | val cmd_edits = | 
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 248 | removed_commands.reverse.map(cmd => (commands0.prev(cmd), None)) ::: | 
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 249 | inserted_commands.map(cmd => (commands2.prev(cmd), Some(cmd))) | 
| 34660 | 250 | |
| 38150 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 251 | doc_edits += (name -> Some(cmd_edits)) | 
| 38151 | 252 | nodes += (name -> new Node(commands2)) | 
| 38150 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 253 | former_states --= removed_commands | 
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 254 | } | 
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 255 | (doc_edits.toList, new Document(new_id, nodes, former_states)) | 
| 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 256 | } | 
| 34485 | 257 | } | 
| 34840 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 258 | } | 
| 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 259 | |
| 34855 
81d0410dc3ac
iterators for ranges of commands/starts -- avoid extra array per document;
 wenzelm parents: 
34853diff
changeset | 260 | |
| 34840 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 261 | class Document( | 
| 38150 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 262 | val id: Document.Version_ID, | 
| 38151 | 263 | val nodes: Map[String, Document.Node], | 
| 38150 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 wenzelm parents: 
37849diff
changeset | 264 | former_states: Map[Command, Command]) // FIXME !? | 
| 34840 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 265 | {
 | 
| 34855 
81d0410dc3ac
iterators for ranges of commands/starts -- avoid extra array per document;
 wenzelm parents: 
34853diff
changeset | 266 | /* command state assignment */ | 
| 34840 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 267 | |
| 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 268 | val assignment = Future.promise[Map[Command, Command]] | 
| 34853 
32b49207ca20
misc tuning and clarification of Document/Change;
 wenzelm parents: 
34840diff
changeset | 269 |   def await_assignment { assignment.join }
 | 
| 34840 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 270 | |
| 34859 | 271 | @volatile private var tmp_states = former_states | 
| 34840 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 272 | |
| 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 273 | def assign_states(new_states: List[(Command, Command)]) | 
| 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 274 |   {
 | 
| 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 275 | assignment.fulfill(tmp_states ++ new_states) | 
| 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 276 | tmp_states = Map() | 
| 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 277 | } | 
| 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 278 | |
| 36990 
449628c148cf
explicit Command.Status.UNDEFINED -- avoid fragile/cumbersome treatment of Option[State];
 wenzelm parents: 
36956diff
changeset | 279 | def current_state(cmd: Command): State = | 
| 34840 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 280 |   {
 | 
| 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 281 | require(assignment.is_finished) | 
| 36990 
449628c148cf
explicit Command.Status.UNDEFINED -- avoid fragile/cumbersome treatment of Option[State];
 wenzelm parents: 
36956diff
changeset | 282 |     (assignment.join).get(cmd) match {
 | 
| 
449628c148cf
explicit Command.Status.UNDEFINED -- avoid fragile/cumbersome treatment of Option[State];
 wenzelm parents: 
36956diff
changeset | 283 | case Some(cmd_state) => cmd_state.current_state | 
| 37186 
349e9223c685
explicit markup for forked goals, as indicated by Goal.fork;
 wenzelm parents: 
37073diff
changeset | 284 | case None => new State(cmd, Command.Status.UNDEFINED, 0, Nil, cmd.empty_markup) | 
| 36990 
449628c148cf
explicit Command.Status.UNDEFINED -- avoid fragile/cumbersome treatment of Option[State];
 wenzelm parents: 
36956diff
changeset | 285 | } | 
| 34840 
6c5560d48561
more precise treatment of document/state assigment;
 wenzelm parents: 
34838diff
changeset | 286 | } | 
| 34318 
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
 wenzelm parents: diff
changeset | 287 | } |