src/Pure/Isar/isar_document.ML
changeset 34212 8c3e1f73953d
parent 34207 88300168baf8
child 34242 5ccdc8bf3849
equal deleted inserted replaced
34211:686f828548ef 34212:8c3e1f73953d
     2     Author:     Makarius
     2     Author:     Makarius
     3 
     3 
     4 Interactive Isar documents.
     4 Interactive Isar documents.
     5 *)
     5 *)
     6 
     6 
     7 signature ISAR_DOCUMENT =
     7 structure Isar_Document: sig end =
     8 sig
       
     9   type state_id = string
       
    10   type command_id = string
       
    11   type document_id = string
       
    12   val no_id: string
       
    13   val create_id: unit -> string
       
    14   val define_command: command_id -> Toplevel.transition -> unit
       
    15   val begin_document: document_id -> Path.T -> unit
       
    16   val end_document: document_id -> unit
       
    17   val edit_document: document_id -> document_id -> (command_id * command_id option) list -> unit
       
    18 end;
       
    19 
       
    20 structure Isar_Document: ISAR_DOCUMENT =
       
    21 struct
     8 struct
    22 
     9 
    23 (* unique identifiers *)
    10 (* unique identifiers *)
    24 
    11 
    25 type state_id = string;
    12 type state_id = string;
   243               NONE => NONE
   230               NONE => NONE
   244             | SOME st => Toplevel.run_command name tr st));
   231             | SOME st => Toplevel.run_command name tr st));
   245       in put_state state_id' state' end;
   232       in put_state state_id' state' end;
   246   in (state_id', ((id, state_id'), make_state') :: updates) end;
   233   in (state_id', ((id, state_id'), make_state') :: updates) end;
   247 
   234 
   248 fun report_updates _ [] = ()
   235 fun report_updates [] = ()
   249   | report_updates (document_id: document_id) updates =
   236   | report_updates updates =
   250       implode (map (fn (id, state_id) => Markup.markup (Markup.edit id state_id) "") updates)
   237       Output.status
   251       |> Markup.markup (Markup.edits document_id)
   238         (implode (map (fn (id, state_id) => Markup.markup (Markup.edit id state_id) "") updates));
   252       |> Output.status;
       
   253 
   239 
   254 in
   240 in
   255 
   241 
   256 fun edit_document (old_id: document_id) (new_id: document_id) edits =
   242 fun edit_document (old_id: document_id) (new_id: document_id) edits =
   257   NAMED_CRITICAL "Isar" (fn () =>
   243   NAMED_CRITICAL "Isar" (fn () =>
   277               val (_, updates) = fold_entries id (new_state name) new_document (prev_state_id, []);
   263               val (_, updates) = fold_entries id (new_state name) new_document (prev_state_id, []);
   278               val new_document' = new_document |> map_entries (fold (set_entry_state o #1) updates);
   264               val new_document' = new_document |> map_entries (fold (set_entry_state o #1) updates);
   279             in (rev updates, new_document') end);
   265             in (rev updates, new_document') end);
   280 
   266 
   281       val _ = define_document new_id new_document';
   267       val _ = define_document new_id new_document';
   282       val _ = report_updates new_id (map #1 updates);
   268       val _ = report_updates (map #1 updates);
   283       val _ = List.app (fn (_, run) => run ()) updates;
   269       val _ = List.app (fn (_, run) => run ()) updates;
   284     in () end);
   270     in () end);
   285 
   271 
   286 end;
   272 end;
   287 
   273 
   308     (P.string >> (fn id => Toplevel.imperative (fn () => end_document id)));
   294     (P.string >> (fn id => Toplevel.imperative (fn () => end_document id)));
   309 
   295 
   310 val _ =
   296 val _ =
   311   OuterSyntax.internal_command "Isar.edit_document"
   297   OuterSyntax.internal_command "Isar.edit_document"
   312     (P.string -- P.string -- V.list (P.string -- (P.string >> SOME) || P.string >> rpair NONE)
   298     (P.string -- P.string -- V.list (P.string -- (P.string >> SOME) || P.string >> rpair NONE)
   313       >> (fn ((id, new_id), edits) => Toplevel.imperative (fn () => edit_document id new_id edits)));
   299       >> (fn ((id, new_id), edits) =>
   314 
   300         Toplevel.position (Position.id_only new_id) o
   315 end;
   301         Toplevel.imperative (fn () => edit_document id new_id edits)));
   316 
   302 
   317 end;
   303 end;
   318 
   304 
       
   305 end;
       
   306