author | wenzelm |
Sat, 17 Oct 2009 17:18:59 +0200 | |
changeset 32971 | 55ba9b6648ef |
parent 32793 | 24ba50c14ec5 |
child 33223 | d27956b4d3b4 |
permissions | -rw-r--r-- |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
1 |
(* Title: Pure/Isar/isar_document.ML |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
2 |
Author: Makarius |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
3 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
4 |
Interactive Isar documents. |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
5 |
*) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
6 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
7 |
signature ISAR_DOCUMENT = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
8 |
sig |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
9 |
type state_id = string |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
10 |
type command_id = string |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
11 |
type document_id = string |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
12 |
val define_command: command_id -> Toplevel.transition -> unit |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
13 |
val begin_document: document_id -> Path.T -> unit |
29468 | 14 |
val end_document: document_id -> unit |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
15 |
val edit_document: document_id -> document_id -> (command_id * command_id option) list -> unit |
32793 | 16 |
val init: unit -> unit |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
17 |
end; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
18 |
|
32467 | 19 |
structure Isar_Document: ISAR_DOCUMENT = |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
20 |
struct |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
21 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
22 |
(* unique identifiers *) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
23 |
|
29484 | 24 |
type state_id = string; |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
25 |
type command_id = string; |
29484 | 26 |
type document_id = string; |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
27 |
|
31443 | 28 |
fun make_id () = "i" ^ serial_string (); |
29467 | 29 |
|
30 |
fun err_dup kind id = error ("Duplicate " ^ kind ^ ": " ^ quote id); |
|
31 |
fun err_undef kind id = error ("Unknown " ^ kind ^ ": " ^ quote id); |
|
32 |
||
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
33 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
34 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
35 |
(** documents **) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
36 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
37 |
(* command entries *) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
38 |
|
29484 | 39 |
datatype entry = Entry of {next: command_id option, state: state_id option}; |
40 |
fun make_entry next state = Entry {next = next, state = state}; |
|
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
41 |
|
29467 | 42 |
fun the_entry entries (id: command_id) = |
43 |
(case Symtab.lookup entries id of |
|
44 |
NONE => err_undef "document entry" id |
|
45 |
| SOME (Entry entry) => entry); |
|
46 |
||
47 |
fun put_entry (id: command_id, entry: entry) = Symtab.update (id, entry); |
|
48 |
||
29489
5dfe03f423c4
edit_document: proper edits/edit markup, including the document id;
wenzelm
parents:
29487
diff
changeset
|
49 |
fun put_entry_state (id: command_id) state entries = |
5dfe03f423c4
edit_document: proper edits/edit markup, including the document id;
wenzelm
parents:
29487
diff
changeset
|
50 |
let val {next, ...} = the_entry entries id |
5dfe03f423c4
edit_document: proper edits/edit markup, including the document id;
wenzelm
parents:
29487
diff
changeset
|
51 |
in put_entry (id, make_entry next state) entries end; |
5dfe03f423c4
edit_document: proper edits/edit markup, including the document id;
wenzelm
parents:
29487
diff
changeset
|
52 |
|
29490 | 53 |
fun reset_entry_state id = put_entry_state id NONE; |
54 |
fun set_entry_state (id, state_id) = put_entry_state id (SOME state_id); |
|
29489
5dfe03f423c4
edit_document: proper edits/edit markup, including the document id;
wenzelm
parents:
29487
diff
changeset
|
55 |
|
5dfe03f423c4
edit_document: proper edits/edit markup, including the document id;
wenzelm
parents:
29487
diff
changeset
|
56 |
|
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
57 |
(* document *) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
58 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
59 |
datatype document = Document of |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
60 |
{dir: Path.T, (*master directory*) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
61 |
name: string, (*theory name*) |
29467 | 62 |
start: command_id, (*empty start command*) |
63 |
entries: entry Symtab.table}; (*unique command entries indexed by command_id*) |
|
64 |
||
65 |
fun make_document dir name start entries = |
|
66 |
Document {dir = dir, name = name, start = start, entries = entries}; |
|
67 |
||
68 |
fun map_entries f (Document {dir, name, start, entries}) = |
|
69 |
make_document dir name start (f entries); |
|
70 |
||
71 |
||
29484 | 72 |
(* iterate entries *) |
29468 | 73 |
|
29507 | 74 |
fun fold_entries id0 f (Document {entries, ...}) = |
29468 | 75 |
let |
76 |
fun apply NONE x = x |
|
29507 | 77 |
| apply (SOME id) x = |
78 |
let val entry = the_entry entries id |
|
79 |
in apply (#next entry) (f (id, entry) x) end; |
|
80 |
in if Symtab.defined entries id0 then apply (SOME id0) else I end; |
|
29468 | 81 |
|
29507 | 82 |
fun first_entry P (Document {start, entries, ...}) = |
29467 | 83 |
let |
29517 | 84 |
fun first _ NONE = NONE |
85 |
| first prev (SOME id) = |
|
29507 | 86 |
let val entry = the_entry entries id |
29519 | 87 |
in if P (id, entry) then SOME (prev, id, entry) else first (SOME id) (#next entry) end; |
29517 | 88 |
in first NONE (SOME start) end; |
29468 | 89 |
|
90 |
||
91 |
(* modify entries *) |
|
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
92 |
|
29484 | 93 |
fun insert_after (id: command_id) (id2: command_id) = map_entries (fn entries => |
94 |
let val {next, state} = the_entry entries id in |
|
95 |
entries |
|
96 |
|> put_entry (id, make_entry (SOME id2) state) |
|
97 |
|> put_entry (id2, make_entry next NONE) |
|
29467 | 98 |
end); |
99 |
||
29468 | 100 |
fun delete_after (id: command_id) = map_entries (fn entries => |
29484 | 101 |
let val {next, state} = the_entry entries id in |
102 |
(case next of |
|
103 |
NONE => error ("No next entry to delete: " ^ quote id) |
|
104 |
| SOME id2 => |
|
105 |
entries |> |
|
29467 | 106 |
(case #next (the_entry entries id2) of |
29484 | 107 |
NONE => put_entry (id, make_entry NONE state) |
29490 | 108 |
| SOME id3 => put_entry (id, make_entry (SOME id3) state) #> reset_entry_state id3)) |
29467 | 109 |
end); |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
110 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
111 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
112 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
113 |
(** global configuration **) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
114 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
115 |
local |
32738 | 116 |
val global_states = Unsynchronized.ref (Symtab.empty: Toplevel.state option future Symtab.table); |
117 |
val global_commands = Unsynchronized.ref (Symtab.empty: Toplevel.transition Symtab.table); |
|
118 |
val global_documents = Unsynchronized.ref (Symtab.empty: document Symtab.table); |
|
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
119 |
in |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
120 |
|
32738 | 121 |
fun change_states f = NAMED_CRITICAL "Isar" (fn () => Unsynchronized.change global_states f); |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
122 |
fun get_states () = NAMED_CRITICAL "Isar" (fn () => ! global_states); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
123 |
|
32738 | 124 |
fun change_commands f = NAMED_CRITICAL "Isar" (fn () => Unsynchronized.change global_commands f); |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
125 |
fun get_commands () = NAMED_CRITICAL "Isar" (fn () => ! global_commands); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
126 |
|
32738 | 127 |
fun change_documents f = NAMED_CRITICAL "Isar" (fn () => Unsynchronized.change global_documents f); |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
128 |
fun get_documents () = NAMED_CRITICAL "Isar" (fn () => ! global_documents); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
129 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
130 |
fun init () = NAMED_CRITICAL "Isar" (fn () => |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
131 |
(global_states := Symtab.empty; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
132 |
global_commands := Symtab.empty; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
133 |
global_documents := Symtab.empty)); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
134 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
135 |
end; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
136 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
137 |
|
29520 | 138 |
(* state *) |
139 |
||
140 |
val empty_state = Future.value (SOME Toplevel.toplevel); |
|
141 |
||
142 |
fun define_state (id: state_id) = |
|
143 |
change_states (Symtab.update_new (id, empty_state)) |
|
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
144 |
handle Symtab.DUP dup => err_dup "state" dup; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
145 |
|
29520 | 146 |
fun put_state (id: state_id) state = change_states (Symtab.update (id, state)); |
147 |
||
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
148 |
fun the_state (id: state_id) = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
149 |
(case Symtab.lookup (get_states ()) id of |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
150 |
NONE => err_undef "state" id |
29484 | 151 |
| SOME state => state); |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
152 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
153 |
|
29520 | 154 |
(* command *) |
155 |
||
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
156 |
fun define_command id tr = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
157 |
change_commands (Symtab.update_new (id, Toplevel.put_id id tr)) |
29484 | 158 |
handle Symtab.DUP dup => err_dup "command" dup; |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
159 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
160 |
fun the_command (id: command_id) = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
161 |
(case Symtab.lookup (get_commands ()) id of |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
162 |
NONE => err_undef "command" id |
29468 | 163 |
| SOME tr => tr); |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
164 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
165 |
|
29520 | 166 |
(* document *) |
167 |
||
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
168 |
fun define_document (id: document_id) document = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
169 |
change_documents (Symtab.update_new (id, document)) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
170 |
handle Symtab.DUP dup => err_dup "document" dup; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
171 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
172 |
fun the_document (id: document_id) = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
173 |
(case Symtab.lookup (get_documents ()) id of |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
174 |
NONE => err_undef "document" id |
29517 | 175 |
| SOME document => document); |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
176 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
177 |
|
29520 | 178 |
|
179 |
(** main operations **) |
|
180 |
||
29468 | 181 |
(* begin/end document *) |
29467 | 182 |
|
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
183 |
fun begin_document (id: document_id) path = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
184 |
let |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
185 |
val (dir, name) = ThyLoad.split_thy_path path; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
186 |
val _ = define_command id Toplevel.empty; |
29520 | 187 |
val _ = define_state id; |
29484 | 188 |
val entries = Symtab.make [(id, make_entry NONE (SOME id))]; |
29467 | 189 |
val _ = define_document id (make_document dir name id entries); |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
190 |
in () end; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
191 |
|
29519 | 192 |
fun end_document (id: document_id) = |
193 |
let |
|
194 |
val document as Document {name, ...} = the_document id; |
|
195 |
val end_state = |
|
196 |
the_state (the (#state (#3 (the |
|
197 |
(first_entry (fn (_, {next, ...}) => is_none next) document))))); |
|
198 |
val _ = |
|
199 |
Future.fork_deps [end_state] (fn () => |
|
200 |
(case Future.join end_state of |
|
201 |
SOME st => |
|
202 |
(Toplevel.run_command name (Toplevel.put_id id (Toplevel.commit_exit Position.none)) st; |
|
203 |
ThyInfo.touch_child_thys name; |
|
204 |
ThyInfo.register_thy name) |
|
29520 | 205 |
| NONE => error ("Failed to finish theory " ^ quote name))); |
29519 | 206 |
in () end; |
29468 | 207 |
|
208 |
||
209 |
(* document editing *) |
|
210 |
||
29507 | 211 |
local |
212 |
||
213 |
fun is_changed entries' (id, {next = _, state}) = |
|
214 |
(case try (the_entry entries') id of |
|
29517 | 215 |
NONE => true |
216 |
| SOME {next = _, state = state'} => state' <> state); |
|
29507 | 217 |
|
29517 | 218 |
fun new_state name (id, _) (state_id, updates) = |
29507 | 219 |
let |
29520 | 220 |
val state_id' = make_id (); |
221 |
val _ = define_state state_id'; |
|
29517 | 222 |
val tr = Toplevel.put_id state_id' (the_command id); |
29520 | 223 |
fun make_state' () = |
224 |
let |
|
225 |
val state = the_state state_id; |
|
226 |
val state' = |
|
227 |
Future.fork_deps [state] (fn () => |
|
228 |
(case Future.join state of |
|
229 |
NONE => NONE |
|
230 |
| SOME st => Toplevel.run_command name tr st)); |
|
231 |
in put_state state_id' state' end; |
|
232 |
in (state_id', ((id, state_id'), make_state') :: updates) end; |
|
29468 | 233 |
|
29489
5dfe03f423c4
edit_document: proper edits/edit markup, including the document id;
wenzelm
parents:
29487
diff
changeset
|
234 |
fun report_updates _ [] = () |
5dfe03f423c4
edit_document: proper edits/edit markup, including the document id;
wenzelm
parents:
29487
diff
changeset
|
235 |
| report_updates (document_id: document_id) updates = |
5dfe03f423c4
edit_document: proper edits/edit markup, including the document id;
wenzelm
parents:
29487
diff
changeset
|
236 |
implode (map (fn (id, state_id) => Markup.markup (Markup.edit id state_id) "") updates) |
5dfe03f423c4
edit_document: proper edits/edit markup, including the document id;
wenzelm
parents:
29487
diff
changeset
|
237 |
|> Markup.markup (Markup.edits document_id) |
5dfe03f423c4
edit_document: proper edits/edit markup, including the document id;
wenzelm
parents:
29487
diff
changeset
|
238 |
|> Output.status; |
5dfe03f423c4
edit_document: proper edits/edit markup, including the document id;
wenzelm
parents:
29487
diff
changeset
|
239 |
|
29507 | 240 |
in |
241 |
||
29520 | 242 |
fun edit_document (old_id: document_id) (new_id: document_id) edits = |
29468 | 243 |
let |
29520 | 244 |
val old_document as Document {name, entries = old_entries, ...} = the_document old_id; |
245 |
val new_document as Document {entries = new_entries, ...} = old_document |
|
246 |
|> fold (fn (id, SOME id2) => insert_after id id2 | (id, NONE) => delete_after id) edits; |
|
247 |
||
248 |
fun cancel_old id = fold_entries id |
|
249 |
(fn (_, {state = SOME state_id, ...}) => K (Future.cancel (the_state state_id)) | _ => K ()) |
|
250 |
old_document (); |
|
251 |
||
252 |
val (updates, new_document') = |
|
253 |
(case first_entry (is_changed old_entries) new_document of |
|
254 |
NONE => |
|
255 |
(case first_entry (is_changed new_entries) old_document of |
|
256 |
NONE => ([], new_document) |
|
257 |
| SOME (_, id, _) => (cancel_old id; ([], new_document))) |
|
258 |
| SOME (prev, id, _) => |
|
259 |
let |
|
260 |
val _ = cancel_old id; |
|
261 |
val prev_state_id = the (#state (the_entry new_entries (the prev))); |
|
262 |
val (_, updates) = fold_entries id (new_state name) new_document (prev_state_id, []); |
|
263 |
val new_document' = new_document |> map_entries (fold (set_entry_state o #1) updates); |
|
264 |
in (rev updates, new_document') end); |
|
265 |
||
266 |
val _ = define_document new_id new_document'; |
|
267 |
val _ = report_updates new_id (map #1 updates); |
|
268 |
val _ = List.app (fn (_, run) => run ()) updates; |
|
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
269 |
in () end; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
270 |
|
29507 | 271 |
end; |
272 |
||
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
273 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
274 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
275 |
(** concrete syntax **) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
276 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
277 |
local structure P = OuterParse structure V = ValueParse in |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
278 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
279 |
val _ = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
280 |
OuterSyntax.internal_command "Isar.define_command" |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
281 |
(P.string -- P.string >> (fn (id, text) => |
32573 | 282 |
Toplevel.position (Position.id_only id) o |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
283 |
Toplevel.imperative (fn () => |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
284 |
define_command id (OuterSyntax.prepare_command (Position.id id) text)))); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
285 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
286 |
val _ = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
287 |
OuterSyntax.internal_command "Isar.begin_document" |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
288 |
(P.string -- P.string >> (fn (id, path) => |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
289 |
Toplevel.imperative (fn () => begin_document id (Path.explode path)))); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
290 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
291 |
val _ = |
29468 | 292 |
OuterSyntax.internal_command "Isar.end_document" |
293 |
(P.string >> (fn id => Toplevel.imperative (fn () => end_document id))); |
|
294 |
||
295 |
val _ = |
|
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
296 |
OuterSyntax.internal_command "Isar.edit_document" |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
297 |
(P.string -- P.string -- V.list (P.string -- (P.string >> SOME) || P.string >> rpair NONE) |
29499
2819ba5f0c32
command 'Isar.edit_document': actually invoke edit_document;
wenzelm
parents:
29490
diff
changeset
|
298 |
>> (fn ((id, new_id), edits) => Toplevel.imperative (fn () => edit_document id new_id edits))); |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
299 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
300 |
end; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
301 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
302 |
end; |
29467 | 303 |