]> matita.cs.unibo.it Git - helm.git/blobdiff - matita/matita/matitaScript.ml
Dead code removed.
[helm.git] / matita / matita / matitaScript.ml
index 04cbb9a8fde4fa493015812b84701ef30390d256..1f05a8837e1e5ecf95fe548839ade424960c73a6 100644 (file)
@@ -66,7 +66,6 @@ let first_line s =
   with Not_found -> s
 
 type guistuff = {
-  mathviewer:MatitaTypes.mathViewer;
   urichooser: NReference.reference list -> NReference.reference list;
   ask_confirmation: title:string -> message:string -> [`YES | `NO | `CANCEL];
 }
@@ -99,28 +98,6 @@ let eval_with_engine include_paths guistuff grafite_status user_goal
   res,"",parsed_text_length
 ;;
 
-(* this function calls the parser in a way that it does not perform inclusions,
- * so that we can ensure the inclusion is performed after the included file 
- * is compiled (if needed). matitac does not need that, since it compiles files
- * in the good order, here files may be compiled on demand. *)
-let wrap_with_make include_paths f x = 
-  match f x with
-     (GrafiteAst.Executable
-       (_,GrafiteAst.NCommand (_,GrafiteAst.Include (_,_,mafilename)))) as cmd
-     ->
-      let root, buri, _, tgt = 
-        try Librarian.baseuri_of_script ~include_paths mafilename
-        with Librarian.NoRootFor _ -> 
-          HLog.error ("The included file '"^mafilename^"' has no root file,");
-          HLog.error "please create it.";
-          raise (Failure ("No root file for "^mafilename))
-      in
-      if MatitacLib.Make.make root [tgt] then
-       cmd
-      else raise (Failure ("Compiling: " ^ tgt))
-   | cmd -> cmd
-;;
-
 let pp_eager_statement_ast = GrafiteAstPp.pp_statement 
 
 let eval_nmacro include_paths (buffer : GText.buffer) guistuff grafite_status user_goal unparsed_text parsed_text script mac =
@@ -134,22 +111,27 @@ let eval_nmacro include_paths (buffer : GText.buffer) guistuff grafite_status us
          let selected = Continuationals.Stack.head_goals status#stack in
          List.filter (fun x,_ -> List.mem x selected) menv         
        in
-       guistuff.mathviewer#screenshot status sequents menv subst name;
+       CicMathView.screenshot status sequents menv subst name;
        [status, parsed_text], "", parsed_text_length
   | TA.NCheck (_,t) ->
       let status = script#grafite_status in
       let _,_,menv,subst,_ = status#obj in
       let ctx = 
-        try let _,(_,ctx,_) = List.hd menv in ctx
-        with Failure "hd" -> []
-      in
+       match Continuationals.Stack.head_goals status#stack with
+          [] -> []
+        | g::tl ->
+           if tl <> [] then
+            HLog.warn
+             "Many goals focused. Using the context of the first one\n";
+           let _, ctx, _ = NCicUtils.lookup_meta g menv in
+            ctx in
       let m, s, status, t = 
         GrafiteDisambiguate.disambiguate_nterm 
           status None ctx menv subst (parsed_text,parsed_text_length,
             NotationPt.Cast (t,NotationPt.Implicit `JustOne))  
           (* XXX use the metasenv, if possible *)
       in
-      guistuff.mathviewer#show_entry (`NCic (t,ctx,m,s));
+      MatitaMathView.show_entry (`NCic (t,ctx,m,s));
       [status, parsed_text], "", parsed_text_length
   | TA.NIntroGuess _loc ->
       let names_ref = ref [] in
@@ -210,12 +192,11 @@ and eval_statement include_paths (buffer : GText.buffer) guistuff
     match statement with
     | `Raw text ->
         if Pcre.pmatch ~rex:only_dust_RE text then raise Margin;
-        let ast = 
-         wrap_with_make include_paths
-          (GrafiteParser.parse_statement grafite_status)
-            (Ulexing.from_utf8_string text)
-        in
-          ast, text
+        let strm =
+         GrafiteParser.parsable_statement grafite_status
+          (Ulexing.from_utf8_string text) in
+        let ast = MatitaEngine.get_ast grafite_status include_paths strm in
+         ast, text
     | `Ast (st, text) -> st, text
   in
   let text_of_loc floc = 
@@ -264,14 +245,28 @@ let fresh_script_id =
   let i = ref 0 in
   fun () -> incr i; !i
 
-class script  ~(source_view: GSourceView2.source_view)
-              ~(mathviewer: MatitaTypes.mathViewer) 
-              ~set_star
-              ~ask_confirmation
-              ~urichooser 
-              () =
+(** Selection handling
+ * Two clipboards are used: "clipboard" and "primary".
+ * "primary" is used by X, when you hit the middle button mouse is content is
+ *    pasted between applications. In Matita this selection always contain the
+ *    textual version of the selected term.
+ * "clipboard" is used inside Matita only and support ATM two different targets:
+ *    "TERM" and "PATTERN", in the future other targets like "MATHMLCONTENT" may
+ *    be added
+ *)
+class script ~ask_confirmation ~urichooser ~(parent:GBin.scrolled_window) ~tab_label () =
+let source_view =
+  GSourceView2.source_view
+    ~auto_indent:true
+    ~insert_spaces_instead_of_tabs:true ~tab_width:2
+    ~right_margin_position:80 ~show_right_margin:true
+    ~smart_home_end:`AFTER
+    ~packing:parent#add_with_viewport
+    () in
 let buffer = source_view#buffer in
 let source_buffer = source_view#source_buffer in
+let similarsymbols_tag_name = "similarsymbolos" in
+let similarsymbols_tag = `NAME similarsymbols_tag_name in
 let initial_statuses current baseuri =
  let empty_lstatus = new GrafiteDisambiguate.status in
  (match current with
@@ -288,31 +283,41 @@ in
 let read_include_paths file =
  try 
    let root, _buri, _fname, _tgt = 
-     Librarian.baseuri_of_script ~include_paths:[] file 
-   in 
-   let rc = 
-    Str.split (Str.regexp " ") 
-     (List.assoc "include_paths" (Librarian.load_root_file (root^"/root")))
+     Librarian.baseuri_of_script ~include_paths:[] file in 
+   let includes =
+    try
+     Str.split (Str.regexp " ") 
+      (List.assoc "include_paths" (Librarian.load_root_file (root^"/root")))
+    with Not_found -> []
    in
-   List.iter (HLog.debug) rc; rc
- with Librarian.NoRootFor _ | Not_found -> []
+   let rc = root :: includes in
+    List.iter (HLog.debug) rc; rc
+ with Librarian.NoRootFor _ | Librarian.FileNotFound _ ->
+  []
 in
 let default_buri = "cic:/matita/tests" in
 let default_fname = ".unnamed.ma" in
 object (self)
   val mutable include_paths_ = []
+  val clipboard = GData.clipboard Gdk.Atom.clipboard
+  (*val primary = GData.clipboard Gdk.Atom.primary*)
+  val mutable similarsymbols = []
+  val mutable similarsymbols_orig = []
+  val similar_memory = Hashtbl.create 97
+  val mutable old_used_memory = false
 
   val scriptId = fresh_script_id ()
 
   val guistuff = {
-    mathviewer = mathviewer;
-    urichooser = urichooser;
+    urichooser = urichooser source_view;
     ask_confirmation = ask_confirmation;
   }
 
   val mutable filename_ = (None : string option)
 
   method has_name = filename_ <> None
+
+  method source_view = source_view
   
   method include_paths =
     include_paths_ @ 
@@ -321,7 +326,7 @@ object (self)
   method private curdir =
     try
      let root, _buri, _fname, _tgt = 
-       Librarian.baseuri_of_script ~include_paths:self#include_paths
+      Librarian.baseuri_of_script ~include_paths:self#include_paths
        self#filename 
      in 
      root
@@ -336,15 +341,111 @@ object (self)
             Librarian.baseuri_of_script ~include_paths:self#include_paths f 
           in 
           buri
-        with Librarian.NoRootFor _ -> default_buri
+        with Librarian.NoRootFor _ | Librarian.FileNotFound _ -> default_buri
 
   method filename = match filename_ with None -> default_fname | Some f -> f
 
   initializer 
+    ignore
+     (source_view#source_buffer#begin_not_undoable_action ();
+      self#reset (); 
+      self#template (); 
+      source_view#source_buffer#end_not_undoable_action ());
+    MatitaMisc.observe_font_size (fun font_size ->
+     source_view#misc#modify_font_by_name
+        (sprintf "%s %d" BuildTimeConf.script_font font_size));
+    source_view#misc#grab_focus ();
+    ignore(source_view#source_buffer#set_language
+     (Some MatitaGtkMisc.matita_lang));
+    ignore(source_view#source_buffer#set_highlight_syntax true);
+    ignore(source_view#connect#after#paste_clipboard 
+        ~callback:(fun () -> self#clean_dirty_lock));
     ignore (GMain.Timeout.add ~ms:300000 
        ~callback:(fun _ -> self#_saveToBackupFile ();true));
     ignore (buffer#connect#modified_changed 
-      (fun _ -> set_star buffer#modified))
+      (fun _ -> self#set_star buffer#modified));
+    (* clean_locked is set to true only "during" a PRIMARY paste
+       operation (i.e. by clicking with the second mouse button) *)
+    let clean_locked = ref false in
+    ignore(source_view#event#connect#button_press
+      ~callback:
+        (fun button ->
+          if GdkEvent.Button.button button = 2 then
+           clean_locked := true;
+          false
+        ));
+    ignore(source_view#event#connect#button_release
+      ~callback:(fun button -> clean_locked := false; false));
+    ignore(source_view#buffer#connect#after#apply_tag
+     ~callback:(
+       fun tag ~start:_ ~stop:_ ->
+        if !clean_locked &&
+           tag#get_oid = self#locked_tag#get_oid
+        then
+         begin
+          clean_locked := false;
+          self#clean_dirty_lock;
+          clean_locked := true
+         end));
+    ignore(source_view#source_buffer#connect#after#insert_text 
+     ~callback:(fun iter str -> 
+        if (MatitaMisc.get_gui ())#main#menuitemAutoAltL#active && (str = " " || str = "\n") then 
+          ignore(self#expand_virtual_if_any iter str)));
+    ignore(source_view#connect#after#populate_popup
+     ~callback:(fun pre_menu ->
+       let menu = new GMenu.menu pre_menu in
+       let menuItems = menu#children in
+       let undoMenuItem, redoMenuItem =
+        match menuItems with
+           [undo;redo;sep1;cut;copy;paste;delete;sep2;
+            selectall;sep3;inputmethod;insertunicodecharacter] ->
+              List.iter menu#remove [ copy; cut; delete; paste ];
+              undo,redo
+         | _ -> assert false in
+       let add_menu_item =
+         let i = ref 2 in (* last occupied position *)
+         fun ?label ?stock () ->
+           incr i;
+           GMenu.image_menu_item ?label ?stock ~packing:(menu#insert ~pos:!i)
+            ()
+       in
+       let copy = add_menu_item ~stock:`COPY () in
+       let cut = add_menu_item ~stock:`CUT () in
+       let delete = add_menu_item ~stock:`DELETE () in
+       let paste = add_menu_item ~stock:`PASTE () in
+       let paste_pattern = add_menu_item ~label:"Paste as pattern" () in
+       copy#misc#set_sensitive self#canCopy;
+       cut#misc#set_sensitive self#canCut;
+       delete#misc#set_sensitive self#canDelete;
+       paste#misc#set_sensitive self#canPaste;
+       paste_pattern#misc#set_sensitive self#canPastePattern;
+       MatitaGtkMisc.connect_menu_item copy self#copy;
+       MatitaGtkMisc.connect_menu_item cut self#cut;
+       MatitaGtkMisc.connect_menu_item delete self#delete;
+       MatitaGtkMisc.connect_menu_item paste self#paste;
+       MatitaGtkMisc.connect_menu_item paste_pattern self#pastePattern;
+       let new_undoMenuItem =
+        GMenu.image_menu_item
+         ~image:(GMisc.image ~stock:`UNDO ())
+         ~use_mnemonic:true
+         ~label:"_Undo"
+         ~packing:(menu#insert ~pos:0) () in
+       new_undoMenuItem#misc#set_sensitive
+        (undoMenuItem#misc#get_flag `SENSITIVE);
+       menu#remove (undoMenuItem :> GMenu.menu_item);
+       MatitaGtkMisc.connect_menu_item new_undoMenuItem
+        (fun () -> self#safe_undo);
+       let new_redoMenuItem =
+        GMenu.image_menu_item
+         ~image:(GMisc.image ~stock:`REDO ())
+         ~use_mnemonic:true
+         ~label:"_Redo"
+         ~packing:(menu#insert ~pos:1) () in
+       new_redoMenuItem#misc#set_sensitive
+        (redoMenuItem#misc#get_flag `SENSITIVE);
+        menu#remove (redoMenuItem :> GMenu.menu_item);
+        MatitaGtkMisc.connect_menu_item new_redoMenuItem
+         (fun () -> self#safe_redo)));
 
   val mutable statements = []    (** executed statements *)
 
@@ -366,6 +467,216 @@ object (self)
   val locked_tag = buffer#create_tag [`BACKGROUND "lightblue"; `EDITABLE false]
   val error_tag = buffer#create_tag [`UNDERLINE `SINGLE; `FOREGROUND "red"]
 
+  (** unicode handling *)
+  method nextSimilarSymbol = 
+    let write_similarsymbol s =
+      let s = Glib.Utf8.from_unichar s in
+      let iter = source_view#source_buffer#get_iter_at_mark `INSERT in
+      assert(Glib.Utf8.validate s);
+      source_view#source_buffer#delete ~start:iter ~stop:(iter#copy#backward_chars 1);
+      source_view#source_buffer#insert ~iter:(source_view#source_buffer#get_iter_at_mark `INSERT) s;
+      (try source_view#source_buffer#delete_mark similarsymbols_tag
+       with GText.No_such_mark _ -> ());
+      ignore(source_view#source_buffer#create_mark ~name:similarsymbols_tag_name
+        (source_view#source_buffer#get_iter_at_mark `INSERT));
+    in
+    let new_similarsymbol =
+      try
+        let iter_ins = source_view#source_buffer#get_iter_at_mark `INSERT in
+        let iter_lig = source_view#source_buffer#get_iter_at_mark similarsymbols_tag in
+        not (iter_ins#equal iter_lig)
+      with GText.No_such_mark _ -> true
+    in
+    if new_similarsymbol then
+      (if not(self#expand_virtual_if_any (source_view#source_buffer#get_iter_at_mark `INSERT) "")then
+        let last_symbol = 
+          let i = source_view#source_buffer#get_iter_at_mark `INSERT in
+          Glib.Utf8.first_char (i#get_slice ~stop:(i#copy#backward_chars 1))
+        in
+        (match Virtuals.similar_symbols last_symbol with
+        | [] ->  ()
+        | eqclass ->
+            similarsymbols_orig <- eqclass;
+            let is_used = 
+              try Hashtbl.find similar_memory similarsymbols_orig  
+              with Not_found -> 
+                let is_used = List.map (fun x -> x,false) eqclass in
+                Hashtbl.add similar_memory eqclass is_used; 
+                is_used
+            in
+            let hd, next, tl = 
+              let used, unused = 
+                List.partition (fun s -> List.assoc s is_used) eqclass 
+              in
+              match used @ unused with a::b::c -> a,b,c | _ -> assert false
+            in
+            let hd, tl = 
+              if hd = last_symbol then next, tl @ [hd] else hd, (next::tl)
+            in
+            old_used_memory <- List.assoc hd is_used;
+            let is_used = 
+              (hd,true) :: List.filter (fun (x,_) -> x <> hd) is_used
+            in
+            Hashtbl.replace similar_memory similarsymbols_orig is_used;
+            write_similarsymbol hd;
+            similarsymbols <- tl @ [ hd ]))
+    else 
+      match similarsymbols with
+      | [] -> ()
+      | hd :: tl ->
+          let is_used = Hashtbl.find similar_memory similarsymbols_orig in
+          let last = HExtlib.list_last tl in
+          let old_used_for_last = old_used_memory in
+          old_used_memory <- List.assoc hd is_used;
+          let is_used = 
+            (hd, true) :: (last,old_used_for_last) ::
+              List.filter (fun (x,_) -> x <> last && x <> hd) is_used 
+          in
+          Hashtbl.replace similar_memory similarsymbols_orig is_used;
+          similarsymbols <- tl @ [ hd ];
+          write_similarsymbol hd
+
+  method private reset_similarsymbols =
+   similarsymbols <- []; 
+   similarsymbols_orig <- []; 
+   try source_view#source_buffer#delete_mark similarsymbols_tag
+   with GText.No_such_mark _ -> ()
+  method private expand_virtual_if_any iter tok =
+    try
+     let len = MatitaGtkMisc.utf8_string_length tok in
+     let last_word =
+      let prev = iter#copy#backward_chars len in
+       prev#get_slice ~stop:(prev#copy#backward_find_char 
+        (fun x -> Glib.Unichar.isspace x || x = Glib.Utf8.first_char "\\"))
+     in
+     let inplaceof, symb = Virtuals.symbol_of_virtual last_word in
+     self#reset_similarsymbols;
+     let s = Glib.Utf8.from_unichar symb in
+     assert(Glib.Utf8.validate s);
+     source_view#source_buffer#delete ~start:iter 
+       ~stop:(iter#copy#backward_chars
+         (MatitaGtkMisc.utf8_string_length inplaceof + len));
+     source_view#source_buffer#insert ~iter
+       (if inplaceof.[0] = '\\' then s else (s ^ tok));
+     true
+    with Virtuals.Not_a_virtual -> false
+    
+  (** selections / clipboards handling *)
+
+  method markupSelected = MatitaMathView.has_selection ()
+  method private textSelected =
+    (source_view#source_buffer#get_iter_at_mark `INSERT)#compare
+      (source_view#source_buffer#get_iter_at_mark `SEL_BOUND) <> 0
+  method private markupStored = MatitaMathView.has_clipboard ()
+  method private textStored = clipboard#text <> None
+  method canCopy = self#textSelected
+  method canCut = self#textSelected
+  method canDelete = self#textSelected
+  (*CSC: WRONG CODE: we should look in the clipboard instead! *)
+  method canPaste = self#markupStored || self#textStored
+  method canPastePattern = self#markupStored
+
+  method safe_undo =
+   (* phase 1: we save the actual status of the marks and we undo *)
+   let locked_mark = `MARK (self#locked_mark) in
+   let locked_iter = source_view#buffer#get_iter_at_mark locked_mark in
+   let locked_iter_offset = locked_iter#offset in
+   let mark2 =
+    `MARK
+      (source_view#buffer#create_mark ~name:"lock_point"
+        ~left_gravity:true locked_iter) in
+   source_view#source_buffer#undo ();
+   (* phase 2: we save the cursor position and we redo, restoring
+      the previous status of all the marks *)
+   let cursor_iter = source_view#buffer#get_iter_at_mark `INSERT in
+   let mark =
+    `MARK
+      (source_view#buffer#create_mark ~name:"undo_point"
+        ~left_gravity:true cursor_iter)
+   in
+    source_view#source_buffer#redo ();
+    let mark_iter = source_view#buffer#get_iter_at_mark mark in
+    let mark2_iter = source_view#buffer#get_iter_at_mark mark2 in
+    let mark2_iter = mark2_iter#set_offset locked_iter_offset in
+     source_view#buffer#move_mark locked_mark ~where:mark2_iter;
+     source_view#buffer#delete_mark mark;
+     source_view#buffer#delete_mark mark2;
+     (* phase 3: if after the undo the cursor was in the locked area,
+        then we move it there again and we perform a goto *)
+     if mark_iter#offset < locked_iter_offset then
+      begin
+       source_view#buffer#move_mark `INSERT ~where:mark_iter;
+       self#goto `Cursor ();
+      end;
+     (* phase 4: we perform again the undo. This time we are sure that
+        the text to undo is not locked *)
+     source_view#source_buffer#undo ();
+     source_view#misc#grab_focus ()
+
+  method safe_redo =
+   (* phase 1: we save the actual status of the marks, we redo and
+      we undo *)
+   let locked_mark = `MARK (self#locked_mark) in
+   let locked_iter = source_view#buffer#get_iter_at_mark locked_mark in
+   let locked_iter_offset = locked_iter#offset in
+   let mark2 =
+    `MARK
+      (source_view#buffer#create_mark ~name:"lock_point"
+        ~left_gravity:true locked_iter) in
+   source_view#source_buffer#redo ();
+   source_view#source_buffer#undo ();
+   (* phase 2: we save the cursor position and we restore
+      the previous status of all the marks *)
+   let cursor_iter = source_view#buffer#get_iter_at_mark `INSERT in
+   let mark =
+    `MARK
+      (source_view#buffer#create_mark ~name:"undo_point"
+        ~left_gravity:true cursor_iter)
+   in
+    let mark_iter = source_view#buffer#get_iter_at_mark mark in
+    let mark2_iter = source_view#buffer#get_iter_at_mark mark2 in
+    let mark2_iter = mark2_iter#set_offset locked_iter_offset in
+     source_view#buffer#move_mark locked_mark ~where:mark2_iter;
+     source_view#buffer#delete_mark mark;
+     source_view#buffer#delete_mark mark2;
+     (* phase 3: if after the undo the cursor is in the locked area,
+        then we move it there again and we perform a goto *)
+     if mark_iter#offset < locked_iter_offset then
+      begin
+       source_view#buffer#move_mark `INSERT ~where:mark_iter;
+       self#goto `Cursor ();
+      end;
+     (* phase 4: we perform again the redo. This time we are sure that
+        the text to redo is not locked *)
+     source_view#source_buffer#redo ();
+     source_view#misc#grab_focus ()
+   
+
+  method copy () =
+   if self#textSelected
+   then begin
+     MatitaMathView.empty_clipboard ();
+     source_view#buffer#copy_clipboard clipboard;
+   end else
+     MatitaMathView.copy_selection ()
+
+  method cut () =
+   source_view#buffer#cut_clipboard clipboard;
+   MatitaMathView.empty_clipboard ()
+
+  method delete () =
+   ignore (source_view#buffer#delete_selection ())
+
+  method paste () =
+    if MatitaMathView.has_clipboard ()
+    then source_view#buffer#insert (MatitaMathView.paste_clipboard `Term)
+    else source_view#buffer#paste_clipboard clipboard;
+    self#clean_dirty_lock
+
+  method pastePattern () =
+    source_view#buffer#insert (MatitaMathView.paste_clipboard `Pattern)
+
   method locked_mark = locked_mark
   method locked_tag = locked_tag
   method error_tag = error_tag
@@ -521,10 +832,8 @@ object (self)
     let grafite_status = self#grafite_status in
     List.iter (fun o -> o grafite_status) observers
 
-  method loadFromString s =
-    buffer#set_text s;
-    self#reset_buffer;
-    buffer#set_modified true
+  method activate =
+    self#notify
 
   method loadFromFile f =
     buffer#set_text (HExtlib.input_file f);
@@ -532,17 +841,23 @@ object (self)
     buffer#set_modified false
 
   method assignFileName file =
-    let file = 
-      match file with 
-      | Some f -> Some (Librarian.absolutize f)
-      | None -> None
-    in
-    filename_ <- file; 
-    include_paths_ <- 
-      (match file with Some file -> read_include_paths file | None -> []);
-    self#reset_buffer;
-    Sys.chdir self#curdir;
-    HLog.debug ("Moving to " ^ Sys.getcwd ())
+   match file with
+      None ->
+       tab_label#set_text default_fname;
+       filename_ <- None;
+       include_paths_ <- [];
+       self#reset_buffer
+    | Some file ->
+       let f = Librarian.absolutize file in
+        tab_label#set_text (Filename.basename f);
+        filename_ <- Some f;
+        include_paths_ <- read_include_paths f;
+        self#reset_buffer
+
+  method set_star b =
+   tab_label#set_text ((if b then "*" else "")^Filename.basename self#filename);
+   tab_label#misc#set_tooltip_text
+    ("URI: " ^ self#buri_of_current_file ^ "\nPATH: " ^ self#filename);
     
   method saveToFile () =
     if self#has_name then
@@ -550,7 +865,7 @@ object (self)
       output_string oc (buffer#get_text ~start:buffer#start_iter
                         ~stop:buffer#end_iter ());
       close_out oc;
-      set_star false;
+      self#set_star false;
       buffer#set_modified false
     else
       HLog.error "Can't save, no filename selected"
@@ -585,7 +900,7 @@ object (self)
     let template = HExtlib.input_file BuildTimeConf.script_template in 
     buffer#insert ~iter:(buffer#get_iter `START) template;
     buffer#set_modified false;
-    set_star false
+    self#set_star false;
 
   method goto (pos: [`Top | `Bottom | `Cursor]) () =
   try  
@@ -683,9 +998,10 @@ object (self)
   method eos = 
     let rec is_there_only_comments lexicon_status s = 
       if Pcre.pmatch ~rex:only_dust_RE s then raise Margin;
-      match
-       GrafiteParser.parse_statement lexicon_status (Ulexing.from_utf8_string s)
-      with
+      let strm =
+       GrafiteParser.parsable_statement lexicon_status
+        (Ulexing.from_utf8_string s)in
+      match GrafiteParser.parse_statement lexicon_status strm with
       | GrafiteAst.Comment (loc,_) -> 
           let _,parsed_text_length = MatitaGtkMisc.utf8_parsed_text s loc in
           (* CSC: why +1 in the following lines ???? *)
@@ -710,17 +1026,32 @@ object (self)
     HLog.debug (sprintf "%d statements:" (List.length statements));
     List.iter HLog.debug statements;
     HLog.debug ("Current file name: " ^ self#filename);
+
+  method has_parent (p : GObj.widget) = parent#coerce#misc#get_oid = p#misc#get_oid
 end
 
-let _script = ref None
+let _script = ref []
 
-let script ~source_view ~mathviewer ~urichooser ~ask_confirmation ~set_star ()
+let script ~urichooser ~ask_confirmation ~parent ~tab_label ()
 =
-  let s = new script 
-    ~source_view ~mathviewer ~ask_confirmation ~urichooser ~set_star () 
-  in
-  _script := Some s;
+  let s = new script ~ask_confirmation ~urichooser ~parent ~tab_label () in
+  _script := s::!_script;
   s
 
-let current () = match !_script with None -> assert false | Some s -> s
+let at_page page =
+ let notebook = (MatitaMisc.get_gui ())#main#scriptNotebook in
+ let parent = notebook#get_nth_page page in
+  try
+   List.find (fun s -> s#has_parent parent) !_script
+  with
+   Not_found -> assert false
+;;
+
+let current () =
+ at_page ((MatitaMisc.get_gui ())#main#scriptNotebook#current_page)
 
+let iter_scripts f = List.iter f !_script;;
+
+let _ =
+ CicMathView.register_matita_script_current (current :> unit -> < advance: ?statement:string -> unit -> unit; grafite_status: GrafiteTypes.status; setGoal: int option -> unit >)
+;;